Character Controller and triggers

I have a problem with the character controller and having it interacting triggers.

The problem occurs when we reach high velocities, but to give a better background to what is happening and what our problem is, I’ll explain a little about how we the game mechanics.


The game I am working on is a really fast phased game, where we still try to imitate a physically correct behavior of a character through the PhysX Character Controller. That means that we are storing and using a velocity vector, and we are updating and moving the player with this velocity. In many cases we make a lot of dissension deepening on the current state of this velocity. In this text I will mainly try to focus on one of them, in an attempt to make it easier too follow.

The character can at any time attempt to interact with walls. Deepening on the current velocity, and direction of the character (the direction it is looking) different interactions will occur.

Basically we have three types of wall interactions; Vertical Wall Run, Horizontal Wall Run and a state we call Wall Sticky (essentially grabs on to the wall ad slide downwards for a moment).

Exactly how the different interactions is determined is not important for this context, but what is important is that we need the velocity of the character to translate in to the interaction, like for an example, when hitting the wall in high speed straight on for a vertical wall run, we want to give the character a boosted speed upwards (the character can use the velocity and turn it into upwards momentum).

One more important aspect is that not ALL walls in the game is valid for these kind of interactions (most of them are though, if they are in an appropriate size), and how we distinguishes these walls is through placing triggers in front of them, covering the surface and some space in front of it (Most environmental interactions in the game follow the same principle, and use triggers to in for characters about the functions of their surroundings).

Image from our level editor showing the triggers for a small sample box level i built for this demonstration:
External Media
Green transparent boxes indicate walls, read boxes indicate high edges, and yellow indicates low edges (simplified explication). The visible icons is placed in the center of the triggers and used for selection and manipulation in the editor.

Upon hitting walls that is “not intractable”, the velocity is adjusted through a “standard bounce” with low retention (though in high speed the character can bounce out from the wall noticeably).

Here in lies our problem. We are updating the player in a constant 60 FPS, no matter what rate the physics scene is updated in. This is for having a guaranty that the player always behaves the same no matter what. All jumps and all dashes, everything needs to behave in the same way ALWAYS. We can’t accept this varying because of a frame rate drop and the errors in nonlinear Euler interpolations. Thus, the player can sometimes run more than one update at the same time as the PhysX scene runes one.

The real problem is that the Character Controller does not interact with or detect triggers, thus the player can sometimes get a delayed interaction with the trigger, or not detect it at all in high speed.

When this occurs with the wall interactions, the character will not know that the wall is intractable upon colliding with it, thus modifying the velocity for a normal bounce, and thus loosing important information before the actual wall interaction test occurs later (if the character did not bounce out of the trigger before the physics scene get a chance to detect it).


[b]We have two, maybe three ways of going about to solve this, but none of them seam any good.

I know this is a lot of text and that my English can be hard to follow at times. But is there anybody who has had a similar problem, or has a suggestion for a solution?[/b]

It might be worth mentioning we are using the 2.8.4 version of PhysX because the game were well on its way before the update were released and we for the moment don’t have the resources to change the version mid development. If these problems are resolved in a newer version of PhysX and you know this for a fact, please let us know! We have looked in to the newer version but could not find that it included any such fixes.

Any feedback is greatly appreciated!

I think what you’re looking for is included in the documentation of the SDK (3.2.1) though. Download it and have a look at the cloth example and the triggers are in the bridges example. Though if I were you i would fix the physx frame rate to let’s say 120 fps then you have accurate information i.e. physx will have twice as less time to advance this.
Anyway good luck with your project.
EDIT:
BTW the picture is not being displayed.

Thanks for the reply!

I am unable to edit the previous post, so I can’t fix the image (it does show for me). But I can make a new attempt with a new upload site.

I will again look in to the new PhysX SDK, and see if I see what I am looking for. Overall it seems allot better, but we don’t have the time and resources to change unless it is absolutely necessary. Everything else except this trigger interaction works near “perfectly” as it is, and changing would require a lot of changes in a lot of code. But as I said, I will look in to it further and maybe make some separate test cases.

Some users are running the game in sub 60 FPS at the moment, so increasing the physics Hz would not be possible for these systems. We cannot guarantee that all users can run the full PhysX scene in 120 FPS, so we don’t want to do something like that in order to make this work.

Ideally we would simulate the PhysX scene in a lower Hz and interpolate between the results for the graphical representation of the physics to make it smooth at higher FPS. The player and gameplay driven content need a high and constant Hz, but the normal physics is the scene is not directly affecting gameplay in any great amount and should thus be able to simulate in a lower and varying Hz without any real problems. At least that is our goal. This should help more users to be able to run the full game in Higher FPS and with smooth gameplay (the camera and input/controls are updated in an as high FPS as possible).

Once again, thanks for the reply, and if you have any particular part of the documentation in mind that you can point me to it would help a lot! (I will try looking in to it now as well in the meantime though).

I am still interested to see if it is possible to solve this in the 2.8.4 version of PhysX, so please let me know if you have any thoughts on the matter.

This is from the 3.2.1 SDK Docs
[b]In particular, here is a (non exhaustive) list of typical problems you run into when using a physics engine for character controllers:

