Files
bansonic_beta_main/Assets/scripts/gamePlay_gameplay/Animation_GenerateJudgementSituationPrefab.cs
T

201 lines
6.2 KiB
C#

using UnityEngine;
using System.Collections;
public class Animation_GenerateJudgementSituationPrefab : MonoBehaviour
{
public static Animation_GenerateJudgementSituationPrefab Instance;
[Header("生成位置 (五个轨道)")]
public GameObject redEffect;
public GameObject greenEffect;
public GameObject yellowEffect;
public GameObject purpleEffect;
public GameObject blueEffect;
[Header("判定飘字 Prefabs")]
public GameObject perfect_judge_prefab;
public GameObject great_judge_prefab;
public GameObject good_judge_prefab;
public GameObject miss_judge_prefab;
[Header("缩放与随机")]
public float baseScale = 1.0f;
public bool useRandomScale = true;
public float minScaleMultiplier = 0.8f;
public float maxScaleMultiplier = 1.2f;
[Header("物理跳跃设置")]
public float jumpForce = 5.0f; // 向上弹起的初始速度
public float gravity = -12.0f; // 重力
[Header("时间与透明度控制 (秒)")]
public float fadeInTime = 0.1f; // 生成后多少秒完成渐显 (0->1)
public float fadeOutStartTime = 0.6f; // 生成后第几秒开始渐隐
public float fadeOutDuration = 0.3f; // 渐隐动画持续时长
// Cache spawn transforms to avoid accessing destroyed GameObject references.
private Transform redSpawn;
private Transform greenSpawn;
private Transform yellowSpawn;
private Transform purpleSpawn;
private Transform blueSpawn;
private void Awake()
{
if (Instance == null) Instance = this;
else
{
Destroy(gameObject);
return;
}
CacheSpawnPoints();
}
private void OnEnable()
{
// In case this object survives scene changes / references are assigned late.
if (redSpawn == null && redEffect != null) CacheSpawnPoints();
}
private void CacheSpawnPoints()
{
// Important: check Unity "fake null" before accessing .transform
redSpawn = redEffect != null ? redEffect.transform : null;
greenSpawn = greenEffect != null ? greenEffect.transform : null;
yellowSpawn = yellowEffect != null ? yellowEffect.transform : null;
purpleSpawn = purpleEffect != null ? purpleEffect.transform : null;
blueSpawn = blueEffect != null ? blueEffect.transform : null;
}
public void SpawnJudgePrefab(string color, string judgeResult)
{
Transform spawnPoint = GetSpawnPoint(color);
if (spawnPoint == null) return;
GameObject prefabToUse = GetJudgePrefab(judgeResult);
if (prefabToUse == null) return;
GameObject instance = Instantiate(prefabToUse, spawnPoint);
instance.transform.localPosition = Vector3.zero;
// 处理缩放
float finalScale = baseScale;
if (useRandomScale) finalScale *= Random.Range(minScaleMultiplier, maxScaleMultiplier);
instance.transform.localScale = new Vector3(finalScale, finalScale, 1f);
// 开启运动逻辑
StartCoroutine(AnimateSprite(instance));
}
private IEnumerator AnimateSprite(GameObject obj)
{
if (obj == null) yield break;
SpriteRenderer sr = obj.GetComponent<SpriteRenderer>();
float elapsed = 0f;
float vVelocity = jumpForce;
Vector3 currentLocalPos = Vector3.zero;
// 计算总生命周期:开始渐隐的时间 + 渐隐持续的时长
float totalLifeTime = fadeOutStartTime + fadeOutDuration;
// 初始透明度
if (sr != null)
{
Color c = sr.color;
c.a = 0f;
sr.color = c;
}
// 只要没到总寿命,就持续执行
while (elapsed < totalLifeTime)
{
if (obj == null) yield break;
float dt = Time.deltaTime;
elapsed += dt;
// --- 1. 物理位移 ---
vVelocity += gravity * dt;
currentLocalPos.y += vVelocity * dt;
obj.transform.localPosition = currentLocalPos;
// --- 2. 透明度逻辑 (基于秒数) ---
if (sr != null)
{
float alpha;
// 渐显阶段:当前时间 < fadeInTime
if (elapsed < fadeInTime)
{
alpha = Mathf.InverseLerp(0f, fadeInTime, elapsed);
}
// 渐隐阶段:当前时间 > fadeOutStartTime
else if (elapsed > fadeOutStartTime)
{
// 在 fadeOutStartTime 到 totalLifeTime 之间从 1 变到 0
alpha = Mathf.InverseLerp(totalLifeTime, fadeOutStartTime, elapsed);
}
// 中间完全显示阶段
else
{
alpha = 1f;
}
Color c = sr.color;
c.a = Mathf.Clamp01(alpha);
sr.color = c;
}
yield return null;
}
// --- 确保最后一帧是完全透明的 ---
if (obj != null && sr != null)
{
Color c = sr.color;
c.a = 0f;
sr.color = c;
}
// 等待渲染完成,防止闪除
yield return new WaitForEndOfFrame();
if (obj != null) Destroy(obj);
}
private Transform GetSpawnPoint(string color)
{
if (string.IsNullOrEmpty(color)) return null;
// If references were destroyed (Unity fake null) try to rebuild cache once.
if (redSpawn == null && greenSpawn == null && yellowSpawn == null && purpleSpawn == null && blueSpawn == null)
{
CacheSpawnPoints();
}
switch (color.ToLower())
{
case "red": return redSpawn;
case "green": return greenSpawn;
case "yellow": return yellowSpawn;
case "purple": return purpleSpawn;
case "blue": return blueSpawn;
default: return null;
}
}
private GameObject GetJudgePrefab(string result)
{
if (string.IsNullOrEmpty(result)) return null;
switch (result.ToLower())
{
case "perfect": return perfect_judge_prefab;
case "great": return great_judge_prefab;
case "good": return good_judge_prefab;
case "miss": return miss_judge_prefab;
default: return null;
}
}
}