Bepu v2 Character Controllers

Discuss any questions about BEPUphysics or problems encountered.
tomweiland
Posts: 99
Joined: Wed May 08, 2019 12:17 am

Bepu v2 Character Controllers

Post by tomweiland »

So I'm about to start working on a character controller, and I'm looking for some guidance.

I previously wrote a super basic one that simply applies velocity based on input, but this is obviously a terrible approach considering that if a key is held down the player will eventually walk right through any colliders in his way.

I'm aware of the character controller demo's existence, but to be honest I'm having a tough time figuring out how it works. I understand it uses motion constraints (although I'm not entirely sure what those are and how they work, is there a rough explanation somewhere?), but it's a lot of code and it's quite overwhelming. Since it's a demo, I would assume that it's quite basic in nature, which is another reason I found the sheer amount of code slightly intimidating.

For the most part, I'm just looking for a few pointers on how to implement the character controller from the demos (or how to go about writing one myself).
Should I copy and paste these 3 files into my project? If so, what would the setup process look like? If not, what approach should I take? What is the CharacterMotionConstraint.tt file for (never seen that file extension, Google says it's a Visual Studio Text Template)?

Thank you for all the time you've put into this project and the great support you provide, it's much appreciated!
Norbo
Site Admin
Posts: 4929
Joined: Tue Jul 04, 2006 4:45 am

Re: Bepu v2 Character Controllers

Post by Norbo »

This thread has a reasonably deep dive on how the v1 version worked (among other things), which mostly maps onto how the version in the v2 demos works: viewtopic.php?f=4&t=2545

The v2 demos character is actually a trimmed down of the original version. It doesn't support things like crouching or stepping out of the box. Most of the apparent complexity arises from handling a bunch of characters in an efficient way, which means vectorized constraints, lower level callback usage, and multithreaded updating.

A brief summary is:
1) The character's body detects contacts with the environment.
2) Those contacts are checked for whether they 'support' the character- that is, the character can walk on them.
3) Character motion constraints are added, removed, and updated based on which characters are supported and their input states.
Should I copy and paste these 3 files into my project? If so, what would the setup process look like?
Pretty much, yes. The CharacterDemo is probably the most concise place to look for an example of how to integrate it.

