using Unity.Netcode; using Unity.Netcode.Components; using UnityEngine; public interface IInteractable { string InteractionPrompt { get; } bool IsInteractionAvailable { get; } void RequestInteraction(); } [AddComponentMenu("")] [RequireComponent(typeof(NetworkObject), typeof(NetworkTransform))] public class NetworkInteractable : NetworkBehaviour, IInteractable { [Header("Interaction")] [SerializeField] private string interactionLabel = "Interact"; [SerializeField, Min(0.1f)] private float maximumInteractionDistance = 3f; protected string InteractionLabel => interactionLabel; public virtual string InteractionPrompt => interactionLabel; public virtual bool IsInteractionAvailable => IsSpawned; public void RequestInteraction() { if (!IsSpawned || !IsInteractionAvailable) return; RequestInteractionServerRpc(); } [Rpc(SendTo.Server, InvokePermission = RpcInvokePermission.Everyone)] private void RequestInteractionServerRpc(RpcParams rpcParams = default) { ulong senderClientId = rpcParams.Receive.SenderClientId; if (!TryGetPlayerObject(senderClientId, out NetworkObject playerObject)) return; float maximumDistanceSquared = maximumInteractionDistance * maximumInteractionDistance; if ((playerObject.transform.position - transform.position).sqrMagnitude > maximumDistanceSquared) return; if (!CanInteractOnServer(senderClientId)) return; InteractOnServer(senderClientId, playerObject); } protected virtual bool CanInteractOnServer(ulong senderClientId) => false; protected virtual void InteractOnServer(ulong senderClientId, NetworkObject playerObject) { } protected bool TryGetPlayerObject(ulong clientId, out NetworkObject playerObject) { playerObject = NetworkManager != null ? NetworkManager.SpawnManager.GetPlayerNetworkObject(clientId) : null; return playerObject != null; } }