我需要我的弓向我的鼠标旋转,但是即使我已将客户端网络转换附加到它并允许它同步 z 轴旋转,它也只能在主机上工作(如果我在主机上旋转,则会出现在客户,但不是相反)。
这是我的玩家角色的代码:
using System.Collections.Generic;
using UnityEngine;
using Unity.Netcode;
using Collider2D = UnityEngine.Collider2D;
public class Player : NetworkBehaviour
{
public static Player LocalInstance {get; private set;}
[SerializeField] private float speed;
private Collider2D[] playerColliders;
private void Awake()
{
playerColliders = GetComponents<Collider2D>();
}
private void Start()
{
GameInput.Instance.OnInteractAction += HandleInteraction;
}
public override void OnNetworkSpawn()
{
if (IsOwner) LocalInstance = this;
}
private void Update()
{
HandleMovement();
}
private void HandleInteraction(object sender, System.EventArgs e)
{
List<Collider2D> contactColliders = new List<Collider2D>();
bool hasInteracted = false;
foreach (Collider2D playerCollider in playerColliders)
{
Physics2D.OverlapCollider(playerCollider, contactColliders);
foreach (Collider2D contactCollider in contactColliders)
{
if (!contactCollider.gameObject.TryGetComponent<IInteractable>(out IInteractable interactable)) continue;
interactable.Interact(this);
hasInteracted = true;
break;
}
if (hasInteracted) break;
}
}
private void HandleMovement()
{
Vector2 direction = GameInput.Instance.GetDirectionVector();
transform.position += (Vector3)(direction * (speed * Time.deltaTime));
}
public NetworkObject GetNetworkObject()
{
return NetworkObject;
}
}
这是我的弓的代码:
using Unity.Netcode;
using UnityEngine;
public class Weapon : NetworkBehaviour, IInteractable
{
[SerializeField] private GameObject attachedPlayerGameObject;
[SerializeField] private Player attachedPlayer;
[SerializeField] private bool isOnPossession = false;
private void LateUpdate()
{
if (!isOnPossession) return;
HandlePlayerPossessionBehaviour();
}
public void Interact(Player interactedPlayer)
{
InteractServerRpc(interactedPlayer.GetNetworkObject());
}
[ServerRpc(RequireOwnership = false)]
private void InteractServerRpc(NetworkObjectReference interactedPlayerNetworkObjectReference)
{
InteractClientRpc(interactedPlayerNetworkObjectReference);
}
[ClientRpc]
private void InteractClientRpc(NetworkObjectReference interactedPlayerNetworkObjectReference)
{
interactedPlayerNetworkObjectReference.TryGet(out NetworkObject interactedPlayerNetworkObject);
Player interactedPlayer = interactedPlayerNetworkObject.GetComponent<Player>();
attachedPlayer = interactedPlayer;
attachedPlayerGameObject = interactedPlayer.gameObject;
isOnPossession = true;
}
private void HandlePlayerPossessionBehaviour()
{
if (attachedPlayerGameObject == null) return;
transform.position = attachedPlayerGameObject.transform.position;
if (attachedPlayer.IsLocalPlayer)
{
FollowPlayerMousePointer();
}
}
private void FollowPlayerMousePointer()
{
Vector2 mousePos = Camera.main.ScreenToWorldPoint(Input.mousePosition);
Vector2 lookDir = mousePos - new Vector2(transform.position.x, transform.position.y);
float angle = Mathf.Atan2(lookDir.y, lookDir.x) * Mathf.Rad2Deg;
transform.eulerAngles = new Vector3(0f, 0f, angle);
}
}
这个问题的解决方案是更改弓对象的所有权以匹配客户端的所有权,如下所示:
private void InteractServerRpc(NetworkObjectReference interactedPlayerNetworkObjectReference, ulong clientId)
{
NetworkObject.ChangeOwnership(clientId);
InteractClientRpc(interactedPlayerNetworkObjectReference);
}