Example #1
0
        public static void Move(AOIEntity aoiEntity, Cell newCell, Cell preCell)
        {
            aoiEntity.Cell = newCell;
            preCell.Remove(aoiEntity);
            newCell.Add(aoiEntity);
            // 通知订阅该newCell Enter的Unit
            foreach (KeyValuePair <long, AOIEntity> kv in newCell.SubsEnterEntities)
            {
                if (kv.Value.SubEnterCells.Contains(preCell.Id))
                {
                    continue;
                }

                kv.Value.EnterSight(aoiEntity);
            }

            // 通知订阅preCell leave的Unit
            foreach (KeyValuePair <long, AOIEntity> kv in preCell.SubsLeaveEntities)
            {
                // 如果新的cell仍然在对方订阅的subleave中
                if (kv.Value.SubLeaveCells.Contains(newCell.Id))
                {
                    continue;
                }

                kv.Value.LeaveSight(aoiEntity);
            }
        }
Example #2
0
        public static void CalcEnterAndLeaveCell(AOIEntity aoiEntity, int cellX, int cellY, HashSet <long> enterCell, HashSet <long> leaveCell)
        {
            enterCell.Clear();
            leaveCell.Clear();
            int r      = (aoiEntity.ViewDistance - 1) / AOIManagerComponent.CellSize + 1;
            int leaveR = r;

            if (aoiEntity.Unit.Type == UnitType.Player)
            {
                leaveR += 1;
            }

            for (int i = cellX - leaveR; i <= cellX + leaveR; ++i)
            {
                for (int j = cellY - leaveR; j <= cellY + leaveR; ++j)
                {
                    long cellId = CreateCellId(i, j);
                    leaveCell.Add(cellId);

                    if (i > cellX + r || i < cellX - r || j > cellY + r || j < cellY - r)
                    {
                        continue;
                    }

                    enterCell.Add(cellId);
                }
            }
        }
Example #3
0
        // leave离开self视野
        public static void LeaveSight(this AOIEntity self, AOIEntity leave)
        {
            if (self.Id == leave.Id)
            {
                return;
            }

            if (!self.SeeUnits.ContainsKey(leave.Id))
            {
                return;
            }

            self.SeeUnits.Remove(leave.Id);
            if (leave.Unit.Type == UnitType.Player)
            {
                self.SeePlayers.Remove(leave.Id);
            }

            leave.BeSeeUnits.Remove(self.Id);
            if (self.Unit.Type == UnitType.Player)
            {
                leave.BeSeePlayers.Remove(self.Id);
            }

            Game.EventSystem.Publish(new EventType.UnitLeaveSightRange {
                A = self, B = leave
            });
        }
Example #4
0
        // cell中的unit进入self的视野
        public static void SubEnter(this AOIEntity self, Cell cell)
        {
            cell.SubsEnterEntities.Add(self.Id, self);
            foreach (KeyValuePair <long, AOIEntity> kv in cell.AOIUnits)
            {
                if (kv.Key == self.Id)
                {
                    continue;
                }

                self.EnterSight(kv.Value);
            }
        }
Example #5
0
        // cell中的unit离开self的视野
        public static void UnSubLeave(this AOIEntity self, Cell cell)
        {
            foreach (KeyValuePair <long, AOIEntity> kv in cell.AOIUnits)
            {
                if (kv.Key == self.Id)
                {
                    continue;
                }

                self.LeaveSight(kv.Value);
            }

            cell.SubsLeaveEntities.Remove(self.Id);
        }
Example #6
0
        // enter进入self视野
        public static void EnterSight(this AOIEntity self, AOIEntity enter)
        {
            // 有可能之前在Enter,后来出了Enter还在LeaveCell,这样仍然没有删除,继续进来Enter,这种情况不需要处理
            if (self.SeeUnits.ContainsKey(enter.Id))
            {
                return;
            }

            if (!AOISeeCheckHelper.IsCanSee(self, enter))
            {
                return;
            }

            if (self.Unit.Type == UnitType.Player)
            {
                if (enter.Unit.Type == UnitType.Player)
                {
                    self.SeeUnits.Add(enter.Id, enter);
                    enter.BeSeeUnits.Add(self.Id, self);
                    self.SeePlayers.Add(enter.Id, enter);
                    enter.BeSeePlayers.Add(self.Id, self);
                }
                else
                {
                    self.SeeUnits.Add(enter.Id, enter);
                    enter.BeSeeUnits.Add(self.Id, self);
                    enter.BeSeePlayers.Add(self.Id, self);
                }
            }
            else
            {
                if (enter.Unit.Type == UnitType.Player)
                {
                    self.SeeUnits.Add(enter.Id, enter);
                    enter.BeSeeUnits.Add(self.Id, self);
                    self.SeePlayers.Add(enter.Id, enter);
                }
                else
                {
                    self.SeeUnits.Add(enter.Id, enter);
                    enter.BeSeeUnits.Add(self.Id, self);
                }
            }
            Game.EventSystem.Publish(new EventType.UnitEnterSightRange()
            {
                A = self, B = enter
            });
        }
