ドアの開閉ギミックを作ります。これがないと建物作っても入れないことに気づいてしまいました。(素通りするようにする方法もありますが、やはりドアは開きたい…!)
普通に片一方を軸にして回転して開くドアです。開閉のアニメーションつき。
スクリプトはUDONノードを使います。
Unityのバージョンは、2022.3.22f1 2025/5月現在、VRCワールド作成用の最新のバージョンです。結構古い解説のだと操作が違ったりしますので気を付けてください。
参考にした動画
準備
自分でドアの外形を作るところから準備しています。もうドアや建物のオブジェクトがあるよという方はヒンジをつけるところまで飛ばしてください
ドアの外形を作る

ちょっとドア周りは省エネで作ろうと思うのでパッケージマネージャからProBuilderをインストールして適当にドアの外形を作ります。
Tools > ProBuilder > ProBuilder Window を出して、右の三点のアイコンでアイコンメニューに変えます。

こういうメニュー画面になるので、一番左上の、Create Shapeからオブジェクトを追加します。
赤い枠線で囲ったオブジェクトは、ドア用?にすでに形が出来てるオブジェクトです。ありがたいですね。ドアの外枠が瞬時に追加できました。

Cubeでドアを作ったらドア部分の完成です。
ヒンジをつける


ドアを回転させるためのヒンジ(蝶番)をつけます。
Create EmptyでEmptyを出して、ドアの右下に配置します。HierarchyでEmpty(親)にドアのCube(子)をドラッグしてペアレントします。

ペアレントすると親のHingeの位置がPivotの位置になり、そこを軸として回転できるようになります。

Colliderをつける
ドアや壁に衝突判定がいるので、Colliderはついてなかったら各オブジェクトにAdd Componentでつけてください(ProBuilderの設定や、Cubeを出した場合は自動でついてる場合もあります)
アニメーションを作成
ドアの開閉アニメーションを作成します

window > Animation > Animation でアニメーション編集画面が開きます
アニメーションタブが出てくるので、下の方にでも配置します。

ドアが閉まってるアニメーションを作成する

Hinge(ヒンジ)オブジェクトを選択して、アニメーションのCreateのボタンを押します。
Assetsの中に作成されるファイル名を聞かれるので、door closed(ドアが閉まるアニメーションの名前)とつけ、保存を押します。

アニメーションファイルが作成されると、HingeオブジェクトのInspector内にAnimatorコンポーネントが追加されています。
Animationタブにもさっきのdoor closedファイルが表示されています。


赤丸のレコードボタンをクリックすると、トランスフォームの回転や移動などを動かしたときにキーフレームが打たれるようになります。
ヒンジを回転でちょっと回して戻す(0に戻らなかったら右のトランスフォームの数値を0に戻す)と何も動いてない状態のキーフレームが打たれます。
キーフレーム自体を選択しCtrl + Cでコピーし、フレーム数を1にして移動させ、Ctrl + Vでペーストし、何も動いてないアニメを2フレーム打ちます。
これで何も動いてないアニメが作成されました。これがドアが閉じてるアニメーションです。
三角の再生ボタンを押してみても何も動かないことを確認してみてください。(再生ボタンをもう一度押すと再生がストップします。)
ドアが開いてるアニメーションを作成する
今度はドアが開いてるときのアニメーションを作ります。

作ったアニメファイル名のところをクリックするとCreate New Clip…と出るのでそこで新しいファイルを作ります。door openと名前をつけました。
ここでファイルを選択できるのでdoor openに合わせておきます。

今度はドアが全開で開いたときの回転角度にして、フレーム0にキーフレームを打ちます。
これもキーフレーム自体をコピーして、フレームを1に進めてペーストして同じアニメーションを2フレーム作ります。

再生ボタンを押すと、ドアが開きっぱなしになって動きはないアニメーションができています。
Animatorエディタで編集する
ドアが開いたアニメと閉じたアニメの2つができました。この二つをトランジションでつなぐためにAnimatorエディタ上で編集する必要があります。
Hinge(ヒンジ)オブジェクトを選択してインスペクター内のAnimatorコンポーネントのController内をダブルクリックすると、Animatorというエディタが開かれます
さきほど作成したdoor closed と door openが見えます


ゲームが始まったときのデフォルトのアニメはオレンジ色で、最初に作ったアニメファイルのものが適用されます。
変更したい場合は、変更したいファイルのノードを右クリックしてSet as Layer Default Stateを選択します。
変数を作る

Animatiorエディタ左、ParametersタブでBoolの”isOpen”という変数を作ります
この変数isOpenがtrueのときドアが開き、falseのときドアが閉まるようにします。
transitionを作る(2つのアニメをつなげるよ)

door closedファイルのノードを右クリックし、Make Transitionを選択。すると矢印の線が出てくるので、door openへつなぎます。
次にdoor openファイルのノードを右クリックし、Make Transitionを選択。矢印の線が出てくるので、door closedへつなぎます。
これで開閉アニメがトランジションでつながるようになりました。
アニメーション遷移のロジックを設定する

