テラシュールブログ

旧テラシュールウェアブログUnity記事。主にUnityのTipsやAR・VR、ニコニコ動画についてのメモを残します。

【Unity】IExposedPropertyTableを使った、アセット↔シーン間連携

今回はPlayableDirectorで使用しているIExposedPropertyTableを利用してみます。

正直言えば使える機能では無いように思いますが、この実装からTimelineのResolver運用周りを見直すことが出来たら幸いです。

IExposedPropertyTableはアセットからシーン内のオブジェクトを参照する

IExposedPropertyTableは、PlayableDirector(Timeline等)で使用されているアセットからシーン内のオブジェクトを参照する為のインターフェースです。
厳密には異なるかもしれませんが、用途としてはそんな感じです。

 

基本的にUnityはシーン間参照が出来ません。シーン内のオブジェクトがシーン内のオブジェクトもしくはシーン外のオブジェクトを参照する事は可能なのですが、シーン外のオブジェクトからシーン内のオブジェクトへアクセスする場合には、動的にオブジェクトを参照する必要があります。

f:id:tsubaki_t1:20171231153756j:plain

IExposedPropertyTableは、上でも紹介している通りアセットからシーン内部のオブジェクトを参照する際に使用できます。

 

TimelineのPlayableAsset(Timelineを定義したもの)がシーン内のオブジェクトを参照するために、こういった機構が必要になったという感じです。

f:id:tsubaki_t1:20171231154350j:plain

まぁ、コードを見れば分かるのですが最終的にScriptableObjectを動かしてるのはSceneのコンポーネントなので、もっと良い手が一杯あるんじゃないかなという気もしますが。

IExposedPropertyTableを実際に使用してみる

実際に使用してみます。

やることとしては、「動作とパラメータを持つScriptableObject」と「シーン内のオブジェクトを選択するIExposedPropertyTableを持つコンポーネント」を用意し、ScriptableObjectにコンポーネントの動きを制御してもらいます。

 

今回の内容では、ScriptableObjectに指定したオブジェクトとカメラを回してもらいます。こんな感じ。

f:id:tsubaki_t1:20171231135316g:plain

サンプルコード

まずはサンプルコードをプロジェクトに入れてみます。

ResolverTestがコンポーネントの割当を行う処理、SampleDataがシーン内のオブジェクトを操作するScriptableObjectです。

SampleDataのDoの内容を書き換えると、他の操作を実現できます。

 

 

gist.github.com

ScriptableObjectのセットアップ

ScriptableObjectのセットアップです。

単純に、ScriptableObjectを作るだけですが。

f:id:tsubaki_t1:20171231135525j:plain

シーン内のオブジェクトとScriptableObjectをバインド

次にシーン内のオブジェクトとScriptableObjectをバインドします。この手順はややっこしいです。

  1. 適当なオブジェクトにResolverTest コンポーネントを登録します。
  2. (初回のみ)ObjとMainCameraの項目を、Expose Propertyします。
  3. オブジェクトをドラッグ&ドロップで登録します。

f:id:tsubaki_t1:20171231143815g:plain

要素を増やす

要素を増やしたい場合、サンプルコードならSampleDataのExposedReferenceを増やせばOKです。

コンポーネント側は特に変更なく、Sceneの操作とScriptableObjectの定義の変更で行けます。

f:id:tsubaki_t1:20171231150101j:plain

Expose Propertyって何してるの?

ScriptableObjectにExpose Nameをセットしています。

Resolver TestはこのExposedNameを保持しているので、ScriptableObjectは同一のExposedNameを参照出来ている感じです。

これを行わない場合、Default Valueを使用するみたいですが、その後のフローが意味不明なので触らない方が吉です。

f:id:tsubaki_t1:20171231144322j:plain

なお、Expose NameはどうもGUIDを生成しているらしく、要するに一度Unexpose Propertyすると他の参照関係が全て駄目になります。

さらに言えば、参照するためのIDが毎回個別に発行される為、SampleDataを継承して多様性的な使い方をしようと思った時、参照先のオブジェクトを全て再登録する必要が出てきます。「クラス名と要素名のパスからのハッシュ」で作ってくれたら楽なんですが…

異なる振る舞いを流し込む的な

クラス名やら要素名やらでハッシュを作ってくれない問題ですが、実は自分でExposedNameをセットしてやれば良いです。

それをもう少し発展させて「振る舞いが異なるが引数が同一の動作の流し込み」を行ってみます。

ソースコードはこんな感じ。
特徴はSampleDataが抽象クラスに変更している点と、SampleDataを継承しているクラスの存在です。

SampleDataを継承したSampleAction達には、異なる動作が定義されており、かつ引数も異なる引数を定義できます。共通の項目は同一のパラメータを使います。

gist.github.com

f:id:tsubaki_t1:20171231152449g:plain

一つの定義で複数の異なるオブジェクトを動かす

IExposedPropertyTableのstatic系との違いは、複数のインスタンス存在出来る点かなと思います。

staticだと登録できるオブジェクトは全体で一つ、これを複数にすると色々と面倒になってきます。

IExposedPropertyTableを使用した場合は、複数のオブジェクトにScriptableObjectで定義した動作を流し込める点が便利です。

まぁ…これが使えるのはSO内にキャッシュを持ってない場合のみで、キャッシュを持つと使えなくなる、しかしキャッシュしないとパフォーマンスのジレンマがありますが。

 

関連

動画の解説
ソースが動画でしか紹介されておらず、かつ全文を公開していないので、実際に試すのに無駄な時間がかかります。

www.youtube.com

tsubakit1.hateblo.jp

良いお年を。