LoginSignup
7
3

More than 5 years have passed since last update.

Script Execution Orderのちょっと深い話

Posted at

まずは普通に

Base クラスから派生する Derived1, Derived2, Derived3 と、派生しない Class4, Class5 を以下のようにヒエラルキーに置いてみます。

Test1.png

Start関数内で自分のクラス名を表示する処理を書いて実行すると、以下のように表示されます。

Test1_Result.png

実行順を指定しない場合はコール順が不定になります。
これはUnityのマニュアルにも記載のある通り、規定の動作です。

Orderを指定する

Script Execution Orderで、
Derived1>Derived2>Derived3>Class4>Class5
の順に実行するように設定します。

Test2.png

実行すると、意図通りの表示となりました。

Test2_Result.png

次は、
Class4>Derived1>Derived2>Derived3>Class5
の順に実行するように設定します。

Test3.png

実行すると、意図通りの表示となりました。

Test3_Result.png

ここまでは問題ありません。

基底クラスに設定するとどうなるか

Class4とClass5の間に、Baseクラスを継承したクラス全てをコールするようにしたい場合、Baseクラスに指定すれば良いように思えます。
例えば以下のような設定をしてみます。

Test4.png

すると以下のような表示になりました。

Test4_Result.png

残念ながら、Script Execution Orderに基底クラスを指定しても、そこから派生したクラスには実行順の設定が反映されません。

Script Execution Orderではなく、スクリプトに直に実行順を書いてみます。

Test5.png

実行してみると、不安定な結果となりました。

Test5_Result.png

継承されたクラスの実行順を操作したい場合、必ず派生先のクラスを指定する必要がありそうです。

マルチシーンの場合

Derived1~3とClass4~5を別々のシーンに分けてみます。

Test6a.png

実行順は元に戻しておきます。

Test6b.png

実行してみると、以下のように表示されます。意図通りですね。

Test6_Result.png

しかしここには罠があります。
Test2シーンをアクティブにして、再度実行してみます。

Test7.png

実行すると、以下のように表示されます。

Test7_Result.png

Class4~5とDerived1~3の実行順が入れ替わってしまいました。
Script Execution Orderは同一シーンの中での実行順を操作するもので、シーンを跨いだ実行順の操作はできないようです。
Test1に最優先で実行して欲しいスクリプトがあったとしても、Test2に置かれているスクリプトより前に実行することは出来ない、ということになります。

この時、Awakeはどのタイミングで呼ばれているのでしょうか。
AwakeとStart、それぞれのタイミングでログを出力するようにしてみます。

Test8_Result.png

AwakeとStartはシーンとは関係なく、別々のレイヤーで呼ばれていることが分かります。
例えばTest1に初期化が必要なオブジェクトがあった場合、Awakeで初期化しておけば、Test2ではStartから使えるようになります。

まとめ

  • 基底クラスにScript Execution Orderは効かない
  • スクリプトの実行順はシーンごとに制御され、シーンを跨いでくれない
7
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
3