EventSystemのExecutionOrderに勝つ


概要

ほら、ScriptのExecutionOrderってあるじゃない。

で、EventSystemのExecutionOrderを上回りたいんだけどよくわからなかったので、調べてみた。



前提知識

UnityのEventSystemは、ざっくり書くと次のような構造でイベントを処理している。


1.EventSystemのUpdateで毎フレーム処理を開始

2.InputModule系でInput系の入力(Input.GetMouseButtonUpとか)を解析

3.奥深くにあるExecuteEvents系を着火

4.処理をUnityEventの系統に変換し、対象となるオブジェクトのメソッドを実行


で、このEventSystemのUpdateが発生する順番が、暗黙でべらぼうに高速なのがわかったっていう話。



調べ方

EventSystemの中で、次のような、StandaloneInputModuleを拡張したクラスを作って、その実行順を上回れないかどうか試す。


public class MyInputModule : StandaloneInputModule {

        public override void Process () {

            Debug.Log("processing. count:" + Time.frameCount + " button:" + Input.GetMouseButtonUp(0));

            base.Process();

        }

 }


で、実際に上回るには、いろいろな方法で実行順をセットできるんだけど、

参考:

【Unity】コンポーネントのイベント実行順についてのTips

http://tsubakit1.hateblo.jp/entry/2017/02/05/003714


個人的な事情により、metadataを書き換える方法で臨んでみる。


まあこんなmetadataを持つようなMonoBehaviourを継承したインスタンスがあったとして、

fileFormatVersion: 2

guid: d539e8a5875684b56879dabc6b0f9847

timeCreated: 1491113951

licenseType: Pro

MonoImporter:

  serializedVersion: 2

  defaultReferences: []

  executionOrder: 0

  icon: {instanceID: 0}

  userData: 

  assetBundleName: 

  assetBundleVariant: 


このexecutionOrderのところをいじればいいわけで。簡単。



いじってみた

-10 x

-100 x

-999 x

-1000 o


-1000になったところで、EventSystemと同列の時間軸に並ぶ。

で、あとはGameObjectの生成順の話になるので、

EventSystemより高速にGameObjectを生成できれば勝てる。