NLDClient-yudde/ProjectNLD/Assets/Code/Scripts/GameWrapper/Timeline/CommonAction/CommonActionBehaviour.cs

400 lines
15 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

using UnityEngine;
using UnityEngine.Playables;
namespace GameWrapper.Timeline.CommonAction
{
/// <summary>
/// 通用动作行为(独立版本)
/// 通过Timeline的生命周期方法自动控制GameObject
/// </summary>
public class CommonActionBehaviour : PlayableBehaviour
{
public ECommonActionType actionType;
public int actionParam1;
public int actionParam2;
public string stringParam;
public Color colorParam;
public float floatParam;
private GameObject targetObject;
private bool originalActiveState;
private bool hasStoredOriginalState;
// 缓存组件引用
private ParticleSystem cachedParticleSystem;
private Animator cachedAnimator;
private Renderer cachedRenderer;
private Material originalMaterial;
private Color originalColor;
private float originalAlpha;
// 缓存PlayableDirector引用用于手动获取绑定对象
private PlayableDirector cachedDirector;
public override void OnPlayableCreate(Playable playable)
{
Debug.Log($"[CommonAction] OnPlayableCreate - ActionType: {actionType}");
}
public override void OnBehaviourPlay(Playable playable, FrameData info)
{
Debug.Log($"[CommonAction] OnBehaviourPlay - ActionType: {actionType}, Param1: {actionParam1}, TargetObject: {(targetObject != null ? targetObject.name : "NULL")}");
// 如果targetObject为null尝试手动获取
if (targetObject == null)
{
TryGetTargetObjectFromGraph(playable);
}
// Clip开始播放时调用
if (targetObject == null)
{
Debug.LogError($"[CommonAction] OnBehaviourPlay - TargetObject is NULL! 请检查Track是否绑定了GameObject");
return;
}
// 保存原始状态(只保存一次)
if (!hasStoredOriginalState)
{
originalActiveState = targetObject.activeSelf;
hasStoredOriginalState = true;
Debug.Log($"[CommonAction] 保存原始状态 - {targetObject.name}, ActiveState: {originalActiveState}");
}
switch (actionType)
{
case ECommonActionType.ActiveSet:
HandleActiveSet();
break;
case ECommonActionType.PlayParticle:
HandlePlayParticle();
break;
case ECommonActionType.ControlAnimator:
HandleControlAnimator();
break;
case ECommonActionType.PlaySound:
HandlePlaySound();
break;
case ECommonActionType.CameraShake:
HandleCameraShake();
break;
case ECommonActionType.MaterialChange:
HandleMaterialChange();
break;
}
}
public override void OnBehaviourPause(Playable playable, FrameData info)
{
Debug.Log($"[CommonAction] OnBehaviourPause - ActionType: {actionType}, IsDone: {playable.GetGraph().GetRootPlayable(0).IsDone()}");
// Clip停止播放时调用
if (targetObject == null)
{
Debug.LogWarning($"[CommonAction] OnBehaviourPause - TargetObject is NULL");
return;
}
// 检查是否是因为Timeline结束而暂停
if (playable.GetGraph().GetRootPlayable(0).IsDone())
{
Debug.Log($"[CommonAction] Timeline结束恢复原始状态 - {targetObject.name}");
// Timeline播放完毕恢复原始状态
RestoreOriginalState();
}
}
public override void ProcessFrame(Playable playable, FrameData info, object playerData)
{
// 获取绑定的GameObject(每帧都会调用,但只在第一次获取)
if (targetObject == null && playerData is GameObject go)
{
targetObject = go;
Debug.Log($"[CommonAction] ProcessFrame获取到绑定对象: {targetObject.name}, ActionType: {actionType}");
CacheComponents();
}
}
/// <summary>
/// 尝试从PlayableGraph中手动获取绑定的对象
/// 用于解决OnBehaviourPlay时ProcessFrame还未执行的时序问题
/// </summary>
private void TryGetTargetObjectFromGraph(Playable playable)
{
Debug.Log($"[CommonAction] 尝试手动获取绑定对象...");
// 尝试通过PlayableDirector获取
try
{
if (cachedDirector == null)
{
var graph = playable.GetGraph();
var resolver = graph.GetResolver();
if (resolver is PlayableDirector director)
{
cachedDirector = director;
Debug.Log($"[CommonAction] 找到PlayableDirector: {director.gameObject.name}");
}
}
if (cachedDirector != null)
{
// 遍历所有绑定找到CommonActionTrack对应的绑定对象
foreach (var output in cachedDirector.playableAsset.outputs)
{
// 检查是否是CommonActionTrack
if (output.sourceObject is CommonActionTrack)
{
var boundObject = cachedDirector.GetGenericBinding(output.sourceObject);
if (boundObject is GameObject go)
{
targetObject = go;
Debug.Log($"[CommonAction] ✅ 通过Director获取到绑定对象: {targetObject.name}");
CacheComponents();
return;
}
else if (boundObject != null)
{
Debug.LogWarning($"[CommonAction] 绑定对象类型不是GameObject: {boundObject.GetType().Name}");
}
else
{
Debug.LogWarning($"[CommonAction] CommonActionTrack未绑定任何对象");
}
}
}
}
}
catch (System.Exception e)
{
Debug.LogWarning($"[CommonAction] 通过Director获取绑定对象失败: {e.Message}");
}
Debug.LogWarning($"[CommonAction] ⚠️ 获取绑定对象失败将等待ProcessFrame");
}
/// <summary>
/// 缓存常用组件引用
/// </summary>
private void CacheComponents()
{
if (targetObject == null)
{
Debug.LogError($"[CommonAction] CacheComponents - targetObject is NULL");
return;
}
Debug.Log($"[CommonAction] 开始缓存组件 - {targetObject.name}");
cachedParticleSystem = targetObject.GetComponent<ParticleSystem>();
if (cachedParticleSystem != null)
Debug.Log($"[CommonAction] 找到ParticleSystem组件");
cachedAnimator = targetObject.GetComponent<Animator>();
if (cachedAnimator != null)
Debug.Log($"[CommonAction] 找到Animator组件");
cachedRenderer = targetObject.GetComponent<Renderer>();
if (cachedRenderer != null)
{
Debug.Log($"[CommonAction] 找到Renderer组件");
originalMaterial = cachedRenderer.material;
if (originalMaterial != null)
{
originalColor = originalMaterial.color;
originalAlpha = originalColor.a;
Debug.Log($"[CommonAction] 保存原始材质 - Color: {originalColor}, Alpha: {originalAlpha}");
}
}
}
/// <summary>
/// 恢复原始状态
/// </summary>
private void RestoreOriginalState()
{
Debug.Log($"[CommonAction] RestoreOriginalState - ActionType: {actionType}");
switch (actionType)
{
case ECommonActionType.ActiveSet:
Debug.Log($"[CommonAction] 恢复ActiveState: {originalActiveState}");
targetObject.SetActive(originalActiveState);
break;
case ECommonActionType.MaterialChange:
if (cachedRenderer != null && originalMaterial != null)
{
Debug.Log($"[CommonAction] 恢复材质颜色: {originalColor}");
cachedRenderer.material.color = originalColor;
}
break;
}
}
#region 动作处理方法
/// <summary>
/// 处理激活/隐藏逻辑
/// </summary>
private void HandleActiveSet()
{
if (targetObject == null)
{
Debug.LogError($"[CommonAction] HandleActiveSet - targetObject is NULL");
return;
}
bool shouldBeActive = actionParam1 == 1;
Debug.Log($"[CommonAction] HandleActiveSet - Object: {targetObject.name}, Param1: {actionParam1}, ShouldBeActive: {shouldBeActive}, CurrentActive: {targetObject.activeSelf}");
if (targetObject.activeSelf != shouldBeActive)
{
targetObject.SetActive(shouldBeActive);
Debug.Log($"[CommonAction] ✅ SetActive执行完成 - {targetObject.name} -> {shouldBeActive}");
}
else
{
Debug.Log($"[CommonAction] 状态已经一致跳过SetActive");
}
}
/// <summary>
/// 处理粒子特效
/// </summary>
private void HandlePlayParticle()
{
if (cachedParticleSystem == null)
{
Debug.LogWarning($"对象 {targetObject.name} 没有ParticleSystem组件");
return;
}
switch (actionParam1)
{
case 1: // 开始播放
cachedParticleSystem.Play();
break;
case 2: // 停止播放
cachedParticleSystem.Stop();
break;
case 3: // 暂停
cachedParticleSystem.Pause();
break;
case 4: // 继续
cachedParticleSystem.Play();
break;
}
}
/// <summary>
/// 处理Animator控制
/// </summary>
private void HandleControlAnimator()
{
if (cachedAnimator == null)
{
Debug.LogWarning($"对象 {targetObject.name} 没有Animator组件");
return;
}
switch (actionParam1)
{
case 1: // 播放动画
if (!string.IsNullOrEmpty(stringParam))
{
cachedAnimator.Play(stringParam);
}
else if (actionParam2 != 0)
{
cachedAnimator.Play(actionParam2);
}
break;
case 2: // 设置Trigger
if (!string.IsNullOrEmpty(stringParam))
{
cachedAnimator.SetTrigger(stringParam);
}
break;
case 3: // 设置Bool为true
if (!string.IsNullOrEmpty(stringParam))
{
cachedAnimator.SetBool(stringParam, true);
}
break;
case 4: // 设置Bool为false
if (!string.IsNullOrEmpty(stringParam))
{
cachedAnimator.SetBool(stringParam, false);
}
break;
}
}
/// <summary>
/// 处理音效播放
/// </summary>
private void HandlePlaySound()
{
// TODO: 集成你们项目的音效系统
// 例如AudioManager.Instance.PlaySound(actionParam1);
Debug.Log($"播放音效 ID: {actionParam1}");
}
/// <summary>
/// 处理相机震动
/// </summary>
private void HandleCameraShake()
{
// TODO: 集成你们项目的相机震动系统
// 例如CameraManager.Instance.Shake(actionParam1 / 10f);
Debug.Log($"相机震动强度: {actionParam1}");
}
/// <summary>
/// 处理材质修改
/// </summary>
private void HandleMaterialChange()
{
Debug.Log($"[CommonAction] HandleMaterialChange - Param1: {actionParam1}");
if (cachedRenderer == null)
{
Debug.LogWarning($"[CommonAction] 对象 {targetObject.name} 没有Renderer组件");
return;
}
switch (actionParam1)
{
case 1: // 修改颜色
Debug.Log($"[CommonAction] 修改颜色 - Color: {colorParam}");
cachedRenderer.material.color = colorParam;
Debug.Log($"[CommonAction] ✅ 颜色修改完成 - 当前颜色: {cachedRenderer.material.color}");
break;
case 2: // 修改透明度
Color currentColor = cachedRenderer.material.color;
Debug.Log($"[CommonAction] 修改透明度 - 原始: {currentColor.a}, 目标: {floatParam}");
currentColor.a = floatParam;
cachedRenderer.material.color = currentColor;
Debug.Log($"[CommonAction] ✅ 透明度修改完成 - 当前透明度: {cachedRenderer.material.color.a}");
break;
default:
Debug.LogWarning($"[CommonAction] 未知的MaterialChange参数: {actionParam1}");
break;
}
}
#endregion
}
}