Programming in VRChat

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

YAML Asset Browser

An editor extension for browse YAML formatted asset of Unity. You can check asset contents comparing with YAML formatted text.

in Japanese: Unity の YAML 形式のアセットを閲覧するエディタ拡張。 YAML 形式のテキストと比較しながらアセットの内容を確認できる。

f:id:naqtn:20190904091825p:plain f:id:naqtn:20190903210742p:plain

README (English)

Open asset file

  • 1: Your project has to use "Force Text" asset serialization setup

    • If you are not sure, check Unity menu > Edit > Project Settings > Editor Settings > Asset Serialization.
    • (Reference: EditorManager in Unity manual ) f:id:naqtn:20190903210843p:plain
  • 2: Open YAML Asset Browser window from Unity menu

    • Unity menu > Window > VRC_Iwsd > Yaml Asset Browser
  • 3: Select an asset object in Project window as usual Unity operation
  • 4: Press "Load" button on toolbar of YAML Asset Browser
    • Then you'll see the tree structure and YAML text of the asset

f:id:naqtn:20190903212508p:plain

  • You can also drag and drop resource file to asset path field
    • You can drag and drop from outside of Unity Editor (using File Explorer on Windows, Finder on Mac (though I don't test it))
    • You can drag scene object from Hierarchy window to see scene asset file
  • If you select a prefab instance in Hierarchy window, YAML Asset Browser loads that prefab
  • If selected object is not related asset, nothing will happen.
  • YAML Asset Browser loads asset file independently from Unity editor. So editing asset doesn't affect to YAML Asset Browser view. To update, you have to reload manually.
  • Each time you select menu, new window will be shown up.
    • Each window does loading independently

Browse

  • Tree view shows asset structure
    • For scene file, you can browse not only GameObject hierarchy but also non-component objects (e.g. LightmapSettings, RenderSettings)
    • TODO: Prefab instances in scene file are not well located in the tree. They are placed in "Others" folder temporarily.
    • TODO: build better hierarchy for animation controller
  • Each tree item has "line xxx" text. This is line number of where the item comes in YAML formatted asset file.
    • If click tree item, then YAML text scrolls to that line
  • Search text input field on toolbar filters tree item by its text matching

f:id:naqtn:20190903215821p:plain

Search

  • Search by fileID (Local Identifier in file)
    • Input "fileID" to search element in the asset
    • Result is shown in text area below
    • If "and select it" is checked, found tree item will be selected.
    • (Hint: You can use double click YAML text to select fileID value and copy from context menu. (parts marked green in following capture))

f:id:naqtn:20190903221902p:plain

  • Search by GUID
    • Input GUID value to search reference target to another asset

f:id:naqtn:20190903223821p:plain

  • Search by fileID and GUID
    • Input fileID and GUID to search reference target in another asset
    • query string format is like "fildID:xxxx guid:xxxx". Extra characters will just be ignored.

f:id:naqtn:20190903225010p:plain

Supported file type and extensions

YAML Asset Browser checks file extension to determine whether it's readable or not. Here's readable asset file type and its extensions.

  • prefab (.prefab)
  • scene (.unity)
  • animation controller (.controller)
  • animation (.anim)
  • material (.mat)
  • render texture (.renderTexture)
  • scriptable object (.asset)
    • You have to drag and drop to load for this type

Known issues

  • Prefab instances (in scene file) are not appears in GameObject hierarchy tree.
  • Stripped prefab in scene file is not handled well
    • (Stripped prefab seems relate to delete child element from prefab. I have to investigate more.)

README (日本語)

アセットファイルを開く

  • 1: プロジェクトの「asset serialization」の設定が「Force Text」になっている必要がある

f:id:naqtn:20190903210843p:plain

  • 2: Unity メニュー から YAML Asset Browser のウィンドウを開く
    • メニュー > Window > VRC_Iwsd > Yaml Asset Browser
  • 3: 通常の Unity 操作と同じように、Project ウィンドウでアセットを選択する
  • 4: YAML Asset Browser のツールバーにある "Load" ボタンを押す
    • アセットの木構造YAML 形式のテキストが表示される

f:id:naqtn:20190903212508p:plain

  • リソースファイルを、アセットパス(path)欄にドロップしてもよい
    • Windowsエクスプローラからのドロップもできる。(Mac の Finder も使えると思うがテストしていない)
    • Hierarchy ウィンドウからシーンをドロップすることもできる
  • Hierarchy ウィンドウでプレハブのインスタンスを選択すると、そのプレハブをロードする
  • 選択したオブジェクトがアセットに関連づいていない場合は何も起きない
  • YAML Asset Browser は Unity エディタとは独立してアセットファイルを読み込む。 このためアセットを編集しても YAML Asset Browser のビューには反映されない。 更新するには手動で再度ロードする必要がある。
  • メニューを選択するたびに新しいウィンドウが表示される。
    • それぞれのウィンドウは独立してロードを行う

閲覧する

  • ツリーはアセットの構造を表示する
    • シーンファイルでは、GameObject だけではなく、LightmapSettings, RenderSettings などの Component ではないオブジェクトも閲覧可能
    • TODO: シーン中のプレハブ・インスタンスはツリーの中で上手く位置づけられていない。"Others" の中に収められている。
    • TODO: アニメーション・コントローラでの適切な木構造作成(は未実装)
  • ツリー中のそれぞれのアイテムには "line xxx" のような表示がされる。これはその要素が YAML 形式のアセットファイルのどの行から来たのかを表示している
    • アイテムをクリックすると、YAML テキストがその行を表示するようにスクロールする
  • ツールバー上の入力欄は、テキスト一致でツリー表示をフィルターする

f:id:naqtn:20190903215821p:plain

検索する

  • fileID での検索 (Local Identifier in file)
    • アセット中の要素を検索するには "fileID" を入力する
    • 検索結果はすぐ下のテキストエリアに表示される
    • "and select it" トグルをオンにしておくと、見つかった要素をツリー中で選択する
    • (ヒント:YAML テキストをダブルクリックすることで fileID の値を選択し、コンテキストメニューからコピーできる。(次のキャプチャで緑の部分))

f:id:naqtn:20190903221902p:plain

  • GUID での検索
    • 他のアセットの参照を検索するには GUID 値を入力する

f:id:naqtn:20190903223821p:plain

  • fileID と GUID での検索
    • 他のアセット中の要素の参照を検索するには fileID と GUID を入力する
    • 検索文字列のフォーマットは "fildID:xxxx guid:xxxx" のようにする。余分な文字は無視される。

f:id:naqtn:20190903225010p:plain

対応ファイル種と拡張子

YAML Asset Browser は拡張子を検査して、読み込めるかどうかを判断している。 以下が対応しているアセットの種類と拡張子である。

  • prefab (.prefab)
  • scene (.unity)
  • animation controller (.controller)
  • animation (.anim)
  • material (.mat)
  • render texture (.renderTexture)
  • scriptable object (.asset)
    • これをロードするにはドラッグ&ドロップの方法を使うこと

既知の問題

  • シーンファイル中のプレハブ・インスタンスが、ツリー上で適切な場所に配置されない
  • シーン中の「Stripped prefab」は上手く扱えていない
    • (「Stripped prefab」はプレハブから子要素を削除することに関係している模様。要調査。)

ActivateTrigger

OnTriggerEnter をきっかけとして指定した動作を行う Standard Assets 中のスクリプト

f:id:naqtn:20190812132552j:plain

Standard Assets/Utility/ActivateTrigger

パラメタ

動作の種類(Mode)

行える動作の種類 Mode は以下。いずれかを選ぶ。

名称 動作内容
Trigger 他の ActivateTrigger へトリガーを送る
Replace 対象 GameObject を別の新規作成したもので置き換える
Activate 対象 GameObject を active にする
Enable 対象 Component(正確には Behaviour) を enable にする
Animate 対象 GameObject の Animation を Play する
Deactivate 対象 GameObject を 非 active にする

OnTriggerEnter に対する動作の実行条件

  • デフォルトでは、「OnTriggerEnterを検出した時に一回限り」実行する
  • triggerCount に値を入れると、「その回数の OnTriggerEnter を受けた時に一回限り」実行する、になる
  • repeatTrigger が有効であると、「OnTriggerEnter を受けた時に毎回」実行する、になる。(triggerCount は無視される)

対象 (target)

  • 対象は target に指定する
  • None にした場合は、この ActivateTrigger が置かれている GameObject が対象になる
  • 指定した対象がどのように扱われるかは Mode による。
  • いろいろなものが指定できてしまうが、動作の意味内容からして無効なものは無視される

NOTE:

  • target に Component を指定しているが Mode で指定された動作が GameObject を必要とする場合は、Component が置かれている GameObject が対象になる。
  • 型が UnityEngine.Object であるため無意味なものも含め色々なものが指定できてしまうが、実行時に無視される。

各 Mode について補足

Mode Trigger 補足

  • 対象 GameObject 以下に置かれている ActivateTrigger でそれぞれ OnTriggerEnter が起きたことと同じになる。

NOTE: BroadcastMessage("DoActivateTrigger") を行っている。 つまり対象を含み、全ての子孫 GameObject 上の ActivateTrigger に働きかける。

Mode Replace 補足

  • 対象 GameObjectを他の新規のGameObjectに置き換える
  • 新規作成する GameObject は source でコピー元を指定する
  • source はシーン上のオブジェクトであっても、プレハブであっても構わない
  • position と rotation だけが新しいオブジェクトに引き継がれる。scale は引き継がれない

NOTE: 内部的には Instantiate と DestroyObject の実行。

Mode Enable 補足

  • 対象となるコンポーネントは Inspector で名前部分をドラッグすることで設定できる
    • Inspector を二つ表示して、片方をロックしてからドラッグする
  • 対象の型は UnityEngine.Component ではなくて UnityEngine.Behaviour になっている
  • よって全てのコンポーネントが指定できるわけではない
    • 例えば AudioSource, Light, StandardAssets 中の C# スクリプト は指定可
    • 例えば MeshRenderer, 各種 Collider は指定不可

NOTE: 継承構造をおさらいすると Behaviour extends Component 、MonoBehaviour extends Behaviour である。 ここは Component でいいはずなのになぜか必要以上に限定して Behaviour にしている。 作者は「C# スクリプトの動作を開始させる」という意図だったのかもしれない。

内部 API

  • DoActivateTrigger() が OnTriggerEnter で実行されるメソッドである
  • BroadcastMessage や Button などから実行できる
  • (private であるため Button の UI Event から実行する設定には特殊な方法が必要)

メモ

  • 名前が実態を表していなくて分かりにくい。
  • ActivateTrigger という名前は「何かを active にする trigger」あるいは「trigger を activate するもの」だと読めるが、実態はそうではない。 「trigger によって何かの動作を activate するもの」である。(歴史的に Mode Activate の動作が先にあって、それに命名が引きずられたのかも)
  • VRC_Trigger の OnEnterTrigger の代替になりうる。万能ではないが。
  • Mode Replace は VRChat ワールド開発において貴重な Instantiate を行う手の一つ。