|
@@ -38,23 +38,6 @@ The code in this tutorial is a combination of these samples.
|
|
|
|
|
|
Motivation: When you load a character model, give it a RigidBodyControl, and use forces to push it around, you do not get the desired behaviour: RigidBodyControl'ed objects (such as cubes and spheres) roll or tip over when pushed by physical forces. This is not the behaviour that you expect of a walking character. JME3's BulletPhysics integration offers a BetterCharacterControl with a `setWalkDirection()` method. You use it to create simple characters that treat floors and walls as solid, and always stays locked upright while moving.
|
|
|
|
|
|
-This code sample creates a simple upright Character:
|
|
|
-
|
|
|
-[source,java]
|
|
|
-----
|
|
|
-
|
|
|
-// Load any model
|
|
|
-Node myCharacter = (Node) assetManager.loadModel("Models/myCharacterModel.mesh.xml");
|
|
|
-rootNode.attachChild(myCharacter);
|
|
|
-// Create a appropriate physical shape for it
|
|
|
-CapsuleCollisionShape capsuleShape = new CapsuleCollisionShape(1.5f, 6f, 1);
|
|
|
-CharacterControl myCharacter_phys = new CharacterControl(capsuleShape, 0.01f);
|
|
|
-// Attach physical properties to model and PhysicsSpace
|
|
|
-myCharacter.addControl(myCharacter_phys);
|
|
|
-bulletAppState.getPhysicsSpace().add(myCharacter_phys);
|
|
|
-
|
|
|
-----
|
|
|
-
|
|
|
To use the BetterCharacterControl, you may load your character like this:
|
|
|
|
|
|
[source,java]
|
|
@@ -68,33 +51,98 @@ playerNode.attachChild(player); // add it to the wrapper
|
|
|
player.move(0,3.5f,0); // adjust position to ensure collisions occur correctly.
|
|
|
player.setLocalScale(0.5f); // optionally adjust scale of model
|
|
|
// setup animation:
|
|
|
- control = player.getControl(AnimControl.class);
|
|
|
- control.addListener(this);
|
|
|
- channel = control.createChannel();
|
|
|
- channel.setAnim("stand");
|
|
|
+control = player.getControl(AnimControl.class);
|
|
|
+control.addListener(this);
|
|
|
+channel = control.createChannel();
|
|
|
+channel.setAnim("stand");
|
|
|
playerControl = new BetterCharacterControl(1.5f, 6f, 1f); // construct character. (If your character bounces, try increasing height and weight.)
|
|
|
playerNode.addControl(playerControl); // attach to wrapper
|
|
|
// set basic physical properties:
|
|
|
- playerControl.setJumpForce(new Vector3f(0,5f,0));
|
|
|
- playerControl.setGravity(new Vector3f(0,1f,0));
|
|
|
+playerControl.setJumpForce(new Vector3f(0,5f,0));
|
|
|
playerControl.warp(new Vector3f(0,10,10)); // warp character into landscape at particular location
|
|
|
// add to physics state
|
|
|
- bulletAppState.getPhysicsSpace().add(playerControl);
|
|
|
- bulletAppState.getPhysicsSpace().addAll(playerNode);
|
|
|
+bulletAppState.getPhysicsSpace().add(playerControl);
|
|
|
+bulletAppState.getPhysicsSpace().addAll(playerNode);
|
|
|
+// You can change the gravity of individual physics objects after they are
|
|
|
+// added to the PhysicsSpace.
|
|
|
+playerControl.setGravity(new Vector3f(0,-1f,0));
|
|
|
+
|
|
|
rootNode.attachChild(playerNode); // add wrapper to root
|
|
|
|
|
|
----
|
|
|
|
|
|
+This table doesn't contain all of the methods of the BetterCharacterControl class, just the commonly used ones. For a full list, see the link:https://javadoc.jmonkeyengine.org/v3.x/index.html[java doc].
|
|
|
+[cols="2", options="header"]
|
|
|
+|===
|
|
|
+
|
|
|
+a| BetterCharacterControl Method
|
|
|
+a| Property
|
|
|
+
|
|
|
+a| warp(new Vector3f(0,10,10)
|
|
|
+a| Move the character somewhere. Note the character also takes the location of any spatial its being attached to at the moment it is attached.
|
|
|
+
|
|
|
+a| jump()
|
|
|
+a| Makes the character jump with the set jump force.
|
|
|
+
|
|
|
+a| setJumpForce(new Vector3f(0,5f,0)
|
|
|
+a| Set the jump force as a Vector3f. The jump force is local to the characters coordinate system, which normally is always z-forward (in world coordinates, parent coordinates when set to applyLocalPhysics)
|
|
|
+
|
|
|
+a| isOnGround()
|
|
|
+a| Check if the character is on the ground. This is determined by a ray test in the center of the character and might return false even if the character is not falling yet.
|
|
|
+
|
|
|
+a| setDucked(true)
|
|
|
+a| Toggle character ducking. When ducked the characters capsule collision shape height will be multiplied by duckedFactor to make the capsule smaller. When unducking, the character will check with a ray test if it can in fact unduck and only do so when its possible. You can check the state of the unducking by checking isDucked().
|
|
|
+
|
|
|
+a| setDuckedFactor(2.0f)
|
|
|
+a| The factor by which the height should be multiplied when ducking.
|
|
|
+
|
|
|
+a|setWalkDirection(new Vector3f(0f,0f,0.1f))
|
|
|
+a|Sets the walk direction of the character. This parameter is frame rate independent and the character will move continuously in the direction given by the vector with the speed given by the vector length in m/s.
|
|
|
+
|
|
|
+a|setViewDirection(new Vector3f(0f,0f,0.1f))
|
|
|
+a|Sets the view direction for the character. Note this only defines the rotation of the spatial in the local x/z plane of the character.
|
|
|
+
|
|
|
+a|resetForward(new Vector3f(0f,0f,0.1f))
|
|
|
+a|Realign the local forward vector to given direction vector, if null is supplied Vector3f.UNIT_Z is used. Input vector has to be perpendicular to current gravity vector. This normally only needs to be called when the gravity direction changed continuously and the local forward vector is off due to drift. E.g. after walking around on a sphere "planet" for a while and then going back to a y-up coordinate system the local z-forward might not be 100% aligned with Z axis.
|
|
|
+
|
|
|
+a|setGravity(new Vector3f(0,-1f,0))
|
|
|
+a|Set the gravity for this character. Note that this also realigns the local coordinate system of the character so that continuous changes in gravity direction are possible while maintaining a sensible control over the character. Only takes effect if the individual physics object has already been added to the PhysicsSpace, otherwise it adopts the PhysicsSpace gravity.
|
|
|
+
|
|
|
+a|setPhysicsDamping(0.9f)
|
|
|
+a|Sets how much the physics forces in the local x/z plane should be dampened. 0 = no dampening, 1 = no external force, default = 0.9
|
|
|
+
|
|
|
+a|setHeightPercent(float percent)
|
|
|
+a|This actually sets a new collision shape to the character to change the height of the capsule.
|
|
|
+
|
|
|
+|===
|
|
|
+
|
|
|
+
|
|
|
== Character Control
|
|
|
|
|
|
+This code sample creates a simple upright Character using a CharacterControl:
|
|
|
+
|
|
|
+[source,java]
|
|
|
+----
|
|
|
+
|
|
|
+// Load any model
|
|
|
+Node myCharacter = (Node) assetManager.loadModel("Models/myCharacterModel.mesh.xml");
|
|
|
+rootNode.attachChild(myCharacter);
|
|
|
+// Create a appropriate physical shape for it
|
|
|
+CapsuleCollisionShape capsuleShape = new CapsuleCollisionShape(1.5f, 6f, 1);
|
|
|
+CharacterControl myCharacter_phys = new CharacterControl(capsuleShape, 0.01f);
|
|
|
+// Attach physical properties to model and PhysicsSpace
|
|
|
+myCharacter.addControl(myCharacter_phys);
|
|
|
+bulletAppState.getPhysicsSpace().add(myCharacter_phys);
|
|
|
+
|
|
|
+----
|
|
|
|
|
|
[IMPORTANT]
|
|
|
====
|
|
|
-The BulletPhysics CharacterControl only collides with “real PhysicsControls (RigidBody). It does not detect collisions with other CharacterControls! If you need additional collision checks, add GhostControls to your characters and create a custom <<jme3/advanced/physics_listeners#,collision listener>> to respond.
|
|
|
+The BulletPhysics CharacterControl only collides with "`real`" PhysicsControls (RigidBody). It does not detect collisions with other CharacterControls! If you need additional collision checks, add GhostControls to your characters and create a custom <<jme3/advanced/physics_listeners#,collision listener>> to respond.
|
|
|
====
|
|
|
|
|
|
|
|
|
-A CharacterControl is a special kinematic object with restricted movement. CharacterControls have a fixed “upward axis, this means they do not topple over when walking over an obstacle (as opposed to RigidBodyControls), which simulates a being's ability to balance upright. A CharacterControl can jump and fall along its upward axis, and it can scale steps of a certain height/steepness.
|
|
|
+A CharacterControl is a special kinematic object with restricted movement. CharacterControls have a fixed "`upward`" axis, this means they do not topple over when walking over an obstacle (as opposed to RigidBodyControls), which simulates a being's ability to balance upright. A CharacterControl can jump and fall along its upward axis, and it can scale steps of a certain height/steepness.
|
|
|
[cols="2", options="header"]
|
|
|
|===
|
|
|
|
|
@@ -118,7 +166,7 @@ a| How steep the slopes and steps are that the character can climb without consi
|
|
|
a| The intensity of gravity for this CharacterControl'ed entity. Tip: To change the direction of gravity for a character, modify the up axis.
|
|
|
|
|
|
a| setWalkDirection(new Vector3f(0f,0f,0.1f))
|
|
|
-a| (CharacterControl only) Make a physical character walk continuously while checking for floors and walls as solid obstacles. This should probably be called “setPositionIncrementPerSimulatorStep. This argument is neither a direction nor a velocity, but the amount to increment the position each physics tick: vector length = accuracy*speed in m/s. +
|
|
|
+a| (CharacterControl only) Make a physical character walk continuously while checking for floors and walls as solid obstacles. This should probably be called "`setPositionIncrementPerSimulatorStep`". This argument is neither a direction nor a velocity, but the amount to increment the position each physics tick: vector length = accuracy*speed in m/s. +
|
|
|
Use `setWalkDirection(Vector3f.ZERO)` to stop a directional motion.
|
|
|
|
|
|
|===
|
|
@@ -242,7 +290,7 @@ Also, add a light source to be able to see the scene.
|
|
|
|
|
|
You create an animated model, such as Oto.mesh.xml.
|
|
|
|
|
|
-. Place the “Oto model into the `assets/Models/Oto/` directory of your project.
|
|
|
+. Place the "`Oto`" model into the `assets/Models/Oto/` directory of your project.
|
|
|
. Create the CollisionShape and adjust the capsule radius and height to fit your character model.
|
|
|
. Create the CharacterControl and adjust the stepheight (here 0.05f) to the height that the character can climb up without jumping.
|
|
|
. Load the visible model. Make sure its start position does not overlap with scene objects.
|