Unity スクリプトリファレンス (API) の CustomAnimationPlayable
クラスを使って、カスタムアニメーションの Playables を作成できます。
スクリプトリファレンス (API) で、 PrepareFrame
メソッドの overloading を使って、必要に応じてノードを処理します。
下のスクリプト例では、アニメーションクリップを次々に再生することが目的です。ノードのウェイトを変えることで一度にひとつのクリップのみが再生されるようにし、クリップのローカルタイムを調整することでアクティベートと同時に開始されるようにします。
また同様にカスタム Playable は、 OnSetPlayState
と OnSetTime
メソッドの使用も可能で、Playable の状態やローカルタイムが変更されたときにカスタム挙動を指定することができます。
using UnityEngine;
using UnityEngine.Experimental.Director;
public class PlayQueuePlayable : CustomAnimationPlayable
{
public int m_CurrentClipIndex = -1;
public float m_TimeToNextClip;
public AnimationMixerPlayable m_Mixer;
public PlayQueuePlayable()
{
m_Mixer = AnimationMixerPlayable.Create();
AddInput(m_Mixer);
}
public void SetInputs(AnimationClip[] clipsToPlay)
{
foreach (AnimationClip clip in clipsToPlay)
{
m_Mixer.AddInput(AnimationClipPlayable.Create(clip));
}
}
override public void PrepareFrame(FrameData info)
{
// 必要なばあいは、次のクリップに進む
m_TimeToNextClip -= (float)info.deltaTime;
if (m_TimeToNextClip <= 0.0f)
{
m_CurrentClipIndex++;
if (m_CurrentClipIndex < m_Mixer.inputCount)
{
var currentClip = m_Mixer.GetInput(m_CurrentClipIndex).CastTo<AnimationClipPlayable>();
// 時間をリセットします。すると、次のクリップが正しい位置で開始します。
currentClip.time = 0;
m_TimeToNextClip = currentClip.clip.length;
}
else
{
//キューが完了したら停止
state = PlayState.Paused;
}
}
// 入力のウェイトを調節
for (int a = 0; a < m_Mixer.inputCount; a++)
{
if (a == m_CurrentClipIndex)
m_Mixer.SetInputWeight(a, 1.0f);
else
m_Mixer.SetInputWeight(a, 0.0f);
}
}
}
[RequireComponent (typeof (Animator))]
public class PlayQueue : MonoBehaviour
{
public AnimationClip[] clipsToPlay;
void Start ()
{
var playQueue = Playable.Create<PlayQueuePlayable>();
playQueue.SetInputs(clipsToPlay);
// キューをプレイヤーに紐づけます
GetComponent<Animator>().Play(playQueue);
}
}
Playable が Unity スクリプトリファレンス (API) によって作成されると、Unity はその Playable に対して行われた接続を内部的に記録します。新しいシーンが読み込まれると、すべての Playable に割り当てられたリソースが Unity によって自動的にリリースされます。
ただし、シーンで特定の Playable の使用が終わったら Playable.Destroy()
を手動で呼び出すとよいでしょう。そうすることによって、Unity が内部リソースを再利用することが可能になり、プロジェクトのスピードが不要に遅くなるのを避けることができます。
注意 Object.Destroy()
と同じ方法で Playable.Destroy()
を使用します。