UdonSharpの基本について

UdonSharpでちょっとしたギミックを作りたいと相談されたので簡単なメモ書きを作ります。
基本的には、VRC World作成の技術ツリーになります。
World作成について、知識と技術がどのレベルにあるかわかりませんので無責任に書きます。
World作成はできるしUdonSharpも動かしたことがある場合は、一番下の[仕様をプログラムにする]の項目だけでOKです。
やりたいこと(仕様)
- オブジェクトAとオブジェクトBがある。
- Aはpickupできる。また位置はGlobalで同期される。
- Aをpickupしてコントローラーのトリガーボタンを押すとBの色が変わる。
- 上記に続いて、トリガーボタンを離すとBの色がもとにもどる。
- Bの色の変化はGlobalとして動かしたい
- 上記のペアを3つ作りたい
- 3つそれぞれで、Bの色は変えたい

入門記事
教科書としては有料ですが、以下のものが適しています。
自分も購入しました。同期周りがこんがらがったりすると、よく5章を読み返しています。
それ以外ですと、blogなどの記事が色々とありますが公開日時が若干古いです。
現在のVCCを使った環境と少々ズレているため、ある程度World作成をしたことがないと記事内容の読み替えがきついかもしれません。
以下の記事などが最初のサンプルを動かすのに適しているでしょう。
ギミックの解析について
また、UdonSharpにて基本処理より踏み込んだものを作ろうとするときは既存のギミックの構造などを見ることが多いです。
やりたいことと同じ機能があるものをBoothで探すのはかなり手っ取り早い手段となります。
今回のやりたいことについて軽く調査しましたが、全く同じのは無いかも?
仕様の一部分については、あふろださんのサンプルギミックに含まれているマネーガンが参考になるかなーと思いました。
World作成したことがない場合
UdonSharpで動くギミックは、VRChatのWorld構築の一つの要素です。
UdonSharpの開発の前に、まずはVCCを使ってWorld作成環境を作り、サンプルワールドをそのままUploadして動作確認ができることが前提となります。
サンプルワールドのUploadからの説明となると、UdonSharp開発の説明に入るまでかなり遠くなってしまうのでよく説明がスキップされます。
この記事でも、もちろんスキップします。一応下にメモ書きを残します。
サンプルワールドのUploadまでの記事
以下の記事が比較的新しいです。
まずはVCCでWorld作成環境を整え、サンプルワールドを開き、テストビルドとuploadができる状態が開発準備が始められる状態となります。

シンプルなコードを動かす
上でも書きましたが、Worldの作成・Uploadできる環境がある状態がスタートです。
以下の記事通りに進めると、UdonSharpを書くためのエディタとしてVisual Studioが導入されています。
記事内容通り進めると、CubeをインタラクトするとCubeが回転するギミックが作成できます。
これはローカル動作となります。
ローカルで動作するギミックがテストビルド&Uploadしてローカル環境で動くならOKです。
(参考)公式サンプル
Unityの上部メニューバー VRChat SDKのところから公式のサンプルプロジェクトを開くことができます。
Sample -> UdonExampleSceneからシーンを開くことができます。
最近のSDK Updateで追加された新規関数に対応した高度なサンプルについては同じ場所の Example CentralからImportすることができます。
公式サンプルで仕様に近いやつ(UdonGraph)
近いやつがありましたが、UdonGraphでした…。一応乗せときます。
UdonExampleSceneに含まれているCubes->Pickupcubeが仕様にやや近いカモ…。
- コンポーネントにVRC Pickup / VRC Object Sync / Udon Behaviour がついている
- UdonGraphがついている

仕様をプログラムにする
インスペクターの構成
以下のような構成にします。これで仕様1,2は満たせます。
- オブジェクトA
- コンポーネント : VRC Object Sync : 位置のGlobal同期
- コンポーネント : VRC Pickup : モノを持てる機能 : AutoHold を Yesに
- コンポーネント : Udon Behaviour : UdonSharpのプログラムをアタッチ
- オブジェクトB
- 追加コンポーネントなし
UdonSharpの構成ポイント
重要な関数
- トリガーボタンを押した時のタイミング : OnPickupUseDown()
- https://udonsharp.docs.vrchat.com/events/#udon-pickup-events
- VRC Pickup AutoHold Yesが必要と思う(確か)
- Global化にはイベント同期を利用 : SendCustomNetworkEvent(VRC.Udon.Common.Interfaces.NetworkEventTarget.All,"Test")
コード
仕様からChatGPTに出力させたもの。
修正1回。トリガーボタンの動作はOnPickupUseDownを使うように指示。
using UdonSharp;
using UnityEngine;
using VRC.SDKBase;
using VRC.Udon;
public class PairController : UdonSharpBehaviour
{
[Header("対象オブジェクト")]
public MeshRenderer targetRenderer; // BのRenderer
[Header("色設定")]
public Color activeColor = Color.red; // トリガー押下時の色
private Color defaultColor; // 元の色を保存
private void Start()
{
if (targetRenderer != null)
{
defaultColor = targetRenderer.material.color;
}
}
public override void OnPickupUseDown()
{
// トリガーを押したら全員に色変更
SendCustomNetworkEvent(VRC.Udon.Common.Interfaces.NetworkEventTarget.All, nameof(SetActiveColor));
}
public override void OnPickupUseUp()
{
// トリガーを離したら全員に元の色に戻す
SendCustomNetworkEvent(VRC.Udon.Common.Interfaces.NetworkEventTarget.All, nameof(SetDefaultColor));
}
public void SetActiveColor()
{
if (targetRenderer != null)
{
targetRenderer.material.color = activeColor;
}
}
public void SetDefaultColor()
{
if (targetRenderer != null)
{
targetRenderer.material.color = defaultColor;
}
}
}
動作
トリガー中だけ色が変わる
その他設定

ギミックの受け渡し
unitypackageとして出力して受け渡しを行います。
開いているシーンファイルを保存して、右クリックからExportでいけるはず。