Input.mousePosition being returnd by both client and server

31 Views Asked by At

Giving this code:

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;
    }
}

I am creating a table-top game on Unity + Mirror. I want everyone on the session to be able to pick up objects. There's no need for Authority in the objects, because everyone should pick and place pieces wherever they want on the game.

Every time I click on the gameObject via client side, the value that returns for Input.mousePosition is the position on the server side. On the server side it works fine, and I can drag and drop the gameObject, but on the client side I keep peeking the wrong values (the values from the server).

I expect to be able for the client to pick up the item and place wherever they want.

1

There are 1 best solutions below

1
A Duck With Grapes On

I believe what is happening is every player tries to hold the object when any client clicks on the object, so the server also tries to move the object when any user clicks it. I would replace the bool IsBeingHeld variable with a GameObject playerHoldingObject variable. When the client clicks on the object, it send a command to the server asking for it to set the playerHoldingObject varible to the player's gameobject. If no one else is already holding the object, the server will do that. Then the client can send a different command asking for the server to update the position of the object, and if that client's game object is the playerHoldingObject, the server will oblige and move the object. When the player lets go of the object, they send one final command to the server asking to drop the object, which will set the playerHoldingObject to null if they are the player currently holding the object, allowing other players to pick up the object. This allows for the server to only listen to movement requests from the player that is holding the object.

This playerHoldingObject varible should only be used on the server, so make sure not to change or use it in any functions used by the clients unless you add the [SyncVar] property to it.