AOIEntitySystem.cs 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181
  1. using System.Collections.Generic;
  2. using Unity.Mathematics;
  3. namespace ET.Server
  4. {
  5. [FriendOf(typeof(AOIEntity))]
  6. [FriendOf(typeof(Cell))]
  7. public static class AOIEntitySystem
  8. {
  9. [ObjectSystem]
  10. public class AwakeSystem: AwakeSystem<AOIEntity, int, float3>
  11. {
  12. protected override void Awake(AOIEntity self, int distance, float3 pos)
  13. {
  14. self.ViewDistance = distance;
  15. self.DomainScene().GetComponent<AOIManagerComponent>().Add(self, pos.x, pos.z);
  16. }
  17. }
  18. [ObjectSystem]
  19. public class DestroySystem: DestroySystem<AOIEntity>
  20. {
  21. protected override void Destroy(AOIEntity self)
  22. {
  23. self.DomainScene().GetComponent<AOIManagerComponent>()?.Remove(self);
  24. self.ViewDistance = 0;
  25. self.SeeUnits.Clear();
  26. self.SeePlayers.Clear();
  27. self.BeSeePlayers.Clear();
  28. self.BeSeeUnits.Clear();
  29. self.SubEnterCells.Clear();
  30. self.SubLeaveCells.Clear();
  31. self.Cell = null;
  32. }
  33. }
  34. // 获取在自己视野中的对象
  35. public static Dictionary<long, AOIEntity> GetSeeUnits(this AOIEntity self)
  36. {
  37. return self.SeeUnits;
  38. }
  39. public static Dictionary<long, AOIEntity> GetBeSeePlayers(this AOIEntity self)
  40. {
  41. return self.BeSeePlayers;
  42. }
  43. public static Dictionary<long, AOIEntity> GetSeePlayers(this AOIEntity self)
  44. {
  45. return self.SeePlayers;
  46. }
  47. // cell中的unit进入self的视野
  48. public static void SubEnter(this AOIEntity self, Cell cell)
  49. {
  50. cell.SubsEnterEntities.Add(self.Id, self);
  51. foreach (KeyValuePair<long, AOIEntity> kv in cell.AOIUnits)
  52. {
  53. if (kv.Key == self.Id)
  54. {
  55. continue;
  56. }
  57. self.EnterSight(kv.Value);
  58. }
  59. }
  60. public static void UnSubEnter(this AOIEntity self, Cell cell)
  61. {
  62. cell.SubsEnterEntities.Remove(self.Id);
  63. }
  64. public static void SubLeave(this AOIEntity self, Cell cell)
  65. {
  66. cell.SubsLeaveEntities.Add(self.Id, self);
  67. }
  68. // cell中的unit离开self的视野
  69. public static void UnSubLeave(this AOIEntity self, Cell cell)
  70. {
  71. foreach (KeyValuePair<long, AOIEntity> kv in cell.AOIUnits)
  72. {
  73. if (kv.Key == self.Id)
  74. {
  75. continue;
  76. }
  77. self.LeaveSight(kv.Value);
  78. }
  79. cell.SubsLeaveEntities.Remove(self.Id);
  80. }
  81. // enter进入self视野
  82. public static void EnterSight(this AOIEntity self, AOIEntity enter)
  83. {
  84. // 有可能之前在Enter,后来出了Enter还在LeaveCell,这样仍然没有删除,继续进来Enter,这种情况不需要处理
  85. if (self.SeeUnits.ContainsKey(enter.Id))
  86. {
  87. return;
  88. }
  89. if (!AOISeeCheckHelper.IsCanSee(self, enter))
  90. {
  91. return;
  92. }
  93. if (self.Unit.Type == UnitType.Player)
  94. {
  95. if (enter.Unit.Type == UnitType.Player)
  96. {
  97. self.SeeUnits.Add(enter.Id, enter);
  98. enter.BeSeeUnits.Add(self.Id, self);
  99. self.SeePlayers.Add(enter.Id, enter);
  100. enter.BeSeePlayers.Add(self.Id, self);
  101. }
  102. else
  103. {
  104. self.SeeUnits.Add(enter.Id, enter);
  105. enter.BeSeeUnits.Add(self.Id, self);
  106. enter.BeSeePlayers.Add(self.Id, self);
  107. }
  108. }
  109. else
  110. {
  111. if (enter.Unit.Type == UnitType.Player)
  112. {
  113. self.SeeUnits.Add(enter.Id, enter);
  114. enter.BeSeeUnits.Add(self.Id, self);
  115. self.SeePlayers.Add(enter.Id, enter);
  116. }
  117. else
  118. {
  119. self.SeeUnits.Add(enter.Id, enter);
  120. enter.BeSeeUnits.Add(self.Id, self);
  121. }
  122. }
  123. EventSystem.Instance.Publish(self.DomainScene(), new EventType.UnitEnterSightRange() { A = self, B = enter });
  124. }
  125. // leave离开self视野
  126. public static void LeaveSight(this AOIEntity self, AOIEntity leave)
  127. {
  128. if (self.Id == leave.Id)
  129. {
  130. return;
  131. }
  132. if (!self.SeeUnits.ContainsKey(leave.Id))
  133. {
  134. return;
  135. }
  136. self.SeeUnits.Remove(leave.Id);
  137. if (leave.Unit.Type == UnitType.Player)
  138. {
  139. self.SeePlayers.Remove(leave.Id);
  140. }
  141. leave.BeSeeUnits.Remove(self.Id);
  142. if (self.Unit.Type == UnitType.Player)
  143. {
  144. leave.BeSeePlayers.Remove(self.Id);
  145. }
  146. EventSystem.Instance.Publish(self.DomainScene(), new EventType.UnitLeaveSightRange { A = self, B = leave });
  147. }
  148. /// <summary>
  149. /// 是否在Unit视野范围内
  150. /// </summary>
  151. /// <param name="self"></param>
  152. /// <param name="unitId"></param>
  153. /// <returns></returns>
  154. public static bool IsBeSee(this AOIEntity self, long unitId)
  155. {
  156. return self.BeSeePlayers.ContainsKey(unitId);
  157. }
  158. }
  159. }