using Unity.Netcode; using UnityEngine; [DisallowMultipleComponent] [RequireComponent(typeof(Collider))] public sealed class CannonRocketSlot : MonoBehaviour, IInteractable { [SerializeField] private Transform snapPoint; private NetworkCannonController cannon; private Collider triggerCollider; public Transform SnapPoint => snapPoint != null ? snapPoint : transform; public Vector3 InteractionPosition => SnapPoint.position; public string InteractionPrompt => cannon != null ? cannon.LoadedRocket != null ? $"Take {cannon.LoadedRocket.RocketTypeId} rocket" : "Rocket slot" : "Rocket slot"; public bool IsInteractionAvailable => cannon != null && cannon.CanTakeRocket; private void Reset() { snapPoint = transform; ResolveCollider(); triggerCollider.isTrigger = true; } private void Awake() => ResolveCollider(); private void OnValidate() { ResolveCollider(); if (triggerCollider != null) triggerCollider.isTrigger = true; } public void Configure(NetworkCannonController owner) => cannon = owner; public void RequestInteraction() { if (IsInteractionAvailable) cannon.RequestTakeRocket(); } private void OnTriggerEnter(Collider other) => TryInsert(other); private void OnTriggerStay(Collider other) => TryInsert(other); private void TryInsert(Collider other) { if (cannon == null || !cannon.IsServer || !cannon.IsSpawned) return; NetworkRocketItem rocket = other.GetComponentInParent(); if (rocket != null) cannon.TryInsertRocket(rocket); } public bool OverlapsAny(Collider[] itemColliders, float clearance) { ResolveCollider(); if (triggerCollider == null || itemColliders == null) return false; Bounds bounds = triggerCollider.bounds; bounds.Expand(Mathf.Max(0f, clearance) * 2f); foreach (Collider itemCollider in itemColliders) { if (itemCollider != null && itemCollider.enabled && bounds.Intersects(itemCollider.bounds)) return true; } return false; } private void ResolveCollider() { if (triggerCollider == null) triggerCollider = GetComponent(); } }