using BaseGames.Core.Events;
using BaseGames.Player;
using UnityEngine;
namespace BaseGames.World
{
public enum CollectibleType { Geo, Item, HPOrb }
///
/// 可收集物(Geo / 道具 / HP 球)。玩家进入触发器自动拾取。
/// _isPersistent = true 时拾取后广播 ID 供存档记录。
///
public class Collectible : MonoBehaviour
{
[Header("配置")]
[SerializeField] private CollectibleType _type;
[SerializeField] private int _geoAmount;
[SerializeField] private string _itemId;
[SerializeField] private bool _isPersistent; // false = 敌人掉落;true = 固定位置(存档)
[SerializeField] private string _collectibleId; // 持久化唯一 ID(_isPersistent = true 时填写)
[Header("物理")]
[SerializeField] private float _bounceForce = 5f;
[Header("事件频道")]
[SerializeField] private StringEventChannelSO _onCollectiblePickup;
private bool _collected;
private void Start()
{
// 给予初始弹跳冲力
var rb = GetComponent();
if (rb != null)
{
var dir = new Vector2(Random.Range(-0.5f, 0.5f), 1f).normalized;
rb.AddForce(dir * _bounceForce, ForceMode2D.Impulse);
}
}
private void OnTriggerEnter2D(Collider2D other)
{
if (_collected) return;
if (!other.CompareTag("Player")) return;
var stats = other.GetComponentInParent();
if (stats == null) return;
_collected = true;
switch (_type)
{
case CollectibleType.Geo:
stats.AddGeo(_geoAmount);
break;
case CollectibleType.Item:
_onCollectiblePickup?.Raise(_itemId);
break;
case CollectibleType.HPOrb:
stats.HealHP(1);
break;
}
if (_isPersistent && !string.IsNullOrEmpty(_collectibleId))
_onCollectiblePickup?.Raise(_collectibleId);
Despawn();
}
private void Despawn()
{
// 若由对象池创建(PooledObject 存在),归还到池;否则直接停用(场景内静态放置的 Collectible)
var po = GetComponent();
if (po != null)
po.ReturnToPool();
else
gameObject.SetActive(false);
}
// ── 运行时配置(由 CollectibleSpawner 在实例化后调用)────────────────
/// 将此 Collectible 配置为 Geo 掉落(实例化后由 CollectibleSpawner 调用)。
public void SetGeo(int amount)
{
_type = CollectibleType.Geo;
_geoAmount = amount;
_isPersistent = false;
}
/// 将此 Collectible 配置为道具掉落(实例化后由 CollectibleSpawner 调用)。
public void SetItem(string itemId)
{
_type = CollectibleType.Item;
_itemId = itemId;
_isPersistent = false;
}
}
}