一.Playable Track入门
下面是一个小例子能够实现自定义Playable Track 中控制灯光的颜色:
实现上面的效果先添加脚本:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Playables;
public class LightControlBehaviour : PlayableBehaviour
{
public Light light;
public Color color = Color.white;
public float intensity = 1;
/// <summary>
/// timeLine 每次更新都会执行此方法
/// </summary>
/// <param name="playable"></param>
/// <param name="info"></param>
/// <param name="playerData"></param>
public override void ProcessFrame(Playable playable, FrameData info, object playerData)
{
if (light != null)
{
light.color = color;
light.intensity = intensity;
}
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Playables;
public class LightControlAsset : PlayableAsset
{
// 在clip中的light对象
public ExposedReference<Light> light;
public Color color = Color.white;
public float intensity = 1;
public override Playable CreatePlayable(PlayableGraph graph, GameObject owner)
{
// 把逻辑和资源联系起来
var playable = ScriptPlayable<LightControlBehaviour>.Create(graph);
var lightControlBehavliur = playable.GetBehaviour();
// 获取到light的对象
lightControlBehavliur.light = light.Resolve(graph.GetResolver());
lightControlBehavliur.color = color;
lightControlBehavliur.intensity = intensity;
return playable;
}
}
二 timeline自定义轨道
(由于PlayableTrack不能复用,不能更换绑定的数据源,所以PlayableTrack并不实用,自定义轨道更实用)
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Timeline;
//绑定的Clip的类型(可以是定义的,也可以是AudioClip等)
[TrackClipType(typeof(LightControlAsset))]
// 绑定的Track对象的类型
[TrackBindingType(typeof(Light))]
public class LightControlTrack : TrackAsset
{
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Playables;
public class LightControlAsset : PlayableAsset
{
// 在clip中的light对象
//public ExposedReference<Light> light;
public Color color = Color.white;
public float intensity = 1;
public override Playable CreatePlayable(PlayableGraph graph, GameObject owner)
{
// 把逻辑和资源联系起来
var playable = ScriptPlayable<LightControlBehaviour>.Create(graph);
var lightControlBehavliur = playable.GetBehaviour();
// 获取到light的对象
//lightControlBehavliur.light = light.Resolve(graph.GetResolver());
lightControlBehavliur.color = color;
lightControlBehavliur.intensity = intensity;
return playable;
}
}
---------------------------------
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Playables;
public class LightControlBehaviour : PlayableBehaviour
{
//public Light light;
public Color color = Color.white;
public float intensity = 1;
/// <summary>
/// timeLine 每次更新都会执行此方法
/// </summary>
/// <param name="playable"></param>
/// <param name="info"></param>
/// <param name="playerData">就是Track中绑定的物体本身</param>
public override void ProcessFrame(Playable playable, FrameData info, object playerData)
{
Light light = playerData as Light;
if (light != null)
{
light.color = color;
light.intensity = intensity;
}
}
}
三 Playable API相关介绍
四Playable创建一个简单的动画(不用Controller状态机播放)
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Animations;
using UnityEngine.Playables;
[RequireComponent(typeof(Animator))]
public class PlayableAnimation : MonoBehaviour
{
public AnimationClip Clip;
private PlayableGraph _playableGraph;
private void Start()
{
1. 创建 playGraph
//_playableGraph = PlayableGraph.Create("PlayableAnimation");
2.创建output AudioPlayableOutput
//var playableOut = AnimationPlayableOutput.Create(_playableGraph,"Animation",GetComponent<Animator>());
3. playables创建
//var clipPlayable = AnimationClipPlayable.Create(_playableGraph, Clip);
4.连接 playable 到 out
//playableOut.SetSourcePlayable(clipPlayable);
5. playables之间的连接
6 播放
//_playableGraph.Play();
//------------以上的步骤可以由下面一句代替-------------
AnimationPlayableUtilities.PlayClip(GetComponent<Animator>(), Clip, out _playableGraph);
}
private void OnDestroy()
{
_playableGraph.Destroy();
}
}
五Playable创建混合动画
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Animations;
using UnityEngine.Playables;
public class PlayableBlendTree : MonoBehaviour
{
public AnimationClip Clip1;
public AnimationClip Clip2;
private PlayableGraph _playableGraph;
private AnimationMixerPlayable _mixPlayable;
[Range(0,1)]
public float weight = 0.5f;
void Start()
{
// 创建 graph
_playableGraph = PlayableGraph.Create("PlayableBlendTree");
// 创建 out
var playableOut = AnimationPlayableOutput.Create(_playableGraph,"Animation",GetComponent<Animator>());
// 创建 mixPlayable
_mixPlayable = AnimationMixerPlayable.Create(_playableGraph, 2);
// 将graph 和 playable 绑定
playableOut.SetSourcePlayable(_mixPlayable);
// 创建clipPlayable
var clipPlayable0 = AnimationClipPlayable.Create(_playableGraph, Clip1);
var clipPlayable1 = AnimationClipPlayable.Create(_playableGraph, Clip2);
_playableGraph.Connect(clipPlayable0,0,_mixPlayable,0);
_playableGraph.Connect(clipPlayable1, 0, _mixPlayable, 1);
// 播放
_playableGraph.Play();
}
// Update is called once per frame
void Update()
{
_mixPlayable.SetInputWeight(0, weight);
_mixPlayable.SetInputWeight(1, 1 - weight);
}
private void OnDestroy()
{
_playableGraph.Destroy();
}
}
六 PlayableGraph 运行时动态修改(添加或删除clip)
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Animations;
using UnityEngine.Playables;
public class PlayableBlendTree : MonoBehaviour
{
public AnimationClip Clip1;
public AnimationClip Clip2;
private PlayableGraph _playableGraph;
private AnimationMixerPlayable _mixPlayable;
[Range(0,1)]
public float weight = 0.5f;
void Start()
{
// 创建 graph
_playableGraph = PlayableGraph.Create("PlayableBlendTree");
// 创建 out
var playableOut = AnimationPlayableOutput.Create(_playableGraph,"Animation",GetComponent<Animator>());
// 创建 mixPlayable
_mixPlayable = AnimationMixerPlayable.Create(_playableGraph, 2);
// 将graph 和 playable 绑定
playableOut.SetSourcePlayable(_mixPlayable);
创建clipPlayable
//var clipPlayable0 = AnimationClipPlayable.Create(_playableGraph, Clip1);
//var clipPlayable1 = AnimationClipPlayable.Create(_playableGraph, Clip2);
playable之间的连接
//_playableGraph.Connect(clipPlayable0,0,_mixPlayable,0);
//_playableGraph.Connect(clipPlayable1, 0, _mixPlayable, 1);
// 播放
_playableGraph.Play();
}
// Update is called once per frame
void Update()
{
_mixPlayable.SetInputWeight(0, weight);
_mixPlayable.SetInputWeight(1, 1 - weight);
if (Input.GetKeyDown(KeyCode.A))
{
创建clipPlayable
var clipPlayable0 = AnimationClipPlayable.Create(_playableGraph, Clip1);
var clipPlayable1 = AnimationClipPlayable.Create(_playableGraph, Clip2);
// playable之间的连接
_playableGraph.Connect(clipPlayable0, 0, _mixPlayable, 0);
_playableGraph.Connect(clipPlayable1, 0, _mixPlayable, 1);
}
if (Input.GetKeyDown(KeyCode.D))
{
// 1. 先断开连接
_playableGraph.Disconnect(_mixPlayable, 0);
_playableGraph.Disconnect(_mixPlayable, 1);
// 2.后销毁
_mixPlayable.Destroy();
_playableGraph.DestroyPlayable(_mixPlayable);
// 最后销毁output 如果只有一个Graph,默认是 0
_playableGraph.DestroyOutput(_playableGraph.GetOutput(0));
}
}
private void OnDestroy()
{
_playableGraph.Destroy();
}
}