MoveComponent.cs 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275
  1. using System.Collections.Generic;
  2. using UnityEngine;
  3. namespace Model
  4. {
  5. [ObjectEvent]
  6. public class MoveComponentEvent : ObjectEvent<MoveComponent>, IAwake, IUpdate
  7. {
  8. public void Awake()
  9. {
  10. this.Get().Awake();
  11. }
  12. public void Update()
  13. {
  14. this.Get().Update();
  15. }
  16. }
  17. public class Speed
  18. {
  19. public long Id;
  20. public Vector3 Value;
  21. public Speed()
  22. {
  23. }
  24. public Speed(long id)
  25. {
  26. this.Id = id;
  27. }
  28. }
  29. public class MoveComponent : Component
  30. {
  31. private AnimatorComponent animatorComponent;
  32. public long mainSpeed;
  33. public Dictionary<long, Speed> speeds = new Dictionary<long, Speed>();
  34. // turn
  35. public Quaternion To;
  36. public Quaternion From;
  37. public float t = float.MaxValue;
  38. public float TurnTime = 0.1f;
  39. public bool IsArrived { get; private set; } = true;
  40. public bool hasDest;
  41. public Vector3 Dest;
  42. public Vector3 MainSpeed
  43. {
  44. get
  45. {
  46. Speed speed;
  47. if (!this.speeds.TryGetValue(this.mainSpeed, out speed))
  48. {
  49. speed = new Speed(this.mainSpeed);
  50. this.speeds.Add(speed.Id, speed);
  51. }
  52. return speed.Value;
  53. }
  54. set
  55. {
  56. Speed speed;
  57. if (!this.speeds.TryGetValue(this.mainSpeed, out speed))
  58. {
  59. speed = new Speed(this.mainSpeed);
  60. this.speeds.Add(speed.Id, speed);
  61. }
  62. speed.Value = value;
  63. animatorComponent?.SetFloatValue("Speed", speed.Value.magnitude);
  64. }
  65. }
  66. public Vector3 Speed
  67. {
  68. get
  69. {
  70. Vector3 speed = new Vector3();
  71. foreach (Speed sp in this.speeds.Values)
  72. {
  73. speed += sp.Value;
  74. }
  75. return speed;
  76. }
  77. }
  78. public void Awake()
  79. {
  80. this.mainSpeed = this.AddSpeed(new Vector3());
  81. this.animatorComponent = this.GetComponent<AnimatorComponent>();
  82. }
  83. public void Update()
  84. {
  85. UpdateTurn();
  86. if (this.IsArrived)
  87. {
  88. return;
  89. }
  90. if (this.Speed == Vector3.zero)
  91. {
  92. return;
  93. }
  94. Unit unit = this.GetEntity<Unit>();
  95. Vector3 moveVector3 = this.Speed * Time.deltaTime;
  96. if (this.hasDest)
  97. {
  98. float dist = (this.Dest - unit.Position).magnitude;
  99. if (moveVector3.magnitude >= dist || dist < 0.1f)
  100. {
  101. unit.Position = this.Dest;
  102. this.IsArrived = true;
  103. return;
  104. }
  105. }
  106. unit.Position = unit.Position + moveVector3;
  107. }
  108. private void UpdateTurn()
  109. {
  110. //Log.Debug($"update turn: {this.t} {this.TurnTime}");
  111. if (this.t > this.TurnTime)
  112. {
  113. return;
  114. }
  115. this.t += Time.deltaTime;
  116. Quaternion v = Quaternion.Slerp(this.From, this.To, this.t / this.TurnTime);
  117. this.GetEntity<Unit>().Rotation = v;
  118. }
  119. public void MoveToDest(Vector3 dest, float speedValue)
  120. {
  121. if ((dest - this.GetEntity<Unit>().Position).magnitude < 0.1f)
  122. {
  123. this.IsArrived = true;
  124. return;
  125. }
  126. this.IsArrived = false;
  127. this.hasDest = true;
  128. Vector3 speed = dest - this.GetEntity<Unit>().Position;
  129. speed = speed.normalized * speedValue;
  130. this.MainSpeed = speed;
  131. this.Dest = dest;
  132. }
  133. public void MoveToDir(Vector3 dir)
  134. {
  135. this.IsArrived = false;
  136. this.hasDest = false;
  137. this.MainSpeed = dir;
  138. }
  139. public long AddSpeed(Vector3 spd)
  140. {
  141. Speed speed = new Speed() { Value = spd };
  142. this.speeds.Add(speed.Id, speed);
  143. return speed.Id;
  144. }
  145. public Speed GetSpeed(long id)
  146. {
  147. Speed speed;
  148. this.speeds.TryGetValue(id, out speed);
  149. return speed;
  150. }
  151. public void RemoveSpeed(long id)
  152. {
  153. Speed speed;
  154. if (!this.speeds.TryGetValue(id, out speed))
  155. {
  156. return;
  157. }
  158. this.speeds.Remove(id);
  159. }
  160. /// <summary>
  161. /// 停止移动Unit,只停止地面正常移动,不停止击飞等移动
  162. /// </summary>
  163. public void Stop()
  164. {
  165. this.speeds.Clear();
  166. this.animatorComponent?.SetFloatValue("Speed", 0);
  167. }
  168. /// <summary>
  169. /// 改变Unit的朝向
  170. /// </summary>
  171. public void Turn2D(Vector3 dir, float turnTime = 0.1f)
  172. {
  173. Vector3 nexpos = this.GetEntity<Unit>().GameObject.transform.position + dir;
  174. Turn(nexpos, turnTime);
  175. }
  176. /// <summary>
  177. /// 改变Unit的朝向
  178. /// </summary>
  179. public void Turn(Vector3 target, float turnTime = 0.1f)
  180. {
  181. Quaternion quaternion = PositionHelper.GetVector3ToQuaternion(this.GetEntity<Unit>().Position, target);
  182. this.To = quaternion;
  183. this.From = this.GetEntity<Unit>().Rotation;
  184. this.t = 0;
  185. this.TurnTime = turnTime;
  186. }
  187. /// <summary>
  188. /// 改变Unit的朝向
  189. /// </summary>
  190. /// <param name="angle">与X轴正方向的夹角</param>
  191. public void Turn(float angle, float turnTime = 0.1f)
  192. {
  193. Quaternion quaternion = PositionHelper.GetAngleToQuaternion(angle);
  194. this.To = quaternion;
  195. this.From = this.GetEntity<Unit>().Rotation;
  196. this.t = 0;
  197. this.TurnTime = turnTime;
  198. }
  199. public void Turn(Quaternion quaternion, float turnTime = 0.1f)
  200. {
  201. this.To = quaternion;
  202. this.From = this.GetEntity<Unit>().Rotation;
  203. this.t = 0;
  204. this.TurnTime = turnTime;
  205. }
  206. public void TurnImmediately(Quaternion quaternion)
  207. {
  208. this.GetEntity<Unit>().Rotation = quaternion;
  209. }
  210. public void TurnImmediately(Vector3 target)
  211. {
  212. Vector3 nowPos = this.GetEntity<Unit>().Position;
  213. if (nowPos == target)
  214. {
  215. return;
  216. }
  217. Quaternion quaternion = PositionHelper.GetVector3ToQuaternion(this.GetEntity<Unit>().Position, target);
  218. this.GetEntity<Unit>().Rotation = quaternion;
  219. }
  220. public void TurnImmediately(float angle)
  221. {
  222. Quaternion quaternion = PositionHelper.GetAngleToQuaternion(angle);
  223. this.GetEntity<Unit>().Rotation = quaternion;
  224. }
  225. public override void Dispose()
  226. {
  227. if (this.Id == 0)
  228. {
  229. return;
  230. }
  231. base.Dispose();
  232. }
  233. }
  234. }