A basic state machine for programmers to prototype Unity AI nav agents in C#.
Goal of this repo is to make fsm-based ai creation processs relatively easy and quick so it can be used to prototype ai behaviours.
Samples to show you how to use Simpletons:
Zombies and survivors following/avoiding each other
https://github.com/andrew-raphael-lukasik/Simpletons/tree/main/Samples/Zombies
pedestrians moving across the street and reacting to traffic lights
https://github.com/andrew-raphael-lukasik/Simpletons/tree/main/Samples/TrafficLights
Key implementation points:
MonoBehaviour
updates it's state machine ai brain by callingTick(time)
method
public class WalkerController : MonoBehaviour
{
[SerializeField] WalkerAI _brain = new WalkerAI( owner:this );
void FixedUpdate ()
{
_brain.Tick( time:Time.time );
}
}
- custom
SimpletonStateMachine
is a place where you design your fsm ai
public WalkerAI ( WalkerController owner )
{
_owner = owner;
// create states:
var start = new WalkerIdleState( _owner );
var idle = new WalkerIdleState( _owner );
var wander = new WalkerWanderState( _owner );
var agro = new WalkerAgroState( _owner );
var attack = new WalkerAttackState( _owner );
var dead = new WalkerDeadState( _owner );
// create transitions:
SimpletonStateTransition start_to_idle, idle_to_wander, wander_to_idle, any_to_agro, agro_to_idle, agro_to_attack, attack_to_agro, any_to_dead;
start_to_idle = new SimpletonStateTransition(
predicate: (state,time) => true ,
destination: idle ,
label: nameof(start_to_idle)
);
idle_to_wander = new SimpletonStateTransition(
predicate: (state,time) => Random.Range(1,6)==1 ,// 20% chance
destination: wander ,
label: nameof(idle_to_wander)
);
wander_to_idle = new SimpletonStateTransition(
predicate: (state,time) => state.completed || time>state.timeExpectedEnd || _owner.navMeshAgent.remainingDistance<1f ,
destination: idle ,
label: nameof(wander_to_idle)
);
any_to_agro = new SimpletonStateTransition(
predicate: (state,time) => _owner.survivorsAround.Count!=0 ,
destination: agro ,
label: nameof(any_to_agro)
);
any_to_dead = new SimpletonStateTransition(
predicate: (state,time) => _owner.Health<=0 ,
destination: idle ,
label: nameof(any_to_dead)
);
/* more transition definitions */
// assign transitions to states:
start.transitions = new SimpletonStateTransition[]{
start_to_idle
};
idle.transitions = new SimpletonStateTransition[]{
any_to_dead ,
idle_to_wander ,
any_to_agro ,
};
/* more transitions assigned to states */
// assign initial state
_initial = start;
Reset();
ConstructorAssertions();
}
To help you understand and debug it, Simpletons come with an inspector window:
Open Package Manager
->Add package from git URL
:
https://github.com/andrew-raphael-lukasik/Simpletons.git#upm
Add this line to the dependencies in manifest.json
:
"dependencies": {
"com.andrewraphaellukasik.simpletons": "https://github.com/andrew-raphael-lukasik/Simpletons.git#upm",
...
}