Files
OGG/Assets/Scripts/PickupItem.cs

157 lines
4.9 KiB
C#

using UnityEngine;
/// <summary>
/// Attach to any pickup object. Spins + bobs like MGS rations.
/// Assign an ItemDefinition asset for full weapon/equip support,
/// or just fill itemName for a simple non-weapon pickup.
/// </summary>
public class PickupItem : MonoBehaviour
{
[Header("Item")]
[Tooltip("Preferred: drag an ItemDefinition ScriptableObject here.")]
public ItemDefinition definition;
[Tooltip("Fallback name if no ItemDefinition is set.")]
public string itemName = "Item";
public Sprite itemIcon;
[Header("Spin & Bob")]
public float spinSpeed = 120f;
public float bobHeight = 0.18f;
public float bobSpeed = 2.2f;
[Header("Pickup")]
public float pickupRadius = 2.0f;
public KeyCode pickupKey = KeyCode.E;
[Header("FX")]
public GameObject pickupParticlesPrefab;
public AudioClip pickupSound;
// ─────────────────────────────────────────
private Vector3 _startPos;
private Transform _playerTransform;
private Inventory _inventory;
private AudioSource _audioSource;
private bool _collected = false;
// Prompt display
private bool _inRange = false;
void Start()
{
_startPos = transform.position;
Player player = FindObjectOfType<Player>();
if (player != null)
{
_playerTransform = player.transform;
_inventory = player.GetComponent<Inventory>();
}
_audioSource = gameObject.AddComponent<AudioSource>();
_audioSource.spatialBlend = 1f;
_audioSource.playOnAwake = false;
// If we have a definition, use its name/icon
if (definition != null)
{
itemName = definition.itemName;
itemIcon = definition.icon;
}
}
void Update()
{
if (_collected) return;
// ── Spin ──────────────────────────────
transform.Rotate(Vector3.up, spinSpeed * Time.deltaTime, Space.World);
// ── Bob ───────────────────────────────
float newY = _startPos.y + Mathf.Sin(Time.time * bobSpeed * Mathf.PI * 2f) * bobHeight;
transform.position = new Vector3(transform.position.x, newY, transform.position.z);
// ── Pickup check ─────────────────────
if (_playerTransform == null) return;
float dist = Vector3.Distance(transform.position, _playerTransform.position);
_inRange = dist <= pickupRadius;
if (_inRange && Input.GetKeyDown(pickupKey))
Collect();
}
void OnGUI()
{
if (_collected || !_inRange) return;
// World-to-screen prompt
Vector3 screenPos = Camera.main != null
? Camera.main.WorldToScreenPoint(_startPos + Vector3.up * (bobHeight + 0.4f))
: Vector3.zero;
if (screenPos.z < 0) return; // behind camera
float sx = screenPos.x;
float sy = Screen.height - screenPos.y; // flip y
string label = definition != null ? definition.itemName : itemName;
bool isWeapon = definition != null && definition.type == ItemDefinition.ItemType.Weapon;
string prompt = $"[{pickupKey}] Pick up {label}";
GUIStyle bg = new GUIStyle(GUI.skin.box);
bg.fontSize = 12;
bg.fontStyle = FontStyle.Bold;
bg.normal.textColor = isWeapon ? new Color(1f, 0.85f, 0.2f) : Color.white;
Vector2 size = bg.CalcSize(new GUIContent(prompt));
Rect bgRect = new Rect(sx - size.x * 0.5f - 6f, sy - size.y - 4f, size.x + 12f, size.y + 6f);
// Dark backing box
Color prev = GUI.color;
GUI.color = new Color(0, 0, 0, 0.65f);
GUI.DrawTexture(bgRect, Texture2D.whiteTexture);
GUI.color = prev;
GUI.Label(bgRect, " " + prompt + " ", bg);
}
void OnDrawGizmosSelected()
{
Gizmos.color = Color.yellow;
Gizmos.DrawWireSphere(transform.position, pickupRadius);
}
void Collect()
{
_collected = true;
_inRange = false;
if (_inventory != null)
{
if (definition != null)
_inventory.AddItem(definition, autoEquip: true);
else
_inventory.AddItem(itemName, itemIcon);
}
else
{
Debug.LogWarning("PickupItem: No Inventory found on player!");
}
if (pickupParticlesPrefab != null)
Instantiate(pickupParticlesPrefab, transform.position, Quaternion.identity);
if (pickupSound != null)
{
_audioSource.PlayOneShot(pickupSound);
Destroy(gameObject, pickupSound.length);
}
else
{
Destroy(gameObject);
}
}
}