-
Notifications
You must be signed in to change notification settings - Fork 12
Using ABMU
ABMU implements agent behaviour through the concept of the Stepper object. A Stepper is a single self-contained method that is defined and executed by an agent. When a Stepper is created, it is automatically added to the execution queue to be executed at subsequent updates.
The overview of a model implemented in ABMU is the following:
-
Agentsdefine their own behaviours asSteppers, and register them with theController. - The
ControllerpassesSteppersto theSchedulerqueue for execution, and handles general top-level model elements, such as addingAgentsto the simulation, keeping track of simulation parameters, etc. - On each frame, the
Schedulerloops through allSteppersregistered to execute at that frame, and calls the relevant method on each agent.
A simulation in ABMU is contained within a Unity scene, and requires 3 elements:
- A Controller object
- An Agent prefab object
- A Scheduler object
ABMU provides two abstract classes for implementing the first two, the AbstractController and the AbstractAgent class. The Scheduler object is created automatically by the controller when the simulation is started.
When creating a controller for a simulation, the simulation controller should inherit from the AbstractController class:
using UnityEngine;
using ABMU.Core;
public class SimpleController : AbstractController
{
// Simulation controller code goes here
}Similarly, a simulation agent should inherit from the AbstractAgent class:
using UnityEngine;
using ABMU.Core;
public class SimpleAgent : AbstractAgent
{
// Simulation Agent code goes here
}The controller and agent abstract classes define methods for initializing the classes, which can (and most probably should) be overriden to implement functionality specific to the simulation:
public class SimpleController : AbstractController
{
public override void Init(){
base.Init();
// Simulation-specific code goes here
}
}
public class SimpleAgent : AbstractAgent
{
public override void Init(){
base.Init();
// Simulation-specific code goes here
}
}Note that when overriding an abstract method, it is important to call the method on the base class as well, before implementing any additional functionality.
Agent behaviours should be defined as methods within the agent class, and can then be added to the scheduler queue for execution as Steppers, using the CreateStepper(MethodName) method. The following code defines an agent behaviour (the Move() method), creates a stepper from that behaviour, and registers it to the scheduler (Stepper registration to the scheduler happens automatically when CreateStepper() is called).
using UnityEngine;
using ABMU.Core;
public class SimpleAgent : AbstractAgent
{
public override void Init(){
base.Init();
CreateStepper(Move); // Converting the behaviour into a Stepper. Registration to the Scheduler happens automatically when a new Stepper is created
}
void Move(){ // Definition of the behaviour method
this.transform.position += Random.insideUnitSphere;
}
}Once a stepper has been created and registered, it will be automatically executed every frame, until it is deregistered. Steppers can be removed from the scheduler queue using the DestroyStepper(Stepper s) function.
Once an agent class has been created, it should be added to a GameObject in the Unity Editor and converted into a prefab, to act as an agent avatar.
Agents should be added to the simulation via the controller. The following code defines a reference to the agent GameObject in the controller (the created agent prefab should be added to the agentPrefab reference field manually from within the Unity Editor), and once the scene is started, adds 100 agents in the scene, and starts execution of the simulation.
using UnityEngine;
using ABMU.Core;
public class SimpleController : AbstractController
{
public GameObject agentPrefab;
public int numberOfAgents = 100;
public override void Init(){
base.Init();
for (int i = 0; i < numberOfAgents; i++)
{
GameObject a = Instantiate(agentPrefab);
a.GetComponent<SimpleAgent>().Init();
}
}
}ABMU automatically controls and advances the simulation, so no additional code is needed from the user. The AbstractController class has a Step() function that advances the simulation by one tick, and is executed during LateUpdate(). The controller's Step() function calls the Tick() method on the Scheduler, which keeps a record of all steppers registered so far and executes them in order.
As initialization and updating is handled by ABMU, users should not implement any of Unity's event functions, i.e. Start(), Update(), FixedUpdate(), LateUpdate(), etc, for agent behaviour and model-related updates, as they may interfere with ABMU's execution order. Unity's event functions can be safely used for non-model related behaviours, such as rendering (for an example of this see the 3DNavigation example, where rooms implement the Start() and LateUpdate() methods to detect agents and render accordingly).