unityzgy/Assets/ThirdPackages/VRPackage/VRTK/Examples/ExampleResources/Scripts/Archery/BowAim.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

172 lines
5.7 KiB
C#

namespace VRTK.Examples.Archery
{
using UnityEngine;
using System.Collections;
public class BowAim : MonoBehaviour
{
public float powerMultiplier;
public float pullMultiplier;
public float pullOffset;
public float maxPullDistance = 1.1f;
public float bowVibration = 0.062f;
public float stringVibration = 0.087f;
private BowAnimation bowAnimation;
private GameObject currentArrow;
private BowHandle handle;
private VRTK_InteractableObject interact;
private VRTK_InteractGrab holdControl;
private VRTK_InteractGrab stringControl;
private Quaternion releaseRotation;
private Quaternion baseRotation;
private bool fired;
private float fireOffset;
private float currentPull;
private float previousPull;
public VRTK_InteractGrab GetPullHand()
{
return stringControl;
}
public bool IsHeld()
{
return interact.IsGrabbed();
}
public bool HasArrow()
{
return currentArrow != null;
}
public void SetArrow(GameObject arrow)
{
currentArrow = arrow;
}
private void Start()
{
bowAnimation = GetComponent<BowAnimation>();
handle = GetComponentInChildren<BowHandle>();
interact = GetComponent<VRTK_InteractableObject>();
interact.InteractableObjectGrabbed += new InteractableObjectEventHandler(DoObjectGrab);
}
private void DoObjectGrab(object sender, InteractableObjectEventArgs e)
{
if (VRTK_DeviceFinder.IsControllerLeftHand(e.interactingObject))
{
holdControl = VRTK_DeviceFinder.GetControllerLeftHand().GetComponent<VRTK_InteractGrab>();
stringControl = VRTK_DeviceFinder.GetControllerRightHand().GetComponent<VRTK_InteractGrab>();
}
else
{
stringControl = VRTK_DeviceFinder.GetControllerLeftHand().GetComponent<VRTK_InteractGrab>();
holdControl = VRTK_DeviceFinder.GetControllerRightHand().GetComponent<VRTK_InteractGrab>();
}
StartCoroutine("GetBaseRotation");
}
private IEnumerator GetBaseRotation()
{
yield return new WaitForEndOfFrame();
baseRotation = transform.localRotation;
}
private void Update()
{
if (currentArrow != null && IsHeld())
{
AimArrow();
AimBow();
PullString();
if (!stringControl.IsGrabButtonPressed())
{
currentArrow.GetComponent<Arrow>().Fired();
fired = true;
releaseRotation = transform.localRotation;
Release();
}
}
else if (IsHeld())
{
if (fired)
{
fired = false;
fireOffset = Time.time;
}
if (!releaseRotation.Equals(baseRotation))
{
transform.localRotation = Quaternion.Lerp(releaseRotation, baseRotation, (Time.time - fireOffset) * 8);
}
}
if (!IsHeld())
{
if (currentArrow != null)
{
Release();
}
}
}
private void Release()
{
bowAnimation.SetFrame(0);
currentArrow.transform.SetParent(null);
Collider[] arrowCols = currentArrow.GetComponentsInChildren<Collider>();
Collider[] BowCols = GetComponentsInChildren<Collider>();
foreach (var c in arrowCols)
{
c.enabled = true;
foreach (var C in BowCols)
{
Physics.IgnoreCollision(c, C);
}
}
currentArrow.GetComponent<Rigidbody>().isKinematic = false;
currentArrow.GetComponent<Rigidbody>().velocity = currentPull * powerMultiplier * currentArrow.transform.TransformDirection(Vector3.forward);
currentArrow.GetComponent<Arrow>().inFlight = true;
currentArrow = null;
currentPull = 0;
ReleaseArrow();
}
private void ReleaseArrow()
{
if (stringControl)
{
stringControl.ForceRelease();
}
}
private void AimArrow()
{
currentArrow.transform.localPosition = Vector3.zero;
currentArrow.transform.LookAt(handle.nockSide.position);
}
private void AimBow()
{
transform.rotation = Quaternion.LookRotation(holdControl.transform.position - stringControl.transform.position, holdControl.transform.TransformDirection(Vector3.forward));
}
private void PullString()
{
currentPull = Mathf.Clamp((Vector3.Distance(holdControl.transform.position, stringControl.transform.position) - pullOffset) * pullMultiplier, 0, maxPullDistance);
bowAnimation.SetFrame(currentPull);
if (!currentPull.ToString("F2").Equals(previousPull.ToString("F2")))
{
VRTK_ControllerHaptics.TriggerHapticPulse(VRTK_ControllerReference.GetControllerReference(holdControl.gameObject), bowVibration);
VRTK_ControllerHaptics.TriggerHapticPulse(VRTK_ControllerReference.GetControllerReference(stringControl.gameObject), stringVibration);
}
previousPull = currentPull;
}
}
}