using System; using System.Collections; using System.Collections.Generic; using UnityEngine; /// /// 行吊控制器 /// 基于标准父级移动轴 /// /// public class HangDiaoController : MonoBehaviour { public static HangDiaoController instance; public enum HangDiaoRunningState { 待机, 横梁移动, 电机移动, 展开吊钩, 收起吊钩, 自由追随 } public class HangDiaoRunningStateEventData { public HangDiaoRunningState runningState; public bool finished; public HangDiaoRunningStateEventData(HangDiaoRunningState state, bool finished) { this.runningState = state; this.finished = finished; } } //行吊运行状态 public delegate void HD_RuningEvent(HangDiaoRunningStateEventData eventData); //行吊完成状态 public HD_RuningEvent RuningStateChanged; public HangDiaoRunningState hangDiaoRuningState = HangDiaoRunningState.待机; //追随目标 public Transform targetPoint; //行吊横梁 public Transform hd_HengLiang; //行吊横梁电机 public Transform hd_HengXiangDianJi; public Transform hd_ShengZi_Chang; public Transform hd_ShengZi_Duan; //挂钩 public Transform hd_GuaGou; //实际挂钩点距挂钩模型的偏移量 public Vector3 guaGouOffset = new Vector3(0, -0.0022f, -0.1745f); //绳子的缩放比例 1 :1.137115 public float shengZiDuan_Scale = 1.37115f; public float shengZiChang_Scale = 1.49664f; //挂钩初始高度(距电机的相对Z轴) private float guaGouInitHeight = -0.5f; //横梁移动速度 public float hengLiangMoveSpeed = 1f; //吊钩移动速度 public float diaoGouMoveSpeed = 0.5f; //横梁电机移动速度 public float hengLiangDianJiMoveSpeed = 1f; //根据时间调整移动速度 public float moveTimeLimit = 2; private bool moveToTarget = false; public void Awake() { instance = this; } // Update is called once per frame void Update() { CheckRuningState(); } /// /// 运行状态检测 /// public void CheckRuningState() { switch (hangDiaoRuningState) { case HangDiaoRunningState.待机: break; case HangDiaoRunningState.横梁移动: HD_HengLiang_Move(); break; case HangDiaoRunningState.电机移动: HD_HengLiangDianJi_Move(); break; case HangDiaoRunningState.展开吊钩: HD_DiaoGou_Open(); break; case HangDiaoRunningState.收起吊钩: HD_DiaoGou_ShouHui(); break; case HangDiaoRunningState.自由追随: UpdataByTagetPoint(); break; default: break; } } /// /// 更新行吊状态至目标位置 /// /// public void SetTargetPos(Vector3 pos) { Vector3 targetPointLocalPosInHangDiao = this.transform.InverseTransformPoint(pos); //行吊位置更新 hd_HengLiang.transform.localPosition = new Vector3(hd_HengLiang.localPosition.x, hd_HengLiang.localPosition.y, targetPointLocalPosInHangDiao.z); //电机位置更新 Vector3 targetPointLocalPosInHengLiang = hd_HengLiang.InverseTransformPoint(pos); hd_HengXiangDianJi.localPosition = new Vector3(targetPointLocalPosInHengLiang.x, hd_HengXiangDianJi.localPosition.y, hd_HengXiangDianJi.localPosition.z); //更新挂钩位置 hd_GuaGou.position = pos - hd_GuaGou.TransformVector(guaGouOffset); //更新绳索缩放 hd_ShengZi_Chang.localScale = new Vector3(1,1,hd_GuaGou.InverseTransformPoint(hd_ShengZi_Chang.position).z / shengZiChang_Scale); hd_ShengZi_Duan.localScale = new Vector3(1,1, hd_GuaGou.InverseTransformPoint(hd_ShengZi_Duan.position).z / shengZiDuan_Scale); } /// /// 移动到目标位置 /// public void MoveToTargetPoint() { if (!moveToTarget) { RuningStateChanged += MoveToTargetRuningStateChanged; } moveToTarget = true; hangDiaoRuningState = HangDiaoRunningState.收起吊钩; } /// /// 在时间范围内移动至目标位置 /// public void MoveToTargetPointInTime() { CheckTimeChangedSpeed(moveTimeLimit); MoveToTargetPoint(); } /// /// 设置目标位置 /// /// public void SetTarget(Transform t) { targetPoint = t; hangDiaoRuningState = HangDiaoRunningState.待机; } public void MoveToTargetRuningStateChanged(HangDiaoRunningStateEventData eventData) { if (!eventData.finished) return; //Debug.Log(hangDiaoRuningState.ToString() + "Finished"); switch (eventData.runningState) { case HangDiaoRunningState.横梁移动: hangDiaoRuningState = HangDiaoRunningState.电机移动; break; case HangDiaoRunningState.电机移动: hangDiaoRuningState = HangDiaoRunningState.展开吊钩; break; case HangDiaoRunningState.展开吊钩: hangDiaoRuningState = HangDiaoRunningState.自由追随; RuningStateChanged -= MoveToTargetRuningStateChanged; moveToTarget = false; break; case HangDiaoRunningState.收起吊钩: hangDiaoRuningState = HangDiaoRunningState.横梁移动; break; } } #region 状态 /// /// 实时更新目标位置 /// public void UpdataByTagetPoint() { if (targetPoint == null) return; Vector3 targetPointLocalPosInHangDiao = this.transform.InverseTransformPoint(targetPoint.position); //行吊位置更新 hd_HengLiang.transform.localPosition = new Vector3(hd_HengLiang.localPosition.x, hd_HengLiang.localPosition.y, targetPointLocalPosInHangDiao.z); //电机位置更新 Vector3 targetPointLocalPosInHengLiang = hd_HengLiang.InverseTransformPoint(targetPoint.position); hd_HengXiangDianJi.localPosition = new Vector3(targetPointLocalPosInHengLiang.x, hd_HengXiangDianJi.localPosition.y, hd_HengXiangDianJi.localPosition.z); //更新挂钩位置 hd_GuaGou.position = targetPoint.position - hd_GuaGou.TransformVector(guaGouOffset); //更新绳索缩放 hd_ShengZi_Chang.localScale = new Vector3(1,1,hd_GuaGou.InverseTransformPoint(hd_ShengZi_Chang.position).z / shengZiChang_Scale); hd_ShengZi_Duan.localScale = new Vector3(1,1,hd_GuaGou.InverseTransformPoint(hd_ShengZi_Duan.position).z / shengZiDuan_Scale); } /// /// 吊钩收回 /// public void HD_DiaoGou_ShouHui() { //更新挂钩位置 hd_GuaGou.localPosition = new Vector3(hd_GuaGou.localPosition.x, hd_GuaGou.localPosition.y , Mathf.MoveTowards(hd_GuaGou.localPosition.z, guaGouInitHeight, diaoGouMoveSpeed * Time.deltaTime)); hd_ShengZi_Chang.localScale = new Vector3(1, 1, hd_GuaGou.InverseTransformPoint(hd_ShengZi_Chang.position).y / shengZiChang_Scale); hd_ShengZi_Duan.localScale = new Vector3(1,1,hd_GuaGou.InverseTransformPoint(hd_ShengZi_Duan.position).y / shengZiDuan_Scale); if (hd_GuaGou.localPosition.z == guaGouInitHeight) RuningStateChanged?.Invoke(new HangDiaoRunningStateEventData(HangDiaoRunningState.收起吊钩, true)); } /// /// 吊钩拉伸 /// public void HD_DiaoGou_Open() { //更新挂钩位置 hd_GuaGou.localPosition = new Vector3(hd_GuaGou.localPosition.x, hd_GuaGou.localPosition.y , Mathf.MoveTowards(hd_GuaGou.localPosition.z, (hd_HengXiangDianJi.InverseTransformPoint(targetPoint.position).z - guaGouOffset.z) , diaoGouMoveSpeed * Time.deltaTime)); hd_ShengZi_Chang.localScale = new Vector3(1, 1, hd_GuaGou.InverseTransformPoint(hd_ShengZi_Chang.position).z / shengZiChang_Scale); hd_ShengZi_Duan.localScale = new Vector3(1,1,hd_GuaGou.InverseTransformPoint(hd_ShengZi_Duan.position).z / shengZiDuan_Scale); if (Mathf.Abs(hd_GuaGou.localPosition.z - (hd_HengXiangDianJi.InverseTransformPoint(targetPoint.position).z - guaGouOffset.z)) < 0.01f) RuningStateChanged?.Invoke(new HangDiaoRunningStateEventData(HangDiaoRunningState.展开吊钩, true)); } /// /// 行吊横梁移动 /// public void HD_HengLiang_Move() { Vector3 targetPointLocalPosInHangDiao = this.transform.InverseTransformPoint(targetPoint.position); //行吊位置更新 hd_HengLiang.transform.localPosition = new Vector3(hd_HengLiang.localPosition.x, hd_HengLiang.localPosition.y , Mathf.MoveTowards(hd_HengLiang.localPosition.z, targetPointLocalPosInHangDiao.z , hengLiangMoveSpeed * Time.deltaTime)); if (hd_HengLiang.localPosition.z == targetPointLocalPosInHangDiao.z) RuningStateChanged?.Invoke(new HangDiaoRunningStateEventData(HangDiaoRunningState.横梁移动, true)); } /// /// 行吊横梁电机移动 /// public void HD_HengLiangDianJi_Move() { //电机位置更新 Vector3 targetPointLocalPosInHengLiang = hd_HengLiang.InverseTransformPoint(targetPoint.position); hd_HengXiangDianJi.localPosition = new Vector3(Mathf.MoveTowards(hd_HengXiangDianJi.localPosition.x, targetPointLocalPosInHengLiang.x , hengLiangMoveSpeed * Time.deltaTime), hd_HengXiangDianJi.localPosition.y, hd_HengXiangDianJi.localPosition.z); if (hd_HengXiangDianJi.localPosition.x == targetPointLocalPosInHengLiang.x) RuningStateChanged?.Invoke(new HangDiaoRunningStateEventData(HangDiaoRunningState.电机移动, true)); } /// /// 根据整体时间改变速度 /// /// public void CheckTimeChangedSpeed(float moveMaxTime) { float targetMoveDistance = 0; //吊钩回收 targetMoveDistance += Mathf.Abs(hd_GuaGou.localPosition.z - guaGouInitHeight); //横梁移动 Vector3 targetPointLocalPosInHangDiao = this.transform.InverseTransformPoint(targetPoint.position); targetMoveDistance += Mathf.Abs(hd_HengLiang.localPosition.z - targetPointLocalPosInHangDiao.z); //电机移动 Vector3 targetPointLocalPosInHengLiang = hd_HengLiang.InverseTransformPoint(targetPoint.position); targetMoveDistance += Mathf.Abs(hd_HengXiangDianJi.localPosition.x - targetPointLocalPosInHengLiang.x); //吊车下放 targetMoveDistance += Mathf.Abs(guaGouInitHeight - (hd_HengXiangDianJi.InverseTransformPoint(targetPoint.position).z - guaGouOffset.z)); float moveSpeed = targetMoveDistance / moveMaxTime; diaoGouMoveSpeed = moveSpeed; hengLiangMoveSpeed = moveSpeed; hengLiangDianJiMoveSpeed = moveSpeed; } #endregion }