Bepu v2 Character Controllers
-
- Posts: 99
- Joined: Wed May 08, 2019 12:17 am
Bepu v2 Character Controllers
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!
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!
Re: Bepu v2 Character Controllers
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.
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.)
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.
Pretty much, yes. The CharacterDemo is probably the most concise place to look for an example of how to integrate it.Should I copy and paste these 3 files into my project? If so, what would the setup process look like?
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.)
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.What is the CharacterMotionConstraint.tt file for (never seen that file extension, Google says it's a Visual Studio Text Template)?
-
- Posts: 99
- Joined: Wed May 08, 2019 12:17 am
Re: Bepu v2 Character Controllers
This was very helpful!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
I totally didn't realize that existed (I really should have checked), thanks!
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?
Re: Bepu v2 Character Controllers
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.)In what cases would I need to change the constraints file?
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.Is there any reason to use CharacterControllers.GetCharacterByBodyHandle over CharacterControllers.GetCharacterByIndex?
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 ShawI 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?
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.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 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.
-
- Posts: 99
- Joined: Wed May 08, 2019 12:17 am
Re: Bepu v2 Character Controllers
So I guess I shouldn't even bother storing the character index that the AllocateCharacter method spits out?
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;
Code: Select all
characters = new CharacterControllers(bufferPool);
Code: Select all
ref CharacterController character = ref Globals.physics.characters.GetCharacterByBodyHandle(gameObject.collider.Handle);
character.TargetVelocity = horizontalVelocity; // horizontalVelocity is a Vector2
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.
Re: Bepu v2 Character Controllers
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.So I guess I shouldn't even bother storing the character index that the AllocateCharacter method spits out?
(I just removed that out parameter since it's almost never useful.)
Yup.You're referring to the MaximumHorizontalForce property correct?
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.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?
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.)
-
- Posts: 99
- Joined: Wed May 08, 2019 12:17 am
Re: Bepu v2 Character Controllers
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?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.)
Last edited by tomweiland on Sat May 25, 2019 11:33 pm, edited 2 times in total.
Re: Bepu v2 Character Controllers
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.
-
- Posts: 99
- Joined: Wed May 08, 2019 12:17 am
Re: Bepu v2 Character Controllers
Ok so both CharacterControllers.TryReportContacts and CharacterControllers.Initialize are being called.
Re: Bepu v2 Character Controllers
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?
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?
-
- Posts: 99
- Joined: Wed May 08, 2019 12:17 am
Re: Bepu v2 Character Controllers
Neither of the two calls are being hit.
Nope.
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.
Re: Bepu v2 Character Controllers
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.
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.
-
- Posts: 99
- Joined: Wed May 08, 2019 12:17 am
Re: Bepu v2 Character Controllers
I stuck a breakpoint in there and it isn't being hit.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
It's running in a regular console app which I built into a server.
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.
Re: Bepu v2 Character Controllers
Right.Barebones - so without any sort of graphical representation right?
-
- Posts: 99
- Joined: Wed May 08, 2019 12:17 am
Re: Bepu v2 Character Controllers
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.