unityzgy/.svn/pristine/bb/bbf4e24e4b9065f35f0662f7e4f253ba25bf2614.svn-base
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

165 lines
4.9 KiB
Plaintext

// Transform Follow|Utilities|90062
namespace VRTK
{
using UnityEngine;
/// <summary>
/// Changes one game object's transform to follow another game object's transform.
/// </summary>
[AddComponentMenu("VRTK/Scripts/Utilities/Object Follow/VRTK_TransformFollow")]
public class VRTK_TransformFollow : VRTK_ObjectFollow
{
/// <summary>
/// The moment at which to follow.
/// </summary>
/// <param name="OnUpdate">Follow in the Update method.</param>
/// <param name="OnLateUpdate">Follow in the LateUpdate method.</param>
/// <param name="OnPreRender">Follow in the OnPreRender method. (This script doesn't have to be attached to a camera.)</param>
/// <param name="OnPreCull">Follow in the OnPreCull method. (This script doesn't have to be attached to a camera.)</param>
public enum FollowMoment
{
OnUpdate,
OnLateUpdate,
OnPreRender,
OnPreCull
}
[Tooltip("The moment at which to follow.")]
[SerializeField]
private FollowMoment _moment = FollowMoment.OnPreRender;
public FollowMoment moment
{
get
{
return _moment;
}
set
{
if (_moment == value)
{
return;
}
if (isActiveAndEnabled)
{
if (_moment == FollowMoment.OnPreRender && value != FollowMoment.OnPreRender)
{
Camera.onPreRender -= OnCamPreRender;
}
if (_moment != FollowMoment.OnPreRender && value == FollowMoment.OnPreRender)
{
Camera.onPreRender += OnCamPreRender;
}
if (_moment == FollowMoment.OnPreCull && value != FollowMoment.OnPreCull)
{
Camera.onPreCull -= OnCamPreCull;
}
if (_moment != FollowMoment.OnPreCull && value == FollowMoment.OnPreCull)
{
Camera.onPreCull += OnCamPreCull;
}
}
_moment = value;
}
}
protected Transform transformToFollow;
protected Transform transformToChange;
public override void Follow()
{
CacheTransforms();
base.Follow();
}
protected override void OnEnable()
{
base.OnEnable();
if (moment == FollowMoment.OnPreRender)
{
Camera.onPreRender += OnCamPreRender;
}
if (moment == FollowMoment.OnPreCull)
{
Camera.onPreCull += OnCamPreCull;
}
}
protected virtual void OnDisable()
{
transformToFollow = null;
transformToChange = null;
Camera.onPreRender -= OnCamPreRender;
Camera.onPreCull -= OnCamPreCull;
}
protected void Update()
{
if (moment == FollowMoment.OnUpdate)
{
Follow();
}
}
protected virtual void LateUpdate()
{
if (moment == FollowMoment.OnLateUpdate)
{
Follow();
}
}
// The following `OnCam*` methods need to have the `Cam` addition to prevent a name clash with the `MonoBehaviour.On*` methods since those are used when this script is attached to a camera.
protected virtual void OnCamPreRender(Camera cam)
{
if (cam.gameObject.transform == VRTK_SDK_Bridge.GetHeadsetCamera())
{
Follow();
}
}
protected virtual void OnCamPreCull(Camera cam)
{
if (cam.gameObject.transform == VRTK_SDK_Bridge.GetHeadsetCamera())
{
Follow();
}
}
protected override Vector3 GetPositionToFollow()
{
return transformToFollow.position;
}
protected override void SetPositionOnGameObject(Vector3 newPosition)
{
transformToChange.position = newPosition;
}
protected override Quaternion GetRotationToFollow()
{
return transformToFollow.rotation;
}
protected override void SetRotationOnGameObject(Quaternion newRotation)
{
transformToChange.rotation = newRotation;
}
protected virtual void CacheTransforms()
{
if (gameObjectToFollow == null || gameObjectToChange == null
|| (transformToFollow != null && transformToChange != null))
{
return;
}
transformToFollow = gameObjectToFollow.transform;
transformToChange = gameObjectToChange.transform;
}
}
}