예제 #1
0
        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();
        }