400 lines
15 KiB
C#
400 lines
15 KiB
C#
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
|
||
}
|
||
}
|