Entities standing on top of each other
Entities standing on top of each other
I'm using the CharacterController for my NPCs and players and because of the design of the game, there are often a lot of creatures that are small enough to be able to jump on top of. I'd like to make it so this doesn't happen and that instead entities just slide off really quick. The same should also happen for other physics items for that matter. I want to avoid a solution that makes the entity's collision mesh with the terrain and other static objects taller though. Any ideas on how I can accomplish this Norbo?
Re: Entities standing on top of each other
Here's a few options that you can mix and match:
1) Set the effective friction to zero. For CharacterControllers standing on top of things, this would look like setting the HorizontalMotionConstraint.Maximum...Force properties to 0 when the supporting object meets some condition. That logic could be added to the CharacterController.Update.
Similar things can be done with pairs of normal physics objects by modifying Materials and MaterialInteractions in the MaterialManager or fiddling with the coefficients in a CollidablePairHandler after its creation by calling UpdateMaterialProperties.
2) There may be some value in applying a force just to make sure objects scoot off of each other. This is most useful when the friction has already been dealt with.
3) The character shapes could be made more rounded. This will tend to make stuff fall off, but it is the most work intensive and may still require the other solutions to work well.
1) Set the effective friction to zero. For CharacterControllers standing on top of things, this would look like setting the HorizontalMotionConstraint.Maximum...Force properties to 0 when the supporting object meets some condition. That logic could be added to the CharacterController.Update.
Similar things can be done with pairs of normal physics objects by modifying Materials and MaterialInteractions in the MaterialManager or fiddling with the coefficients in a CollidablePairHandler after its creation by calling UpdateMaterialProperties.
2) There may be some value in applying a force just to make sure objects scoot off of each other. This is most useful when the friction has already been dealt with.
3) The character shapes could be made more rounded. This will tend to make stuff fall off, but it is the most work intensive and may still require the other solutions to work well.
Re: Entities standing on top of each other
For #1: The comment on the Maximum*Force properties says it controls how much force the character can exert in those situations. Wouldn't setting it to 0 make the entity's just get stuck on top of each other?
For #2: How do I detect this situation so I can apply the force?
For #2: How do I detect this situation so I can apply the force?
Re: Entities standing on top of each other
The character's body has its friction set to zero by a collision event set in its constructor (RemoveFriction). The HorizontalMotionConstraint is the only thing that stops relative sliding motion. So, in most cases, the character would slide off if there was any preexisting relative velocity.For #1: The comment on the Maximum*Force properties says it controls how much force the character can exert in those situations. Wouldn't setting it to 0 make the entity's just get stuck on top of each other?
In the case where there is insufficient or zero relative velocity, the character could stick around (if it didn't try to jump or something). #2 complements #1 in this regard- even if there's no relative velocity that would make it slide off, a little boost will handle it.
For a character, examine the support after CollectSupportData runs. If the support is something that should be slid off of, handle friction/apply forces as needed.For #2: How do I detect this situation so I can apply the force?
For a non-character, standard collision event/pair and contact scanning stuff.
I also forgot to mention another easy approach: after the CollectSupportData runs, do your own test to see if the support is valid, as before. If it isn't, set the supportData.HasTraction to false. The character will then slide on the object. The HorizontalMotionConstraint.MaximumSlidingForce other sliding properties will apply during this state.
Re: Entities standing on top of each other
Ok I added this to the IBeforeSolverUpdateable.Update on the CharacterController:
There's two issues though. It seems to wait until the character has come to a complete stop on top of the other entity before it applies the force and it still allows the character to kind of fight the pushing force so they can stay on top. Any ideas?
Code: Select all
if(SupportFinder.HasTraction && supportData.SupportObject.Tag is CharacterSynchronizer)
{
Body.LinearVelocity += Body.OrientationMatrix.Forward * 100;
SupportFinder.ClearSupportData();
supportData = new SupportData();
}
Re: Entities standing on top of each other
By clearing the support entirely, the character should behave as though it is floating as far as friction is concerned. The Air properties would apply. The defaults for that are very weak, and that's a large velocity change- it should scoot (and quickly) unless the air control has been increased a huge amount.
One potential cause: if that chunk was at the end of the update method, the constraint would still be using the old support data and would fight against the velocity. If that's the problem, put the chunk up right after the CollectSupportData call.
One potential cause: if that chunk was at the end of the update method, the constraint would still be using the old support data and would fight against the velocity. If that's the problem, put the chunk up right after the CollectSupportData call.
Re: Entities standing on top of each other
Well my world scale is about 10x bigger than the default so that force isn't that huge actually. And I have the air force increased because otherwise players just kind of lose all velocity mid-air and drop straight down, making long-jumps pretty much impossible. Also I moved the code up to right after the CollectSupportData call and it still kinda feels like a delayed reaction
Re: Entities standing on top of each other
For testing purposes, try setting the maximum forces to zero in that situation and see how it reacts.
Re: Entities standing on top of each other
I set them to 0, I can still manage to stay on top of an entity though. I think the delay might be from the net code.
Code: Select all
if(SupportFinder.HasTraction && supportData.SupportObject.Tag is CharacterSynchronizer)
{
Body.LinearVelocity += Body.OrientationMatrix.Forward * 10;
if(maxair == 0)
{
maxair = HorizontalMotionConstraint.MaximumAirForce;
maxforce = HorizontalMotionConstraint.MaximumForce;
maxslide = HorizontalMotionConstraint.MaximumSlidingForce;
HorizontalMotionConstraint.MaximumAirForce = 0;
HorizontalMotionConstraint.MaximumForce = 0;
HorizontalMotionConstraint.MaximumSlidingForce = 0;
}
SupportFinder.ClearSupportData();
supportData = new SupportData();
}
else if(maxair != 0)
{
HorizontalMotionConstraint.MaximumAirForce = maxair;
HorizontalMotionConstraint.MaximumForce = maxforce;
HorizontalMotionConstraint.MaximumSlidingForce = maxslide;
maxair = 0;
}
Re: Entities standing on top of each other
External interference is indeed a suspect.
For reference, that LinearVelocity += 10 * forward line should apply an acceleration roughly 6x stronger than gravity (assuming your gravity is about (0, -100, 0) and a time step duration of 1/60). It should be very immediately visible if the character's not fighting it.
For reference, that LinearVelocity += 10 * forward line should apply an acceleration roughly 6x stronger than gravity (assuming your gravity is about (0, -100, 0) and a time step duration of 1/60). It should be very immediately visible if the character's not fighting it.
Re: Entities standing on top of each other
Any ideas on why the character is still able to apply force while standing on another entity? I thought setting those 3 max force variables to 0 would prevent that
Re: Entities standing on top of each other
It shouldn't be able to- I would recommend trying to create an isolated repro in the BEPUphysicsDemos. That should narrow the issue or at least allow me to take a look if needed.