using UnityEngine; [RequireComponent(typeof(Collider))] public abstract class PickupItem : MonoBehaviour { [Header("Hover & Rotation Animation")] [SerializeField] private float rotationSpeed = 90f; [SerializeField] private float bobFrequency = 2f; [SerializeField] private float bobAmplitude = 0.2f; [Header("Pickup Feedback")] [SerializeField] private GameObject pickupVFXPrefab; [SerializeField] private AudioClip pickupSFX; [SerializeField] private string pickupMessage = "Picked up item!"; [Header("Respawn Settings")] [SerializeField] private bool respawns = false; [SerializeField] private float respawnTime = 15f; private Vector3 startPosition; private Collider itemCollider; private Renderer[] itemRenderers; private bool isCollected = false; protected virtual void Awake() { itemCollider = GetComponent(); itemCollider.isTrigger = true; itemRenderers = GetComponentsInChildren(); startPosition = transform.position; } protected virtual void Update() { if (isCollected) return; // Rotate item transform.Rotate(Vector3.up, rotationSpeed * Time.deltaTime, Space.World); // Bob up and down float newY = startPosition.y + Mathf.Sin(Time.time * bobFrequency) * bobAmplitude; transform.position = new Vector3(transform.position.x, newY, transform.position.z); } private void OnTriggerEnter(Collider other) { if (isCollected) return; if (other.CompareTag("Player")) { if (CanCollect(other.gameObject)) { Collect(other.gameObject); } } } protected virtual bool CanCollect(GameObject player) { return true; } protected abstract void ApplyPickupEffect(GameObject player); private void Collect(GameObject player) { isCollected = true; ApplyPickupEffect(player); // Play VFX if (pickupVFXPrefab != null) { GameObject vfx = Instantiate(pickupVFXPrefab, transform.position, Quaternion.identity); Destroy(vfx, 2.0f); } // Play SFX if (pickupSFX != null) { AudioSource.PlayClipAtPoint(pickupSFX, transform.position); } // Display toast notification on UI if (!string.IsNullOrEmpty(pickupMessage) && UIController.Instance != null) { UIController.Instance.ShowNotification(pickupMessage); } if (respawns) { SetVisibility(false); Invoke(nameof(Respawn), respawnTime); } else { Destroy(gameObject); } } private void Respawn() { isCollected = false; SetVisibility(true); } private void SetVisibility(bool visible) { if (itemCollider != null) itemCollider.enabled = visible; if (itemRenderers != null) { foreach (var rend in itemRenderers) { rend.enabled = visible; } } } }