Example #7
0
        public static void Remove(this AOIManagerComponent self, AOIEntity aoiEntity)
        {
            if (aoiEntity.Cell == null)
            {
                return;
            }

            // 通知订阅该Cell Leave的Unit
            aoiEntity.Cell.Remove(aoiEntity);
            foreach (KeyValuePair <long, AOIEntity> kv in aoiEntity.Cell.SubsLeaveEntities)
            {
                kv.Value.LeaveSight(aoiEntity);
            }

            // 通知自己订阅的Enter Cell,清理自己
            foreach (long cellId in aoiEntity.SubEnterCells)
            {
                Cell cell = self.GetCell(cellId);
                aoiEntity.UnSubEnter(cell);
            }

            foreach (long cellId in aoiEntity.SubLeaveCells)
            {
                Cell cell = self.GetCell(cellId);
                aoiEntity.UnSubLeave(cell);
            }

            // 检查
            if (aoiEntity.SeeUnits.Count > 1)
            {
                Log.Error($"aoiEntity has see units: {aoiEntity.SeeUnits.Count}");
            }

            if (aoiEntity.BeSeeUnits.Count > 1)
            {
                Log.Error($"aoiEntity has beSee units: {aoiEntity.BeSeeUnits.Count}");
            }
        }
Example #8
0
        public static void Add(this AOIManagerComponent self, AOIEntity aoiEntity, float x, float y)
        {
            int cellX = (int)(x * 1000) / AOIManagerComponent.CellSize;
            int cellY = (int)(y * 1000) / AOIManagerComponent.CellSize;

            if (aoiEntity.ViewDistance == 0)
            {
                aoiEntity.ViewDistance = 1;
            }

            AOIHelper.CalcEnterAndLeaveCell(aoiEntity, cellX, cellY, aoiEntity.SubEnterCells, aoiEntity.SubLeaveCells);

            // 遍历EnterCell
            foreach (long cellId in aoiEntity.SubEnterCells)
            {
                Cell cell = self.GetCell(cellId);
                aoiEntity.SubEnter(cell);
            }

            // 遍历LeaveCell
            foreach (long cellId in aoiEntity.SubLeaveCells)
            {
                Cell cell = self.GetCell(cellId);
                aoiEntity.SubLeave(cell);
            }

            // 自己加入的Cell
            Cell selfCell = self.GetCell(AOIHelper.CreateCellId(cellX, cellY));

            aoiEntity.Cell = selfCell;
            selfCell.Add(aoiEntity);
            // 通知订阅该Cell Enter的Unit
            foreach (KeyValuePair <long, AOIEntity> kv in selfCell.SubsEnterEntities)
            {
                kv.Value.EnterSight(aoiEntity);
            }
        }
Example #9
0
        protected override async ETTask Run(EventType.ChangePosition args)
        {
            await ETTask.CompletedTask;
            Vector3 oldPos   = args.OldPos;
            Unit    unit     = args.Unit;
            int     oldCellX = (int)(oldPos.x * 1000) / AOIManagerComponent.CellSize;
            int     oldCellY = (int)(oldPos.z * 1000) / AOIManagerComponent.CellSize;
            int     newCellX = (int)(unit.Position.x * 1000) / AOIManagerComponent.CellSize;
            int     newCellY = (int)(unit.Position.z * 1000) / AOIManagerComponent.CellSize;

            if (oldCellX == newCellX && oldCellY == newCellY)
            {
                return;
            }

            AOIEntity aoiEntity = unit.GetComponent <AOIEntity>();

            if (aoiEntity == null)
            {
                return;
            }

            unit.Domain.GetComponent <AOIManagerComponent>().Move(aoiEntity, newCellX, newCellY);
        }
