Thanks, that kind of works but not always. I don’t know if I initiated my character correct but it did it this way.
[java]
private void createNinja() {
ninjaNode = (Node) assetManager
.loadModel(“Models/Ninja/Ninja.mesh.xml”);
ninjaNode.setShadowMode(RenderQueue.ShadowMode.CastAndReceive);
ninjaNode.setLocalScale(0.06f);
ninjaNode.setLocalTranslation(new Vector3f(55, 3.3f, -60));
ninjaControl = new GameCharControl(1.6f, 4f, 5f);// (2, 4, 0.5f);
// radius (meters), height (meters),
// gravity (mass)
ninjaControl.setJumpForce(new Vector3f(0, 100, 0));
ninjaNode.addControl(ninjaControl);
rootNode.attachChild(ninjaNode);
bulletAppState.getPhysicsSpace().add(ninjaControl);
getPhysicsSpace().add(ninjaControl);
animationControl = ninjaNode.getControl(AnimControl.class);
animationChannel = animationControl.createChannel();
}[/java]
Then the ninja could walk stairs and slopes if it used the CharacterControl but I switched to BetterCharacterControl and I don’t want to go back so I’m trying to changes and it works but only sometimes. I use the ninja model and the q3 level and the variables tooSteep and isWalkableStep change to correct values when debugged but not always, for example if the ninja walks over a step to the side it becomes difficult to walk steps and it slides too much walking downward. The code for the subclassed BetterCharacterControl that I tried is
[java]public class GameCharControl extends BetterCharacterControl {
private static Vector3f[] upAxisDirection = new Vector3f[] {
new Vector3f(1.0f, 0.0f, 0.0f), new Vector3f(0.0f, 1.0f, 0.0f),
new Vector3f(0.0f, 0.0f, 1.0f), };
boolean tooSteep = false;
boolean isWalkableStep = false;
float maxSlope = 5;
float maxStepHeight = 2;
protected float maxSlopeRadians; // Slope angle that is set (used for
// returning the exact value)
protected float maxSlopeCosine; // Cosine equivalent of m_maxSlopeRadians
// (calculated once when set, for
// optimization)
// protected float gravity;
public float getMaxSlope() {
return maxSlope;
}
// public void setMaxSlope(float maxSlope) {
// this.maxSlope = maxSlope;
// }
public GameCharControl(float x, float y, float z) {
super(x, y, z);
}
public void setMaxSlope(float slopeRadians) {
maxSlopeRadians = slopeRadians;
maxSlopeCosine = (float) Math.cos((float) slopeRadians);
}
@Override
public void update(float tpf) {
super.update(tpf);
checkSlope();
checkWalkableStep();
System.out.println("tooSteep " + tooSteep + "isWalkableStep "
+ isWalkableStep);
if (tooSteep && isWalkableStep) {
System.out.println("changing ");
rigidBody.setLinearVelocity(rigidBody.getLinearVelocity().add(0,
9500, 0));
}
}
protected void checkSlope() {
if (this.getWalkDirection().length() > 0) {
List<PhysicsRayTestResult> results = space.rayTest(
rigidBody.getPhysicsLocation(),
rigidBody.getPhysicsLocation().add(
walkDirection.normalize().mult(getFinalRadius())));
for (PhysicsRayTestResult physicsRayTestResult : results) {
float angle = physicsRayTestResult
.getHitNormalLocal()
.normalize()
.angleBetween(
physicsRayTestResult.getHitNormalLocal()
.setY(0).normalize());
System.out.println("angle " + angle);
if (Math.abs(angle * FastMath.RAD_TO_DEG - 90) > maxSlope) {
tooSteep = true;
return;
}
}
tooSteep = false;
}
}
private void checkWalkableStep() {
if (walkDirection.length() > 0) {
if (tooSteep) {
float maxStepHeight = 100;
List<PhysicsRayTestResult> results = space
.rayTest(
rigidBody.getPhysicsLocation().add(0,
maxStepHeight, 0),
rigidBody
.getPhysicsLocation()
.add(0, maxStepHeight, 0)
.add(walkDirection.normalize().mult(
getFinalRadius())));
for (PhysicsRayTestResult physicsRayTestResult : results) {
isWalkableStep = false;
return;
}
isWalkableStep = true;
return;
}
}
isWalkableStep = false;
}
}[/java]
I’d like to improve it with a maxSlope that works in all cases but it’s too difficult.