public void Update(float dt) { AgentState newState = currentState; switch (status) { case AgentStatus.WaitingForRoute: { if (solverJob.CurrentState.HasFlag(AgentJobStatus.Running)) { return; // still waiting, agent is done for this cyclus } if (solverJob.CurrentState.HasFlag(AgentJobStatus.Completed)) { var path = new Sequence <PathDescription>(solverJob.PathSequence.Select(t => new PathDescription(t, 0, 1)).ToList()); updateApproachRoute(path); updateDepartRoute(path); throw new InvalidOperationException("Something goes wrong here, approach and end routes should be somewhere halfway the segments they are attached to"); this.pathSequence = path; currentState = createInitialState(0); status = AgentStatus.GoingToRoute; goto case AgentStatus.GoingToRoute; } if (solverJob.CurrentState.HasFlag(AgentJobStatus.Error)) { status = AgentStatus.NoRouteFound; goto case AgentStatus.NoRouteFound; } } break; case AgentStatus.GoingToRoute: { var result = currentState.Update(this, dt, getSpeed, pathSequence, out newState); if (result.HasFlag(AgentStateResult.ChangedPath)) { status = AgentStatus.FollowingRoute; } if (result.HasFlag(AgentStateResult.Moved)) { isLastKnownTransformValid = false; } } break; case AgentStatus.FollowingRoute: { var result = currentState.Update(this, dt, getSpeed, pathSequence, out newState); if (result.HasFlag(AgentStateResult.ChangedPath)) { if (newState.PathIndex == pathSequence.Count - 1) { status = AgentStatus.GoingToDestination; } } if (result.HasFlag(AgentStateResult.Moved)) { isLastKnownTransformValid = false; } } break; case AgentStatus.GoingToDestination: { var result = currentState.Update(this, dt, getSpeed, pathSequence, out newState); if (result.HasFlag(AgentStateResult.ChangedPath)) { DestinationReached(); } if (result.HasFlag(AgentStateResult.Moved)) { isLastKnownTransformValid = false; } } break; case AgentStatus.NoRouteFound: { // agent is lost! find a way to get out of this situation. } break; } previousState = currentState; currentState = newState; }
private IAIPath getPath(AgentState state) => state.PathIndex >= 0 && state.PathIndex < pathSequence.Count ? pathSequence[state.PathIndex].Path : null;
private float getSpeed(AgentState state) => getSpeed(state, MaxSpeed);
public static AgentStateResult Update(this AgentState currentState, IAgent agent, float dt, GetSpeedDelegate getSpeed, IList <PathDescription> paths, out AgentState newState) { var result = AgentStateResult.None; var speed = getSpeed(currentState); var progress = currentState.Progress; var increment = speed * dt; progress += increment; if (Mathf.Abs(increment) > 0.000001) { result |= AgentStateResult.Moved; } var currentIndex = currentState.PathIndex; var currentPath = paths[currentIndex]; var length = currentPath.Path.GetLength() * currentPath.End; var pointer = currentState.Pointer; if (progress >= length) { do { progress -= length; result |= AgentStateResult.ChangedPath; currentIndex++; if (currentIndex >= paths.Count) { newState = new AgentState(currentIndex, progress, null); return(result | AgentStateResult.ReachedEnd); } currentPath = paths[currentIndex]; progress += currentPath.Start * currentPath.Path.GetLength(); // move to path start according to description length = currentPath.Path.GetLength() * currentPath.End; currentState.Pointer?.Disconnect(); }while (progress >= length); pointer = (currentPath.Path as IAgentChainAIPath)?.Connect(agent); } newState = new AgentState(currentIndex, progress, pointer); return(result); }