(lack of) continuous collision detection: Typical physics engines use discrete collision checks, leading to the notorious ‘tunneling effect’ that has plagued various commercial & non-commercial physics packages for years. This leads to three main problems:

the tunneling effect itself : if your character goes too fast it might tunnel through a wall
as a consequence, the maximum velocity of your character might be limited (hence also limiting the game play possibilities)
even if you do not tunnel, the character might jitter when pushed forward in a corner for example, because the engine keeps moving it back and forth to slightly different positions.
No direct control: a rigid body is typically controlled with impulses or forces. It is usually not possible to move it directly to its final position, you first have to convert the delta position vector to impulses/forces, apply them, and hope that the character will be where you wanted it to be as a result. Usually it does not work too well, in particular when the physics engine uses an imperfect linear solver.

Trouble with friction: When the character is standing on a ramp, you do not want it to slide. You want infinite friction here. When the character is moving forward on that same ramp, you do not want it to slow down. You want no friction here. When the character is sliding against a wall, you do not want it to slow down either. You want no friction here as well. Usually it is either 0 or infinite. However the friction model might not be perfect, and what you actually get is very little friction (you can still feel the character slowing down) or a very-big-but-not-infinite one (the character slides very slowly on that ramp no matter how artificially big the friction parameters are). The conflicting requirements for ramps also mean that usually there is simply no way to perfectly model desired behavior.

Trouble with restitution: You should avoid restitution. When the character moves fast and collides with a wall, you do not want it to bounce away from it. When the character falls from a height and lands on the ground, flexing his legs, you definitely do not want any bounce to happen. But once again, even when the restitution is exactly zero, you can nonetheless sometimes get a small bump. This is not only related to the imperfect nature of the linear solver, it also has to do with how typical penetration-depth-based engines recover from overlap situations, sometimes applying excessive forces that separate the objects too much.

Undesired jumps: You often want a character to stick to the ground, no matter what the physical behavior should be. For example characters in action games tend to move fast, at unrealistic speeds. When they reach the top of a ramp, the physics engine often makes them jump a bit, in the same way a fast car would jump in the streets of San Francisco. But that is often not what you want: you want the character to stick to the ground regardless of its current velocity. This is sometimes implemented using fixed joints, which is an excessively complex solution to a very simple problem that can been solved without the complexity of a physics engine.

Undesired rotations: Finally, a character is always standing up and never rotating. However physics engines often have poor support for that sort of constraints, and a great deal of effort is often put into preventing a capsule around the character from falling (it should always stands up on its tip). This is again often implemented using artificial joints, and the resulting system is neither very robust nor very fast.

To summarize, a lot of effort can be spent on tweaking and disabling the physics engine’s features simply to emulate what’s otherwise a much less complex piece of custom code. It is natural to instead keep using that simple piece of custom code.

[/b]

Thanks for such long reply! I really appreciate it, though I think you might have misunderstood our problem. Perhaps I did not explain it well enough. I’m sorry for that!

We are currently using a version of the PhysX Character Controller, called NxController/NxCapsuleController. That controller is not physically simulated. It is rather a so-called Kinematic Actor, or an actor with a body with the flag NX_BF_KINEMATIC raised.

That means the physics body is not affected by other physical bodies, and it can move straight through other actors. However, it does collide against other dynamic actors in the scene during the scene update. Though, it will not get affect by the collisions, and only affecting the other actors. This is very useful for all gameplay related stuff that does not need to be fully simulated. This usually means that you have to handle the collision on your own, however, the NxController does handle Continuous Collision upon calling the function “move”. The controller can then choose to react to or to ignore other actors through a simple callback system.

Thanks to this, we do not have any of the problems you described, although we try to imitate a somewhat physical “correct” behavior to some degree. Mainly for gameplay purpose, but also because that is what the player will expect from the player-character in these situations. We do have the character bounce against walls if she reaches a really high speed, but that is because we explicitly programmed that behavior.

Our problem lies in how triggers are handled with the NxController/kinematic actors in PhysX. The triggers are not “triggered” upon moving inside them, they are rather triggered upon the next scene update cycle if the actor is still in contact with the trigger shapes. This would not be a problem unless we had decoupled the scene update and “none physics driven” gameplay update. As I described in another post above, our player-character is simulated in a constant 60 Hz, no matter how often the scene is updated, or what FPS the game runs in. Even if you play the game at 20 FPS, the player is still simulated with 60 FPS, so to speak. This is really good for many reasons, but it also cases this problem (this is the only problem we have had with this system). So we are now looking for a solution for this.

We do have one solution that would involve updating the player, but queuing up the actual moves of the actor until right before the next scene simulation. Though, doing this would remove some of the accuracy with the player’s behavior. It would no longer be possible to react to collisions that occur during these moves until they are all performed. The player’s state changes due to such collisions would also be delayed, and that could cause some other potential problems. Thus it something we would like to avoid if possible.

