Проблема
Вы звоните
[Command]
public void CmdPlaceBlock()
{
GameObject newBlock = Instantiate(blockPrefab, buildPos, Quaternion.identity);
Block tempBlock = bSys.allBlocks[blockSelectCounter];
newBlock.name = tempBlock.blockName + "-Block";
newBlock.GetComponent<MeshRenderer>().material = tempBlock.blockMaterial;
NetworkServer.SpawnWithClientAuthority(newBlock, connectionToClient);
}
без параметра.
A Command
вызывается на клиенте, но выполняетсяна сервере
=> с локальными переменными сервера !
Так, например, buildPos
всегда будет иметь значение по умолчанию 0,0,0
на сервере, поскольку из-за
if(!isLocalPlayer) return;
позже строка
buildPos = new Vector3(Mathf.Round(point.x), Mathf.Round(point.y), Mathf.Round(point.z));
никогда не выполняетсяна сервере.То же самое относится, например, к blockSelectCounter
и, возможно, к другим значениям, от которых зависит CmdPlaceBlock
.
Решение
Вы должны передать клиенту buildPos
значение (а также все другие значения, которые различаются на клиенте и сервере) для команды сервера, поэтому сервер знает, в какую правильную позицию должен быть помещен новый объект:
//...
if (Input.GetMouseButtonDown(0))
{
CmdPlaceBlock(buildPos);
}
//...
[Command]
public void CmdPlaceBlock(Vector3 spawnPosition)
{
GameObject newBlock = Instantiate(blockPrefab, spawnPosition, Quaternion.identity);
Block tempBlock = bSys.allBlocks[blockSelectCounter];
newBlock.name = tempBlock.blockName + "-Block";
newBlock.GetComponent<MeshRenderer>().material = tempBlock.blockMaterial;
NetworkServer.SpawnWithClientAuthority(newBlock, connectionToClient);
}
Я добавил только пример дляЗнание позиции всегда будет отличаться на клиенте и сервере.Но это также может относиться к другим вашим значениям, таким как, например, blockSelectCounter
.
. Сделайте это изменение для всех значений, которые должны быть значениями клиента и , а не значениями сервера.
Обратите внимание, что типы, которые можно передавать между сетевыми методами, ограничены!Вы не можете передавать, например, любые ссылки на компоненты.
Допустимые типы аргументов:
- Базовый тип (byte, int, float, string, UInt64 и т. Д.)
- Встроенный математический тип Unity (Vector3, Quaternion и т. Д.),
- Массивы основных типов
- Структуры, содержащие допустимые типы
- NetworkIdentity
- NetworkInstanceId
- NetworkHash128
- GameObject с подключенным компонентом NetworkIdentity.
Дополнительные подсказки
Для удобства чтения и количества строк вы должны изменить такие вещи, как, например,
if (buildModeOn)
{
// weapon.SetActive(false);
crossHairOn = true;
}
else
{
// weapon.SetActive(true);
crossHairOn = false;
}
на просто
// weapon.SetActive(!buildModeOn);
crossHairOn = buildModeOn;
и проверять bools не как
if (isLocalPlayer == false)
, а скорее
if(!isLocalPlayer)
Просто читать / писать проще;)