namespace ChivaXR.VR { using System.Collections.Generic; using UnityEngine; public struct CVR_InteractableTriggerEventArgs { public IVR_Interactable interactable; public CVR_TriggerTool triggerTool; public CVR_ToolType toolType; public Collider[] triggerObjects; } /// /// 工具的触发检测参数 /// public struct ToolTriggerInfos { public float trigger_DetectionRange; //触发检测范围 public CVR_TriggerList.CheckTypes toolCheckTypes; public string[] toolCheckInfos; public CVR_ButtonPressTypes buttonPressType; public CVR_ButtonTypes buttonType; } /// /// Trigger /// /// this object /// public delegate void CVRInteractableTriggerEventHandler(object sender, CVR_InteractableTriggerEventArgs e); /// /// 交互工具触发器 /// [RequireComponent(typeof(IVR_Interactable))] public class CVR_TriggerTool : MonoBehaviour { private IVR_Interactable interactable; private GameObject currentHand; private List _colliders = new List(); private CVR_TriggerList triggerList; public CVR_TriggerList TriggerList { get { if (triggerList == null) { triggerList = this.gameObject.AddComponent(); } return triggerList; } } /// /// 触发点 /// public Transform triggerPoint; /// /// 触发范围 /// public float triggerRange = 0.1f; /// /// 按键触发类型 /// public CVR_ButtonPressTypes buttonPressType = CVR_ButtonPressTypes.PressDown; /// /// 按键类型 /// public CVR_ButtonTypes buttonType = CVR_ButtonTypes.Trigger; public event CVRInteractableTriggerEventHandler InteractableTrigger; private void Awake() { interactable = this.GetComponent(); CVR_ToolManager.Instance.RegisterTriggerTool(interactable.GetToolType(), this); } private void Update() { if (interactable.CVR_IsGrabbed() && interactable.CVR_CheckButtonState(buttonType, buttonPressType)) { if (triggerPoint == null) { Debug.LogError(this.transform.name + "未添加TriggerPoint"); return; } //射线检测 RayCheck(triggerPoint.position, triggerRange); } } /// /// 球形射线检测 /// /// /// /// private void RayCheck(Vector3 center, float radius) { _colliders.Clear(); Collider[] hitColliders = Physics.OverlapSphere(center, radius); for (int i = 0; i < hitColliders.Length; i++) { if (CVR_TriggerList.Check(hitColliders[i].gameObject, TriggerList)) { _colliders.Add(hitColliders[i]); } } OnInteractableObjectTrigger(this, new CVR_InteractableTriggerEventArgs() { interactable = this.interactable, triggerTool = this, toolType = interactable.GetToolType(), triggerObjects = _colliders.ToArray() }); } public virtual void OnInteractableObjectTrigger(object sender, CVR_InteractableTriggerEventArgs e) { if (InteractableTrigger != null) { InteractableTrigger(this, e); } } /// ///重置工具触发参数 /// /// public void ResetTriggerInfo(ToolTriggerInfos triggerToolInfo) { triggerRange = triggerToolInfo.trigger_DetectionRange; TriggerList.checkType = triggerToolInfo.toolCheckTypes; TriggerList.identifiers.Clear(); TriggerList.identifiers.AddRange(triggerToolInfo.toolCheckInfos); buttonPressType = triggerToolInfo.buttonPressType; buttonType = triggerToolInfo.buttonType; } } }