One other solution would be to explicitly scan for trigger shapes with a swept capsule right after a move, and invoke them manually (might then have to prevent invoking them again when the scene is simulated). But doing this would be more expensive and not a 100% accurate, because the player is not always moving in a complete straight line when performing a move. Though, the error would be so small that it would be most unlikely to really cause a problem.

So we want to evaluate other solutions and see if anyone here on the forums have had similar problems or if someone would have a suggestion for another maybe better solution.


(This is not related to our problem though, but we do have gameplay that is driven by the “real” physics engine; an example of such gameplay object would be one of our enemies that are a hovering drone that is physics driven and use forces to turn, steer and accelerate. That is mainly because it is much more satisfying to shoot a drone that behaves natural upon bullet impacts and when colliding with walls or getting blasted away in explosions! :) It is also effect full to kill it because it then loses its anti-gravity behavior and plummets to the ground like a normal dynamic physics actor.)


Thanks again for the reply, and please let me hear your thoughts on our suggested solutions or if you have any suggestions for solving this problem! ^^

I might add that we will probably test to recreate parts of our system in the 3.2.1 version on Monday and see if the new version handles triggers better. If that is the case, we might consider to switch/upgrade. Though that will make us tear up a lot of code in an almost finished game and in an almost finished engine… not that pleasant ^^; IMO …

I looked through the code of the new character controller for 3.2.1 and noticed some code that filtered out triggers:

// Ubi (EA) : Discarding Triggers :
  if(shape->getFlags() & PxShapeFlag::eTRIGGER_SHAPE)
   continue;

This code were in the “findTouchedGeometry” function. We might need to change this, but then at least there is a solution if we rebuild a new type of character controller with a slight change. But we will have to test around and see if this actually solves the problem, and if so, see if we can afford to upgrade.

As we have been doing some reading and testing with PhysX 3.2.1 now, I have some updates on this matter.

I noticed that the documentation still say that the triggers will only “trigger” upon the fetch results call after a simulation. Thus, the same problem remains. However, we have noticed that it might be easier to modify the controller to handle triggers in the 3.X versions of PhysX. But the hunt for solutions continues. We are currently leaning towards trying to detect triggers in the movement code for the controller, and stooping the “normal” trigger function form reacting on controllers in order to stop multiple reactions on the same event.

Have anyone been working with modifying the controller, do you have any tips to give me or do you have any other ideas? I will continue to work anyway, but I appreciate all feedback or information I get!

Thanks!

It’s something I found while researching for my project. Hope it helps somehow.

Hey any news on the issue ?

Sorry for my absence, but, no. There is no news on the development. We have briefly tried the 3.x code, but they have the same problem as our current system.

We do not have problem setting up triggers, only problem with a delayed response from character controllers.

We will probably solve this through one of the previously mention methods, if no one else have any better suggestions.

I had my hopes for maybe someone from the Nvidia staff to comment on the issue, especially since it still is an issue in 3.X versions of PhysX. But I don’t think they will comment on it, and we start to run out on time. We can’t delay the solution much further. We have a game to finish after all : ). I will have to come back to try to find a better solution later on if there is time (more like an optimization than anything else probably).

Thanks for trying to help out! :)

I’m sorry for the late response.

I don’t think you have to upgrade to 3.x because 2.8 should be able to handle triggers for CCT and the 2.8 CCT source is available as well.

I’m not very clear the delayed/missing trigger problem you’re seeing when CCT moves really fast. How fast are we talking about? I’m moving CCT at 100 meters in a move call and still get all the NX_TRIGGER_ON_ENTER, NX_TRIGGER_ON_STAY, NX_TRIGGER_ON_LEAVE. There’s rar file attached (renamed as .jpg).

onTrigger is called at fetchResults. I would imagine you do get the NX_TRIGGER_ON_ENTER at the moment the CCT enters a trigger shape, and it’s still far from the actual wall, and you still have time (it’s still the same frame) to do your game logics. Can you make the trigger shapes bigger if this is not the case?

Another way is doing an overlap test after a move call to see if the CCT is inside a volume. However, the onTrigger should already tell you this.

Thanks for the reply! No matter if it is late : )

Yeah, we have located the problem to be that we do several player simulations in one physics frame. With other words, fetch result is not called every time the player moves. That is the reason behind the delayed trigger response. One of the solutions I mentioned above is to exclude the player from all normal trigger interaction and handles the trigger interaction manually through a sweep test after each movement (although I have read that there are some accuracy problems with sweep tests, especially if sweeping short distances). That was close to one of your suggestions as well, so I guess that is the best way to go around the problem.

I guess the controller is meant to only do one move and one reaction for each scene simulation, but it would have been nice if the triggers were triggered immediately upon moving instead of afterwards. The late response makes it impossible to do good collision handling in the callback from the controller, if you want to take into account triggers.

As all of our gameplay objects, that are not fully physically simulated, is updating in a constant Hz separate from the scene, we will probably have to handle all trigger interactions for gameplay purpose on our own. Probably look into modifying the character controller code in some way.

Thanks for the help so far! I’ll report back with result of how things went as soon as I get some time to test this out. But I’m occupied with some other tasks for the moment, so it might take a month or so before I can get back on polish and bug hunting.