Hi all,
Recently, I have been trying to implement swimming in my game.
This is the code I have so far. It detects when a player is in water, and once it does, repurposes the jump key to a “swim key”.
What I wanted, was that if you are submerged, and press the swim key, for the player to move upwards to the surface of the water, and stick to the top of it, whilst being able to move around. Then sink if the swim key was released. What i attempted to do was give the player a walk direction that moves them upwards, however, upon testing if the swim key is held down, the game crashed and produces the following error.
If anyone could please explain this error, and help me fix it, or even suggest a better way, to make the character surface the water, please let me know.
All help will be apprecieated.
Code:
if ((player.onGround() != true) && (player.getPhysicsLocation().y <= -18f)) {
Waterborn = true;
if (jump) {
player.setWalkDirection(new Vector3f(0f,2f,0f));
}
} else {
Waterborn = false;
if (jump) {
player.jump();
}
}
Error:
java.lang.ArithmeticException: This matrix cannot be inverted
at com.jme3.math.Matrix4f.invert(Matrix4f.java:1474)
at com.jme3.math.Matrix4f.invert(Matrix4f.java:1446)
at com.jme3.water.WaterFilter.preFrame(WaterFilter.java:154)
at com.jme3.post.FilterPostProcessor.preFrame(FilterPostProcessor.java:326)
at com.jme3.renderer.RenderManager.renderViewPort(RenderManager.java:957)
at com.jme3.renderer.RenderManager.render(RenderManager.java:1029)
at com.jme3.app.SimpleApplication.update(SimpleApplication.java:252)
at com.jme3.system.lwjgl.LwjglAbstractDisplay.runLoop(LwjglAbstractDisplay.java:151)
at com.jme3.system.lwjgl.LwjglDisplay.runLoop(LwjglDisplay.java:185)
at com.jme3.system.lwjgl.LwjglAbstractDisplay.run(LwjglAbstractDisplay.java:228)
at java.lang.Thread.run(Thread.java:744)
I do wonder how the newer version solves it, though… since the issue is that the walk direction is the same as the up vector and so the rest of the matrix cannot be properly created.
You might be better off just giving an up force to the character when swimming is on and let them continue to swim in the direction they are facing (perhaps exactly the direction they are facing but then you still run into the same issue if they look straight up).
I’ve already tried this, and due to the nature of my if statement, it causes the “Waterborn” Boolean to constantly flicker between true and false which means gravity is constantly being changed. Although this doesn’t happen when the gravity is not changed.
I haven’t tried this yet but underwater and swimming are something I am interested in…
What about using a ghost control and check for overlapping?
If using SimpleWaterProcessor, can you attach a control with as close a shape to the underwater environment, like a BoxCollisionShape and add one to spatial and when overlapping do whatever?
Edit: Actually, could just use a node for the control and place it wherever you wanted for swimming, regardless of water type.