290 lines
10 KiB
C#
290 lines
10 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; // ���ϵ���ij�ʼ�ٶ�
|
||
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;
|
||
|
||
// Track last scene to detect scene changes
|
||
private int lastSceneIndex = -1;
|
||
|
||
private void Awake()
|
||
{
|
||
if (Instance == null)
|
||
{
|
||
Instance = this;
|
||
// ע�⣺������һ�δ���ʱ�������������¼���
|
||
// DontDestroyOnLoad(gameObject); // �� �Ƴ������������������¼���ʱ������
|
||
}
|
||
else if (Instance != this)
|
||
{
|
||
Destroy(gameObject);
|
||
return;
|
||
}
|
||
|
||
CacheSpawnPoints();
|
||
lastSceneIndex = UnityEngine.SceneManagement.SceneManager.GetActiveScene().buildIndex;
|
||
}
|
||
|
||
private void Start()
|
||
{
|
||
// Ensure spawn points are cached after all scene objects are initialized
|
||
CacheSpawnPointsIfNeeded();
|
||
}
|
||
|
||
private void OnEnable()
|
||
{
|
||
// Detect scene reload and refresh cache
|
||
int currentSceneIndex = UnityEngine.SceneManagement.SceneManager.GetActiveScene().buildIndex;
|
||
if (currentSceneIndex != lastSceneIndex)
|
||
{
|
||
if (JudgeManager.IsDebugEnabled) Debug.Log($"[Animation_Generate] Scene changed detected (from {lastSceneIndex} to {currentSceneIndex}), refreshing spawn point cache");
|
||
lastSceneIndex = currentSceneIndex;
|
||
CacheSpawnPoints();
|
||
}
|
||
else
|
||
{
|
||
CacheSpawnPointsIfNeeded();
|
||
}
|
||
}
|
||
|
||
private void CacheSpawnPointsIfNeeded()
|
||
{
|
||
// Only recache if any of the references appear to be invalid (destroyed)
|
||
if (redSpawn == null || greenSpawn == null || yellowSpawn == null || purpleSpawn == null || blueSpawn == null)
|
||
{
|
||
// Check if the effect GameObjects are still valid
|
||
bool anyInvalid = (redEffect == null || redEffect.transform == null) ||
|
||
(greenEffect == null || greenEffect.transform == null) ||
|
||
(yellowEffect == null || yellowEffect.transform == null) ||
|
||
(purpleEffect == null || purpleEffect.transform == null) ||
|
||
(blueEffect == null || blueEffect.transform == null);
|
||
|
||
if (anyInvalid || redSpawn == 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;
|
||
|
||
if (JudgeManager.IsDebugEnabled)
|
||
{
|
||
Debug.Log($"[Animation_Generate] Cached spawn points: red={redSpawn!=null}, green={greenSpawn!=null}, yellow={yellowSpawn!=null}, purple={purpleSpawn!=null}, blue={blueSpawn!=null}");
|
||
}
|
||
}
|
||
|
||
public void SpawnJudgePrefab(string color, string judgeResult)
|
||
{
|
||
if (string.IsNullOrEmpty(color))
|
||
{
|
||
Debug.LogError("[Animation_Generate] SpawnJudgePrefab called with empty color!");
|
||
return;
|
||
}
|
||
|
||
if (string.IsNullOrEmpty(judgeResult))
|
||
{
|
||
Debug.LogError("[Animation_Generate] SpawnJudgePrefab called with empty judgeResult!");
|
||
return;
|
||
}
|
||
|
||
Transform spawnPoint = GetSpawnPoint(color);
|
||
if (spawnPoint == null)
|
||
{
|
||
Debug.LogError($"[Animation_Generate] Could not find spawn point for color: {color}");
|
||
return;
|
||
}
|
||
|
||
GameObject prefabToUse = GetJudgePrefab(judgeResult);
|
||
if (prefabToUse == null)
|
||
{
|
||
Debug.LogError($"[Animation_Generate] Could not find judge prefab for result: {judgeResult}. Available: perfect={perfect_judge_prefab != null}, great={great_judge_prefab != null}, good={good_judge_prefab != null}, miss={miss_judge_prefab != null}");
|
||
return;
|
||
}
|
||
|
||
if (JudgeManager.IsDebugEnabled) Debug.Log($"[Animation_Generate] Spawning judge prefab: color={color}, result={judgeResult}, prefab={prefabToUse.name}");
|
||
|
||
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;
|
||
|
||
// ��ÿ�ε���ʱ����Ƿ���Ҫ���»���
|
||
CacheSpawnPointsIfNeeded();
|
||
|
||
Transform point = null;
|
||
switch (color.ToLower())
|
||
{
|
||
case "red": point = redSpawn; break;
|
||
case "green": point = greenSpawn; break;
|
||
case "yellow": point = yellowSpawn; break;
|
||
case "purple": point = purpleSpawn; break;
|
||
case "blue": point = blueSpawn; break;
|
||
default:
|
||
Debug.LogWarning($"[Animation_Generate] Unknown color: {color}");
|
||
return null;
|
||
}
|
||
|
||
if (point == null)
|
||
{
|
||
Debug.LogError($"[Animation_Generate] Spawn point for color {color} is null. Check if effects are assigned in inspector. Make sure the effect object is active in the scene.");
|
||
}
|
||
|
||
return point;
|
||
}
|
||
|
||
private GameObject GetJudgePrefab(string result)
|
||
{
|
||
if (string.IsNullOrEmpty(result)) return null;
|
||
|
||
GameObject prefab = null;
|
||
switch (result.ToLower())
|
||
{
|
||
case "perfect": prefab = perfect_judge_prefab; break;
|
||
case "great": prefab = great_judge_prefab; break;
|
||
case "good": prefab = good_judge_prefab; break;
|
||
case "miss": prefab = miss_judge_prefab; break;
|
||
default:
|
||
Debug.LogWarning($"[Animation_Generate] Unknown judge result: {result}");
|
||
return null;
|
||
}
|
||
|
||
if (prefab == null)
|
||
{
|
||
Debug.LogError($"[Animation_Generate] Judge prefab for '{result}' is not assigned in inspector! Check Animation_GenerateJudgementSituationPrefab component.");
|
||
}
|
||
|
||
return prefab;
|
||
}
|
||
} |