Character controllers and collisions

I’m new to jMonkey and I’m trying to get basic movement and collision up and running, but I’m not sure of the best strategy. What I want is a character controller that will take some movement vector each frame and follow it, colliding with solid geometry (and other controllers, e.g. enemies). I want to make a 3D platformer, with no physics simulation necessary and all jumping, falling, sliding, moving platforms etc. fine tuned in code, without being handled by the physics engine. Ideally it would be nice if the controller I picked could handle changes in gravity direction as well (think Ratchet & Clank gravboots or Mario Galaxy), but I could live without it. As far as I can tell, there are a few possibilities (please feel free to correct me on any of the assumptions/beliefs stated below):

  • BetterCharacterControl:
    Pros: Collides properly, goes up slopes, can probably be easily extended to remove all of the unwanted features (the relatively simplistic grounded check, the way gravity is handled, the ducking mechanic etc.)
    Cons: Has lots of unnecessary features / features I’d want to replace, doesn’t have a built-in system to ignore steep slopes, tends to “fly off” the top of slopes and generally behaves more as a physical object and less as a Mario-esque platform character. Also can’t collide with other BetterCharacterControls (I think?)

  • PhysicsCharacter:
    Pros: Quite simple, just provides the basics for movement and handles collisions properly, also seems to handle slopes and steps nicely.
    Cons: Would probably want to replace the gravity and jump handling to fit my purposes.

  • Using a dynamic RigidbodyControl, using setAngularFactor(0):
    Pros: Collides properly and goes up slopes, can be pushed by objects, preventing the need to implement a custom pushing mechanism.
    Cons: Doesn’t have any slope steepness control, I’ll probably want a custom pushing mechanism anyway (as it will tie in with moving platforms etc.), might limit how much I can fine-tune the controls.

  • Using a kinematic RigidbodyControl:
    Pros: Can directly move the character around, without the physics engine interfering with my movement code, other objects can detect collisions with the character.
    Cons: Moves through objects, without any collision handling!

  • Using sweeptests to check for collisions and using the results to change the movement vector before translating:
    Pros: Can control every aspect of the movement, doesn’t fall prey to the physics issues I talk about below.
    Cons: Hard work! My collision code won’t be as good as the built-in stuff, will probably have lots of edge-cases and issues and takes a long time to develop. My current very basic implementation still sometimes walks through things and can’t easily move parallel to solid objects either. Would also need to prevent other objects from moving through the player, and have extra sweeps for above and below the character.

On top of the issues outlined above, I’ve found that all of the physics-based methods (i.e. all those except for the custom sweep-test method and the kinematic rigidbody, including the BetterCharacterControl), suffer from quite serious jerkiness in their motion, as shown here (using a PhysicsCharacter, but it’s the same effect for the others):

The green box is a simple case of calling setLocalTranslation() on a Node containing spatials, the wireframe capsule is a PhysicsCharacter, with the same input vector.

I assume this is the result of user error on my part! I’m currently using all of the methods outlined above through the use of setWalkDirection/setLocalTranslation/setLinearVelocity (as appropriate) called from the controlUpdate function of a custom class extending AbstractControl (if it matters at all, the way it’s currently set up (due to how I’m testing this) is that ControlA calls a function in ControlB, which calls the setWalkDirection etc. function).

Also, is it correct that the physics based controllers add a frame of input lag to movements? Is this likely to be an issue and is it at all avoidable?

So far, if the jerky movement can be fixed, the PhysicsCharacter seems like the best tool for the job. Are there any pitfalls I might want to watch out for if I choose this route? Would I be better off with one of the others (or something I haven’t tried)?

On a completely unrelated note, I love the dark theme for the forums and wiki, but will the syntax highlighting colours in the wiki be changed to give better contrast? I assume the current colours are left over from the old theme, but the black booleans are very hard to see and the green function names would be better if they were a bit lighter at least.

Thanks in advance for your help, sorry if I’m just being daft and missing something obvious!

1 Like

It seems that the jerky motion in the video was the result of me incorrectly multiplying the translation vector used in setWalkDirection by tpf rather than physicsSpace.getAccuracy(), so that seems to be sorted now.

Are there any thoughts or alternative suggestions for which method I should be using to control movement or should I just continue using the PhysicsCharacter? Would it be possible to add an extra kinematic collider to enable PhysicsCharacters to collide with each other? I haven’t looked into the physics spaces and collision groups too deeply yet, but would it relatively simple to make character A ignore collisions with its own kinematic rgidbody, but still collide with that of character B (and vice versa)?