408 lines
13 KiB
C#
408 lines
13 KiB
C#
using UnityEngine;
|
||
using System.Collections;
|
||
using DarkTonic.MasterAudio;
|
||
using DG.Tweening;
|
||
|
||
/// <summary>
|
||
/// 场景1过场管理器 - 女巫与魔镜对话事件
|
||
/// 继承CutsceneBase基类
|
||
/// </summary>
|
||
public class Scene1Cutscene : CutsceneBase
|
||
{
|
||
#region 配置
|
||
|
||
[Header("生成位置")]
|
||
public Transform witchSpawnPoint;
|
||
public Transform mirrorSpawnPoint;
|
||
|
||
[Header("音频配置")]
|
||
public string witchAudio1_1 = "1.1"; // "魔镜魔镜,谁是这个世界上最美的女人?"
|
||
public string witchAudio1_3 = "1.3"; // "啊啊啊~该死的白雪公主,我一定要杀死她。"
|
||
public string mirrorAudio1_2 = "1.2"; // "白雪公主是这个世界上最美的女人。"
|
||
public string mirrorAudio1_4 = "1.4"; // "你怎么来了,白雪公主..."
|
||
|
||
[Header("时间配置")]
|
||
public float delayBeforeTalk = 1f; // 走到魔镜面前后等待时间
|
||
public float delayAfterMirrorFlash = 1f; // 魔镜闪一下后等待时间
|
||
public float delayAfterWitchLeave = 1f; // 女巫离开后等待时间
|
||
|
||
[Header("女巫移动配置")]
|
||
public float witchWalkToMirrorDuration = 2f; // 女巫走到魔镜面前的时间
|
||
public float witchWalkToMirrorDistance = 3f; // 女巫走到魔镜的距离
|
||
public float witchLeaveTurnDuration = 1f; // 女巫离开转身时间
|
||
public float witchLeaveWalkDistance = 5f; // 女巫离开走动距离
|
||
public float witchLeaveWalkDuration = 3f; // 女巫离开走动时间
|
||
public float witchFadeDuration = 1f; // 女巫渐隐时间
|
||
|
||
[Header("魔镜配置")]
|
||
public float mirrorFlashDuration = 0.5f; // 魔镜闪烁时间
|
||
public float mirrorFlyDuration = 2f; // 魔镜飞向玩家时间
|
||
public float mirrorTransformDuration = 2f; // 魔镜变传送门时间
|
||
|
||
#endregion
|
||
|
||
#region 状态
|
||
|
||
public enum CutsceneState
|
||
{
|
||
None,
|
||
SpawnBoth, // 同时生成女巫和魔镜
|
||
WitchWalkToMirror, // 女巫走到魔镜面前
|
||
WitchTalk1, // 女巫说话 [1.1]
|
||
MirrorFlash, // 魔镜闪一下
|
||
MirrorTalk1, // 魔镜回答 [1.2]
|
||
WitchAngry, // 女巫愤怒 [1.3]
|
||
WitchLeave, // 女巫离开
|
||
MirrorTurnToPlayer, // 魔镜转向玩家
|
||
MirrorFlyToPlayer, // 魔镜飞向玩家
|
||
MirrorTalk2, // 魔镜说话 [1.4]
|
||
MirrorTransform, // 魔镜变传送门
|
||
Complete
|
||
}
|
||
|
||
public CutsceneState currentState = CutsceneState.None;
|
||
|
||
#endregion
|
||
|
||
#region 角色引用
|
||
|
||
private Witch witchController;
|
||
private Mirror mirrorController;
|
||
|
||
#endregion
|
||
|
||
#region 实现抽象方法
|
||
|
||
public override void StartCutscene()
|
||
{
|
||
if (isPlaying)
|
||
{
|
||
Debug.LogWarning("[Scene1Cutscene] 过场动画已在播放中");
|
||
return;
|
||
}
|
||
|
||
isPlaying = true;
|
||
currentStep = 0;
|
||
currentState = CutsceneState.None;
|
||
|
||
if (debugMode)
|
||
Debug.Log("[Scene1Cutscene] ========== 开始场景1过场动画 ==========");
|
||
|
||
StartCoroutine(PlayCutsceneSequence());
|
||
}
|
||
|
||
public override string GetCurrentStateDescription()
|
||
{
|
||
return $"步骤{currentStep}: {currentState}";
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region 过场动画流程
|
||
|
||
private IEnumerator PlayCutsceneSequence()
|
||
{
|
||
// ========== 步骤1: 同时生成女巫和魔镜 ==========
|
||
currentState = CutsceneState.SpawnBoth;
|
||
currentStep = 1;
|
||
|
||
SpawnWitch();
|
||
SpawnMirror();
|
||
|
||
if (debugMode)
|
||
Debug.Log("[Scene1Cutscene] 步骤1: 生成女巫和魔镜");
|
||
|
||
yield return new WaitForSeconds(0.5f);
|
||
|
||
// ========== 步骤2: 女巫走到魔镜面前 ==========
|
||
currentState = CutsceneState.WitchWalkToMirror;
|
||
currentStep = 2;
|
||
|
||
if (debugMode)
|
||
Debug.Log("[Scene1Cutscene] 步骤2: 女巫走到魔镜面前...");
|
||
|
||
var mirrorObj = GetCharacter("Mirror");
|
||
if (witchController != null && mirrorObj != null)
|
||
{
|
||
// 让女巫面向魔镜
|
||
witchController.LookAtMirror(mirrorObj.transform, 0.5f);
|
||
yield return new WaitForSeconds(0.5f);
|
||
|
||
// 女巫向前走到魔镜面前
|
||
bool walkComplete = false;
|
||
witchController.MoveForward(witchWalkToMirrorDistance, witchWalkToMirrorDuration, () =>
|
||
{
|
||
walkComplete = true;
|
||
});
|
||
yield return new WaitUntil(() => walkComplete);
|
||
}
|
||
else
|
||
{
|
||
yield return new WaitForSeconds(witchWalkToMirrorDuration);
|
||
}
|
||
|
||
// ========== 步骤3: 等待1秒,女巫说话 [1.1] ==========
|
||
currentState = CutsceneState.WitchTalk1;
|
||
currentStep = 3;
|
||
|
||
yield return new WaitForSeconds(delayBeforeTalk);
|
||
|
||
if (debugMode)
|
||
Debug.Log("[Scene1Cutscene] 步骤3: 女巫: '魔镜魔镜,谁是这个世界上最美的女人?'");
|
||
|
||
if (witchController != null)
|
||
{
|
||
witchController.PlayTalkAnim();
|
||
witchController.PlayAudio(witchAudio1_1);
|
||
}
|
||
|
||
yield return WaitForAudioComplete(witchAudio1_1, 5f);
|
||
|
||
// ========== 步骤4: 魔镜闪一下 ==========
|
||
currentState = CutsceneState.MirrorFlash;
|
||
currentStep = 4;
|
||
|
||
if (debugMode)
|
||
Debug.Log("[Scene1Cutscene] 步骤4: 魔镜闪一下...");
|
||
|
||
if (mirrorController != null)
|
||
{
|
||
mirrorController.Glow(2f, mirrorFlashDuration);
|
||
}
|
||
yield return new WaitForSeconds(mirrorFlashDuration);
|
||
|
||
// 等待1秒
|
||
yield return new WaitForSeconds(delayAfterMirrorFlash);
|
||
|
||
// ========== 步骤5: 魔镜回答 [1.2] ==========
|
||
currentState = CutsceneState.MirrorTalk1;
|
||
currentStep = 5;
|
||
|
||
if (debugMode)
|
||
Debug.Log("[Scene1Cutscene] 步骤5: 魔镜: '白雪公主是这个世界上最美的女人。'");
|
||
|
||
if (mirrorController != null)
|
||
{
|
||
mirrorController.PlayTalkAnim();
|
||
mirrorController.PlayAudio(mirrorAudio1_2);
|
||
}
|
||
|
||
yield return WaitForAudioComplete(mirrorAudio1_2, 4f);
|
||
|
||
// ========== 步骤6: 女巫愤怒 [1.3] ==========
|
||
currentState = CutsceneState.WitchAngry;
|
||
currentStep = 6;
|
||
|
||
if (debugMode)
|
||
Debug.Log("[Scene1Cutscene] 步骤6: 女巫: '啊啊啊~该死的白雪公主,我一定要杀死她。'");
|
||
|
||
if (witchController != null)
|
||
{
|
||
witchController.PlayAngryAnim();
|
||
witchController.PlayAudio(witchAudio1_3);
|
||
}
|
||
|
||
yield return WaitForAudioComplete(witchAudio1_3, 5f);
|
||
|
||
// ========== 步骤7: 女巫气冲冲离开 ==========
|
||
currentState = CutsceneState.WitchLeave;
|
||
currentStep = 7;
|
||
|
||
if (debugMode)
|
||
Debug.Log("[Scene1Cutscene] 步骤7: 女巫气冲冲离开...");
|
||
|
||
if (witchController != null)
|
||
{
|
||
bool witchLeft = false;
|
||
witchController.LeaveScene(
|
||
witchLeaveTurnDuration,
|
||
witchLeaveWalkDistance,
|
||
witchLeaveWalkDuration,
|
||
witchFadeDuration,
|
||
() => { witchLeft = true; }
|
||
);
|
||
|
||
yield return new WaitUntil(() => witchLeft);
|
||
}
|
||
else
|
||
{
|
||
yield return new WaitForSeconds(witchLeaveTurnDuration + witchLeaveWalkDuration + witchFadeDuration);
|
||
}
|
||
|
||
// 等待1秒
|
||
yield return new WaitForSeconds(delayAfterWitchLeave);
|
||
|
||
// ========== 步骤8: 魔镜转向玩家 ==========
|
||
currentState = CutsceneState.MirrorTurnToPlayer;
|
||
currentStep = 8;
|
||
|
||
if (debugMode)
|
||
Debug.Log("[Scene1Cutscene] 步骤8: 魔镜转向玩家...");
|
||
|
||
if (mirrorController != null)
|
||
{
|
||
mirrorController.TurnToPlayer(1f);
|
||
}
|
||
yield return new WaitForSeconds(1f);
|
||
|
||
// ========== 步骤9: 魔镜飞向玩家 ==========
|
||
currentState = CutsceneState.MirrorFlyToPlayer;
|
||
currentStep = 9;
|
||
|
||
if (debugMode)
|
||
Debug.Log("[Scene1Cutscene] 步骤9: 魔镜飞向玩家...");
|
||
|
||
if (mirrorController != null)
|
||
{
|
||
bool mirrorArrived = false;
|
||
mirrorController.FlyToPlayer(mirrorFlyDuration, () => { mirrorArrived = true; });
|
||
yield return new WaitUntil(() => mirrorArrived);
|
||
}
|
||
else
|
||
{
|
||
yield return new WaitForSeconds(mirrorFlyDuration);
|
||
}
|
||
|
||
// ========== 步骤10: 魔镜说话 [1.4] ==========
|
||
currentState = CutsceneState.MirrorTalk2;
|
||
currentStep = 10;
|
||
|
||
if (debugMode)
|
||
Debug.Log("[Scene1Cutscene] 步骤10: 魔镜: '你怎么来了,白雪公主。快进入我的魔镜世界中...'");
|
||
|
||
if (mirrorController != null)
|
||
{
|
||
mirrorController.PlayTalkAnim();
|
||
mirrorController.PlayAudio(mirrorAudio1_4);
|
||
}
|
||
|
||
yield return WaitForAudioComplete(mirrorAudio1_4, 8f);
|
||
|
||
// ========== 步骤11: 魔镜变传送门 ==========
|
||
currentState = CutsceneState.MirrorTransform;
|
||
currentStep = 11;
|
||
|
||
if (debugMode)
|
||
Debug.Log("[Scene1Cutscene] 步骤11: 魔镜变传送门...");
|
||
|
||
if (mirrorController != null)
|
||
{
|
||
bool transformed = false;
|
||
mirrorController.TransformToPortal(mirrorTransformDuration, () => { transformed = true; });
|
||
yield return new WaitUntil(() => transformed);
|
||
}
|
||
else
|
||
{
|
||
yield return new WaitForSeconds(mirrorTransformDuration);
|
||
}
|
||
|
||
// ========== 完成 ==========
|
||
currentState = CutsceneState.Complete;
|
||
currentStep = 12;
|
||
|
||
TriggerComplete();
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region 私有方法
|
||
|
||
/// <summary>
|
||
/// 生成女巫 - 使用GameManager的预制体
|
||
/// </summary>
|
||
private void SpawnWitch()
|
||
{
|
||
Vector3 spawnPos = witchSpawnPoint != null ? witchSpawnPoint.position : Vector3.zero;
|
||
Vector3 spawnRot = witchSpawnPoint != null ? witchSpawnPoint.eulerAngles : Vector3.zero;
|
||
|
||
var witchObj = CreateWitch(spawnPos, spawnRot, "Witch");
|
||
|
||
if (witchObj != null)
|
||
{
|
||
witchController = witchObj.GetComponent<Witch>();
|
||
if (witchController == null)
|
||
{
|
||
witchController = witchObj.AddComponent<Witch>();
|
||
}
|
||
witchController.Init();
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 生成魔镜 - 使用GameManager的预制体
|
||
/// </summary>
|
||
private void SpawnMirror()
|
||
{
|
||
Vector3 spawnPos = mirrorSpawnPoint != null ? mirrorSpawnPoint.position : Vector3.zero;
|
||
Vector3 spawnRot = mirrorSpawnPoint != null ? mirrorSpawnPoint.eulerAngles : Vector3.zero;
|
||
|
||
var mirrorObj = CreateMirror(spawnPos, spawnRot, "Mirror");
|
||
|
||
if (mirrorObj != null)
|
||
{
|
||
mirrorController = mirrorObj.GetComponent<Mirror>();
|
||
if (mirrorController == null)
|
||
{
|
||
mirrorController = mirrorObj.AddComponent<Mirror>();
|
||
}
|
||
mirrorController.Init();
|
||
}
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region 事件链
|
||
|
||
/// <summary>
|
||
/// 下一个事件(水晶雕像事件)
|
||
/// </summary>
|
||
[Header("事件链")]
|
||
public CrystalStatueEvent nextCrystalStatueEvent;
|
||
|
||
/// <summary>
|
||
/// 重写完成方法,触发下一个事件
|
||
/// </summary>
|
||
protected virtual void TriggerComplete()
|
||
{
|
||
base.TriggerComplete();
|
||
|
||
// 触发水晶雕像事件
|
||
if (nextCrystalStatueEvent != null)
|
||
{
|
||
if (debugMode)
|
||
Debug.Log("[Scene1Cutscene] 触发水晶雕像事件...");
|
||
|
||
DOVirtual.DelayedCall(1f, () =>
|
||
{
|
||
nextCrystalStatueEvent.StartCutscene();
|
||
});
|
||
}
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region 编辑器辅助
|
||
|
||
#if UNITY_EDITOR
|
||
[ContextMenu("开始过场动画")]
|
||
private void TestStartCutscene()
|
||
{
|
||
StartCutscene();
|
||
}
|
||
|
||
[ContextMenu("停止过场动画")]
|
||
private void TestStopCutscene()
|
||
{
|
||
StopCutscene();
|
||
}
|
||
|
||
[ContextMenu("清理所有对象")]
|
||
private void TestCleanup()
|
||
{
|
||
Cleanup();
|
||
}
|
||
#endif
|
||
|
||
#endregion
|
||
}
|