Скорость пули различна на разных устройствах — Unity Mirror

#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 что намного дешевле. Затем отправка команды каждый кадр обходится чрезвычайно дорого / рассылает спам по сети, поэтому может случиться так, что сеть достигнет предела и сообщения будут задерживаться … что может привести к задержке любых других автоматических компонентов, синхронизирующих положение объектов, поскольку они используют тот же канал связи, что и ваши вызовы RPC

2. Также внутри [Command] вы уже знаете , что вы должны быть хостом/сервером … так что проверка на isServer наличие совершенно излишня

3. @derHugo Как я могу переместить объект в положение касания без использования обновления или мне следует заменить обновление на fixedupdate?

4. Вы должны в основном делать то, что делает NetworkTransform: отправлять данные о местоположении только время от времени (например, каждые 0,1 единицы или 0,1 секунды), а затем на стороне получателя Lerp к последней полученной позиции в Update