1) Create a CharacterControllers system instance.
2) Set up contact callbacks to inform the system of character contact data. (See CharacterNarrowphaseCallbacks.)
3) Create a character controller instance using CharacterControllers.AllocateCharacter. (See CharacterInput constructor.)
4) Whenever you want to change a character's motion goals, grab a reference to its CharacterController instance using CharacterControllers.GetCharacterByBodyHandle. (See CharacterInput.UpdateCharacterGoals. Note that the character system doesn't automatically force activation when the fields are changed; it's a raw access.)
What is the CharacterMotionConstraint.tt file for (never seen that file extension, Google says it's a Visual Studio Text Template)?
It is indeed a text template. They're just forms of compile time code generation- writing C# to write C#. It's used in a few different places in the engine to avoid language abstraction overheads and manually duplicated code. If you don't make any changes to the constraints, you don't actually need the .tt file since it's just used to generate the .cs file.
tomweiland
Posts: 99
Joined: Wed May 08, 2019 12:17 am

Re: Bepu v2 Character Controllers

Post by tomweiland »

Norbo wrote: Wed May 22, 2019 9:37 pm This thread has a reasonably deep dive on how the v1 version worked (among other things), which mostly maps onto how the version in the v2 demos works: viewtopic.php?f=4&t=2545
This was very helpful!
Norbo wrote: Wed May 22, 2019 9:37 pm Pretty much, yes. The CharacterDemo is probably the most concise place to look for an example of how to integrate it.
I totally didn't realize that existed (I really should have checked), thanks!
Norbo wrote: Wed May 22, 2019 9:37 pm If you don't make any changes to the constraints, you don't actually need the .tt file since it's just used to generate the .cs file.
In what cases would I need to change the constraints file?

Is there any reason to use CharacterControllers.GetCharacterByBodyHandle over CharacterControllers.GetCharacterByIndex?

I have yet to integrate this, so maybe it doesn't happen in v2, but in v1, my players were able to easily push large dynamic objects that had 50x more mass than them. Is this intended/to be expected? If so, is there a way to get around this behavior?
Maybe the large objects don't even need to be dynamic - I just need them to be affected by collisions with static objects like the terrain, but I need to be able to apply impulses...all without them being heavily affected by objects like characters that are much lighter than themselves. What would be the best approach to achieve this?
Norbo
Site Admin
Posts: 4929
Joined: Tue Jul 04, 2006 4:45 am

Re: Bepu v2 Character Controllers

Post by Norbo »

In what cases would I need to change the constraints file?
Hopefully never, since they're pretty mathy and vectorized. A user could conceivably want to modify some low level behavior, though- perhaps a tightly integrated direction dependent maximum movement force or something. (Most things can be done outside the constraint, though perhaps with slightly less robustness.)
Is there any reason to use CharacterControllers.GetCharacterByBodyHandle over CharacterControllers.GetCharacterByIndex?
Conceptually, the handle is the identity of of the character, while the index is just a location in memory. It's the difference between saying "hey John, come here" and "hey you in the 7th chair from the left, come here". People might swap chairs over time. If you want to reliably beckon John, you should use his name rather than where he was sitting at some arbitrary time. But if you really do just want the person in the 7th chair from the left, then you can do that too.
I have yet to integrate this, so maybe it doesn't happen in v2, but in v1, my players were able to easily push large dynamic objects that had 50x more mass than them. Is this intended/to be expected? If so, is there a way to get around this behavior?
Characters have a configurable maximum force property. By default it's pretty high (especially in v1) to simulate more arcadey acceleration. Of course, if you can accelerate 10x faster than Usain Bolt, you can also push heavier things than Brian Shaw :P
Maybe the large objects don't even need to be dynamic - I just need them to be affected by collisions with static objects like the terrain, but I need to be able to apply impulses...all without them being heavily affected by objects like characters that are much lighter than themselves. What would be the best approach to achieve this?
If they can respond to collisions with anything in a physical way, they have to be dynamic. One option would be just to reduce the character's maximum force until they can't shove stuff around as much. Or increase the mass of the heavy objects more.

If those don't work for design reasons, you could resort to some nonphysical hacks like making the character not collide with the dynamic body at all, then adding a proxy kinematic body that only collides with characters and perfectly follows the dynamic body's motion. I would recommend physically consistent solutions where possible, though.
tomweiland
Posts: 99
Joined: Wed May 08, 2019 12:17 am

Re: Bepu v2 Character Controllers

Post by tomweiland »

Norbo wrote: Fri May 24, 2019 9:47 pm If you want to reliably beckon John, you should use his name rather than where he was sitting at some arbitrary time.
So I guess I shouldn't even bother storing the character index that the AllocateCharacter method spits out?
Norbo wrote: Fri May 24, 2019 9:47 pm Characters have a configurable maximum force property.
You're referring to the MaximumHorizontalForce property correct?

I'm having some issues with getting the character to move. I'm fairly certain I integrated the necessary code from the demo, but maybe I missed something?
This is how I'm adding characters:

Code: Select all

CharacterController controller = Globals.physics.characters.AllocateCharacter(gameObject.collider.Handle, out controllerID);
controller.LocalUp = new Vector3(0f, 1f, 0f);
controller.JumpVelocity = 6;
controller.MaximumHorizontalForce = 20;
controller.MaximumVerticalForce = 100;
controller.CosMaximumSlope = (float)Math.Cos(Math.PI * 0.4f);
controller.MinimumSupportDepth = 0.4 * -0.01f;
controller.MinimumSupportContinuationDepth = -0.1f;
Globals.physics.characters is defined like this:

Code: Select all

characters = new CharacterControllers(bufferPool);
I'm applying movement like this:

Code: Select all

ref CharacterController character = ref Globals.physics.characters.GetCharacterByBodyHandle(gameObject.collider.Handle);
character.TargetVelocity = horizontalVelocity; // horizontalVelocity is a Vector2
The simulation is using the CharacterNarrowPhaseCallbacks and the characters have a sleep threshold of -1.
I also checked to make sure horizontalVelocity isn't zero when keys are pressed, and it's not...so as far as I can tell, the character should be moving.
Norbo
Site Admin
Posts: 4929
Joined: Tue Jul 04, 2006 4:45 am

Re: Bepu v2 Character Controllers

Post by Norbo »

So I guess I shouldn't even bother storing the character index that the AllocateCharacter method spits out?
Pretty much, unless you have a very specific need for it and you know that it's going to be used before the index gets invalidated by a removal.

(I just removed that out parameter since it's almost never useful.)
You're referring to the MaximumHorizontalForce property correct?
Yup.
I'm having some issues with getting the character to move. I'm fairly certain I integrated the necessary code from the demo, but maybe I missed something?
The posted code looks fine, though there may be something wrong with the other unposted setup. I'd recommend confirming that the CharacterControllers.TryReportContacts function is actually getting called. If it's not, then the callbacks aren't hooked up.

Also confirm that CharacterControllers.PrepareForContacts and CharacterControllers.AnalyzeContacts are actually getting run. If not, the event handlers weren't hooked up, which implies the CharacterControllers.Initialize function wasn't called. (In the CharacterDemo, this takes place in the CharacterNarrowphaseCallbacks.Initialize function.)
tomweiland
Posts: 99
Joined: Wed May 08, 2019 12:17 am

Re: Bepu v2 Character Controllers

Post by tomweiland »

Norbo wrote: Sat May 25, 2019 10:27 pm Also confirm that CharacterControllers.PrepareForContacts and CharacterControllers.AnalyzeContacts are actually getting run. If not, the event handlers weren't hooked up, which implies the CharacterControllers.Initialize function wasn't called. (In the CharacterDemo, this takes place in the CharacterNarrowphaseCallbacks.Initialize function.)
In my setup, CharacterControllers.Initialize is being called inside CharacterNarrowphaseCallbacks.Initialize. CharacterNarrowphaseCallbacks.Initialize isn't being called anywhere - is that supposed to happen internally or do I need to set that up? If so, where? After the simulation is created?
Last edited by tomweiland on Sat May 25, 2019 11:33 pm, edited 2 times in total.
Norbo
Site Admin
Posts: 4929
Joined: Tue Jul 04, 2006 4:45 am

Re: Bepu v2 Character Controllers

Post by Norbo »

INarrowPhaseCallbacks.Initialize is called internally, you don't have call it directly. If the function isn't getting hit (as determined by breakpoint), then chances are the callbacks passed to Simulation.Create weren't correct.
tomweiland
Posts: 99
Joined: Wed May 08, 2019 12:17 am

Re: Bepu v2 Character Controllers

Post by tomweiland »

Ok so both CharacterControllers.TryReportContacts and CharacterControllers.Initialize are being called.
Norbo
Site Admin
Posts: 4929
Joined: Tue Jul 04, 2006 4:45 am

Re: Bepu v2 Character Controllers

Post by Norbo »

In this sort of situation I'd usually recommend trying to reproduce it in the demos to isolate potential issues, but given the graphics compatibility issues there...

1) Are any constraints ever being created in CharacterControllers.AnalyzeContacts? (There are two calls to Simulation.Solver.Add in that function, are either ever hit?)
2) Are the constraints ever hit? (StaticCharacterMotionFunctions.Prestep or DynamicCharacterMotionFunctions.Prestep).
3) If no to both of the above, is the character ever standing on a supporting surface? The constraints can only act if there are supporting contacts.
4) If either constraint is hit, does at least one lane of the constraint vector look reasonable? For example, does index 0 of the prestepData.MaximumHorizontalForce vector match the value defined externally?
tomweiland
Posts: 99
Joined: Wed May 08, 2019 12:17 am

