Skip to main content

データ入力ウォッチャー

データ入力の値がいつ変更されたかを知りたいことはよくあります。たとえば、次のコードでは、ユーザーがデータフォルダーのMyPluginFilesディレクトリからファイルを選択できます。

[DataInput]
[AutoCompleteList(nameof(AutoCompletePluginFiles), forceSelection: true)]
public string SelectedFile;

protected async UniTask<AutoCompleteList> AutoCompletePluginFiles() {
return AutoCompleteList.Single(Context.PersistentDataManager.GetFileEntries("MyPluginFiles").Select(it => new AutoCompleteEntry {
label = it.fileName,
value = it.path
}));
}

ユーザーが新しいファイルを選択したときに知りたいとします。単純な方法は、毎フレームSelectedFileの値を確認することですが、これは非効率で煩雑です。代わりに、OnCreate()でウォッチャーを登録できます。

protected override void OnCreate() {
base.OnCreate();
Watch<string>(nameof(SelectedFile), OnSelectedFileChanged);
}

protected void OnSelectedFileChanged(string from, string to) {
if (to == null) {
// The user has cleared the selected file
}
// More logic to handle the file change
}

オーバーロードされたWatch<T>(Entity otherEntity, string dataInputKey, Action<T, T> onChange, bool deep = true)メソッドを使用して、別のエンティティのデータ入力を監視することもできます。

ヒント

ウォッチャーは、エンティティが破棄されると自動的に登録解除されます。

アセットの状態を監視する​

単なる値の変更以上を監視したい場合があります。たとえば、ユーザーが新しいCharacterを選択するたびにメッセージを出力する、次のシンプルなアセットを考えてみましょう。

[DataInput]
public CharacterAsset Character;

protected override void OnCreate() {
base.OnCreate();
Watch<CharacterAsset>(nameof(Character), OnCharacterChanged);
}

protected void OnCharacterChanged(CharacterAsset from, CharacterAsset to) {
if (to != null) Debug.Log("New character file selected! " + to.Source);
}

ただし、このウォッチャーがトリガーされるのは、現在のアセットのCharacterデータ入力の値が変わったときだけです。つまり、シーンにキャラクターが2つある場合、ユーザーが一方のキャラクターからもう一方に変更するとウォッチャーがトリガーされます。しかし、シーン内にキャラクターアセットが1つだけあり、ユーザーがそのキャラクターアセットに入り、Sourceデータ入力を変更した場合、このウォッチャーはトリガーされません。

この場合は、WatchAssetを使用できます。

protected override void OnCreate() {
base.OnCreate();
WatchAsset(nameof(Character), OnCharacterChanged);
}

protected void OnCharacterChanged() {
if (Character.IsNonNullAndActive()) Debug.Log("New character file selected! " + Character.Source);
}

このウォッチャーは、Characterの値が変更されたときと、CharacterアセットのSourceデータ入力が変更されたときの両方でトリガーされるようになりました。

情報

なぜこれが機能するのでしょうか。WatchAssetメソッドは、アセットのアクティブ状態が変わったときにもウォッチャーをトリガーします。Warudoでは、Sourceデータ入力を持つすべてのアセットは、Sourceデータ入力に基づいてアクティブ状態を切り替えます。たとえば、CharacterAssetはSourceで.vrmモデルまたは.warudo形式のキャラクターModを読み込み、PropAssetはSourceで.warudo形式の道具Modを読み込みます。アクティブ状態がtrueになるのは、Sourceが正常に読み込まれた場合のみです。

現在Sourceが選択されているアクティブなアセットがあるとします。ユーザーが新しいSourceを選択すると、アクティブ状態はfalseに設定され(ウォッチャーがトリガーされます)、新しいSourceが正常に読み込まれれば再びtrueに設定されます(ウォッチャーがもう一度トリガーされます)。上記のコードでは、最初のトリガー時にはキャラクターアセットがまだアクティブではないため、メッセージを出力するのは2回目のトリガーだけです。

複数のデータ入力を監視する​

複数のデータ入力を監視し、どの入力が変わったかは問わず、いずれかが変更されたときにコールバック関数を実行したい場合は、WatchAllメソッドを使用できます。

protected override void OnCreate() {
base.OnCreate();
WatchAll(new [] { nameof(A), nameof(B), nameof(C) }, OnAnyDataInputChanged);
}

protected void OnAnyDataInputChanged() {
// Called when A, B, or C changes
}
最終更新日 2026.10.06