unityzgy/Assets/ThirdPackages/VRPackage/SteamVR/Extras/SteamVR_Teleporter.cs
ayuan9957 bf12e02276 feat: 多语言本地化系统 - 支持中/英/法/俄实时切换
- LocalizationManager: 新增翻译表(SetFormatted/SetDuration/LocalizeOperateMsg)
- LoginPanel: InputField placeholder本地化、字体颜色保持
- HistoryPanel: 用时数据本地化、placeholder本地化
- RecordDetailPanel: 操作详情消息本地化(LanguageChanged重建)
- AppraiseWindowBase: 评价等级本地化、操作消息重建
- EditorAppraiser: 所有评估消息改用InjectOperateMsgLocalized
- StudentOperateRecorder: 新增InjectOperateMsgLocalized方法
- LocalizationLanguageTestBar: 单例模式、ScreenSpaceOverlay筛选
- 字体切换时保留颜色和verticalOverflow
2026-07-16 10:05:59 +08:00

99 lines
3.0 KiB
C#

using UnityEngine;
using System.Collections;
public class SteamVR_Teleporter : MonoBehaviour
{
public enum TeleportType
{
TeleportTypeUseTerrain,
TeleportTypeUseCollider,
TeleportTypeUseZeroY
}
public bool teleportOnClick = false;
public TeleportType teleportType = TeleportType.TeleportTypeUseZeroY;
Transform reference
{
get
{
var top = SteamVR_Render.Top();
return (top != null) ? top.origin : null;
}
}
void Start()
{
var trackedController = GetComponent<SteamVR_TrackedController>();
if (trackedController == null)
{
trackedController = gameObject.AddComponent<SteamVR_TrackedController>();
}
trackedController.TriggerClicked += new ClickedEventHandler(DoClick);
if (teleportType == TeleportType.TeleportTypeUseTerrain)
{
// Start the player at the level of the terrain
var t = reference;
if (t != null)
t.position = new Vector3(t.position.x, Terrain.activeTerrain.SampleHeight(t.position), t.position.z);
}
}
void DoClick(object sender, ClickedEventArgs e)
{
if (teleportOnClick)
{
// First get the current Transform of the the reference space (i.e. the Play Area, e.g. CameraRig prefab)
var t = reference;
if (t == null)
return;
// Get the current Y position of the reference space
float refY = t.position.y;
// Create a plane at the Y position of the Play Area
// Then create a Ray from the origin of the controller in the direction that the controller is pointing
Plane plane = new Plane(Vector3.up, -refY);
Ray ray = new Ray(this.transform.position, transform.forward);
// Set defaults
bool hasGroundTarget = false;
float dist = 0f;
if (teleportType == TeleportType.TeleportTypeUseTerrain) // If we picked to use the terrain
{
RaycastHit hitInfo;
TerrainCollider tc = Terrain.activeTerrain.GetComponent<TerrainCollider>();
hasGroundTarget = tc.Raycast(ray, out hitInfo, 1000f);
dist = hitInfo.distance;
}
else if (teleportType == TeleportType.TeleportTypeUseCollider) // If we picked to use the collider
{
RaycastHit hitInfo;
hasGroundTarget = Physics.Raycast(ray, out hitInfo);
dist = hitInfo.distance;
}
else // If we're just staying flat on the current Y axis
{
// Intersect a ray with the plane that was created earlier
// and output the distance along the ray that it intersects
hasGroundTarget = plane.Raycast(ray, out dist);
}
if (hasGroundTarget)
{
// Get the current Camera (head) position on the ground relative to the world
Vector3 headPosOnGround = new Vector3(SteamVR_Render.Top().head.position.x, refY, SteamVR_Render.Top().head.position.z);
// We need to translate the reference space along the same vector
// that is between the head's position on the ground and the intersection point on the ground
// i.e. intersectionPoint - headPosOnGround = translateVector
// currentReferencePosition + translateVector = finalPosition
t.position = t.position + (ray.origin + (ray.direction * dist)) - headPosOnGround;
}
}
}
}