protected override void Run(object changeRotation) { EventType.ChangePosition args = changeRotation as EventType.ChangePosition;; AOIUnitComponent aoiUnitComponent = args?.Unit?.GetComponent <AOIUnitComponent>(); aoiUnitComponent?.Turn(args.Unit.Rotation); }
/// <summary> /// 删除一个 AOI 对象 ,同时有可能触发它相对其它 AOI 对象的离开消息。 /// </summary> /// <param name="self"></param> /// <param name="unit"></param> public static void RemoveUnit(this AOISceneComponent self, AOIUnitComponent unit) { Log.Info("RemoveUnit:" + unit.Id); unit.Scene = null; if (unit.Cell != null) { using (var ListenerGrids = unit.Cell.GetNearbyGrid(unit.Range)) { for (int i = 0; i < ListenerGrids.Count; i++) { var item = ListenerGrids[i]; item.RemoveListener(unit); if (unit.Type == UnitType.Player) { using (var list = item.GetAllUnit()) { for (int j = 0; j < list.Count; j++) { var t = list[j]; Game.EventSystem.Publish(new AOIRemoveUnit() { Receive = unit, Unit = t }); } } } } } unit.Cell.Remove(unit); } }
/// <summary> /// 移动一个 AOI 对象, 设置新的 (2D / 3D) 坐标 /// </summary> /// <param name="self"></param> /// <param name="position"></param> public static void Move(this AOIUnitComponent self, Vector3 position) { var oldpos = self.Position; self.Position = position; AOICell cell = self.Scene.GetAOIGrid(position); var oldgrid = self.Cell; if (cell != oldgrid)//跨格子了:AOI刷新 { self.ChangeTo(cell); } //触发器刷新 自己进入或离开别人的 if (self.Collider != null) { self.Collider.AfterChangeBroadcastToOther(self.Collider.GetRealPos(oldpos), self.Collider.GetRealRot()); } //触发器刷新 别人进入或离开自己的 for (int i = 0; i < self.SphereTriggers.Count; i++) { var item = self.SphereTriggers[i]; item.AfterChangePosition(item.GetRealPos(oldpos)); } }
/// <summary> /// 注册一个 AOI 对象, 同时设置其默认 AOI 半径。注:每个对象都有一个默认的 AOI 半径,凡第一次进入半径范围的其它物体,都会触发 AOI 消息。 /// </summary> /// <param name="self"></param> /// <param name="unit"></param> public static void RegisterUnit(this AOISceneComponent self, AOIUnitComponent unit) { unit.Scene = self; AOICell cell = self.GetAOIGrid(unit.Position); cell.Add(unit); Log.Info("RegisterUnit:" + unit.Id + " Position:" + unit.Position + " grid x:" + cell.posx + ",y:" + cell.posy + " type" + unit.Type + " range" + unit.Range); using (var ListenerGrids = cell.GetNearbyGrid(unit.Range)) { for (int i = 0; i < ListenerGrids.Count; i++) { var item = ListenerGrids[i]; item.AddListener(unit); if (unit.Type == UnitType.Player) { using (var list = item.GetAllUnit()) { for (int j = 0; j < list.Count; j++) { var t = list[j]; Game.EventSystem.Publish(new AOIRegisterUnit() { Receive = unit, Unit = t }); } } } } } }
protected override void Run(object changePosition) { EventType.ChangePosition args = changePosition as EventType.ChangePosition;; AOIUnitComponent aoiUnitComponent = args.Unit.GetComponent <AOIUnitComponent>(); if (aoiUnitComponent == null || aoiUnitComponent.IsDisposed) { return; } aoiUnitComponent.Move(args.Unit.Position); }
/// <summary> /// 获取周围指定圈数指定类型AOI对象 /// </summary> /// <param name="self"></param> /// <param name="turnNum"></param> /// <param name="type"></param> /// <returns></returns> public static ListComponent <AOICell> GetNearbyGrid(this AOIUnitComponent self, int turnNum = 1) { if (turnNum < 0) { turnNum = self.Range; } if (self.Cell != null) { return(self.Cell.GetNearbyGrid(turnNum)); } return(ListComponent <AOICell> .Create()); }
/// <summary> /// 获取周围指定圈数指定类型AOI对象 /// </summary> /// <param name="self"></param> /// <param name="turnNum"></param> /// <param name="type"></param> /// <returns></returns> public static ListComponent <AOIUnitComponent> GetNearbyUnit(this AOIUnitComponent self, int turnNum = 1, UnitType type = UnitType.ALL) { if (turnNum < 0) { turnNum = self.Range; } if (self.Cell != null) { return(self.Cell.GetNearbyUnit(turnNum, type)); } return(ListComponent <AOIUnitComponent> .Create()); }
/// <summary> /// 旋转一个 AOI 对象, 设置新的 (2D / 3D) 方向 /// </summary> /// <param name="self"></param> /// <param name="rotation"></param> public static void Turn(this AOIUnitComponent self, Quaternion rotation) { var oldRotation = self.Rotation; self.Rotation = rotation; //触发器刷新 自己的 for (int i = 0; i < self.SphereTriggers.Count; i++) { var item = self.SphereTriggers[i]; item.AfterChangeRotation(oldRotation); } }
/// <summary> /// 刷新 AOI 对象,半径范围的其它物体,重新触发 AOI 消息 /// </summary> /// <param name="self"></param> public static void RefreshUnit(this AOIUnitComponent self) { if (self.Type == UnitType.Player) { // 把周围的人通知给自己 var units = self.GetNearbyUnit(self.Range); for (int i = 0; i < units.Count; i++) { var item = units[i]; Game.EventSystem.Publish(new AOIRegisterUnit() { Receive = self, Unit = item }); } units.Dispose(); } }
/// <summary> /// 进入格子 /// </summary> /// <param name="self"></param> /// <param name="unit"></param> public static void Add(this AOICell self, AOIUnitComponent unit) { unit.Cell = self; if (Define.Debug && self.idUnits[unit.Type].Contains(unit))//Debug开启检测 { Log.Error("self.idUnits[unit.Type].Contains(unit)"); } self.idUnits[unit.Type].Add(unit); for (int i = 0; i < self.ListenerUnits.Count; i++) { var item = self.ListenerUnits[i]; if (item.Type == UnitType.Player) { Game.EventSystem.Publish(new EventType.AOIRegisterUnit() { Receive = item, Unit = unit }); } } }
/// <summary> /// 离开触发器 /// </summary> /// <param name="from"></param> /// <param name="to"></param> /// <param name="stepPara"></param> /// <param name="costId"></param> /// <param name="cost"></param> /// <param name="config"></param> public void OnColliderOut(AOIUnitComponent from, AOIUnitComponent to, SkillStepPara stepPara, List <int> costId, List <int> cost, SkillConfig config) { // Log.Info("触发"+type.ToString()+to.Id+" "+from.Id); // Log.Info("触发"+type.ToString()+to.Position+" Dis: "+Vector3.Distance(to.Position,from.Position)); if (stepPara.Paras.Length > 4) { List <int[]> buffInfo = stepPara.Paras[4] as List <int[]>; if (buffInfo != null && buffInfo.Count > 0) { var buffC = to.Parent.GetComponent <CombatUnitComponent>().GetComponent <BuffComponent>(); for (int i = 0; i < buffInfo.Count; i++) { if (buffInfo[i][2] == 1) { buffC.RemoveByConfigId(buffInfo[i][0]); } } } } }
/// <summary> /// 离开 /// </summary> /// <param name="self"></param> /// <param name="unit"></param> public static void Remove(this AOICell self, AOIUnitComponent unit) { if (self == null || self.IsDisposed) { return; } if (self.idUnits.ContainsKey(unit.Type)) { for (int i = 0; i < self.ListenerUnits.Count; i++) { var item = self.ListenerUnits[i]; if (item.Type == UnitType.Player) { Game.EventSystem.Publish(new EventType.AOIRemoveUnit() { Receive = item, Unit = unit }); } } self.idUnits[unit.Type].Remove(unit); unit.Cell = null; } }
/// <summary> /// 移除监视 /// </summary> /// <param name="self"></param> /// <param name="unit"></param> /// <returns></returns> public static void RemoveListener(this AOICell self, AOIUnitComponent unit) { // Log.Info("RemoveListener"+unit.Id+" "+self.posx+","+self.posy); self.ListenerUnits.Remove(unit); }
/// <summary> /// 进入触发器 /// </summary> /// <param name="from"></param> /// <param name="to"></param> /// <param name="stepPara"></param> /// <param name="costId"></param> /// <param name="cost"></param> /// <param name="config"></param> public void OnColliderIn(AOIUnitComponent from, AOIUnitComponent to, SkillStepPara stepPara, List <int> costId, List <int> cost, SkillConfig config) { var combatU = to.Parent.GetComponent <CombatUnitComponent>(); // Log.Info("触发"+type.ToString()+to.Id+" "+from.Id); // Log.Info("触发"+type.ToString()+to.Position+" Dis: "+Vector3.Distance(to.Position,from.Position)); int formulaId = 0;//公式 if (stepPara.Paras.Length > 1) { int.TryParse(stepPara.Paras[1].ToString(), out formulaId); } float percent = 1;//实际伤害百分比 if (stepPara.Paras.Length > 2) { float.TryParse(stepPara.Paras[2].ToString(), out percent); } int maxNum = 0; if (stepPara.Paras.Length > 3) { int.TryParse(stepPara.Paras[3].ToString(), out maxNum); } if (maxNum != 0 && stepPara.Count >= maxNum) { return; //超上限 } stepPara.Count++; List <int[]> buffInfo = null;//添加的buff if (stepPara.Paras.Length > 4) { buffInfo = stepPara.Paras[4] as List <int[]>; if (buffInfo == null) { string[] vs = stepPara.Paras[4].ToString().Split(';'); buffInfo = new List <int[]>(); for (int i = 0; i < vs.Length; i++) { var data = vs[i].Split(','); int[] temp = new int[data.Length]; for (int j = 0; j < data.Length; j++) { temp[j] = int.Parse(data[i]); } buffInfo.Add(temp); } stepPara.Paras[4] = buffInfo; } } if (buffInfo != null && buffInfo.Count > 0) { var buffC = combatU.GetComponent <BuffComponent>(); for (int i = 0; i < buffInfo.Count; i++) { buffC.AddBuff(buffInfo[i][0], TimeHelper.ClientNow() + buffInfo[i][1]); } } FormulaConfig formula = FormulaConfigCategory.Instance.Get(formulaId); if (formula != null) { FormulaStringFx fx = FormulaStringFx.GetInstance(formula.Formula); NumericComponent f = from.GetParent <Unit>().GetComponent <NumericComponent>(); NumericComponent t = to?.GetParent <Unit>().GetComponent <NumericComponent>(); float value = fx.GetData(f, t); int realValue = (int)value; if (realValue != 0) { float now = t.GetAsFloat(NumericType.HpBase); Log.Info(now); if (now <= realValue) { t.Set(NumericType.HpBase, 0); } else { t.Set(NumericType.HpBase, now - realValue); } EventSystem.Instance.Publish(new EventType.AfterCombatUnitGetDamage() { From = from.Parent.GetComponent <CombatUnitComponent>(), Unit = combatU, Value = realValue }); } } }
/// <summary> /// 获取自己能被谁看到 /// </summary> /// <param name="self"></param> /// <returns></returns> public static List <AOIUnitComponent> GetBeSeeUnits(this AOIUnitComponent self) { return(self.Cell.ListenerUnits); }
/// <summary> /// 改变格子 /// </summary> /// <param name="self"></param> /// <param name="newgrid"></param> public static void ChangeTo(this AOIUnitComponent self, AOICell newgrid) { AOICell oldgrid = self.Cell; Log.Info(self.Id + "From: " + " grid x:" + oldgrid.posx + ",y:" + oldgrid.posy + " ChangeTo:grid x:" + newgrid.posx + ",y:" + newgrid.posy); #region 广播给别人 using (DictionaryComponent <AOIUnitComponent, int> dic = DictionaryComponent <AOIUnitComponent, int> .Create()) { //Remove if (oldgrid.idUnits.ContainsKey(self.Type)) { for (int i = 0; i < oldgrid.ListenerUnits.Count; i++) { var item = oldgrid.ListenerUnits[i]; if (item.Type == UnitType.Player && item != self) { dic.Add(item, -1); } } oldgrid.idUnits[self.Type].Remove(self); self.Cell = null; } else { Log.Error("unit.Type=" + self.Type + "未添加就删除"); } //Add self.Cell = newgrid; if (Define.Debug && newgrid.idUnits[self.Type].Contains(self)) { Log.Error("newgrid.idUnits[self.Type].Contains(self)"); } newgrid.idUnits[self.Type].Add(self); for (int i = 0; i < newgrid.ListenerUnits.Count; i++) { var item = newgrid.ListenerUnits[i]; if (item.Type == UnitType.Player && item != self) { if (dic.ContainsKey(item)) { dic[item] += 1; } else { dic.Add(item, 1); } } } foreach (var item in dic) { if (item.Value > 0) { Game.EventSystem.Publish(new EventType.AOIRegisterUnit() { Receive = item.Key, Unit = self, }); } else if (item.Value < 0) { Game.EventSystem.Publish(new EventType.AOIRemoveUnit() { Receive = item.Key, Unit = self }); } } } #endregion #region 广播给自己 && 刷新监听 var older = oldgrid.GetNearbyGrid(self.Range); var newer = newgrid.GetNearbyGrid(self.Range); DictionaryComponent <AOICell, int> temp = DictionaryComponent <AOICell, int> .Create(); for (int i = 0; i < older.Count; i++) { var item = older[i]; temp[item] = -1; } for (int i = 0; i < newer.Count; i++) { var item = newer[i]; if (temp.ContainsKey(item)) { temp[item] = 0; } else { temp[item] = 1; } } ListComponent <AOIUnitComponent> adder = ListComponent <AOIUnitComponent> .Create(); ListComponent <AOIUnitComponent> remover = ListComponent <AOIUnitComponent> .Create(); foreach (var item in temp) { if (item.Value > 0) { item.Key.AddListener(self); adder.AddRange(item.Key.GetAllUnit()); } else if (item.Value < 0) { item.Key.RemoveListener(self); remover.AddRange(item.Key.GetAllUnit()); } } if (self.Type == UnitType.Player) { for (int i = 0; i < adder.Count; i++) { var item = adder[i]; if (item == self) { continue; } Log.Info("AOIRegisterUnit" + item.Id); Game.EventSystem.Publish(new EventType.AOIRegisterUnit { Receive = self, Unit = item }); } for (int i = 0; i < remover.Count; i++) { var item = remover[i]; if (item == self) { continue; } Log.Info("AOIRemoveUnit" + item.Id); Game.EventSystem.Publish(new EventType.AOIRemoveUnit() { Receive = self, Unit = item }); } } temp.Dispose(); newer.Dispose(); older.Dispose(); adder.Dispose(); remover.Dispose(); #endregion }