public override void Update(float frameTime) { // If we asked for a new action we don't want to dump the existing one. if (_actionRequest != null) { if (_actionRequest.Status != JobStatus.Finished) { return; } ReceivedAction(); // Do something next tick return; } _planCooldownRemaining -= frameTime; // Might find a better action while we're doing one already if (_planCooldownRemaining <= 0.0f) { _planCooldownRemaining = PlanCooldown; _actionCancellation = new CancellationTokenSource(); _actionRequest = _planner.RequestAction(new AiActionRequest(SelfEntity.Uid, _blackboard, _availableActions), _actionCancellation); return; } // When we spawn in we won't get an action for a bit if (CurrentAction == null) { return; } var outcome = CurrentAction.Execute(frameTime); switch (outcome) { case Outcome.Success: if (CurrentAction.ActionOperators.Count == 0) { CurrentAction.Shutdown(); CurrentAction = null; // Nothing to compare new action to _blackboard.GetState <LastUtilityScoreState>().SetValue(0.0f); } break; case Outcome.Continuing: break; case Outcome.Failed: CurrentAction.Shutdown(); CurrentAction = null; _blackboard.GetState <LastUtilityScoreState>().SetValue(0.0f); break; default: throw new ArgumentOutOfRangeException(); } }