实现CanvasGroup的补间动画
1) 轨道资源类
using UnityEngine; using UnityEngine.Playables; [System.Serializable] public class CanvasGroupClip : PlayableAsset { [SerializeField] private ExposedReference<CanvasGroup> _target; [SerializeField] private float _startValue; [SerializeField] private float _endValue; public override Playable CreatePlayable(PlayableGraph graph, GameObject go) { var playable = ScriptPlayable<CanvasGroupBehaviour>.Create(graph); var canvasGroup = _target.Resolve(graph.GetResolver()); playable.GetBehaviour().Init(canvasGroup, _startValue, _endValue); return playable; } }
2) 轨道资源行为类
using UnityEngine; using UnityEngine.Playables; [System.Serializable] public class CanvasGroupBehaviour : PlayableBehaviour { public CanvasGroup _canvasGroup; public float _startValue; public float _endValue; public void Init(CanvasGroup canvasGroup, float startValue, float endValue) { _canvasGroup = canvasGroup; _startValue = startValue; _endValue = endValue; } public override void ProcessFrame(Playable playable, FrameData info, object playerData) { if (null == _canvasGroup) return; float progress = (float)(playable.GetTime() / playable.GetDuration()); float alpha = Mathf.Lerp(_startValue, _endValue, progress); _canvasGroup.alpha = alpha; Debug.Log($"CanvasGroupBehaviour: alpha: {alpha}"); } }
创建一个Playable轨道
PlayableGraph的可视化图形:
更加优雅的写法
上面的代码_startValue, _endValue需要在两个类中都写一遍,还得给他们赋值,下面的代码写法只需要在Behaviour中写一遍
using UnityEngine; using UnityEngine.Playables; [System.Serializable] public class CanvasGroupClip : PlayableAsset { public CanvasGroupBehaviour template = new CanvasGroupBehaviour(); public override Playable CreatePlayable(PlayableGraph graph, GameObject go) { var playable = ScriptPlayable<CanvasGroupBehaviour>.Create(graph, template); return playable; } }
#
using UnityEngine; using UnityEngine.Playables; [System.Serializable] public class CanvasGroupBehaviour : PlayableBehaviour { [SerializeField] private ExposedReference<CanvasGroup> _target; [SerializeField] public float _startValue; [SerializeField] public float _endValue; private CanvasGroup _canvasGroup; public override void OnGraphStart(Playable playable) { _canvasGroup = _target.Resolve(playable.GetGraph().GetResolver()); } public override void ProcessFrame(Playable playable, FrameData info, object playerData) { if (null == _canvasGroup) return; float progress = (float)(playable.GetTime() / playable.GetDuration()); float alpha = Mathf.Lerp(_startValue, _endValue, progress); _canvasGroup.alpha = alpha; Debug.Log($"CanvasGroupBehaviour: alpha: {alpha}"); } }
#