2023-09-01 アバターが制御不能に回転しないように TeleportTo を連続して使う方法
This page is available in English: English
注記
このページは AI(Claude)によって翻訳されています。翻訳に誤りが含まれる可能性があります。
TeleportTo を連続して使い、独自の移動システムを作ろうとすると、プレイヤーが制御不能に回転してしまうことがあります。
これは何年も前から口伝えで知られてきた知識ですが、私が調べた限り、完全に説明している記事はオンライン上に見つかりませんでした。
TeleportTo (U#) の AlignRoomWithSpawnPoint (U#)(U# 以外のドキュメントには記載がありません)と、
TrackingDataType.Origin (U#)(ドキュメント)がどう連携するのかは、
それぞれの説明を見ただけで自力で理解することを求められているかのようです。
というのも、Networking.LocalPlayer.GetRotation() を渡すという直感的な方法で関数を呼び出しても、
テレポート後のプレイヤーの回転が、指定した回転と等しくなる保証はないからです。
プレイヤーを同じ回転のままテレポートさせるには、次の 2 つが必要です。
- プレイヤー自身ではなくプレイヤーのルームの中心をテレポートさせる、
VRC_SceneDescriptor.SpawnOrientation.AlignRoomWithSpawnPointを引数に取るバージョンの TeleportTo 関数を使うこと。 Networking.LocalPlayer.GetTrackingData(VRCPlayerApi.TrackingDataType.Origin)を使って、ワールド内における現在のプレイヤーのルームの中心を求めること。
次の関数をそのままプロジェクトで使用できます。
/*
This code snippet is released into the public domain.
If the public domain is not applicable where you are, then it's released under the terms of
the CC0 1.0 Universal, which is essentially the same as public domain.
*/
// Teleporting to self should always result in the player not moving
StableTeleportTo(Networking.LocalPlayer.GetPosition());
// Teleport to other position
public Vector3 destinationPos = ...;
StableTeleportTo(destinationPos);
private static void StableTeleportTo(Vector3 destinationPos)
{
var playerPos = Networking.LocalPlayer.GetPosition();
var playerOrigin = Networking.LocalPlayer.GetTrackingData(VRCPlayerApi.TrackingDataType.Origin);
var posToOrigin = playerOrigin.position - playerPos;
var destinationOrigin = destinationPos + posToOrigin;
Networking.LocalPlayer.TeleportTo(
destinationOrigin,
playerOrigin.rotation,
VRC_SceneDescriptor.SpawnOrientation.AlignRoomWithSpawnPoint
);
}
この関数は連続的なテレポートのために設計されているため、回転に関するパラメータは受け取りません。
プレイヤーが目的地に位置するようにルームの中心の位置を計算し、その位置にプレイヤーのルームの中心をテレポートさせます。