119 lines
3.1 KiB
C#
119 lines
3.1 KiB
C#
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<Collider>();
|
|
itemCollider.isTrigger = true;
|
|
itemRenderers = GetComponentsInChildren<Renderer>();
|
|
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;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|