using UnityEngine; using Mirror; using Mirror.Experimental; using NetworkTransform = Mirror.NetworkTransform; public class PropGrab : NetworkBehaviour, IInteractable { [SyncVar(hook = nameof(OnPlayerChanged))] public NetworkIdentity _player; private Rigidbody _rb; private GameObject _eyesObject; private NetworkTransform _netTransform; private NetworkRigidbody _netRigidBody; void Start() { _rb = GetComponent(); _netTransform = GetComponent(); _netRigidBody = GetComponent(); } void Update() { if (!hasAuthority || _player == null || _eyesObject == null) return; if (_player.isLocalPlayer) { Vector3 targetPos = _eyesObject.transform.position + _eyesObject.transform.forward; Vector3 tarForce = targetPos - _rb.transform.position; Vector3 force = (tarForce * 20f - _rb.velocity) * Time.deltaTime * 40f; _rb.AddForce(force, ForceMode.Impulse); CmdAddForce(force); } // _rb.MoveRotation(_eyesObject.transform.rotation); // _rb.transform.rotation = _eyesObject.transform.rotation; // transform.position = Vector3.Lerp(transform.position, targetPos, 0.95f); } [Command(requiresAuthority = false)] void CmdAddForce(Vector3 force) { _rb.AddForce(force, ForceMode.Impulse); } // [ClientRpc] // void RpcAddForce(Vector3 force) // { // _rb.AddForce(force, ForceMode.Impulse); // } public void Interact() { CmdInteract(); } [Command(requiresAuthority = false)] private void CmdInteract(NetworkConnectionToClient sender = null) { var currentClient = netIdentity.connectionToClient; if (currentClient != null && currentClient.identity.netId == sender.identity.netId) { ResetPlayer(); return; } else if (currentClient != null) return; netIdentity.AssignClientAuthority(sender); _player = sender.identity; } private void OnPlayerChanged(NetworkIdentity oldPlayer, NetworkIdentity newPlayer) { _netTransform.clientAuthority = newPlayer != null; _netRigidBody.clientAuthority = newPlayer != null; if (newPlayer != null) { Grab(newPlayer); } else { Drop(oldPlayer); } } [Server] public void ResetPlayer() { netIdentity.RemoveClientAuthority(); _player = null; } private void Grab(NetworkIdentity player) { player.gameObject.GetComponent().SetGrabbedProp(this); _eyesObject = _player.gameObject.GetComponent()._eyesObject; gameObject.layer = LayerMask.NameToLayer("Grab"); } void Drop(NetworkIdentity player) { player.gameObject.GetComponent().SetGrabbedProp(null); // netIdentity.RemoveClientAuthority(); _player = null; _eyesObject = null; gameObject.layer = LayerMask.NameToLayer("Default"); } }