/// <summary> /// 寻路到某个点然后做某事,如果当前距离小于目标距离则直接进入状态,否则就寻路到适合的地点再进行寻路 /// </summary> /// <param name="self"></param> /// <param name="target">目标地点</param> /// <param name="targetRange">目标距离</param> /// <param name="targetState">目标状态</param> public static void NavigateTodoSomething(this UnitPathComponent self, Vector3 target, float targetRange, AFsmStateBase targetState) { if (Vector3.Distance((self.Entity as Unit).Position, target) >= targetRange) { if (!self.Entity.GetComponent <StackFsmComponent>().ChangeState <NavigateState>(StateTypes.Run, "Navigate", 1)) { ReferencePool.Release(targetState); return; } self.MoveTodoSomething(target, self.Entity.GetComponent <StackFsmComponent>().GetCurrentFsmState(), targetState, targetRange) .Coroutine(); } else { self.Entity.GetComponent <StackFsmComponent>().ChangeState(targetState); } }
/// <summary> /// 移动到目标点,随后进入指定状态(如果有的话) /// </summary> /// <param name="self"></param> /// <param name="target"></param> /// <param name="bindState"></param> /// <param name="nextState"></param> /// <param name="targetRange">目标范围,当自身与目标位置小于等于此范围时,则停止寻路,进入NextState</param> /// <returns></returns> private static async ETVoid MoveTodoSomething(this UnitPathComponent self, Vector3 target, AFsmStateBase bindState, AFsmStateBase nextState = null, float targetRange = 0) { self.BindState = bindState; self.NextState = nextState; self.Target = target; self.TargetRange = targetRange; Unit unit = self.GetParent <Unit>(); RecastPathComponent recastPathComponent = Game.Scene.GetComponent <RecastPathComponent>(); RecastPath recastPath = ReferencePool.Acquire <RecastPath>(); recastPath.StartPos = unit.Position; recastPath.EndPos = new Vector3(target.x, target.y, target.z); self.RecastPath = recastPath; //TODO 因为目前阶段只有一张地图,所以默认mapId为10001 recastPathComponent.SearchPath(10001, self.RecastPath); //Log.Debug($"find result: {self.ABPath.Result.ListToString()}"); self.CancellationTokenSource?.Cancel(); self.CancellationTokenSource = new CancellationTokenSource(); await self.MoveAsync(self.RecastPath.Results); self.CancellationTokenSource.Dispose(); self.CancellationTokenSource = null; if (nextState != null) { self.Entity.GetComponent <StackFsmComponent>().ChangeState(nextState); } self.Entity.GetComponent <StackFsmComponent>().RemoveState(bindState.StateName); }