目录
一、脚本事件运用
Add添加Playable Track轨道,在后面的轨道中右键会有Event System Playable文本显示,点击创建。
代码部分:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Playables;
//Timeline脚本事件运用
public class EventSystemPlayable : PlayableAsset
{
public string eventId;
public string param;
public override Playable CreatePlayable(PlayableGraph graph, GameObject owner)
{
var playable = ScriptPlayable<NewPlayableBehaviour>.Create(graph);
playable.GetBehaviour().eventId = eventId;
playable.GetBehaviour().param = param;
return playable;
}
}
public class NewPlayableBehaviour : PlayableBehaviour
{
public string eventId;
public string param;
public override void OnBehaviourPlay(Playable playable, FrameData info)
{
Debug.Log("发送事件 id :"+ eventId+ "___param :"+ param);
//EventMgr.Instance.SendEvent(eventId, param);
}
public override void PrepareFrame(Playable playable, FrameData info)
{
Debug.Log("触发时每帧都执行");
}
}
运行结果:
二、常用接口使用
using System;
using UnityEngine;
using UnityEngine.Timeline;
using UnityEngine.Playables;
using Cinemachine.Timeline;
using Cinemachine;
public static class TimelineHelper
{
#region ModifyTrack 修改一个Track
/// <summary>
/// 修改一个Track
/// </summary>
/// <param name="director">PlayableDirector</param>
/// <param name="trackName">通道名称</param>
/// <param name="value">要附着的物体</param>
public static void ModifyTrack(PlayableDirector director, string trackName, GameObject value, bool addAnimator)
{
try
{
foreach (PlayableBinding item in director.playableAsset.outputs)
{
if (item.streamName == trackName)
{
if (addAnimator)
{
Animator animator = value.GetComponent<Animator>();
if (animator == null)
{
animator = value.AddComponent<Animator>();
}
animator.cullingMode = AnimatorCullingMode.AlwaysAnimate;
SkinnedMeshRenderer[] smr = value.GetComponentsInChildren<SkinnedMeshRenderer>();
if (smr != null)
{
for (int i = 0; i < smr.Length; i++)
{
smr[i].updateWhenOffscreen = true;
}
}
}
director.SetGenericBinding(item.sourceObject, value);
break;
}
}
}
catch (Exception e)
{
Debug.LogError(e.ToString());
}
}
#endregion
#region ModifyAudioClip 修改一个ModifyAudioClip
/// <summary>
/// 修改一个ModifyAudioClip
/// </summary>
/// <param name="director">PlayableDirector</param>
/// <param name="trackIndex">通道索引</param>
/// <param name="clipName">片段名称</param>
/// <param name="value">要附着的物体</param>
public static void ModifyAudioClip(PlayableDirector director, int trackIndex, string clipName, AudioClip audioClip)
{
TimelineAsset tl = director.playableAsset as TimelineAsset;
TrackAsset track = tl.GetOutputTrack(trackIndex);
foreach (var item in track.GetClips())
{
AudioPlayableAsset audioAsset = item.asset as AudioPlayableAsset;
if (clipName == item.displayName)
{
audioAsset.clip = audioClip;
break;
}
}
}
#endregion
#region ModifyControlClip 修改一个ControlClip
/// <summary>
/// 修改一个ControlClip
/// </summary>
/// <param name="director">PlayableDirector</param>
/// <param name="trackIndex">通道索引</param>
/// <param name="clipName">片段名称</param>
/// <param name="value">要附着的物体</param>
public static void ModifyControlClip(PlayableDirector director,int trackIndex, int clipIndex, GameObject value)
{
if (value == null || director == null)
{
Debug.LogWarning("TimelineHelper.ModifyControlClip value == null || director == null return!!");
return;
}
try
{
if (!director.playableGraph.IsValid())
{
director.RebuildGraph();
}
TimelineAsset tl = director.playableAsset as TimelineAsset;
TrackAsset track = tl.GetOutputTrack(trackIndex);
int index = 0;
foreach (var item in track.GetClips())
{
if (index == clipIndex)
{
ControlPlayableAsset asset = item.asset as ControlPlayableAsset;
director.playableGraph.GetResolver().SetReferenceValue(asset.sourceGameObject.exposedName, value);
break;
}
++index;
}
}
catch (Exception e)
{
Debug.LogError(e.ToString());
}
}
#endregion
public static void ModifyAnimationClip(PlayableDirector director, int trackIndex, int clipIndex, AnimationClip value)
{
if (value == null || director == null)
{
Debug.LogWarning("TimelineHelper.ModifyAnimationClip value == null || director == null return!!");
return;
}
try
{
if (!director.playableGraph.IsValid())
{
director.RebuildGraph();
}
TimelineAsset tl = director.playableAsset as TimelineAsset;
TrackAsset track = tl.GetOutputTrack(trackIndex);
int index = 0;
foreach (var item in track.GetClips())
{
if (index == clipIndex)
{
AnimationPlayableAsset asset = item.asset as AnimationPlayableAsset;
asset.clip = value;
break;
}
++index;
}
}
catch (Exception e)
{
Debug.LogError(e.ToString());
}
}
public static void SetClipRootMotionOffset(PlayableDirector director, int trackIndex, int clipIndex, CinemachineVirtualCamera vcam)
{
if (vcam == null || director == null)
{
return;
}
try
{
TimelineAsset tl = director.playableAsset as TimelineAsset;
TrackAsset track = tl.GetOutputTrack(trackIndex);
int index = 0;
foreach (var item in track.GetClips())
{
if (index == clipIndex)
{
AnimationPlayableAsset clip = item.asset as AnimationPlayableAsset;
//Debug.Log("vcam " + vcam.name);
CinemachineTransposer transposer = (CinemachineTransposer)vcam.GetCinemachineComponent(CinemachineCore.Stage.Body);
if (transposer)
{
clip.position = transposer.m_FollowOffset;
}
clip.rotation = vcam.transform.rotation;
break;
}
++index;
}
}
catch (Exception e)
{
Debug.LogError (e.ToString());
}
}
#region ModifyCinemachineClip 修改一个ModifyCinemachineClip
/// <summary>
/// 修改一个ModifyCinemachineClip
/// </summary>
/// <param name="director">PlayableDirector</param>
/// <param name="trackIndex">通道索引</param>
/// <param name="clipName">片段名称</param>
/// <param name="value">要附着的物体</param>
public static void ModifyCinemachineClip(PlayableDirector director, int trackIndex, int clipIndex, GameObject vcamGo)
{
if (vcamGo == null || director == null)
{
return;
}
CinemachineVirtualCameraBase vcam = vcamGo.GetComponent<CinemachineVirtualCameraBase>();
if (vcam == null)
{
return;
}
try
{
if (!director.playableGraph.IsValid())
{
director.RebuildGraph();
}
TimelineAsset tl = director.playableAsset as TimelineAsset;
//Debug.Log("trackIndex " + trackIndex);
//Debug.Log("clipIndex " + clipIndex.ToString());
TrackAsset track = tl.GetOutputTrack(trackIndex);
int index = 0;
foreach (var item in track.GetClips())
{
if (index == clipIndex)
{
CinemachineShot shot = item.asset as CinemachineShot;
director.playableGraph.GetResolver().SetReferenceValue(shot.VirtualCamera.exposedName, vcam);
break;
}
++index;
}
}
catch (Exception e)
{
Debug.LogError(e.ToString());
}
}
#endregion
public static string GetTimeStamp()
{
TimeSpan ts = DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, 0);
return Convert.ToInt64(ts.TotalSeconds).ToString() + UnityEngine.Random.Range(0, 100);
}
public static void ReguildGraph(PlayableDirector director)
{
if (!director.playableGraph.IsValid())
{
director.RebuildGraph();
}
}
}