代码示例
前言
这里将Cinemachine的Timeline相关的代码复制出来,为扩展提供一些模板,原理还请参看之前的Timeline自定义
CinemachineTrack
using System;
using UnityEngine;
using UnityEngine.Playables;
using UnityEngine.Timeline;
namespace Cinemachine.Timeline
{
[Serializable]
[TrackClipType(typeof(CinemachineShot))]
[TrackMediaType(TimelineAsset.MediaType.Script)]
[TrackBindingType(typeof(CinemachineBrain))]
[TrackColor(0.53f, 0.0f, 0.08f)]
public class CinemachineTrack : TrackAsset
{
public override Playable CreateTrackMixer(
PlayableGraph graph, GameObject go, int inputCount)
{
// Hack to set the display name of the clip to match the vcam
foreach (var c in GetClips())
{
CinemachineShot shot = (CinemachineShot)c.asset;
CinemachineVirtualCameraBase vcam = shot.VirtualCamera.Resolve(graph.GetResolver());
if (vcam != null)
c.displayName = vcam.Name;
}
var mixer = ScriptPlayable<CinemachineMixer>.Create(graph);
mixer.SetInputCount(inputCount);
return mixer;
}
}
}
CinemachineMixer
using UnityEngine;
using UnityEngine.Playables;
namespace Cinemachine.Timeline
{
public sealed class CinemachineMixer : PlayableBehaviour
{
// The brain that this track controls
private CinemachineBrain mBrain;
private int mBrainOverrideId = -1;
private bool mPlaying;
public override void OnGraphStop(Playable playable)
{
if (mBrain != null)
mBrain.ReleaseCameraOverride(mBrainOverrideId); // clean up
mBrainOverrideId = -1;
}
public override void ProcessFrame(Playable playable, FrameData info, object playerData)
{
base.ProcessFrame(playable, info, playerData);
// Get the brain that this track controls.
// Older versions of timeline sent the gameObject by mistake.
GameObject go = playerData as GameObject;
if (go == null)
mBrain = (CinemachineBrain)playerData;
else
mBrain = go.GetComponent<CinemachineBrain>();
if (mBrain == null)
return;
// Find which clips are active. We can process a maximum of 2.
// In the case that the weights don't add up to 1, the outgoing weight
// will be calculated as the inverse of the incoming weight.
int activeInputs = 0;
ICinemachineCamera camA = null;
ICinemachineCamera camB = null;
float camWeight = 1f;
for (int i = 0; i < playable.GetInputCount(); ++i)
{
CinemachineShotPlayable shot
= ((ScriptPlayable<CinemachineShotPlayable>)playable.GetInput(i)).GetBehaviour();
float weight = playable.GetInputWeight(i);
if (shot != null && shot.VirtualCamera != null
&& playable.GetPlayState() == PlayState.Playing
&& weight > 0.0001f)
{
if (activeInputs == 1)
camB = camA;
camWeight = weight;
camA = shot.VirtualCamera;
++activeInputs;
if (activeInputs == 2)
break;
}
}
float deltaTime = info.deltaTime;
if (!mPlaying)
{
if (mBrainOverrideId < 0)
mLastOverrideFrame = -1;
float time = Time.realtimeSinceStartup;
deltaTime = Time.unscaledDeltaTime;
if (!Application.isPlaying && (mLastOverrideFrame < 0 || time - mLastOverrideFrame > Time.maximumDeltaTime))
deltaTime = -1;
mLastOverrideFrame = time;
}
// Override the Cinemachine brain with our results
mBrainOverrideId = mBrain.SetCameraOverride(
mBrainOverrideId, camB, camA, camWeight, deltaTime);
}
float mLastOverrideFrame;
public override void PrepareFrame(Playable playable, FrameData info)
{
mPlaying = info.evaluationType == FrameData.EvaluationType.Playback;
}
}
}
CinemachineShot(ClipAsset)
using UnityEngine;
using UnityEngine.Playables;
using UnityEngine.Timeline;
namespace Cinemachine.Timeline
{
public sealed class CinemachineShot : PlayableAsset, IPropertyPreview
{
public ExposedReference<CinemachineVirtualCameraBase> VirtualCamera;
public override Playable CreatePlayable(PlayableGraph graph, GameObject owner)
{
var playable = ScriptPlayable<CinemachineShotPlayable>.Create(graph);
playable.GetBehaviour().VirtualCamera = VirtualCamera.Resolve(graph.GetResolver());
return playable;
}
// IPropertyPreview implementation
public void GatherProperties(PlayableDirector director, IPropertyCollector driver)
{
driver.AddFromName<Transform>("m_LocalPosition.x");
driver.AddFromName<Transform>("m_LocalPosition.y");
driver.AddFromName<Transform>("m_LocalPosition.z");
driver.AddFromName<Transform>("m_LocalRotation.x");
driver.AddFromName<Transform>("m_LocalRotation.y");
driver.AddFromName<Transform>("m_LocalRotation.z");
driver.AddFromName<Camera>("field of view");
driver.AddFromName<Camera>("near clip plane");
driver.AddFromName<Camera>("far clip plane");
}
}
}
CinemachineShotPlayable(ClipPlayable)
using UnityEngine;
using UnityEngine.Playables;
using UnityEngine.Timeline;
namespace Cinemachine.Timeline
{
internal sealed class CinemachineShotPlayable : PlayableBehaviour
{
public CinemachineVirtualCameraBase VirtualCamera;
}
}
PlayableDirector(控制TimeLine使用)
void ShowFunction()
{
//--设置时间
playableDirector.time = playableDirector.duration / 2;
//--开始播放
playableDirector.Play();
//--暂停
playableDirector.Pause();
//--恢复
playableDirector.Resume();
//--停止
playableDirector.Stop();
//--获取根节点的Playable
PlayableGraph pg = playableDirector.playableGraph;
Playable rpa = pg.GetRootPlayable(0);
//--获取根节点的输入节点,可以使用递归获取所有playable节点
for (int i = 0; i < rpa.GetInputCount(); i++)
{
var ppa = rpa.GetInput(i);
}
foreach (var bingding in playableDirector.playableAsset.outputs)
{
//bingding.streamName--轨道名称
// bingding.sourceObject--轨道--获取到轨道就可以获取ClipAsset
TrackAsset trackAsset = bingding.sourceObject as TrackAsset;
//bingding.outputTargetType--轨道绑定的类型
}
}
结束语
以上就是简单的用法。可以复制粘贴了。