using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.Events; using VRTK; //被一个/多个固定物影响交互的物体 同时又影响其他物体交互 public abstract class FixedAbs : MonoBehaviour,IFixed,IVRGrabOperater { //影响本物体交互的固定器 [SerializeField] protected IFixator [] fixators; //处于可固定位置 protected bool onFixedPos; protected VRTK_InteractableObject interactableObject; protected FixedStateEnum currentFixedState; public FixedStateEnum CurrentFixedState { get { return currentFixedState; } } public FixatorStateEnum FixatorState => throw new System.NotImplementedException(); protected virtual void Awake() { interactableObject = this.GetComponentInChildren(); interactableObject.InteractableObjectUngrabbed += UnGrabbed;//物体放开时执行 interactableObject.InteractableObjectGrabbed += Grabbed;//物体放开时执行 } //物体被手柄放开时 private void UnGrabbed(object sender, InteractableObjectEventArgs e) { UnGrabbed(); } //物体被手柄放开时 private void Grabbed(object sender, InteractableObjectEventArgs e) { Grabbed(); } //固定器发生变化时 public virtual void FixatorChanged(IFixator fixator, FixatorStateEnum fixatorState) { if (!onFixedPos) return;//不在固定位置 固定器发生变化 不做处理 //固定器打开时 检索是否所有的都被打开 都被打开 则本物体可以交互 if (fixatorState == FixatorStateEnum.UnLocking) { IFixator lockedFixator = ArrayHelper.Find(fixators, p => p.FixatorState == FixatorStateEnum.Locking); if (lockedFixator == null)//所有的固定器都被打开 { currentFixedState = FixedStateEnum.Free; SetInteractable(true);//开启交互 } else { currentFixedState = FixedStateEnum.HalfFixed; //部分固定器被打开了 变为半紧固状态 } } else if (fixatorState == FixatorStateEnum.Locking)//固定器锁上时 判定是否固定物体 { if (onFixedPos)//在正确位置 { SetInteractable(false);//关闭交互 } IFixator lockedFixator = ArrayHelper.Find(fixators, p => p.FixatorState == FixatorStateEnum.UnLocking); if (lockedFixator == null)//所有的固定器都锁上了 { currentFixedState = FixedStateEnum.Fixed; } else//部分固定器锁上了 { currentFixedState = FixedStateEnum.HalfFixed; // 半紧固状态 } } } //初始化固定器 注册固定器状态变化事件 public void InitFixator(IFixator[] fixators) { this.fixators = fixators; for (int i = 0; i < fixators.Length; i++) { fixators[i].ReisterStateChanged(FixatorChanged); } } //改变物体可交互状态 public virtual void SetInteractable(bool interactable) { interactableObject.isGrabbable = false; } //被抓取物体放下时执行 public abstract void UnGrabbed(); //被抓取时执行 public abstract void Grabbed(); //到达安装位置 起到遮挡/固定作用 public void Locking() { } //到达开启位置 移除遮挡/固定作用 public void UnLocking() { } public void SetUseInteractable(bool interactable) { interactableObject.isUsable = false; } }