added inventory and stamina system
This commit is contained in:
156
Assets/Scripts/PickupItem.cs
Normal file
156
Assets/Scripts/PickupItem.cs
Normal file
@@ -0,0 +1,156 @@
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user