HangDiaoController.cs 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318
  1. using System;
  2. using System.Collections;
  3. using System.Collections.Generic;
  4. using UnityEngine;
  5. /// <summary>
  6. /// 行吊控制器
  7. /// 基于标准父级移动轴
  8. /// </summary>
  9. ///
  10. public class HangDiaoController : MonoBehaviour
  11. {
  12. public static HangDiaoController instance;
  13. public enum HangDiaoRunningState
  14. {
  15. 待机,
  16. 横梁移动,
  17. 电机移动,
  18. 展开吊钩,
  19. 收起吊钩,
  20. 自由追随
  21. }
  22. public class HangDiaoRunningStateEventData
  23. {
  24. public HangDiaoRunningState runningState;
  25. public bool finished;
  26. public HangDiaoRunningStateEventData(HangDiaoRunningState state, bool finished)
  27. {
  28. this.runningState = state;
  29. this.finished = finished;
  30. }
  31. }
  32. //行吊运行状态
  33. public delegate void HD_RuningEvent(HangDiaoRunningStateEventData eventData);
  34. //行吊完成状态
  35. public HD_RuningEvent RuningStateChanged;
  36. public HangDiaoRunningState hangDiaoRuningState = HangDiaoRunningState.待机;
  37. //追随目标
  38. public Transform targetPoint;
  39. //行吊横梁
  40. public Transform hd_HengLiang;
  41. //行吊横梁电机
  42. public Transform hd_HengXiangDianJi;
  43. public Transform hd_ShengZi_Chang;
  44. public Transform hd_ShengZi_Duan;
  45. //挂钩
  46. public Transform hd_GuaGou;
  47. //实际挂钩点距挂钩模型的偏移量
  48. public Vector3 guaGouOffset = new Vector3(0, -0.0022f, -0.1745f);
  49. //绳子的缩放比例 1 :1.137115
  50. public float shengZiDuan_Scale = 1.37115f;
  51. public float shengZiChang_Scale = 1.49664f;
  52. //挂钩初始高度(距电机的相对Z轴)
  53. private float guaGouInitHeight = -0.5f;
  54. //横梁移动速度
  55. public float hengLiangMoveSpeed = 1f;
  56. //吊钩移动速度
  57. public float diaoGouMoveSpeed = 0.5f;
  58. //横梁电机移动速度
  59. public float hengLiangDianJiMoveSpeed = 1f;
  60. //根据时间调整移动速度
  61. public float moveTimeLimit = 2;
  62. private bool moveToTarget = false;
  63. public void Awake()
  64. {
  65. instance = this;
  66. }
  67. // Update is called once per frame
  68. void Update()
  69. {
  70. CheckRuningState();
  71. }
  72. /// <summary>
  73. /// 运行状态检测
  74. /// </summary>
  75. public void CheckRuningState()
  76. {
  77. switch (hangDiaoRuningState)
  78. {
  79. case HangDiaoRunningState.待机:
  80. break;
  81. case HangDiaoRunningState.横梁移动:
  82. HD_HengLiang_Move();
  83. break;
  84. case HangDiaoRunningState.电机移动:
  85. HD_HengLiangDianJi_Move();
  86. break;
  87. case HangDiaoRunningState.展开吊钩:
  88. HD_DiaoGou_Open();
  89. break;
  90. case HangDiaoRunningState.收起吊钩:
  91. HD_DiaoGou_ShouHui();
  92. break;
  93. case HangDiaoRunningState.自由追随:
  94. UpdataByTagetPoint();
  95. break;
  96. default:
  97. break;
  98. }
  99. }
  100. /// <summary>
  101. /// 更新行吊状态至目标位置
  102. /// </summary>
  103. /// <param name="pos"></param>
  104. public void SetTargetPos(Vector3 pos)
  105. {
  106. Vector3 targetPointLocalPosInHangDiao = this.transform.InverseTransformPoint(pos);
  107. //行吊位置更新
  108. hd_HengLiang.transform.localPosition = new Vector3(hd_HengLiang.localPosition.x, hd_HengLiang.localPosition.y, targetPointLocalPosInHangDiao.z);
  109. //电机位置更新
  110. Vector3 targetPointLocalPosInHengLiang = hd_HengLiang.InverseTransformPoint(pos);
  111. hd_HengXiangDianJi.localPosition = new Vector3(targetPointLocalPosInHengLiang.x, hd_HengXiangDianJi.localPosition.y, hd_HengXiangDianJi.localPosition.z);
  112. //更新挂钩位置
  113. hd_GuaGou.position = pos - hd_GuaGou.TransformVector(guaGouOffset);
  114. //更新绳索缩放
  115. hd_ShengZi_Chang.localScale = new Vector3(1,1,hd_GuaGou.InverseTransformPoint(hd_ShengZi_Chang.position).z / shengZiChang_Scale);
  116. hd_ShengZi_Duan.localScale = new Vector3(1,1, hd_GuaGou.InverseTransformPoint(hd_ShengZi_Duan.position).z / shengZiDuan_Scale);
  117. }
  118. /// <summary>
  119. /// 移动到目标位置
  120. /// </summary>
  121. public void MoveToTargetPoint()
  122. {
  123. if (!moveToTarget)
  124. {
  125. RuningStateChanged += MoveToTargetRuningStateChanged;
  126. }
  127. moveToTarget = true;
  128. hangDiaoRuningState = HangDiaoRunningState.收起吊钩;
  129. }
  130. /// <summary>
  131. /// 在时间范围内移动至目标位置
  132. /// </summary>
  133. public void MoveToTargetPointInTime()
  134. {
  135. CheckTimeChangedSpeed(moveTimeLimit);
  136. MoveToTargetPoint();
  137. }
  138. /// <summary>
  139. /// 设置目标位置
  140. /// </summary>
  141. /// <param name="t"></param>
  142. public void SetTarget(Transform t)
  143. {
  144. targetPoint = t;
  145. hangDiaoRuningState = HangDiaoRunningState.待机;
  146. }
  147. public void MoveToTargetRuningStateChanged(HangDiaoRunningStateEventData eventData)
  148. {
  149. if (!eventData.finished) return;
  150. //Debug.Log(hangDiaoRuningState.ToString() + "Finished");
  151. switch (eventData.runningState)
  152. {
  153. case HangDiaoRunningState.横梁移动:
  154. hangDiaoRuningState = HangDiaoRunningState.电机移动;
  155. break;
  156. case HangDiaoRunningState.电机移动:
  157. hangDiaoRuningState = HangDiaoRunningState.展开吊钩;
  158. break;
  159. case HangDiaoRunningState.展开吊钩:
  160. hangDiaoRuningState = HangDiaoRunningState.自由追随;
  161. RuningStateChanged -= MoveToTargetRuningStateChanged;
  162. moveToTarget = false;
  163. break;
  164. case HangDiaoRunningState.收起吊钩:
  165. hangDiaoRuningState = HangDiaoRunningState.横梁移动;
  166. break;
  167. }
  168. }
  169. #region 状态
  170. /// <summary>
  171. /// 实时更新目标位置
  172. /// </summary>
  173. public void UpdataByTagetPoint()
  174. {
  175. if (targetPoint == null) return;
  176. Vector3 targetPointLocalPosInHangDiao = this.transform.InverseTransformPoint(targetPoint.position);
  177. //行吊位置更新
  178. hd_HengLiang.transform.localPosition = new Vector3(hd_HengLiang.localPosition.x, hd_HengLiang.localPosition.y, targetPointLocalPosInHangDiao.z);
  179. //电机位置更新
  180. Vector3 targetPointLocalPosInHengLiang = hd_HengLiang.InverseTransformPoint(targetPoint.position);
  181. hd_HengXiangDianJi.localPosition = new Vector3(targetPointLocalPosInHengLiang.x, hd_HengXiangDianJi.localPosition.y, hd_HengXiangDianJi.localPosition.z);
  182. //更新挂钩位置
  183. hd_GuaGou.position = targetPoint.position - hd_GuaGou.TransformVector(guaGouOffset);
  184. //更新绳索缩放
  185. hd_ShengZi_Chang.localScale = new Vector3(1,1,hd_GuaGou.InverseTransformPoint(hd_ShengZi_Chang.position).z / shengZiChang_Scale);
  186. hd_ShengZi_Duan.localScale = new Vector3(1,1,hd_GuaGou.InverseTransformPoint(hd_ShengZi_Duan.position).z / shengZiDuan_Scale);
  187. }
  188. /// <summary>
  189. /// 吊钩收回
  190. /// </summary>
  191. public void HD_DiaoGou_ShouHui()
  192. {
  193. //更新挂钩位置
  194. hd_GuaGou.localPosition =
  195. new Vector3(hd_GuaGou.localPosition.x, hd_GuaGou.localPosition.y
  196. , Mathf.MoveTowards(hd_GuaGou.localPosition.z, guaGouInitHeight, diaoGouMoveSpeed * Time.deltaTime));
  197. hd_ShengZi_Chang.localScale = new Vector3(1, 1, hd_GuaGou.InverseTransformPoint(hd_ShengZi_Chang.position).y / shengZiChang_Scale);
  198. hd_ShengZi_Duan.localScale = new Vector3(1,1,hd_GuaGou.InverseTransformPoint(hd_ShengZi_Duan.position).y / shengZiDuan_Scale);
  199. if (hd_GuaGou.localPosition.z == guaGouInitHeight)
  200. RuningStateChanged?.Invoke(new HangDiaoRunningStateEventData(HangDiaoRunningState.收起吊钩, true));
  201. }
  202. /// <summary>
  203. /// 吊钩拉伸
  204. /// </summary>
  205. public void HD_DiaoGou_Open()
  206. {
  207. //更新挂钩位置
  208. hd_GuaGou.localPosition =
  209. new Vector3(hd_GuaGou.localPosition.x, hd_GuaGou.localPosition.y
  210. , Mathf.MoveTowards(hd_GuaGou.localPosition.z,
  211. (hd_HengXiangDianJi.InverseTransformPoint(targetPoint.position).z - guaGouOffset.z)
  212. , diaoGouMoveSpeed * Time.deltaTime));
  213. hd_ShengZi_Chang.localScale = new Vector3(1, 1, hd_GuaGou.InverseTransformPoint(hd_ShengZi_Chang.position).z / shengZiChang_Scale);
  214. hd_ShengZi_Duan.localScale = new Vector3(1,1,hd_GuaGou.InverseTransformPoint(hd_ShengZi_Duan.position).z / shengZiDuan_Scale);
  215. if (Mathf.Abs(hd_GuaGou.localPosition.z - (hd_HengXiangDianJi.InverseTransformPoint(targetPoint.position).z - guaGouOffset.z)) < 0.01f)
  216. RuningStateChanged?.Invoke(new HangDiaoRunningStateEventData(HangDiaoRunningState.展开吊钩, true));
  217. }
  218. /// <summary>
  219. /// 行吊横梁移动
  220. /// </summary>
  221. public void HD_HengLiang_Move()
  222. {
  223. Vector3 targetPointLocalPosInHangDiao = this.transform.InverseTransformPoint(targetPoint.position);
  224. //行吊位置更新
  225. hd_HengLiang.transform.localPosition = new Vector3(hd_HengLiang.localPosition.x, hd_HengLiang.localPosition.y
  226. , Mathf.MoveTowards(hd_HengLiang.localPosition.z, targetPointLocalPosInHangDiao.z
  227. , hengLiangMoveSpeed * Time.deltaTime));
  228. if (hd_HengLiang.localPosition.z == targetPointLocalPosInHangDiao.z)
  229. RuningStateChanged?.Invoke(new HangDiaoRunningStateEventData(HangDiaoRunningState.横梁移动, true));
  230. }
  231. /// <summary>
  232. /// 行吊横梁电机移动
  233. /// </summary>
  234. public void HD_HengLiangDianJi_Move()
  235. {
  236. //电机位置更新
  237. Vector3 targetPointLocalPosInHengLiang = hd_HengLiang.InverseTransformPoint(targetPoint.position);
  238. hd_HengXiangDianJi.localPosition = new Vector3(Mathf.MoveTowards(hd_HengXiangDianJi.localPosition.x, targetPointLocalPosInHengLiang.x
  239. , hengLiangMoveSpeed * Time.deltaTime), hd_HengXiangDianJi.localPosition.y, hd_HengXiangDianJi.localPosition.z);
  240. if (hd_HengXiangDianJi.localPosition.x == targetPointLocalPosInHengLiang.x)
  241. RuningStateChanged?.Invoke(new HangDiaoRunningStateEventData(HangDiaoRunningState.电机移动, true));
  242. }
  243. /// <summary>
  244. /// 根据整体时间改变速度
  245. /// </summary>
  246. /// <param name="moveMaxTime"></param>
  247. public void CheckTimeChangedSpeed(float moveMaxTime)
  248. {
  249. float targetMoveDistance = 0;
  250. //吊钩回收
  251. targetMoveDistance += Mathf.Abs(hd_GuaGou.localPosition.z - guaGouInitHeight);
  252. //横梁移动
  253. Vector3 targetPointLocalPosInHangDiao = this.transform.InverseTransformPoint(targetPoint.position);
  254. targetMoveDistance += Mathf.Abs(hd_HengLiang.localPosition.z - targetPointLocalPosInHangDiao.z);
  255. //电机移动
  256. Vector3 targetPointLocalPosInHengLiang = hd_HengLiang.InverseTransformPoint(targetPoint.position);
  257. targetMoveDistance += Mathf.Abs(hd_HengXiangDianJi.localPosition.x - targetPointLocalPosInHengLiang.x);
  258. //吊车下放
  259. targetMoveDistance += Mathf.Abs(guaGouInitHeight -
  260. (hd_HengXiangDianJi.InverseTransformPoint(targetPoint.position).z - guaGouOffset.z));
  261. float moveSpeed = targetMoveDistance / moveMaxTime;
  262. diaoGouMoveSpeed = moveSpeed;
  263. hengLiangMoveSpeed = moveSpeed;
  264. hengLiangDianJiMoveSpeed = moveSpeed;
  265. }
  266. #endregion
  267. }