はじめに
Unity TimelineのActivation Trackで適当なオブジェクトを割り当て、そのオブジェクトのOnEnable()
,OnDisble()
でスクリプトを実行する方法があります。
その方法を試そうとActivation Trackをいじくりまわしていたところ、OnEnable()
が何故かTimeline上で非アクティブにしているのにも関わらず、最初に実行されたり、また弄ると実行されなかったりと、動作がよくわからなかったので、実行結果が変化する原因を探ってみました。
結果だけ知りたい方は、現状でわかったこと まで読み飛ばしてください。
#環境
- Unity2018.1.3f1
Activation Trackで関わってくる知識
Unityのイベント関数について
Unityのイベント関数について、詳しくは イベント関数の実行順を見てください。
Start()
, Update()
,OnEnable()
,OnDisable()
については、以下の通りになります。
Start()
スクリプトのインスタンスが有効になると、最初のフレームのアップデート前に Start が呼び出される
Update()の前に呼び出される関数です。
Update()
フレームごとに一度呼び出されます。これは、フレームのアップデートのメインとなる関数です。
OnEnable()
(オブジェクトがアクティブな場合にのみ呼び出されます。) この関数は、オブジェクトを有効にした直後に呼び出されます。これは、MonoBehaviour インスタンスが作成されたとき (例えば、レベルが起動されたときや、スクリプトコンポーネントがアタッチされたゲームオブジェクトがインスタンス化されたとき) に発生します。
Unityでタイムラインを使ってゲームのイベントシーンの動きを作成してみる
では、タイムライン上でシーンの切り替えを行う際にOnEnable()
を使用していました。
今回、私もこの記事を参考にし、あるタイミングでタイムラインを切り替えるためにこの関数を使用しました。
OnDisable()
オブジェクトが破棄される直前のフレーム更新後に OnDestroy が呼び出されます。(オブジェクトは Object.Destroy あるいはシーン終了時に破棄されます)
実行順番
実行順番は
OnEnable()
Start()
Update()
OnDisable()
になります。
Playable Directorについて
Playable Directorのプロパティーについて、Play On Awake
とWrap Mode
について説明します
Play On Awake
チェックすることでゲームプレイ開始と同時にタイムラインも動作します。
Wrap Mode
タイムラインインスタンスが再生を終了するときの動作です
- Hold
- タイムラインの最後の状態を維持します。
- Loop
- タイムラインを繰り返し再生します。
- None
- タイムラインの再生前に戻します。
ロックボタン
Timelineの右上にあるボタン
他のオブジェクトを押したとき、勝手にTimeline参照先が切り替わらないようにするもの。
とりあえず、ここを押しとけといわれる箇所。
正直よくわかっていません
Timelineウィンドウは、他のオブジェクトを選択するたびに表示が途切れますので、ロックをかけておくことをおすすめします。
また、「Preview」が押されていない場合は、Trackにオブジェクトを紐付けることができません。Previewが押せない場合は、
一度noneを選択して、再度指定のTimelineを選ぶと押せるようになります。
と書いてました
Previewボタン
用意したもの
Cubeオブジェクトを用意し、そこに作成したスクリプトをアタッチします。
作成したスクリプトは以下になります。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class EventTest : MonoBehaviour {
// Use this for initialization
private bool isOnceUpdate=true;
void Start () {
Debug.Log("Start");
}
void OnEnable(){
Debug.Log("OnEnable");
}
// Update is called once per frame
void Update () {
if(!isOnceUpdate) return;
Debug.Log("Update");
isOnceUpdate=false;
}
void OnDisable(){
isOnceUpdate=true;
Debug.Log("OnDisable");
}
}
Update
が何回も表示されるのは鬱陶しいので、1回だけ表示するようにしました。
また、タイムラインも2つ用意しました。
- Activeタイムクリップを再生直後に配置したTimeLine(FirstActive)
- emptyはTimelineの再生長さを長くするために配置しています。
- Activeタイムクリップを再生から少し時間をおいて配置したTimeLine(LastActive)
現状でわかったこと
いろいろと弄っていた結果、
__Previewボタン__を__OFF状態__で、スクリプトをアタッチしているオブジェクトをアクティブにすれば、実行時にそのオブジェクトがアクティブになり(おそらくフレーム1回分)、その後、TimelineのActivation Trackにそってアクティブ状態が切り替わることがわかりました
わかりにくいので、具体例を出します。
ここでは、Activeタイムクリップを再生から少し時間をおいて配置したTimeLine(LastActive)を用意し、EventTestというオブジェクトをバインディングしてます。また、EventTestにはEventTest.csを割り当てています。
現在、__Preview : ON__でEventTestが__非アクティブ__になっていますが、
__Preview : OFF__にすると
EventTestが__アクティブ__になります。
TimeLineを非アクティブにした場合もEventTestが__アクティブ__になります。
つまり、EventTargetはTimelineに操作されていない状態ではアクティブ状態にあるので、
実行した場合、最初にOnEnable()
やStart()
が呼ばれます。
実行回数は1回ずつ実行していました。
なぜそのようなことになるかは具体的には調べ上げていないのですが、
Activation Trackを使ったスクリプト実行をしようとして上手くいかなければ
__Previewボタン__を疑ってください。
最後に
おそらく、【Unity】知らないと苦労するかもしれない、Timelineと座標の話の「Timelineを編集後、キャラの位置がズレるのはPreview中にキャラの位置を編集しているため」の項目に書かれている内容と似ている気がします。
どなたか詳しい方がいらっしゃいましたら、教えていただきたいです。