예제 #1
0
        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;
        }
예제 #2
0
 private IAIPath getPath(AgentState state) => state.PathIndex >= 0 && state.PathIndex < pathSequence.Count ? pathSequence[state.PathIndex].Path : null;
예제 #3
0
 private float getSpeed(AgentState state) => getSpeed(state, MaxSpeed);
예제 #4
0
        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);
        }