Example #10
0
        protected override void Run(object changePosition)
        {
            EventType.ChangePosition args = changePosition as EventType.ChangePosition;
            Vector3 oldPos   = args.OldPos.Value;
            Unit    unit     = args.Unit;
            int     oldCellX = (int)(oldPos.x * 1000) / AOIManagerComponent.CellSize;
            int     oldCellY = (int)(oldPos.z * 1000) / AOIManagerComponent.CellSize;
            int     newCellX = (int)(unit.Position.x * 1000) / AOIManagerComponent.CellSize;
            int     newCellY = (int)(unit.Position.z * 1000) / AOIManagerComponent.CellSize;

            if (oldCellX == newCellX && oldCellY == newCellY)
            {
                return;
            }

            AOIEntity aoiEntity = unit.GetComponent <AOIEntity>();

            if (aoiEntity == null)
            {
                return;
            }

            unit.Domain.GetComponent <AOIManagerComponent>().Move(aoiEntity, newCellX, newCellY);
        }
Example #11
0
 public static void Add(this Cell self, AOIEntity aoiEntity)
 {
     self.AOIUnits.Add(aoiEntity.Id, aoiEntity);
 }
Example #12
0
 public static void Remove(this Cell self, AOIEntity aoiEntity)
 {
     self.AOIUnits.Remove(aoiEntity.Id);
 }
Example #13
0
 /// <summary>
 /// 是否在Unit视野范围内
 /// </summary>
 /// <param name="self"></param>
 /// <param name="unitId"></param>
 /// <returns></returns>
 public static bool IsBeSee(this AOIEntity self, long unitId)
 {
     return(self.BeSeePlayers.ContainsKey(unitId));
 }
Example #14
0
 public static Dictionary <long, AOIEntity> GetSeePlayers(this AOIEntity self)
 {
     return(self.SeePlayers);
 }
Example #15
0
 public static void UnSubEnter(this AOIEntity self, Cell cell)
 {
     cell.SubsEnterEntities.Remove(self.Id);
 }
Example #16
0
 public static void SubLeave(this AOIEntity self, Cell cell)
 {
     cell.SubsLeaveEntities.Add(self.Id, self);
 }
Example #17
0
        public static void Move(this AOIManagerComponent self, AOIEntity aoiEntity, int cellX, int cellY)
        {
            long newCellId = AOIHelper.CreateCellId(cellX, cellY);

            if (aoiEntity.Cell.Id == newCellId) // cell没有变化
            {
                return;
            }

            // 自己加入新的Cell
            Cell newCell = self.GetCell(newCellId);

            Move(aoiEntity, newCell, aoiEntity.Cell);

            AOIHelper.CalcEnterAndLeaveCell(aoiEntity, cellX, cellY, aoiEntity.enterHashSet, aoiEntity.leaveHashSet);

            // 算出自己leave新Cell
            foreach (long cellId in aoiEntity.leaveHashSet)
            {
                if (aoiEntity.SubLeaveCells.Contains(cellId))
                {
                    continue;
                }

                Cell cell = self.GetCell(cellId);
                aoiEntity.SubLeave(cell);
            }

            // 算出需要通知离开的Cell
            aoiEntity.SubLeaveCells.ExceptWith(aoiEntity.leaveHashSet);
            foreach (long cellId in aoiEntity.SubLeaveCells)
            {
                Cell cell = self.GetCell(cellId);
                aoiEntity.UnSubLeave(cell);
            }

            // 这里交换两个HashSet,提高性能
            ObjectHelper.Swap(ref aoiEntity.SubLeaveCells, ref aoiEntity.leaveHashSet);

            // 算出自己看到的新Cell
            foreach (long cellId in aoiEntity.enterHashSet)
            {
                if (aoiEntity.SubEnterCells.Contains(cellId))
                {
                    continue;
                }

                Cell cell = self.GetCell(cellId);
                aoiEntity.SubEnter(cell);
            }

            // 离开的Enter
            aoiEntity.SubEnterCells.ExceptWith(aoiEntity.enterHashSet);
            foreach (long cellId in aoiEntity.SubEnterCells)
            {
                Cell cell = self.GetCell(cellId);
                aoiEntity.UnSubEnter(cell);
            }

            // 这里交换两个HashSet,提高性能
            ObjectHelper.Swap(ref aoiEntity.SubEnterCells, ref aoiEntity.enterHashSet);
        }