#unity3d
Вопрос:
У меня есть игра, в которой она стреляет пулями там, где пользователь касается экрана. Затем я тестирую игру в симуляторе nox и редакторе unity. Моя проблема в том, что локальный игрок, который стреляет пулей, имеет более высокую скорость пули по сравнению с другим сетевым устройством, которое является редактором unity. Я не использовал сетевое преобразование в пуле только для сетевой идентификации.
Вот мой код:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Networking;
using Mirror;
using UnityEngine.EventSystems;
public class ShootHooks : NetworkBehaviour
{
[SerializeField]private GameObject bulletPrefab;
[SerializeField] private float _moveSpeed = 2f;
[SerializeField] private Camera _camera;
public GameObject hook;
private GameObject localPlayer;
public Transform hand;
Vector3 touch_Pos = new Vector3(0, 0, 0);
public bool isReturnHook = false;
uint hookNetId;
private bool isHookMoving = false;
private void Awake()
{
if (!_camera) _camera = Camera.main;
}
private void Start()
{
if (isLocalPlayer == false)
{
return;
}
GameObject hand = transform.GetChild(0).gameObject;
this.CmdInstantiateHook(GetComponent<NetworkIdentity>().netId);
}
void Update()
{
int i = 0;
if (this.isLocalPlayer)
{
while (i < Input.touchCount)
{
Touch t = Input.GetTouch(i);
if (t.phase == TouchPhase.Began)
{
if (!EventSystem.current.IsPointerOverGameObject(t.fingerId))
{
if (!isHookMoving)
{
touch_Pos = _camera.ScreenToWorldPoint(t.position);
isHookMoving = true;
}
}
}
i;
}
if (isHookMoving)
CmdMoveHook(hookNetId, touch_Pos);
}
}
[Command]
private void CmdMoveHook(uint hookNetID, Vector3 touchPosition)
{
if (!isServer)
{
GameObject hook = NetworkIdentity.spawned[hookNetID].gameObject;
hook.transform.position = Vector3.MoveTowards(hook.transform.position, touchPosition, _moveSpeed * Time.deltaTime);
}
else
{
RpcMoveHook(hookNetID, touchPosition);
}
}
[ClientRpc]
private void RpcMoveHook(uint hookNetID, Vector3 touchPosition)
{
GameObject hook = NetworkIdentity.spawned[hookNetID].gameObject;
hook.transform.position = Vector3.MoveTowards(hook.transform.position, touchPosition, _moveSpeed * Time.deltaTime);
}
[TargetRpc]
public void TargetSetUserHook(NetworkConnection target, uint hookNetID)
{
hookNetId = hookNetID;
}
[Command]
void CmdInstantiateHook(uint playerNetID)
{
hook = Instantiate(bulletPrefab, this.transform.position, Quaternion.identity);
hook.GetComponent<HookScript>().parentPlayerNetID = playerNetID;
NetworkServer.Spawn(hook, connectionToClient);
TargetSetUserHook(connectionToClient, hook.GetComponent<NetworkIdentity>().netId);
}
}
Я создал экземпляр пули при запуске, прикрепив ее к руке игрока.
Комментарии:
1. Есть довольно много мелких проблем/замечаний: для начала не используйте
GetTouch
повторно .. скорее повторяйте,Input.touches
что намного дешевле. Затем отправка команды каждый кадр обходится чрезвычайно дорого / рассылает спам по сети, поэтому может случиться так, что сеть достигнет предела и сообщения будут задерживаться … что может привести к задержке любых других автоматических компонентов, синхронизирующих положение объектов, поскольку они используют тот же канал связи, что и ваши вызовы RPC2. Также внутри
[Command]
вы уже знаете , что вы должны быть хостом/сервером … так что проверка наisServer
наличие совершенно излишня3. @derHugo Как я могу переместить объект в положение касания без использования обновления или мне следует заменить обновление на fixedupdate?
4. Вы должны в основном делать то, что делает NetworkTransform: отправлять данные о местоположении только время от времени (например, каждые 0,1 единицы или 0,1 секунды), а затем на стороне получателя
Lerp
к последней полученной позиции вUpdate