123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248 |
- = Steer Behaviors
- :revnumber: 2.0
- :revdate: 2020/07/23
- Steer behaviors allows you to control the locomotion of "`characters`", this can reduce drastically the time needed to develop a game since for almost every game we need to set how these "`characters`" will be moving around the scene.
- [cols="2",caption=]
- .YouTube
- |===
- a|.Steer behaviors in action
- image:ai/steer/hqdefault.jpg[youtu.be/yyzTntsGV00,width="",height="",link=https://youtu.be/yyzTntsGV00]
- a|
- |===
- Be sure that you have checked the demos: They can be downloaded here: link:http://jmesteer.bdevel.org[jmesteer.bdevel.org]
- == First steps
- The steer behaviors AI is integrated with MonkeyBrains so before start coding be sure that you have checked the xref:ai/monkey_brains.adoc[monkey brains documentation].
- Be sure to create a reference to MonkeyBrains from your project.
- Finally, do not forget to import the `com.jme3.ai.agents.behaviors.npc.steering` package.
- == Overview
- *Available behaviours:*
- * Move
- * Seek
- * Arrive
- * Flee
- * Pursuit
- * Leader follow
- * Evade
- * Cohesion
- * Alignment
- * Obstacle Avoidance
- * Unaligned obstacle avoidance
- * Hide
- * Slow
- * Queuing
- * Containment
- * Path follow
- * Wall approach
- * Wander Area
- * Simple Wander
- * Relative wander
- * Sphere wander
- * Box explore
- * Separation
- All the behaviours extend from the `AbstractSteeringBehavior` class.
- == Adding a steer behavior
- Create instances from the steer behavior classes, They are located in the `com.jme3.ai.agents.behaviors.npc.steering` package.
- If we want to add more than one steer behavior, we need to create a container:
- [WARNING]
- ====
- If you add more than one steer behavior to a `SimpleMainBehavior` it will cause problems in the rotation of the agents.
- ====
- [cols="2", options="header"]
- |===
- a| Container
- a| Purpose
- a| CompoundSteeringBehavior
- a| Contains and merges several `AbstractSteeringBehavior` instances
- a| BalancedCompoundSteeringBehavior
- <a| Each force generated inside this container is reduced in relation with a proportion factor: "`Partial Force`" / "`Total`" container force
- |===
- Once we know which container fits better for our agent, We create a new instance and add all the behaviors that we need:
- [source,java]
- ----
- SimpleMainBehaviour mainBehavior = new SimpleMainBehavior(myAgent);
- CompoundSteeringBehavior steer = new CompoundSteeringBehavior(myAgent);
- //BalancedCompoundSteeringBehavior steer = new BalancedCompoundSteeringBehavior(myAgent);
- steer.addSteerBehavior(steerBehavior1);
- steer.addSteerBehavior(steerBehavior2);
- mainBehaviour.addBehavior(steer);
- myAgent.setMainBehavior(mainBehavior);
- ----
- [NOTE]
- ====
- Note that you can have nested containers, like is shown in the following example:
- ====
- [source,java]
- ----
- SimpleMainBehaviour mainBehavior = new SimpleMainBehavior(myAgent);
- CompoundSteeringBehavior steer = new CompoundSteeringBehavior(myAgent);
- BalancedCompoundSteeringBehavior nestedSteer = new BalancedCompoundSteeringBehavior(myAgent);
- nestedSteer.addSteerBehavior(steerBehavior1);
- steer.addSteerBehavior(nestedSteer);
- steer.addSteerBehavior(steerBehavior2);
- mainBehavior.addBehavior(steer);
- myAgent.setMainBehavior(mainBehavior);
- ----
- == Prioritizing behaviors
- You can assign priority layers: The steering controller first checks the higher layer to see if all the behaviors returns a value higher than `minLengthToInvalidSteer`, if so it uses that layer. Otherwise, it moves on to the second layer, and so on.
- To assign priority layers add behaviors with the following function:
- ....
- addSteerBehavior (AbstractSteeringBehavior behavior, int priority, float minLengthToInvalidSteer)
- ....
- [TIP]
- ====
- To optimize the process speed add the behaviors with the lowest priority first.
- ====
- [NOTE]
- ====
- The layer and the min length to consider the behavior invalid are 0 by default.
- ====
- == Setting up forces
- If a behavior extends from the `AbstractStrengthSteeringBehavior` class, you can manage how the produced forces will work.
- Use `setupStrengthControl(float scalar)` to increase/decrease the steer force produced by a behavior or `setupStrengthControl(Plane plane)` If you want to work with 2D behaviors.
- Example:
- [source,java]
- ----
- Plane horizontalPlane = new Plane(new Vector3f(0,1,0), 0);
- steerBehavior1.setupStrengthControl(0.5f); //Force reduced a 50%
- steerBehavior2.setupStrengthControl(horizontalPlane); //Force contained in the XZ plane
- steerContainer.setupStrengthControl(horizontalPlane, 2f); //Contained in the XZ plane and increased a 100%
- ----
- == Implementing your own steer behavior
- To benefit from all the features, you have to create a new class that extends from `AbstractStrengthSteeringBehavior`.
- The responsible for the agent's acceleration is the vector returned in the `calculateRawSteering()` method:
- [source,java]
- ----
- @Override
- protected Vector3f calculateRawSteering() {
- Vector3f steerForce = Vector3f.ZERO;
- //calculations
- return steerForce;
- }
- ----
- In addition, you can change a brake factor which will reduce the resultant velocity for the agent:
- [source,java]
- ----
- @Override
- protected Vector3f calculateRawSteering(){
- this.setBrakingFactor(0.5f); //The agent's velocity will be reduced a 50%
- return Vector3f.ZERO;
- }
- ----
- [WARNING]
- ====
- The braking force must be a float contained in the [0,1] interval
- ====
- [NOTE]
- ====
- 0 means the maximum braking force and 1 No braking force
- ====
- === Strict arguments
- To ensure that the behavior will work as you had planned it to work It's recommended to create your own link:http://docs.oracle.com/javase/7/docs/api/java/lang/IllegalArgumentException.html[IllegalArgumentException] class. To do this, create your own container class extending from `com.jme3.ai.agents.behaviors.npc.steering.SteeringExceptions`; Each exception inside the container class extends from `SteeringBehaviorException`. Furthermore, It will help users to recognize better which is the origin of any problem.
- Example:
- [source,java]
- ----
- public class CustomSteeringExceptions extends SteeringExceptions {
- public static class CustomRuntimeException extends SteeringBehaviorException {
- public CustomRuntimeException(String msg) { super(msg); }
- }
- // ... other exceptions ...
- }
- ----
- [source,java]
- ----
- public SteerBehaviorConstructor(Agent agent, int value, Spatial spatial) {
- super(agent, spatial);
- if(value > 5) throw new CustomSteeringExceptions.customRuntimeException ("Value must be lower than 5");
- this.value = value;
- }
- ----
- == Useful links
- java steer behaviors project: link:http://jmesteer.bdevel.org/[jmesteer.bdevel.org]
|