优化整体流程和修复HUD数值更新BUG
This commit is contained in:
@@ -0,0 +1,205 @@
|
||||
# 灵灯碰触流程重构
|
||||
|
||||
## Task 1: 灵灯只伤害第一个碰到的敌人
|
||||
|
||||
修改 `Assets/eco/SpiritLantern.cs` 的 `OnTriggerEnter`:
|
||||
|
||||
```csharp
|
||||
private void OnTriggerEnter(Collider other)
|
||||
{
|
||||
if (_recalled) return; // 新增:已触发则忽略后续碰撞
|
||||
if (other.CompareTag("Player")) return;
|
||||
HealthSystem health = other.GetComponent<HealthSystem>();
|
||||
if (health != null)
|
||||
{
|
||||
health.Damage(damageOnContact);
|
||||
StartRecallSequence(); // 改名原 Recall(),改为协程流程
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Task 2: 灵灯 2s 渐隐消失 + 灯光同步消失
|
||||
|
||||
修改 `Assets/eco/SpiritLantern.cs`,将 `Recall()` 改为分阶段流程:
|
||||
|
||||
```csharp
|
||||
private void StartRecallSequence()
|
||||
{
|
||||
if (_recalled) return;
|
||||
_recalled = true;
|
||||
// 1. 立即取消事件订阅 + 通知系统(回收灵灯名额)
|
||||
if (_ownerSystem != null) _ownerSystem.UnregisterLantern(this);
|
||||
OnLanternRecalled?.Invoke();
|
||||
OnLanternRecalled = null;
|
||||
// 2. 禁用碰撞体,开始 2s 渐隐
|
||||
GetComponent<Collider>().enabled = false;
|
||||
StartCoroutine(FadeOutAndDestroy(2f));
|
||||
}
|
||||
|
||||
private IEnumerator FadeOutAndDestroy(float duration)
|
||||
{
|
||||
var sr = GetComponent<SpriteRenderer>();
|
||||
var light = GetComponent<LightSource>();
|
||||
float startAlpha = sr != null ? sr.color.a : 1f;
|
||||
float startIntensity = light != null ? light.Intensity : 1f;
|
||||
float elapsed = 0f;
|
||||
while (elapsed < duration)
|
||||
{
|
||||
elapsed += Time.deltaTime;
|
||||
float t = elapsed / duration;
|
||||
if (sr != null)
|
||||
sr.color = new Color(sr.color.r, sr.color.g, sr.color.b, Mathf.Lerp(startAlpha, 0f, t));
|
||||
if (light != null)
|
||||
light.SetIntensity(Mathf.Lerp(startIntensity, 0f, t));
|
||||
yield return null;
|
||||
}
|
||||
Destroy(gameObject);
|
||||
}
|
||||
```
|
||||
|
||||
同时修改超时回收(`lifetime <= 0` 时)也走 `StartRecallSequence()` 而非直接销毁。
|
||||
|
||||
## Task 3: 敌人被灵灯杀死时的消失特效 + 魂灵掉落
|
||||
|
||||
修改 `Assets/eco/SpiritLantern.cs` 的 `OnTriggerEnter`,在调用 `health.Damage()` 之前读取敌人 maxHealth 并保存敌人位置:
|
||||
|
||||
```csharp
|
||||
private void OnTriggerEnter(Collider other)
|
||||
{
|
||||
if (_recalled) return;
|
||||
if (other.CompareTag("Player")) return;
|
||||
HealthSystem health = other.GetComponent<HealthSystem>();
|
||||
if (health != null)
|
||||
{
|
||||
// 在伤害前记录信息(用于掉落)
|
||||
Vector3 deathPos = other.transform.position;
|
||||
int enemyMaxHp = GetMaxHealth(health);
|
||||
health.Damage(damageOnContact);
|
||||
// 如果敌人死亡(血量<=0),生成魂灵掉落
|
||||
// 注意:Die() 会 Destroy gameObject,所以位置已提前保存
|
||||
if (health health <= 0) // 需要用反射或公开属性判断
|
||||
SpawnSoulDrops(deathPos, enemyMaxHp);
|
||||
StartRecallSequence();
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
由于 `HealthSystem.health` 是 private,需要在 HealthSystem 中添加一个公开属性:
|
||||
|
||||
```csharp
|
||||
// HealthSystem.cs 新增
|
||||
public bool IsDead => _isDead;
|
||||
public int MaxHealth => maxHealth;
|
||||
```
|
||||
|
||||
然后改为:
|
||||
```csharp
|
||||
health.Damage(damageOnContact);
|
||||
if (health.IsDead)
|
||||
SpawnSoulDrops(deathPos, health.MaxHealth);
|
||||
```
|
||||
|
||||
## Task 4: 创建魂灵掉落物脚本 `SoulDrop.cs`
|
||||
|
||||
新建 `Assets/eco/SoulDrop.cs`:
|
||||
|
||||
```csharp
|
||||
public class SoulDrop : MonoBehaviour
|
||||
{
|
||||
[SerializeField] private float flyDuration = 0.8f;
|
||||
[SerializeField] private int scoreValue = 1;
|
||||
|
||||
private RectTransform _targetUI; // HUD 魂灵图标位置
|
||||
|
||||
public void Initialize(RectTransform targetUI)
|
||||
{
|
||||
_targetUI = targetUI;
|
||||
StartCoroutine(FlyToHUD());
|
||||
}
|
||||
|
||||
private IEnumerator FlyToHUD()
|
||||
{
|
||||
Vector3 startPos = transform.position;
|
||||
// 获取目标屏幕位置
|
||||
Camera cam = Camera.main;
|
||||
Vector3 targetScreenPos = new Vector3(_targetUI.position.x, _targetUI.position.y, cam.WorldToScreenPoint(startPos).z);
|
||||
Vector3 targetWorldPos = cam.ScreenToWorldPoint(targetScreenPos);
|
||||
|
||||
float elapsed = 0f;
|
||||
while (elapsed < flyDuration)
|
||||
{
|
||||
elapsed += Time.deltaTime;
|
||||
float t = elapsed / flyDuration;
|
||||
// 抛物线轨迹
|
||||
transform.position = Vector3.Lerp(startPos, targetWorldPos, t);
|
||||
transform.localScale = Vector3.one * (1f - t * 0.5f); // 缩小
|
||||
yield return null;
|
||||
}
|
||||
// 到达 HUD,加分
|
||||
if (ScoreManager.Instance != null)
|
||||
ScoreManager.Instance.AddScore(scoreValue);
|
||||
Destroy(gameObject);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Task 5: 魂灵掉落物生成逻辑
|
||||
|
||||
在 `SpiritLantern.cs` 中添加:
|
||||
|
||||
```csharp
|
||||
[SerializeField] private GameObject soulDropPrefab;
|
||||
|
||||
private void SpawnSoulDrops(Vector3 position, int enemyMaxHp)
|
||||
{
|
||||
int count = enemyMaxHp * Random.Range(2, 6); // 2~5倍
|
||||
RectTransform hudTarget = GameHUD.SoulIconRect; // 静态引用
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
Vector3 offset = new Vector3(Random.Range(-0.3f, 0.3f), Random.Range(0f, 0.3f), Random.Range(-0.3f, 0.3f));
|
||||
GameObject drop = Instantiate(soulDropPrefab, position + offset, Quaternion.identity);
|
||||
SoulDrop soul = drop.GetComponent<SoulDrop>();
|
||||
if (soul != null)
|
||||
soul.Initialize(hudTarget);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Task 6: GameHUD 暴露魂灵图标 RectTransform
|
||||
|
||||
修改 `Assets/UI/GameHUD.cs`,添加静态引用:
|
||||
|
||||
```csharp
|
||||
public static RectTransform SoulIconRect { get; private set; }
|
||||
|
||||
void Start()
|
||||
{
|
||||
// ... 现有代码 ...
|
||||
if (soulIcon != null)
|
||||
SoulIconRect = soulIcon.rectTransform;
|
||||
}
|
||||
```
|
||||
|
||||
## Task 7: 创建魂灵掉落物预制体
|
||||
|
||||
- 创建一个小精灵 GameObject(SpriteRenderer + Collider2D trigger + SoulDrop 脚本)
|
||||
- 保存为 `Assets/eco/Prefabs/SoulDrop.prefab`
|
||||
- 将预制体引用赋给 SpiritLantern.prefab 的 `soulDropPrefab` 字段
|
||||
|
||||
## Task 8: 创建魂灵掉落物 Sprite 资源
|
||||
|
||||
- 使用 `ImageGen` 工具生成一个小光点/魂灵图标
|
||||
- 导入 Unity 并赋给 SoulDrop.prefab 的 SpriteRenderer
|
||||
|
||||
---
|
||||
|
||||
## 涉及文件汇总
|
||||
|
||||
| 文件 | 修改类型 |
|
||||
|------|---------|
|
||||
| `Assets/eco/SpiritLantern.cs` | 重构碰撞+渐隐+掉落逻辑 |
|
||||
| `Assets/2.5D Engine/Scripts/HealthSystem.cs` | 新增 `IsDead`、`MaxHealth` 公开属性 |
|
||||
| `Assets/UI/GameHUD.cs` | 新增 `SoulIconRect` 静态属性 |
|
||||
| `Assets/eco/SoulDrop.cs` | **新建** 魂灵掉落物脚本 |
|
||||
| `Assets/eco/Prefabs/SoulDrop.prefab` | **新建** 魂灵掉落物预制体 |
|
||||
| `Assets/eco/Prefabs/SpiritLantern.prefab` | 新增 `soulDropPrefab` 引用 |
|
||||
Reference in New Issue
Block a user