客户端和服务器都返回Input.mousePosition

问题描述 投票:0回答:1

给出此代码:

using Mirror;
using UnityEngine;
using Vector3 = UnityEngine.Vector3;

public class InteractableObject : NetworkBehaviour
{
    public float offsetHeight = 0.2f;

    private bool isBeingHeld = false;
    private Rigidbody rb;

    void Start()
    {
        rb = GetComponent<Rigidbody>();
    }

    
    void Update()
    {
        if (Input.GetMouseButtonDown(0))
        {
            // Verifique se o clique do mouse ocorreu neste objeto
            if (CheckMouseHit())
            {
                // Comece a segurar o objeto
                CmdStartHoldObject();
            }
        }

        if (isBeingHeld)
        {
            // Atualize a posição do objeto para seguir o mouse
            Vector3 newPosition = GetMouseWorldPosition();
            CmdMoveObject(newPosition);
            if (Input.GetMouseButtonUp(0))
            {
                // Solte o objeto
                CmdStopHoldObject();
            }
        }
    }

    [Command(requiresAuthority =false)]
    private void CmdStartHoldObject()
    {
        isBeingHeld = true;
        rb.isKinematic = true;
        RpcStartHoldObject();
    }

    [ClientRpc]
    private void RpcStartHoldObject()
    {
        isBeingHeld = true;
        rb.isKinematic = true;
    }

    [Command(requiresAuthority = false)]
    private void CmdMoveObject(Vector3 newPosition)
    {
        transform.position = newPosition;
        RpcMoveObject(newPosition);
    }

    [ClientRpc]
    private void RpcMoveObject(Vector3 newPosition)
    {
        transform.position = newPosition;
    }

    [Command(requiresAuthority = false)]
    private void CmdStopHoldObject()
    {
        isBeingHeld = false;
        rb.isKinematic = false;
        RpcStopHoldObject();
    }

    [ClientRpc]
    private void RpcStopHoldObject()
    {
        isBeingHeld = false;
        rb.isKinematic = false;
    }

    
    private Vector3 GetMouseWorldPosition()
    {
        Vector3 mousePos = Input.mousePosition;
        mousePos.z = Camera.main.transform.position.y - offsetHeight; // Ajuste da profundidade
        var pos = Camera.main.ScreenToWorldPoint(mousePos);
        return pos;  
    }

    
    private bool CheckMouseHit()
    {
        Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
        RaycastHit hit;
        return Physics.Raycast(ray, out hit) && hit.transform == transform;
    }
}

我正在 Unity + Mirror 上创建一个桌面游戏。 我希望会议上的每个人都能够捡起物体。物体中不需要权威,因为每个人都应该在游戏中随心所欲地挑选和放置棋子。

每次我通过客户端点击游戏对象时,Input.mousePosition 返回的值就是服务器端的位置。 在服务器端它工作正常,我可以拖放游戏对象,但在客户端我不断地查看错误的值(来自服务器的值)。

我希望客户能够拿起物品并将其放置在他们想要的任何地方。

c# unity-game-engine multiplayer unity3d-mirror
1个回答
0
投票

我相信正在发生的事情是当任何客户端单击该对象时,每个玩家都尝试握住该对象,因此当任何用户单击该对象时,服务器也会尝试移动该对象。我将用 GameObject PlayerHoldingObject 变量替换 bool IsBeingHeld 变量。当客户端单击该对象时,它会向服务器发送一条命令,要求其将playerHoldingObject 变量设置为玩家的游戏对象。如果没有其他人持有该对象,服务器将执行此操作。然后,客户端可以发送不同的命令,要求服务器更新该对象的位置,如果该客户端的游戏对象是playerHoldingObject,则服务器将强制并移动该对象。当玩家放开该物体时,他们会向服务器发送一个最终命令,要求放下该物体,如果他们是当前持有该物体的玩家,该服务器会将playerHoldingObject设置为null,从而允许其他玩家拾取该物体。这允许服务器仅侦听来自持有该对象的玩家的移动请求。

此playerHoldingObject变量只能在服务器上使用,因此请确保不要在客户端使用的任何函数中更改或使用它,除非向其添加[SyncVar]属性。

© www.soinside.com 2019 - 2024. All rights reserved.