public virtual void LateUpdate() { if (CurrentAction != null && CurrentAction.Running) { if (CurrentAction.ShouldAbort()) { AbortPlan(); return; } else { Profiler.BeginSample("Agent.Run"); var actionStatus = CurrentAction.Perform(); CurrentAction.OnPerform?.Invoke(); if (actionStatus == EActionStatus.Failed) { AbortPlan(); } if (actionStatus == EActionStatus.Success) { CurrentAction.PostPerform(); CurrentAction.OnPostPerform?.Invoke(); CurrentAction.Running = false; } Profiler.EndSample(); } Profiler.BeginSample("Agent.CanAbortPlan"); if (PlannerSettings.CanAbortPlans && CurrentAction.CanAbort() && Time.time - _planStartTime > PlannerSettings.PlanRate) { AbortPlan(); } Profiler.EndSample(); return; } if (_replan || ActionQueue == null) { foreach (var goal in _orderedGoals) { Profiler.BeginSample("Agent.Plan"); ActionQueue = Planner.Plan(this, goal.Key, World.Instance.StateMap, Actions, States.GetStates(), false); _planStartTime = Time.time; Profiler.EndSample(); if (ActionQueue == null) { continue; } CurrentGoal = goal; _replan = false; StoredActionQueue.Clear(); foreach (var action in ActionQueue) { StoredActionQueue.Enqueue(action); } break; } } // Goal reached! if (ActionQueue != null && ActionQueue.Count == 0) { if (CurrentGoal.Once) { Goals.Remove(CurrentGoal); _orderedGoals.Remove(CurrentGoal); } _replan = true; } // Try do Action Profiler.BeginSample("Agent.PrePerform"); if (ActionQueue != null && ActionQueue.Count > 0) { CurrentAction = ActionQueue.Dequeue(); if (CurrentAction.PrePerform()) { if (CurrentAction.TrackStopWatch) { CurrentAction.Stopwatch.Restart(); } else { CurrentAction.Stopwatch.Reset(); } CurrentAction.Running = true; CurrentAction.OnPrePerform?.Invoke(); } else { AbortPlan(); } } Profiler.EndSample(); }