using UnityEngine; using UnityEngine.InputSystem; /// /// Simple world pickup for bat or hammer. Uses Input System action "WeaponPickup" via WeaponManager to equip when in range. /// Plays the pickup animation on the player, hides the world pickup, and shows the in-hand weapon. /// Assumes the player already has WeaponManager and the weapon models hidden on hand. /// [RequireComponent(typeof(Collider))] public class WeaponPickup : MonoBehaviour { public enum PickupType { Bat, Hammer } public PickupType pickupType = PickupType.Bat; [Header("Pickup Settings")] public float pickUpRange = 2.5f; public Transform player; [Header("Input System")] [SerializeField] private string pickupActionName = "WeaponPickup"; private bool _playerInTrigger; private PlayerInput _playerInput; private InputAction _pickupAction; // action named "WeaponPickup" in the input asset // Tracks the pickup the player is currently inside (single-player assumption) public static WeaponPickup currentPickupInRange; private void Reset() { var col = GetComponent(); col.isTrigger = true; // Ensure trigger events fire by having a kinematic Rigidbody on the pickup var rb = GetComponent(); if (rb == null) { rb = gameObject.AddComponent(); } rb.isKinematic = true; rb.useGravity = false; } private void OnEnable() { // Attempt to bind immediately if player is already assigned TryBindInput(); } private void OnTriggerEnter(Collider other) { // Robustly detect the player even if a child collider enters var wm = other.GetComponentInParent(); if (wm != null) { player = wm.transform; _playerInTrigger = true; currentPickupInRange = this; TryBindInput(); } } private void OnTriggerExit(Collider other) { var wm = other.GetComponentInParent(); if (wm != null && player == wm.transform) { _playerInTrigger = false; if (currentPickupInRange == this) currentPickupInRange = null; } } private void Update() { if (player == null) { // Lazy find player by component to be safer var wm = FindObjectOfType(); if (wm != null) player = wm.transform; } // Ensure input is bound/enabled (even though we don't read it here) TryBindInput(); // IMPORTANT: Do not handle input here. WeaponManager exclusively handles the WeaponPickup action. // Proximity fallback: if triggers fail, still allow pickup when close if (player != null) { bool near = Vector3.Distance(player.position, transform.position) <= pickUpRange; if (near) { currentPickupInRange = this; } else if (!_playerInTrigger && currentPickupInRange == this) { currentPickupInRange = null; } } } private void TryBindInput() { if (player == null) return; if (_playerInput == null) { _playerInput = player.GetComponent(); } if (_playerInput == null) return; if (_pickupAction == null) { _pickupAction = _playerInput.actions?.FindAction(pickupActionName, false); } if (_pickupAction != null && !_pickupAction.enabled) { _pickupAction.SafeEnable(); } } private void OnDisable() { // Keep action enabled via PlayerInput; only clear local refs if (currentPickupInRange == this) currentPickupInRange = null; _pickupAction = null; _playerInput = null; } // Expose for global handler (called by WeaponManager when button pressed and in range) public void TryEquip() { if (player == null) return; // Safety: ensure still in range and not holding a weapon bool inRange = _playerInTrigger || Vector3.Distance(player.position, transform.position) <= pickUpRange; var wm = player.GetComponent(); if (!inRange || wm == null) { return; } if (wm.IsWeaponEquipped) { // Let WeaponManager handle dropping with the same button return; } // Play pickup animation if available var anim = player.GetComponent(); if (anim != null) { anim.PlayAnimation(AnimationNames.WeaponPickup); } switch (pickupType) { case PickupType.Bat: wm.EquipWeaponFromPickup(WeaponManager.WeaponType.Bat, this); break; case PickupType.Hammer: wm.EquipWeaponFromPickup(WeaponManager.WeaponType.Hammer, this); break; } // Hide the world pickup (simulate taking it). You can pool/destroy instead. gameObject.SetActive(false); // Clear static reference if this was the current pickup if (currentPickupInRange == this) currentPickupInRange = null; } // Called by WeaponManager to place this pickup back into the world when dropping public void PlaceAsDropped(Transform playerTransform) { gameObject.SetActive(true); transform.position = playerTransform.position + Vector3.up * 0.25f; transform.rotation = Quaternion.Euler(0f, playerTransform.eulerAngles.y, 0f); // Prevent instant re-trigger by disabling collider briefly var col = GetComponent(); if (col != null) { StartCoroutine(DisableColliderBrief(col)); } } private System.Collections.IEnumerator DisableColliderBrief(Collider col) { bool prev = col.enabled; col.enabled = false; yield return new WaitForSeconds(0.2f); col.enabled = prev; } }