【VRChat】テレポーターを作る:プレイヤーを瞬間移動させる方法

作成: 2025-12-19

ワールド内移動を快適にするテレポーターとポータルの実装。VRCPlayerApi.TeleportToを使った基本テレポートから見た目も同期するポータルまで。

概要

広大なワールドや、複数のエリアに分かれたワールドでは、プレイヤーが快適に移動するための手段が不可欠です。テレポーターポータルは、プレイヤーを瞬時に別の場所へ移動させ、ワールドの探索を容易にするための強力なギミックです。

UdonSharpでは、プレイヤーを制御するためのインターフェースであるVRCPlayerApiが提供するTeleportTo()メソッドを使用することで、この機能を簡単に実装できます。

本記事では、基本的なテレポーターの実装から、より発展的な応用例まで、具体的なスクリプトと設定方法を解説します。

  1. 基本的なテレポーター: プレイヤーがオブジェクトに触れるか、クリックすると指定した場所に移動する。
  2. ランダムテレポーター: 複数の候補地の中からランダムな場所に移動する。

VRCPlayerApi.TeleportTo()メソッド

このメソッドがテレポート機能の核心です。プレイヤーの位置と回転を強制的に変更します。

player.TeleportTo(Vector3 position, Quaternion rotation);

  • player: テレポートさせたいプレイヤーのVRCPlayerApiオブジェクト。自分自身を移動させる場合はNetworking.LocalPlayerを使用します。
  • position: 移動先のワールド座標 (Vector3)。
  • rotation: 移動後のプレイヤーの向き (Quaternion)。

多くの場合、移動先の座標と向きを直接指定する代わりに、シーンに配置した目印となるGameObjectのTransformコンポーネントを利用するのが便利です。Transformにはpositionrotationの両方の情報が含まれています。

player.TeleportTo(destinationTransform.position, destinationTransform.rotation);

補足: TeleportTo()には第3引数としてVRC_SceneDescriptor.SpawnOrientationを指定できます。これはテレポート後のプレイヤーの向きをどのように決定するかを制御します(デフォルトはAlignPlayerWithSpawnPoint)。

パターン1: 基本的なテレポーター(トリガー式)

プレイヤーが特定のエリア(トリガー)に入ると、指定した目的地へテレポートするギミックです。ポータルや魔法陣のような見た目のギミックに適しています。

Unityエディタでの設定

  1. テレポート元の作成: ポータルとなるオブジェクト(例: 装飾された床)を作成します。このオブジェクトにBox Colliderを追加し、Is Triggerにチェックを入れます。これがプレイヤーの侵入を検知するセンサーになります。
  2. テレポート先の作成: 空のGameObjectを作成し、「DestinationPoint」などの分かりやすい名前を付けます。これをプレイヤーがテレポートしたい場所に配置します。青いZ軸の矢印がテレポート後のプレイヤーの正面方向になるため、オブジェクトの向きも調整しておきます。
  3. スクリプトのアタッチ: テレポート元のオブジェクトに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. テレポート元の作成: パターン1と同様に、クリックまたはトリガーとなるオブジェクトを用意します。
  2. テレポート先の作成: 複数のテレポート先となる空の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()を組み合わせることで、ランダムなテレポートも簡単に実装できます。

テレポートは、プレイヤーの体験をスムーズにし、ワールドの構造を豊かにするための基本的ながら非常に強力なツールです。このギミックをマスターして、プレイヤーを驚かせるような空間移動を演出してみましょう。