102 lines
3.5 KiB
C#
102 lines
3.5 KiB
C#
using BaseGames.Core.Events;
|
||
using BaseGames.Player;
|
||
using UnityEngine;
|
||
|
||
namespace BaseGames.World
|
||
{
|
||
public enum CollectibleType { LingZhu, Item, HPOrb }
|
||
|
||
/// <summary>
|
||
/// 可收集物(LingZhu / 道具 / HP 球)。玩家进入触发器自动拾取。
|
||
/// _isPersistent = true 时拾取后广播 ID 供存档记录。
|
||
/// </summary>
|
||
public class Collectible : MonoBehaviour
|
||
{
|
||
[Header("配置")]
|
||
[SerializeField] private CollectibleType _type;
|
||
[SerializeField] private int _lingZhuAmount;
|
||
[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; // 道具获取(EVT_ItemPickup)
|
||
[SerializeField] private StringEventChannelSO _onCollectibleSaved; // 持久化记录(EVT_CollectibleSaved)
|
||
|
||
private bool _collected;
|
||
|
||
private void Start()
|
||
{
|
||
// 给予初始弹跳冲力
|
||
var rb = GetComponent<Rigidbody2D>();
|
||
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<PlayerStats>();
|
||
if (stats == null) return;
|
||
|
||
_collected = true;
|
||
|
||
switch (_type)
|
||
{
|
||
case CollectibleType.LingZhu:
|
||
stats.AddLingZhu(_lingZhuAmount);
|
||
break;
|
||
|
||
case CollectibleType.Item:
|
||
_onCollectiblePickup?.Raise(_itemId);
|
||
break;
|
||
|
||
case CollectibleType.HPOrb:
|
||
stats.HealHP(1);
|
||
break;
|
||
}
|
||
|
||
if (_isPersistent && !string.IsNullOrEmpty(_collectibleId))
|
||
_onCollectibleSaved?.Raise(_collectibleId);
|
||
|
||
Despawn();
|
||
}
|
||
|
||
private void Despawn()
|
||
{
|
||
// 若由对象池创建(PooledObject 存在),归还到池;否则直接停用(场景内静态放置的 Collectible)
|
||
var po = GetComponent<Core.Pool.PooledObject>();
|
||
if (po != null)
|
||
po.ReturnToPool();
|
||
else
|
||
gameObject.SetActive(false);
|
||
}
|
||
|
||
// ── 运行时配置(由 CollectibleSpawner 在实例化后调用)────────────────
|
||
|
||
/// <summary>将此 Collectible 配置为 LingZhu 採落(实例化后由 CollectibleSpawner 调用)。</summary>
|
||
public void SetLingZhu(int amount)
|
||
{
|
||
_type = CollectibleType.LingZhu;
|
||
_lingZhuAmount = amount;
|
||
_isPersistent = false;
|
||
}
|
||
|
||
/// <summary>将此 Collectible 配置为道具掉落(实例化后由 CollectibleSpawner 调用)。</summary>
|
||
public void SetItem(string itemId)
|
||
{
|
||
_type = CollectibleType.Item;
|
||
_itemId = itemId;
|
||
_isPersistent = false;
|
||
}
|
||
}
|
||
}
|