using XFramework; using UnityEngine.UI; using UnityEngine; using System; using VRTK; using UnityEngine.Events; //千斤顶控制器 到达指定位置时可以升起 public class QianJinDingCtrl : VRGrabInterractableBase { Transform transform_rootrod; Transform transform_firstrod; Transform transform_secondrod; CollisionCtrl collisionctrl_dingban; public Rigidbody rigCar; float currentChangeDir;//当前千斤顶长度变化方向 1伸长 2缩短 public float changeSpeed = 0.03f; float firstTargetValue = 0.1f; float secondTargetValue = 1.4f; UnityAction startUserOver;//开始使用完成 UnityAction stopUserOver;//结束使用完成 public event UnityAction OnUsedEvent;//交互触发事件 Collider[] thisColliders; QianJinDingInter dingInter;//千斤顶顶起的物体只有在千斤顶工作时 开启物理效果避免被撞飞 protected override void Awake() { base.Awake(); thisCollider.enabled = true; vRTK_Interactable.touchHighlightColor = Color.yellow; vRTK_Interactable.touchHighlightColor.a = 0.4f; InitEvent(); onFixedPos = false; SetUseInteractable(false); thisColliders = this.GetComponents(); if (GroupLearnHelper.isGroup) { this.gameObject.AddComponent(); this.gameObject.AddComponent(); } } private void SetUseInteractable(bool v) { vRTK_Interactable.isUsable = v; } void InitEvent() { transform_firstrod = this.transform.FindChildTrans("Transform_FirstRod"); transform_secondrod = this.transform.FindChildTrans("Transform_SecondRod"); collisionctrl_dingban = this.GetComponent(); collisionctrl_dingban.AddCollisionChangedEvent(CollisionEvent); vRTK_Interactable.InteractableObjectUsed += InteractableObjectUsed; } //顶起车辆时 禁用抓取状态 private void CollisionEvent(CollisionEnum arg0, Collision arg1) { //在工作位置顶起了一个质量较大的物体 禁用抓取状态 if (onFixedPos && arg1.gameObject.GetComponent()?.mass > 500) { switch (arg0) { case CollisionEnum.enter: SetGrabInteractable(false); dingInter = arg1.transform.GetComponent(); dingInter?.StartWork(); break; case CollisionEnum.exit: SetGrabInteractable(true); break; default: break; } } } //主动交互Use private void InteractableObjectUsed(object sender, InteractableObjectEventArgs e) { OnUsedEvent?.Invoke(); OnUsed(); } /// /// 主动/同步Use执行 /// public void OnUsed() { SetUseInteractable(false);//执行过程 先关闭 避免再次触发 if (currentProcess == ProcessEnum.teardown) Open(); else if (currentProcess == ProcessEnum.assemble) Close(); } //被抓取时 禁用use protected override void OnGrabbed(object sender, InteractableObjectEventArgs e) { base.OnGrabbed(sender, e); for (int i = 0; i < thisColliders.Length; i++) { thisColliders[i].isTrigger = true; } SetUseInteractable(false); } protected override void Ungrabbed(object sender, InteractableObjectEventArgs e) { base.Ungrabbed(sender, e); for (int i = 0; i < thisColliders.Length; i++) { thisColliders[i].isTrigger = false; } } //完成归位 启用交互逻辑 protected override void HomgingOver() { base.HomgingOver(); SetUseInteractable(true); } //撑开 private void Open() { currentChangeDir = 1; } //缩回 private void Close() { currentChangeDir = -1; dingInter?.StartWork(); } protected void FixedUpdate() { if (currentChangeDir != 0) { ChangeLength(currentChangeDir); } //if (Input.GetKeyDown(KeyCode.Space)) //{ // Open(); //} //if (Input.GetKeyDown(KeyCode.A)) //{ // Close(); //} } private void ChangeLength(float dir) { if (dir > 0) { HoistUp(dir); } else { ComeDown(dir); } } //升起 private void HoistUp(float upDir) { if (rigCar) rigCar.isKinematic = false; if (transform_firstrod.localPosition.z < firstTargetValue) { transform_firstrod.localPosition += new Vector3(0, 0, upDir) * Time.fixedDeltaTime * changeSpeed; } else if (transform_secondrod != null && transform_secondrod.localPosition.z < secondTargetValue) { transform_secondrod.localPosition += new Vector3(0, 0, upDir) * Time.fixedDeltaTime * changeSpeed; } else//到达目标长度 顶起了装备 { if (rigCar) rigCar.isKinematic = true; currentChangeDir = 0; startUserOver?.Invoke(); dingInter?.OnStabilize(); } } //降下 private void ComeDown(float downDir) { if (rigCar) rigCar.isKinematic = false; if (transform_firstrod.localPosition.z > -0.03f) { transform_firstrod.localPosition += new Vector3(0, 0, downDir) * Time.fixedDeltaTime * changeSpeed; } else if (transform_secondrod != null && transform_secondrod.localPosition.z > 0.44f) { transform_secondrod.localPosition += new Vector3(0, 0, downDir) * Time.fixedDeltaTime * changeSpeed; } else//到达目标长度 { if (rigCar) rigCar.isKinematic = true; currentChangeDir = 0; stopUserOver?.Invoke(); SetGrabInteractable(true);//降下之后启用抓取逻辑 } } //激活操作 注册操作完成事件 public override void Active(ProcessEnum stepName, UnityAction finishedEvent) { vRTK_Interactable.usingState = 0; currentProcess = stepName; if (stepName == ProcessEnum.assemble)//组装流程时 { SetUseInteractable(true);//启用升降逻辑 atFreePos = finishedEvent;//移除特定位置时认为操作完成 } else if (stepName == ProcessEnum.teardown)//拆卸流程时 { SetGrabInteractable(true);//启用抓取逻辑 startUserOver = finishedEvent;//升起完成后 视为流程完成 } } //退出激活状态 public override void UnActive(ProcessEnum stepName) { base.UnActive(stepName); SetGrabInteractable(false); SetUseInteractable(false); startUserOver = null; } }