Programming in VRChat

VRChat でのプログラミングについて調べたことの書き溜め

Unity オブジェクトの「アクティブ」とコンポーネントの「有効」

ワールドやアバターを構成する Unity のオブジェクトやコンポーネントは、配置したまま一時的に機能を停止させることが出来る。

f:id:naqtn:20180420213708p:plain

VRChat では

  • オブジェクトの active は SetGameObjectActive で設定する。
  • コンポーネントの enable は SetComponentActive で設定する。
  • いずれも引数の設定で、有効化(True)、無効化(False)、変更(Toggle)の操作ができる。
  • 初期状態は上のキャプチャの位置のチェックボックスで設定する。
  • 関連するトリガーとして OnEnable がある。

オブジェクトの「アクティブ」

ここからは VRChat から離れて、その前提となる Unity の知識を整理する。 (毎度混乱するので公式のマニュアルから知識を書き出してまとめてみる。混乱は歴史的事情なのかなぁ?)

  • GameObject にはオブジェクトが動作するか(駆動されるか)どうかを意味する "active" という概念がある。
  • 親子木構造の中での active について
    • GameObject は木構造をなすのでオブジェクト自身が active と設定されていても、親が active でない場合にはオブジェクトは駆動されない。
    • 設定関数は SetActive は、そのオブジェクト自身の active 状態を設定する。
    • プロパティ activeSelf は、そのオブジェクト自身の active 状態を保持する。
    • プロパティ activeInHierarchy は、木構造の中で active かどうかを反映する。つまりオブジェクトがシーンの中で実際に active かどうかを示す。
  • マニュアル

コンポーネントの「有効」

  • コンポーネントの「有効」の定義があるのは、Component クラスではなくそれを継承する Behaviour
    • 変数名は enabled
    • d が付く動詞の過去分詞形。
    • (active の方は形容詞 active であって、動詞過去分詞形 activated ではない。)
  • GameObject の active と異なり別途の設定関数は無い。enabled に直接代入するように書く。
  • 状態変化を受け取る関数 OnEnable, OnDisable が定義されているのは Behaviour ではなく、それを継承する MonoBehaviour
    • 関数名は正確には OnEnable と d が付かない。変数名と微妙に違う。
  • OnEnable, OnDisableenabled だけではなく、その MonoBehaviour が add されている GameObject の active 状態も合わせて反映する。
    • 要するに「その MonoBehaviour が駆動されるかどうか」の状態変化をきちんと反映してくれる。
    • 例えば親の GameObjectSetActive 呼び出しで、子に add されている MonoBehaviourOnEnable, OnDisable まできちんと呼んでくれる。
    • OnEnable() のドキュメント は そのへん「This function is called when the object becomes enabled and active.」というように、 enabled と active がなんかごっちゃに書いてある。(初見分かりにくい。object に enabled の概念があるように読める。)
  • マニュアル・チュートリアル

(おまけ) Awake, Start, OnDestroy

考察

  • インスペクタでチェックボックスを持つコンポーネントと持たないコンポーネントがあるのは、継承元が Behaviour なのか Component なのかの違いと思われる。
  • 理解が混乱する要因:
    • 名称について、形容詞、動詞、過去分詞、の使い方の方針が良く分からない。一貫性が感じられない。
    • 説明文章の中では MonoBehaviour という語に言及されることは稀。 「有効」の概念は Component ではなく MonoBehaviour で定義されていて、かつ通常これを継承してスクリプトは書かれるわけだが、 それらは「コンポーネント」と呼ばれる。また「有効」についても Component 自身にはその概念が無いのだが「コンポーネントの有効」のように呼ばれる。
  • VRChat の OnEnable について:
    • OnEnable トリガーの説明 「when the gameobject the VRC_Trigger component is attched to is enabled」は(も)かなりいい加減。 これではオブジェクトに enable があるように読めるし、VRC_Trigger 自身の enabled について何も言及していない。
    • OnEnable の発生条件はきちんと分かっていない。参考: http://vrcworld.wiki.fc2.com/wiki/OnEnable
    • 対になる OnDisable が無い。 OnDisable が VRChat 2018.2.1 で追加された。