線の部分をクリックすると、インスペクターに、アニメーション遷移の設定画面が開きます。
下のConditionsに、Animatorエディタで作った変数isOpenをセットして、(右下の+ボタンで追加します)その値がどんなときにアニメーション遷移するかを決めることができます。
door closed → door openの矢印のときは、isOpenをtrueにセット。(isOpenがtrueのときドアが開くようにしたい)
door open → door closedの矢印のときはisOpenをfalseにセット(isOpenがfalseのときドアが閉まるようにしたい)
トランジションのスピード

アニメーション遷移の設定画面下にアニメーションプレビュー画面があります。
再生を押すと今の閉じるとき、開くときのアニメーションが再生されますが、デフォルトの状態だとおそらくめちゃくちゃ早いと思います。
これからこのスピードを調整していきます。
※Settingsメニューが閉じているので三角ボタンをクリックして開いてください。

Has Exit Time…チェックをすると、現在のアニメーションが終了するまで、遷移が始まらない。
Exit Time...次のアニメまでに何回リピートするか
1.0 すべてのアニメが終了するまで次のアニメが始まらない
2.0 二回ループで次のアニメが始まる
Fixed Duration
チェックあり…遷移時間は 秒数で固定
チェックなし…遷移時間は アニメーションの長さに対する割合
Interuption Source …どのトランジションで中断できるか。Next State(次のアニメ)をいれる。
閉じる・開くアニメもスピードを調整し、プレビューでアニメーションを確認してください。
スクリプトを書く
今度は、ドアを選択することで開閉するスクリプトを書いていきます。Udonノードを使います。

Scene画面に戻り、ドアのオブジェクトを選択。
Add ComponentでUdon Behaviourを追加します。

プロジェクトファイルで右クリック、Create > VRChat > Udon > Udon Graph Program Assetを選択し、スクリプトファイルを作成しファイル名を決めます。今回はdoor open scriptという名前にしました。
それをUdon BehaviourのProgram Sourceにドラッグします。
Open Udon Graphでエディタが出てきます

Udonノードを組んでいく
やりたいこと:ドアを選択すると、Animatorで作った変数isOpenをtrue/falseで切り替える
- Animatorコンポーネントを取得する変数
- true/falseを切り替える変数
が必要
変数を作る


Animatorコンポーネント取得用変数
Udonノードエディタの左側に変数を作る箇所があります。
Variablesの右の+をクリックし、変数タイプAnimatorをクリック。変数名をtargetAnimにしてpublicにチェックをする(publicにチェックをするとUdon behaviourのコンポーネント内に変数が現れます。※Compileをクリックが必要)

true/falseを切り替える変数
今度は変数タイプboolのisOpenという変数を作ります。これもpublicにチェックを入れます。
Compileボタンを押すとUdon behaviourコンポーネント内に変数が現れます。

ノード

エディタ内で右クリック > Create Node
ノード検索画面が出てくるのでここから出します。
例:Animator > set bool
どのタイプの関数なのかは上に薄い色の文字で書いてあります

変数のtrue/falseをアニメーションの切り替えとつなげる

作った変数はドラッグするとノードとして使えます。

このように組むことで
Animatorコンポーネントのstring名のbool値「isOpen」を、ここで設定した変数isOpenのbool値にセットする
ということになります。
コンポーネントにさっきpublicで作成したisOpenのチェックをon/offすることで、アニメーションの開く/閉じるを操作することができます。
ドアクリックでisOpenのtrue/falseをトグルする

変数に値をセットする関数は、Ctrlを押しながら変数をエディタにドラッグします。

このように組むことで
ドアクリックするとisOpenの変数の値が切り替わるようになります。
UnaryNegation(単項否定)は一つの値を反対の値にする関数です。
Set isOpenのsendChangeにチェックを入れることでその変数の値が変化したときに「変更イベント」が発生するようになります。

この変更イベントのノードは、変数をAltを押しながらドラッグすることで出せます
Udon Graph全体はこんな感じ。(まだ他のプレイヤーと同期していません)


コンポーネントの変数にHingeオブジェクトをセットするのを忘れないでください。
isOpenの値はゲームスタート時にon(開く)/off(閉じる)どうなっているかです。
Interaction Textはゲーム内で表示されるテキストなので、Openとか好きな文字を入れてください
Compileを押してシミュレーションでテストしてみましょう。(押しても何も動かんという場合、インタラクトのProximityが足りない場合もあります。)
※このドアにはColliderがついており、開閉のさいにキャラクターとぶつかります。(開閉時にコライダーをオフにしたりしてぶつかるのを避けることができるようですが、そのノードはまだ作れません。)
他のプレイヤーのドアの開閉を同期する
VRCは、ドアの開閉などの動作は同期しなければ、他人が開いたドアやスイッチなどは影響せず、自分がイベントを起こさないと動作しません。
ドアの開閉を他のユーザーと同期させます。

まずUdon BehaviourのSynchronizationをManualにします

isOpenの変数をsyncedにチェック
Set isOpen周りにノードをいくつか追加しています。
Networking > SetOwner
Networking > Get LocalPlayer
UdonBehaviour > RequestSerialization
これで一人のキャラクターがドアを開閉したことが、その他のキャラクターにも見えるようになり、ドアの状態も同期されるようになります。