Re: Bepu v2 Character Controllers

Post by tomweiland »

Norbo wrote: Sun May 26, 2019 12:59 am 1) Are any constraints ever being created in CharacterControllers.AnalyzeContacts? (There are two calls to Simulation.Solver.Add in that function, are either ever hit?)
Neither of the two calls are being hit.
Norbo wrote: Sun May 26, 2019 12:59 am 2) Are the constraints ever hit? (StaticCharacterMotionFunctions.Prestep or DynamicCharacterMotionFunctions.Prestep).
Nope.
Norbo wrote: Sun May 26, 2019 12:59 am 3) If no to both of the above, is the character ever standing on a supporting surface? The constraints can only act if there are supporting contacts.
I'm spawning the character on top of a static box, and he's not falling into the void, so yes he should be standing on a supporting surface.
Norbo
Site Admin
Posts: 4929
Joined: Tue Jul 04, 2006 4:45 am

Re: Bepu v2 Character Controllers

Post by Norbo »

Is the AnalyzeContactsForCharacterRegion ever seeing a support contact? That would be anywhere in this branch: https://github.com/bepu/bepuphysics2/bl ... rs.cs#L558

Is this running on CoreCLR, or a different runtime like Unity or some other Mono implementation?

Could you reproduce this in a completely isolated project for me to look at? Just a barebones console application that reproduces the issue with nothing but the physics would work. This would be much faster than continuing to remotely debug.
tomweiland
Posts: 99
Joined: Wed May 08, 2019 12:17 am

Re: Bepu v2 Character Controllers

Post by tomweiland »

Norbo wrote: Sun May 26, 2019 6:15 pm Is the AnalyzeContactsForCharacterRegion ever seeing a support contact? That would be anywhere in this branch: https://github.com/bepu/bepuphysics2/bl ... rs.cs#L558
I stuck a breakpoint in there and it isn't being hit.
Norbo wrote: Sun May 26, 2019 6:15 pm Is this running on CoreCLR, or a different runtime like Unity or some other Mono implementation?
It's running in a regular console app which I built into a server.
Norbo wrote: Sun May 26, 2019 6:15 pm Could you reproduce this in a completely isolated project for me to look at? Just a barebones console application that reproduces the issue with nothing but the physics would work. This would be much faster than continuing to remotely debug.
Barebones - so without any sort of graphical representation right? Because otherwise that would be quite tedious since all my graphics are currently only client side.
Norbo
Site Admin
Posts: 4929
Joined: Tue Jul 04, 2006 4:45 am

Re: Bepu v2 Character Controllers

Post by Norbo »

Barebones - so without any sort of graphical representation right?
Right.
tomweiland
Posts: 99
Joined: Wed May 08, 2019 12:17 am

Re: Bepu v2 Character Controllers

Post by tomweiland »

I was able to reproduce the issue in a fresh console app. Unfortunately the file was to big to upload here, so here's the Google Drive link.
Post Reply