コード例 #1
0
    protected override void SetupStateMachine()
    {
        stateMachine = new StateMachine();

        // Set Up States
        var walkRandomWithinCircle = new MoveToRandomWithinCircle(this, agent, SpawnPatrolRadius);
        var walkToTarget           = new MoveToTarget(this, agent, MoveState.Walking);
        var standAndWait           = new StandAndWait();
        var runAwayFromPlayer      = new RunAwayFromTransform(this, agent, playerProximity, MoveState.Running);
        var startRunningAway       = new StartRunningAway(this, agent, playerProximity, EscapedPlayerRadius);


        //////----
        // Set Transitions
        //

        // walkToTarget
        stateMachine.AddTransition(walkToTarget, standAndWait, ReachedGoalPosition());
        stateMachine.AddTransition(walkToTarget, standAndWait, GotStuck());

        // standAndWait
        stateMachine.AddTransition(standAndWait, walkRandomWithinCircle, WaitFor(standAndWait, IdleTime));

        // startRunningAway
        stateMachine.AddTransition(startRunningAway, runAwayFromPlayer, () => true);

        // runAwayFromPlayer
        stateMachine.AddTransition(runAwayFromPlayer, startRunningAway, GotStuck());
        stateMachine.AddTransition(runAwayFromPlayer, startRunningAway, WaitFor(runAwayFromPlayer, 1.0f));
        stateMachine.AddTransition(runAwayFromPlayer, walkRandomWithinCircle, EscapedFromPlayer());


        // One-frame States
        stateMachine.AddTransition(walkRandomWithinCircle, walkToTarget, () => true);

        //////----
        // Set Universal Transitions
        //

        // One-frame States
        stateMachine.AddUniversalTransition(startRunningAway, WantToRunFromPlayer());

        // Conditions
        Func <bool> ReachedGoalPosition() =>
        () => Vector3.Distance(transform.position, goalPosition) <= agent.stoppingDistance + 0.2f;

        Func <bool> GotStuck() =>
        () => timeSinceLastProgress > StuckTime;

        Func <bool> WaitFor(IWaitableState state, float seconds) =>
        () => state.GetTimeElapsed() > seconds;

        Func <bool> WantToRunFromPlayer() =>
        () => (stateMachine._curState != runAwayFromPlayer) && playerProximity.IsInRange;

        Func <bool> EscapedFromPlayer() =>
        () => !playerProximity.IsInRange;


        // Set initial state
        stateMachine.SetState(walkRandomWithinCircle);
    }
コード例 #2
0
    protected override void SetupStateMachine()
    {
        stateMachine = new StateMachine();

        // Set Up States
        var randomPointFarAway     = new RandomOnNavMesh(this, transform, minDistanceToNextLocation);
        var walkRandomWithinCircle = new MoveToRandomWithinCircle(this, agent, locationPatrolRadius);
        var walkToTarget           = new MoveToTarget(this, agent, MoveState.Walking);
        var standAndWait           = new StandAndWait();


        //////----
        // Set Transitions
        //

        // randomPointFarAway
        stateMachine.AddTransition(randomPointFarAway, walkToTarget, RandomPointIsGood());

        // walkToTarget
        stateMachine.AddTransition(walkToTarget, standAndWait, ReachedGoalPosition());
        stateMachine.AddTransition(walkToTarget, randomPointFarAway, GotStuck());

        // standAndWait
        stateMachine.AddTransition(standAndWait, walkRandomWithinCircle, WaitFor(standAndWait, waitTimeBetweenSmallMoves));

        // walkRandomWithinCircle
        stateMachine.AddTransition(walkRandomWithinCircle, walkToTarget, () => true);

        //////----
        // Universal Transitions
        //

        stateMachine.AddUniversalTransition(randomPointFarAway, PatrolTimerExpired());

        // Conditions
        Func <bool> ReachedGoalPosition() =>
        () =>
        {
            if (!(Vector3.Distance(transform.position, goalPosition) <= agent.stoppingDistance + 0.2f))
            {
                return(false);
            }

            isInTransit = false;
            return(true);
        };


        Func <bool> RandomPointIsGood() =>
        () =>
        {
            var vector = transform.position - initialPosition;
            return(Vector3.Dot(vector, vector) > minDistanceToNextLocation * minDistanceToNextLocation);
        };

        Func <bool> PatrolTimerExpired() =>
        () =>
        {
            if (timeAtThisLocation > timeSpentAtEachLocation)
            {
                timeAtThisLocation = 0.0f;
                isInTransit        = true;
                return(true);
            }

            return(false);
        };

        Func <bool> GotStuck() =>
        () => timeSinceLastProgress > StuckTime;

        Func <bool> WaitFor(IWaitableState state, float seconds) =>
        () => state.GetTimeElapsed() > seconds;


        // Set initial state
        stateMachine.SetState(randomPointFarAway);
    }