概要
広大なワールドや、複数のエリアに分かれたワールドでは、プレイヤーが快適に移動するための手段が不可欠です。テレポーターやポータルは、プレイヤーを瞬時に別の場所へ移動させ、ワールドの探索を容易にするための強力なギミックです。
UdonSharpでは、プレイヤーを制御するためのインターフェースであるVRCPlayerApiが提供するTeleportTo()メソッドを使用することで、この機能を簡単に実装できます 。
本記事では、基本的なテレポーターの実装から、より発展的な応用例まで、具体的なスクリプトと設定方法を解説します。
- 基本的なテレポーター: プレイヤーがオブジェクトに触れるか、クリックすると指定した場所に移動する。
- ランダムテレポーター: 複数の候補地の中からランダムな場所に移動する。
VRCPlayerApi.TeleportTo()メソッド
このメソッドがテレポート機能の核心です。プレイヤーの位置と回転を強制的に変更します。
player.TeleportTo(Vector3 position, Quaternion rotation);
player: テレポートさせたいプレイヤーのVRCPlayerApiオブジェクト。自分自身を移動させる場合はNetworking.LocalPlayerを使用します。position: 移動先のワールド座標 (Vector3)。rotation: 移動後のプレイヤーの向き (Quaternion)。
多くの場合、移動先の座標と向きを直接指定する代わりに、シーンに配置した目印となるGameObjectのTransformコンポーネントを利用するのが便利です。Transformにはpositionとrotationの両方の情報が含まれています。
player.TeleportTo(destinationTransform.position, destinationTransform.rotation);
補足:
TeleportTo()には第3引数としてVRC_SceneDescriptor.SpawnOrientationを指定できます。これはテレポート後のプレイヤーの向きをどのように決定するかを制御します(デフォルトはAlignPlayerWithSpawnPoint)。
パターン1: 基本的なテレポーター(トリガー式)
プレイヤーが特定のエリア(トリガー)に入ると、指定した目的地へテレポートするギミックです。ポータルや魔法陣のような見た目のギミックに適しています。
Unityエディタでの設定
- テレポート元の作成: ポータルとなるオブジェクト(例: 装飾された床)を作成します。このオブジェクトに
Box Colliderを追加し、Is Triggerにチェックを入れます。これがプレイヤーの侵入を検知するセンサーになります。 - テレポート先の作成: 空のGameObjectを作成し、「DestinationPoint」などの分かりやすい名前を付けます。これをプレイヤーがテレポートしたい場所に配置します。青いZ軸の矢印がテレポート後のプレイヤーの正面方向になるため、オブジェクトの向きも調整しておきます。
- スクリプトのアタッチ: テレポート元のオブジェクトにUdon Behaviourコンポーネントを追加し、後述するスクリプトを割り当てます。
スクリプト: SimpleTeleporter.cs
using UdonSharp;
using UnityEngine;
using VRC.SDKBase;
public class SimpleTeleporter : UdonSharpBehaviour
{
[Header("設定")]
[Tooltip("テレポート先の位置と向きを示すTransformを割り当てます。")]
public Transform destination;
// プレイヤーがトリガーに入ったときに呼び出される
public override void OnPlayerTriggerEnter(VRCPlayerApi player)
{
// 自分自身(ローカルプレイヤー)がトリガーに入った場合のみ処理
if (player.isLocal)
{
// 目的地が設定されているか確認
if (destination != null)
{
Debug.Log($"{player.displayName}を{destination.name}へテレポートさせます。");
player.TeleportTo(destination.position, destination.rotation);
}
else
{
Debug.LogError("テレポート先が設定されていません!");
}
}
}
}
Unityでの最終設定
- テレポート元のオブジェクトのInspectorを開きます。
Simple TeleporterコンポーネントのDestinationフィールドに、シーンに配置した「DestinationPoint」オブジェクトをドラッグ&ドロップします。
これで、プレイヤーがポータルオブジェクトのCollider範囲内に入ると、即座にDestinationPointの位置と向きにテレポートします。
応用: Interact式のテレポーターを作りたい場合は、OnPlayerTriggerEnterの代わりにInteractイベントを使い、その中でNetworking.LocalPlayer.TeleportTo()を呼び出すように変更します。
パターン2: ランダムテレポーター
複数の目的地の中から、ランダムに選ばれた一つの場所へテレポートするギミックです。ミステリーツアーや、ゲームのリスポーン地点を散らしたい場合などに活用できます。
Unityエディタでの設定
- テレポート元の作成: パターン1と同様に、クリックまたはトリガーとなるオブジェクトを用意します。
- テレポート先の作成: 複数のテレポート先となる空のGameObject(DestinationPoint_A, DestinationPoint_B, ...)を作成し、ワールドの各所に配置します。
スクリプト: RandomTeleporter.cs
using UdonSharp;
using UnityEngine;
using VRC.SDKBase;
public class RandomTeleporter : UdonSharpBehaviour
{
[Header("設定")]
[Tooltip("テレポート先の候補となるTransformを複数割り当てます。")]
public Transform[] destinations;
public override void Interact()
{
// 候補地が一つも設定されていない場合は何もしない
if (destinations == null || destinations.Length == 0)
{
Debug.LogError("テレポート先の候補が設定されていません!");
return;
}
// 0から候補地の数-1までの範囲でランダムな整数を生成
int randomIndex = Random.Range(0, destinations.Length);
// ランダムに選ばれた目的地を取得
Transform randomDestination = destinations[randomIndex];
// 選ばれた目的地が有効か確認
if (randomDestination != null)
{
Debug.Log($"ランダムな目的地: {randomDestination.name} へテレポートします。");
Networking.LocalPlayer.TeleportTo(randomDestination.position, randomDestination.rotation);
}
else
{
Debug.LogWarning($"インデックス{randomIndex}の目的地が無効です。再試行します。");
// エラーハンドリング: 例えば、もう一度Interactを呼ぶ、別の場所を選ぶなど
Interact();
}
}
}
Unityでの最終設定
RandomTeleporter.csをテレポート元のUdon Behaviourに割り当てます。Random TeleporterコンポーネントのDestinationsフィールドの右にある鍵マークをクリックして、配列のサイズを編集できるようにします。Sizeに目的地の数を入力します(例: 3)。- 表示された
Element 0,Element 1, ... の各フィールドに、シーンに配置した複数の「DestinationPoint」オブジェクトをそれぞれドラッグ&ドロップします。
これで、このオブジェクトをInteractするたびに、登録された目的地の中からランダムな一箇所にテレポートするようになります。
まとめ
- プレイヤーのテレポートは
VRCPlayerApi.TeleportTo(position, rotation)メソッドで実装します。 - 自分自身をテレポートさせる場合は
Networking.LocalPlayerを使用します。 - テレポート先は、空のGameObjectを「目印」としてシーンに配置し、その
Transformをスクリプトに渡すのが簡単で確実です。 OnPlayerTriggerEnterを使えばトリガー式、Interactを使えばボタン式のテレポーターを実装できます。Transformの配列とRandom.Range()を組み合わせることで、ランダムなテレポートも簡単に実装できます。
テレポートは、プレイヤーの体験をスムーズにし、ワールドの構造を豊かにするための基本的ながら非常に強力なツールです。このギミックをマスターして、プレイヤーを驚かせるような空間移動を演出してみましょう。