给出此代码:
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 返回的值就是服务器端的位置。 在服务器端它工作正常,我可以拖放游戏对象,但在客户端我不断地查看错误的值(来自服务器的值)。
我希望客户能够拿起物品并将其放置在他们想要的任何地方。
我相信正在发生的事情是当任何客户端单击该对象时,每个玩家都尝试握住该对象,因此当任何用户单击该对象时,服务器也会尝试移动该对象。我将用 GameObject PlayerHoldingObject 变量替换 bool IsBeingHeld 变量。当客户端单击该对象时,它会向服务器发送一条命令,要求其将playerHoldingObject 变量设置为玩家的游戏对象。如果没有其他人持有该对象,服务器将执行此操作。然后,客户端可以发送不同的命令,要求服务器更新该对象的位置,如果该客户端的游戏对象是playerHoldingObject,则服务器将强制并移动该对象。当玩家放开该物体时,他们会向服务器发送一个最终命令,要求放下该物体,如果他们是当前持有该物体的玩家,该服务器会将playerHoldingObject设置为null,从而允许其他玩家拾取该物体。这允许服务器仅侦听来自持有该对象的玩家的移动请求。
此playerHoldingObject变量只能在服务器上使用,因此请确保不要在客户端使用的任何函数中更改或使用它,除非向其添加[SyncVar]属性。