VRChatのUdonでObject-Spawnさせたくてキレ散らかした
Merlin is GOD (MerlinさんはUSharpの開発者だ。一日三回礼拝の時間を取ろう。)
前置き
これは2021年2月頃の環境での知見。
君がこの記事を読んでいる頃にはすでに素晴らしく明瞭な手段が実装されているかもしれない。
あとVRChatって?とかUdonSharpに関してなどは全部省く。全部解ってる人が読むための記事であって、ココからそれらに興味を持ってもらう目的はない。
今回の目的
SDK2ではオブジェクトをスポーン(spawn)させることができる。
無尽蔵に物を増やし、しかもそれは他人と共有(同期)することができるのだ。
今回の目的は、それをSDK3でやりたい。というもの。
(別にUsharpでなくとも、仕組みとしては純正のnooodleなudonでも変わらない)
ここまでが前置き。次に早速だが結論を書こう。
結論
Udonでできないのは、スポーンさせたオブジェクトの同期 のみ。
あと正直それほどキレ散らかしてはいない。
目次
愚痴
SDK2で使用していたRPCとか、Networking.Instanceが未実装(?)なのが大体の原因。
現状VRCInstanceがスポーンに位置付けられているが、クライアント同士で「それが同一のモノである」という結びつきがなされていないらしい。NetworkIDがどうとか聞いた。「Usharp」で検索して出てくる記事は全部読むしかない。
そして俺はプログラムに詳しい訳でも、特別全能な訳でもない。
この記事の全てを鵜呑みにしてはいけない。なにか見落としている可能性はある。
DynamicPrefabとか…
スポーンの前に立ちはだかる問題
スポーンできないよぉ~ とだけほざく赤ちゃんの言葉を汲み取ると、いくつかの「できない」が出てくると思う。
- 本当に物が生成されていない
- シーンの原点に生成される
- 誰か一人の画面にしか生成されない
- 生成されたモノのudonが死んでる
- 生成されたモノの位置が同期しない
大方上記のどれかだろう。
結論で述べたのは5. についてで、これだけが不可能らしいという事。
代替案
スポーンできないんならどうしたら良いんだ!
あらかじめ出現させるオブジェクトをシーン上に配置して、非表示にしておく。使う時に表示して、移動させれば解決!
複数個を管理するのが面倒で、個数制限が付く以外は十分だ。
公式ディスコードのudonチャンネルでも「同期しないん?」との質問には「Object Poolが多くの場合有効」と回答があった。メイ見たもん。
じゃあ仕方ないね。
立ちはだかる問題の解決法
同期はしないにしても1~4の解決法を教えろという人がいるだろうから書いておく。
- spawn(Instance)させるオブジェクトはAssetsからではなく、Sceneに配置したモノを使用する。親オブジェクトを非表示にしても問題ないので、スポーンさせるオリジナルは一つのオブジェクトにまとめてしまおう。
- これは結論付けたように不可能。プレイヤー同士で同じものだと認識できていないらしい。
生成させた後、動機を必要としないならVRCInstanceを使っていこう。
次に君が検索する単語
「Object Pool」「オブジェクトプール」「ゲームオブジェクト 配列」