115 lines
3.9 KiB
C#
115 lines
3.9 KiB
C#
using UnityEngine;
|
|
using UnityEngine.UI;
|
|
using System.Collections;
|
|
|
|
namespace GameFramework
|
|
{
|
|
/// <summary>
|
|
/// 魂灵掉落物 —— 敌人被灵灯击杀后掉落。
|
|
/// 从敌人位置飞向 HUD 魂灵计数图标,到达后加分并自毁。
|
|
/// </summary>
|
|
public class SoulDrop : MonoBehaviour
|
|
{
|
|
[Header("飞行参数")]
|
|
[Tooltip("飞向 HUD 的飞行时间(秒)")]
|
|
[SerializeField] private float flyDuration = 0.8f;
|
|
|
|
[Tooltip("每个掉落物的分数")]
|
|
[SerializeField] private int scoreValue = 1;
|
|
|
|
[Header("延迟")]
|
|
[Tooltip("出生后的随机延迟范围(秒),避免所有掉落物同时起飞")]
|
|
[SerializeField] private float delayMin = 0f;
|
|
[SerializeField] private float delayMax = 0.3f;
|
|
|
|
private RectTransform _targetUI;
|
|
private SpriteRenderer _sr;
|
|
|
|
private void Awake()
|
|
{
|
|
_sr = GetComponent<SpriteRenderer>();
|
|
}
|
|
|
|
/// <summary>
|
|
/// 初始化掉落物:设置目标 UI 并启动飞行协程。
|
|
/// </summary>
|
|
public void Initialize(RectTransform targetUI)
|
|
{
|
|
_targetUI = targetUI;
|
|
StartCoroutine(DelayedFly());
|
|
}
|
|
|
|
private IEnumerator DelayedFly()
|
|
{
|
|
// 随机延迟,让掉落物有先后起飞的效果
|
|
float delay = Random.Range(delayMin, delayMax);
|
|
if (delay > 0f)
|
|
yield return new WaitForSeconds(delay);
|
|
|
|
yield return StartCoroutine(FlyToHUD());
|
|
}
|
|
|
|
private IEnumerator FlyToHUD()
|
|
{
|
|
Vector3 startPos = transform.position;
|
|
Camera cam = Camera.main;
|
|
if (cam == null || _targetUI == null)
|
|
{
|
|
// 降级处理:直接加分
|
|
AddScoreAndDestroy();
|
|
yield break;
|
|
}
|
|
|
|
// 目标:HUD 魂灵图标的屏幕位置
|
|
Vector3 targetScreenPos = _targetUI.position;
|
|
// 保持深度一致,避免转换出错
|
|
float depth = Mathf.Abs(cam.WorldToScreenPoint(startPos).z);
|
|
targetScreenPos.z = depth;
|
|
Vector3 targetWorldPos = cam.ScreenToWorldPoint(targetScreenPos);
|
|
|
|
float elapsed = 0f;
|
|
while (elapsed < flyDuration)
|
|
{
|
|
elapsed += Time.deltaTime;
|
|
float t = Mathf.Clamp01(elapsed / flyDuration);
|
|
|
|
// 带弧度的飞行轨迹(先高后低)
|
|
float arc = Mathf.Sin(t * Mathf.PI) * 0.5f;
|
|
Vector3 pos = Vector3.Lerp(startPos, targetWorldPos, t);
|
|
pos.y += arc;
|
|
transform.position = pos;
|
|
|
|
// 逐渐缩小 + 旋转
|
|
float scale = Mathf.Lerp(1f, 0.3f, t);
|
|
transform.localScale = Vector3.one * scale;
|
|
transform.Rotate(0, 0, 360f * Time.deltaTime);
|
|
|
|
// 渐隐效果(最后 30% 开始变淡)
|
|
if (_sr != null && t > 0.7f)
|
|
{
|
|
float fadeT = (t - 0.7f) / 0.3f;
|
|
_sr.color = new Color(_sr.color.r, _sr.color.g, _sr.color.b, 1f - fadeT);
|
|
}
|
|
|
|
yield return null;
|
|
}
|
|
|
|
AddScoreAndDestroy();
|
|
}
|
|
|
|
private void AddScoreAndDestroy()
|
|
{
|
|
// 确保 ScoreManager 存在(直接从 Gameplay 场景启动时可能没有)
|
|
if (ScoreManager.Instance == null)
|
|
{
|
|
var go = new GameObject("ScoreManager");
|
|
go.AddComponent<ScoreManager>();
|
|
Debug.Log("[SoulDrop] 自动创建 ScoreManager");
|
|
}
|
|
Debug.Log($"[SoulDrop] 加分 +{scoreValue},当前总分: {ScoreManager.Instance.CurrentScore + scoreValue}");
|
|
ScoreManager.Instance.AddScore(scoreValue);
|
|
Destroy(gameObject);
|
|
}
|
|
}
|
|
}
|