降ってくるCubeをUseするとCubeがリスポーンするObjectPoolを使ったサンプルの解説
ObjectPoolとは?
オブジェクトの生成は処理負荷が高いため、あらかじめ出現限界数分のオブジェクトを生成しておき使い回すことで生成を回避する手法のこと。ゲームでよく使われる設計パターンの1つで、例えばシューティングゲームだと敵や弾が出現と消滅を大量に行われているように見えますが、実は表示・非表示を繰り返しているだけで同じ敵と弾を使い回しています。
Udonスクリプト作成
サンプルのPooledBoxとObjectPoolをU#に書き直し
Udon Graph


U#
public class PooledBoxBySharp : UdonSharpBehaviour
{
public VRCObjectPool pool;
Vector3 initialPosition;
void Start()
{
initialPosition = transform.localPosition;
}
private void OnEnable()
{
Debug.Log($"{name} enabled");
transform.localPosition = initialPosition;
}
public override void Interact()
{
if (Networking.IsOwner(gameObject))
{
ReturnObject();
}
else
{
SendCustomNetworkEvent(VRC.Udon.Common.Interfaces.NetworkEventTarget.Owner, nameof(ReturnObject));
}
}
public void ReturnObject()
{
pool.Return(gameObject);
Debug.Log($"{gameObject.name} returned");
}
}
public class ObjectPoolBySharp : UdonSharpBehaviour
{
float lastSpawnTime;
public VRCObjectPool pool;
public float spawnRate = 5;
void Start()
{
lastSpawnTime = float.MinValue;
}
private void Update()
{
if ((Time.realtimeSinceStartup - lastSpawnTime > spawnRate) && Networking.IsOwner(gameObject))
{
lastSpawnTime = Time.realtimeSinceStartup;
pool.TryToSpawn();
}
}
}
シーン作成
さきほどのスクリプトとVRCObjectPoolコンポーネントを追加。
Pooled Boxは後述で作成するオブジェクトのことです。

適当にCubeを複数配置してPooled Boxを作成します。さきほどのスクリプトを追加するだけで特に難しいことはないです。

さいごに
公式ドキュメントで調べても特にObjectPoolに関する情報がほとんどなかった。 サンプルコードを見てない人はObjectPoolコンポーネントの存在に気付かないかも?
オブジェクトを使いまわす