Files
MRArcadia/Assets/_Arcadia/Scripts/Item/PuzzleCompleteCG.cs
2026-04-01 15:53:13 +08:00

470 lines
14 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using DG.Tweening;
using DragonLi.Core;
/// <summary>
/// 拼图完成CG控制器 - 播放桃花绽放、桃花雨等完成特效
/// </summary>
public class PuzzleCompleteCG : MonoBehaviour
{
[Header("CG设置")]
[SerializeField] private float cgTotalDuration = 10f; // CG总时长
[SerializeField] private bool playOnEnable = false; // 是否在激活时自动播放
[Header("桃花树")]
[SerializeField] private List<GameObject> peachTrees; // 桃树列表
[SerializeField] private List<Transform> blossomPoints; // 花骨朵绽放点
[SerializeField] private GameObject blossomPrefab; // 桃花绽放特效预制体
[SerializeField] private float blossomDelayBetweenTrees = 0.5f; // 每棵树绽放间隔
[SerializeField] private float blossomDuration = 2f; // 单棵树绽放时长
[Header("桃花雨")]
[SerializeField] private ParticleSystem peachRainEffect; // 桃花雨特效
[SerializeField] private float peachRainDelay = 3f; // 桃花雨开始延迟
[SerializeField] private float peachRainDuration = 5f; // 桃花雨持续时间
[SerializeField] private Transform peachRainArea; // 桃花雨区域
[SerializeField] private float rainAreaWidth = 10f; // 雨区域宽度
[SerializeField] private float rainAreaHeight = 5f; // 雨区域高度
[Header("猴子跳舞")]
[SerializeField] private List<Animator> monkeyAnimators; // 猴子动画控制器列表
[SerializeField] private string monkeyDanceAnimName = "dance"; // 猴子跳舞动画名
[SerializeField] private float monkeyDanceDelay = 2f; // 猴子跳舞延迟
[SerializeField] private float monkeyDanceDuration = 8f; // 猴子跳舞时长
[Header("相机动画")]
[SerializeField] private Camera mainCamera; // 主相机
[SerializeField] private Transform cameraStartPos; // 相机起始位置
[SerializeField] private Transform cameraEndPos; // 相机结束位置
[SerializeField] private float cameraMoveDuration = 5f; // 相机移动时长
[SerializeField] private float cameraDelay = 1f; // 相机动画延迟
[Header("灯光效果")]
[SerializeField] private Light mainLight; // 主光源
[SerializeField] private Color normalLightColor = Color.white; // 正常灯光颜色
[SerializeField] private Color cgLightColor = new Color(1f, 0.9f, 0.7f); // CG灯光颜色暖色调
[SerializeField] private float lightTransitionDuration = 3f; // 灯光渐变时长
[Header("音效")]
[SerializeField] private string cgStartSound = "1.51"; // CG开始音效
[SerializeField] private string blossomSound = "1.52"; // 花绽放音效
[SerializeField] private string peachRainSound = "1.53"; // 桃花雨音效
[SerializeField] private string monkeyDanceSound = "1.54"; // 猴子跳舞音效
[SerializeField] private int bgmCueName = 1; // 结束BGM
[Header("UI")]
[SerializeField] private GameObject cgUIPanel; // CG UI面板
[SerializeField] private UnityEngine.UI.Text cgText; // CG文字
[SerializeField] private float textFadeDelay = 8f; // 文字淡入延迟
// CG播放状态
private bool isPlayingCG = false;
private Coroutine cgCoroutine;
public bool IsPlayingCG => isPlayingCG;
private void Start()
{
if (playOnEnable)
{
PlayCompleteCG();
}
}
#region CG播放控制
/// <summary>
/// 播放完成CG
/// </summary>
public void PlayCompleteCG()
{
if (isPlayingCG) return;
isPlayingCG = true;
cgCoroutine = StartCoroutine(PlayCGSequence());
Debug.Log("开始播放拼图完成CG...");
}
/// <summary>
/// 停止CG播放
/// </summary>
public void StopCG()
{
if (cgCoroutine != null)
{
StopCoroutine(cgCoroutine);
cgCoroutine = null;
}
isPlayingCG = false;
// 重置所有效果
ResetAllEffects();
Debug.Log("CG播放已停止");
}
/// <summary>
/// CG播放序列
/// </summary>
private IEnumerator PlayCGSequence()
{
// 播放CG开始音效
if (!string.IsNullOrEmpty(cgStartSound))
{
GameManager.Ins?.PlaySound2DRPC(cgStartSound);
}
// 切换BGM
GameManager.Ins?.PlayBGM(bgmCueName);
// 显示CG UI
if (cgUIPanel != null)
{
cgUIPanel.SetActive(true);
}
// 灯光渐变
StartCoroutine(TransitionLight());
// 相机动画(如果有设置)
if (mainCamera != null && cameraStartPos != null && cameraEndPos != null)
{
yield return new WaitForSeconds(cameraDelay);
StartCoroutine(MoveCamera());
}
// 桃花绽放
yield return new WaitForSeconds(1f);
StartCoroutine(PlayBlossomEffect());
// 猴子跳舞
yield return new WaitForSeconds(monkeyDanceDelay);
StartCoroutine(PlayMonkeyDance());
// 桃花雨
yield return new WaitForSeconds(peachRainDelay - monkeyDanceDelay);
StartCoroutine(PlayPeachRain());
// 文字淡入
yield return new WaitForSeconds(textFadeDelay - peachRainDelay);
ShowEndingText();
// 等待CG完成
yield return new WaitForSeconds(cgTotalDuration - textFadeDelay);
// CG结束
OnCGComplete();
}
#endregion
#region
/// <summary>
/// 灯光渐变
/// </summary>
private IEnumerator TransitionLight()
{
if (mainLight == null) yield break;
float elapsed = 0f;
Color startColor = mainLight.color;
while (elapsed < lightTransitionDuration)
{
mainLight.color = Color.Lerp(startColor, cgLightColor, elapsed / lightTransitionDuration);
elapsed += Time.deltaTime;
yield return null;
}
mainLight.color = cgLightColor;
}
/// <summary>
/// 相机移动动画
/// </summary>
private IEnumerator MoveCamera()
{
if (mainCamera == null || cameraStartPos == null || cameraEndPos == null) yield break;
// 设置起始位置
mainCamera.transform.position = cameraStartPos.position;
mainCamera.transform.rotation = cameraStartPos.rotation;
// 移动到结束位置
float elapsed = 0f;
Vector3 startPos = cameraStartPos.position;
Vector3 endPos = cameraEndPos.position;
Quaternion startRot = cameraStartPos.rotation;
Quaternion endRot = cameraEndPos.rotation;
while (elapsed < cameraMoveDuration)
{
mainCamera.transform.position = Vector3.Lerp(startPos, endPos, elapsed / cameraMoveDuration);
mainCamera.transform.rotation = Quaternion.Lerp(startRot, endRot, elapsed / cameraMoveDuration);
elapsed += Time.deltaTime;
yield return null;
}
mainCamera.transform.position = endPos;
mainCamera.transform.rotation = endRot;
}
/// <summary>
/// 桃花绽放效果
/// </summary>
private IEnumerator PlayBlossomEffect()
{
// 播放花绽放音效
if (!string.IsNullOrEmpty(blossomSound))
{
GameManager.Ins?.PlaySound2DRPC(blossomSound);
}
// 每棵树依次绽放
foreach (var tree in peachTrees)
{
// 在树上创建绽放特效
if (blossomPrefab != null && blossomPoints.Count > 0)
{
// 随机选择绽放点
foreach (var point in blossomPoints)
{
if (Random.value > 0.5f) // 随机绽放
{
GameObject blossom = Instantiate(blossomPrefab, point.position, point.rotation);
blossom.transform.SetParent(tree.transform);
// 播放绽放动画
blossom.transform.localScale = Vector3.zero;
blossom.transform.DOScale(1f, blossomDuration).SetEase(Ease.OutBack);
// 延迟后淡出
DOVirtual.DelayedCall(blossomDuration + 1f, () =>
{
blossom.GetComponent<Renderer>()?.material.DOFade(0f, 1f).OnComplete(() =>
{
Destroy(blossom);
});
});
}
}
}
// 等待下一棵树
yield return new WaitForSeconds(blossomDelayBetweenTrees);
}
}
/// <summary>
/// 桃花雨效果
/// </summary>
private IEnumerator PlayPeachRain()
{
// 播放桃花雨音效
if (!string.IsNullOrEmpty(peachRainSound))
{
GameManager.Ins?.PlaySound2DRPC(peachRainSound);
}
if (peachRainEffect != null)
{
peachRainEffect.Play();
// 设置雨区域大小
if (peachRainArea != null)
{
var shape = peachRainEffect.shape;
shape.scale = new Vector3(rainAreaWidth, rainAreaHeight, 1f);
}
// 持续播放
yield return new WaitForSeconds(peachRainDuration);
peachRainEffect.Stop();
}
else
{
yield return new WaitForSeconds(peachRainDuration);
}
}
/// <summary>
/// 猴子跳舞动画
/// </summary>
private IEnumerator PlayMonkeyDance()
{
// 播放猴子跳舞音效
if (!string.IsNullOrEmpty(monkeyDanceSound))
{
GameManager.Ins?.PlaySound2DRPC(monkeyDanceSound);
}
// 让所有猴子开始跳舞
foreach (var animator in monkeyAnimators)
{
if (animator != null)
{
animator.Play(monkeyDanceAnimName);
// 随机延迟,让每个猴子跳舞节奏不同
yield return new WaitForSeconds(Random.Range(0.1f, 0.3f));
}
}
// 持续跳舞
yield return new WaitForSeconds(monkeyDanceDuration);
// 停止跳舞
foreach (var animator in monkeyAnimators)
{
if (animator != null)
{
animator.Play("idle");
}
}
}
/// <summary>
/// 显示结束文字
/// </summary>
private void ShowEndingText()
{
// if (cgText != null)
// {
// cgText.gameObject.SetActive(true);
// cgText.text = "拼图完成!\n桃花源已重现...";
//
// // 淡入动画
// var canvasGroup = cgText.GetComponent<UnityEngine.UI.CanvasGroup>();
// if (canvasGroup == null) canvasGroup = cgText.gameObject.AddComponent<UnityEngine.UI.CanvasGroup>();
//
// canvasGroup.alpha = 0f;
// canvasGroup.DOFade(1f, 1f);
// }
}
/// <summary>
/// CG完成回调
/// </summary>
private void OnCGComplete()
{
isPlayingCG = false;
Debug.Log("拼图完成CG播放完毕");
// 触发游戏胜利结算
GameManager.Ins?.GameOver(GameState.Victory);
// 隐藏CG UI
if (cgUIPanel != null)
{
cgUIPanel.SetActive(false);
// var canvasGroup = cgUIPanel.GetComponent<UnityEngine.UI.CanvasGroup>();
// if (canvasGroup != null)
// {
// canvasGroup.DOFade(0f, 2f).OnComplete(() =>
// {
// cgUIPanel.SetActive(false);
// });
// }
// else
// {
// cgUIPanel.SetActive(false);
// }
}
}
#endregion
#region
/// <summary>
/// 重置所有效果
/// </summary>
private void ResetAllEffects()
{
// 停止桃花雨
if (peachRainEffect != null)
{
peachRainEffect.Stop();
}
// 重置灯光
if (mainLight != null)
{
mainLight.color = normalLightColor;
}
// 重置相机
if (mainCamera != null && cameraStartPos != null)
{
mainCamera.transform.position = cameraStartPos.position;
mainCamera.transform.rotation = cameraStartPos.rotation;
}
// 停止猴子跳舞
foreach (var animator in monkeyAnimators)
{
if (animator != null)
{
animator.Play("idle");
}
}
// 隐藏UI
if (cgUIPanel != null)
{
cgUIPanel.SetActive(false);
}
if (cgText != null)
{
cgText.gameObject.SetActive(false);
}
}
#endregion
#region
/// <summary>
/// 设置桃树列表(外部调用)
/// </summary>
public void SetPeachTrees(List<GameObject> trees)
{
peachTrees = trees;
}
/// <summary>
/// 设置猴子动画控制器列表(外部调用)
/// </summary>
public void SetMonkeyAnimators(List<Animator> animators)
{
monkeyAnimators = animators;
}
/// <summary>
/// 添加单个桃树
/// </summary>
public void AddPeachTree(GameObject tree)
{
if (peachTrees == null) peachTrees = new List<GameObject>();
peachTrees.Add(tree);
}
/// <summary>
/// 添加单个猴子
/// </summary>
public void AddMonkeyAnimator(Animator animator)
{
if (monkeyAnimators == null) monkeyAnimators = new List<Animator>();
monkeyAnimators.Add(animator);
}
#endregion
}