Need a Collider without momentum

First Problem

  • Flax Collision detection requires a RigidBody/Character Controller,
    there is no collision between static Colliders

  • RigidBody requires “Simulation” to be enabled, and this will have a Linear (translation) and Angular (rotation) impact/momentum towards the object

  • Not all collisions in the game need this simulation, some of them only need to check simple “hitTest” or a simple movement.
    an example case :
    Fire projectiles, I don’t need my projectile to have crazy momentum nor do I care how my fireballs are going to rotate when it hits.
    To achieve this in current Flax version, this is what I have to do :
    A) Set my projectile as Static Collider and make the Target Enemy as RigidBody/CharacterController.
    The downside is if my projectile hits the Wall or any other static Collider I can not detect collision, so the projectile will penetrate through the map

    B) So my only option is to set my projectile as RigidBody, so my projectile can detect collision with any Collider. But I’m concerned about the performance since I am not going to use all those fancy momentum simulations anyway, I can just write a simple code to move Actor.Position and only need the “OnCollisionEnter()” event in the Collider.

Second Problem

  • RigidBody is hard to control, especially when we want to reduce or disable some simulations
    collision-flax-1 - VEED
    As you can see in the video, the blue capsule is “CharacterController” and the white capsule is “RigidBody”, the Rigid Body will slide downward when it touches the slope.
    I even attached a “PhysicalMaterial with Friction value of 1,000,000,000” to the RigidBody in the video.
    And it still slides downward.

  • Currently we can lock the rotation, which is useful to prevent the object from rolling around

  • The problem lies in the “translation”, since it will always be affected by momentum.
    If you lock the translation, then no collision will occur (it will straight fall through the floor)

  • Surprisingly CharacterController does not have this problem and is not affected by momentum.

  • So the only thing I can do to achieve the same result with CharacterController,
    is to increase the “Linear Damping” to high value, then write custom code to stop all forces once it touches the floor.

So from what I tested, these are my options if I want to have a collision between objects

  • Use CharacterController for Players and Enemies, which is the intended design.
    This is good and there is no problem with it.

  • I am confused with how I deal with Non-Character objects, but still want the object to detect collision with the map (Static Colliders)
    For example, if you want to make a game like the latest Zelda Tears of Kingdom,
    where you move objects realtime in the map to solve puzzles.

  • “Kinematics RigidBody” is not affected by momentum and is a good solution, but it does not detect collision with Static Colliders

  • Regular RigidBody is affected by momentum simulation, so it’s hard to predict the exact position to control in an event or puzzle sequences

  • Using Static Collider is not an option, because it will not trigger “OnCollisionEnter” with other Static Colliders.

  • What is the point of separating how momentum work on CharacterController and RigidBody?
    Making all of them has a parameter to enable/disable momentum will give more freedom to user.

  • Is there something I miss? I am sure the devs have good reasons to make the Collision system as it is,
    so It might be me just using the engine in a wrong way?

  • Am I supposed to use “CharacterController” for all of the objects I mentioned above?

Suggestions

  • Instead of forcing the user to use specific class for specific feature,
    so like use “kinetics” for this, but for that use “RigidBody”, however for anything else use “Collider” , etc
    It will lead to confusion for beginners on how to use the feature = hard to learn

  • Also by making things specific, it’s hard to please everyone like the problems I mentioned above where there will be someone or some game that requires a combination of features, and separating it into different objects will make it harder (if not impossible) for these users.
    This is also why I personaly think Unreal concept of separating features like Actor, Pawn, Character, etc is a terrible idea.

  • So in my opinion, if possible you can try to make a simple single “Collider” but with ALL the features that RigidBody, etc has.
    Then in each objects inspector parameters, simply allow the user to enable/disable the feature they need or don’t need. So we can have a RigidBody with the momentum turned off for example. And allow ALL Colliders to trigger Collision detection, so there is no need to separate Static or RigidBody.

Thanks.

I can only really try and answer your questions from a Unity perspective (I just got here!), but perhaps that still helps as both engines are using PhysX:

I’m guessing, but I assume that all the physics and character controller code is from PhysX (via some wrappers).

The static colliders are not designed to be moving, so no detection between them is necessary (if they aren’t moving they can’t bump into each other).

The dynamic rigidbody provides the basic physics information for a dynamic object (mass, inertia and velocity). It’s difficult to create believable dynamic behaviour without this for objects of different sizes and shapes for example.

Kinematic rigidbodies are pretty much character controllers without the extras.

The character controller is a kinematic based object (it works with prescribed displacements and does not care about anything getting in the way!).

You have a few options for collisions:

  1. Make your fireball a physics object by adding a rigidbody.
    Unless you are planning to have a very large number of these active at the same time, the overhead of the rigidbody physics should be minor. If you are targeting PC/Console I would not expect there to be any problems running a few hundred RBs (obviously this becomes far more costly if they are all close together with a large number of potential collision events, but hopefully that is not your case).

  2. Use a trigger collider to detect collision and script the response that you want to that collision (beware of tunnelling if you are just moving the transform). I’m not sure how flax addresses this, but in Unity you could use a kinematic rigidbody with MovePosition etc. Note, a kinematic will not interact with a static collider, you will still need the trigger collider and script, but this effectively lets you write your own custom response to collision).

  3. If you are going to have a large number of fireballs created and destroyed you should be using some sort of object pooling system - my feel is that the instancing overhead will out-weigh the physics overhead.

Second Problem
a) Because the character controller is kinematic it has no concept of inertia, so its behaviour is as I would expect.

b) Whilst there is no cap on PhysX friction forces, those forces are dependent on the normal force, which may be affected by the bounce value of either collider. I have not done any experimenting but I assume oscillations in the normal force as the collider settles are allowing it to slip down the slope a little. Even with bounce = 0 on both colliders, I’m sure there will still be some oscillations due the the restored position of the impacting collider and the application of gravity to it. If you want it to stop instantly you can detect the collision with the ground (secondary trigger collider or shape cast) and override the rigidbody velocity to Vector3.zero (I would suggest for a couple of physics steps) then allow it to return to PhysX derived velocities.

I hope some of that provides a few ideas.

1 Like

Hey, thanks for your reply!
I understand now, your explanation clarifies things up.

About my options though

1. Make your fireball a physics object by adding a rigidbody.

Yeah, that’s what I think is the most suitable solution especially if I want my projectile to detect collision with the map (static colliders).
So I need to be aware of the performance cost if I want to spawn huge amount of bullets.

Second Problem though

I still need to run more tests in Flax, because

  • Using RigidBody means I need to override the forces by custom script, like you said
  • Using CharacterController seems like a good idea, but it has some strange interaction with other non-Kinematic RigidBody
    (In my test, the CharacterController pushes other RigidBodies when approaching in a specific angle, but will get pushed / runover by the same RigidBodies in other angles. Do you think this is the expected behaviour?)
    Also there might be some bugs in Flax’s CharacterController collision detection
    RigidBody when moving ignores collision with Character Controller · Issue #1237 · FlaxEngine/FlaxEngine · GitHub

So for now I’m leaning on using RigidBody + Custom Scripts for my Characters.
Thanks

When mentioning rigidbodies it is very important to be clear if they are kinematic or not, I think there would be far fewer problems with PhysX if they gave kinematic rigidbodies a different name instead of using a flag on the non-kinematic rigidbody to completely change its behaviour.

Most of the time, if you are using a non-kinematic rigidbody then you should only be overriding its velocity / position for very specifc events, e.g. to prevent the slide and bounce behaviour you saw on the slope. Most of the time you should be moving it by adding forces and torques and letting the physics engine resolve the motion.

A character controller (essentially a kinematic rigidbody) can push any non-kinematic rigidbody out of the way because it has no concept of force/mass/inertia. Caveat: If the non-kinematic rigidbody is anchored, I’d assume they would pass through each other, or perhaps the controller would stop.

A non-kinematic rigidbody should not be able to push a character controller so I am surprised to read:
“In my test, the CharacterController pushes other RigidBodies when approaching in a specific angle, but will get pushed / runover by the same RigidBodies in other angles. Do you think this is the expected behaviour?” No. Perhaps this is some function of the collision resolution on the character controller?

I’ve noticed that sometimes the character controller pings off a sharp angle / high step that catches it in just right spot, this can be mitigated to some extent by playing with: contact offset 12 on a radius 40, height 100 collider, using a controller with slope limit 45, step offset 30. I’ve not tested this a lot, but it seemed more stable for my little experiment.

In the “bug report” you link to, I am not sure that is a bug. It is unclear to me if the rigidbody is kinematic or not and it is unclear if AddMovement is just moving the transform (which will make collision detection unreliable).

I think the character controller is the easiest way to implement a basic player controller, but if you require more advanced interaction with the rest of the physics you will need to detect collisions and script it - in Unity this is done with CharacterController.OnControllerColliderHit(ControllerColliderHit) you’d have to research Flax.

Bear in mind that if you use a non-kinematic rigidbody for your player you need to be careful how you move it to preserve true physics interaction, e.g. if you set velocity that will override some impact effects with other physics objects, but it can be complex to apply forces and torques to provide the player with precise movement, e.g. on stairs or uneven ground (this is by far the most complex controller for general purpose use). A kinematic rigidbody is basically a home made character controller - many people prefer this as you have more control over exactly what is going on, but of course you have to code your own step and slope code.

I’ve not played with any of the physics in Flax, so I apologize in advance if I am accidentally giving you the wrong information… :slight_smile:

Sorry, In my post what I meant by “rigid bodies” are all “Non-Kinematics Rigid Bodies”.

From my test, CharacterController in Flax can interact with “Non-Kinematics Rigid Bodies” although it has its own weird problem like I wrote above.
Also, unlike regular Kinematic Rigid body, a CharacterController can interact with static Collider. So it won’t penetrate a static Collider.

Taking aside all of these PhysX features, basically what I needed for a game is a Collider that can interact with both Non-Kinematic Rigid bodies and Static colliders.
I was thinking to use CharacterController at first but since it has this weird “can push non-kinematic rigid bodies, but sometimes get pushed by them” problems, I probably will use a non-kinematic rigid body but combined with custom script to deal with “sliding at slopes” etc I posted above.

This is interesting. I also checked the Script API for RigidBody class

There’s no method called “AddMovement” there, so it seems like AddMovement is a method from Actor Class, which is like you said can mess up with the collision because it is not an intended function to move a RigidBody.
From the Script Reference, the git issue might be resolved if the reporter called “RigidBody.AddForce()”
I still need to do some tests though.

Well since you’re here, you should play with Flax now lol.
But thanks for your information, it helped me a lot :grinning:

1 Like

Hi again,
I have further tested “Kinematic Rigid Body” and “CharacterController” collision behaviors.

A-1. CharacterController vs Non-Kinematic RigidBody

  • The Character model with red outfit = CharacterController
  • The rolling sphere = Non-Kinematic RigidBody
    This is what I meant by CharacterController can be pushed around/affected by Non-Kinematic RigidBody in above post.
    characontrol_01_

A-2. CharacterController vs Static Collider

  • The Character model with red outfit = CharacterController
  • The Slope = Static Collider
    characontrol_02_

B-1. Kinematic RigidBody vs Non-Kinematic RigidBody

  • The Character model with red outfit = Kinematic RigidBody
  • The rolling sphere = Non-Kinematic RigidBody
    kinematic_01_

B-2. Kinematic RigidBody vs Static Collider

  • The Character model with red outfit = Kinematic RigidBody
  • The Slope = Static Collider
    kinematic_02_

My Goal
What I wanted is a Collider who can behave like

  • B-1, when colliding with Non-Kinematic RigidBody
    So the Character can push around / influence Non-Kinematic RigidBodies and not the other way around
  • A-2, when colliding with Static Colliders
    Basically a Kinematic RigidBody that interacts with Static Collider.

What do you think is the best way to achieve this?
I thought to use Kinematic RigidBody then using Trigger Collider and push the Character manually using Script to prevent penetration with static colliders. But the API does not provide any ContactPoint during Trigger, the Physics API also does not return Contact data only "hit or not " boolean checks.

Well, I didn’t find anything nice, but one approach would be to use a character controller, this gives you the slopes, steps and static collisions.

I added a second capsule trigger collider to this that was slightly larger and added a collision trigger handler script to it that was like this (excuse ugliness, lack of error handling and hard coded reference to my character controller):

public class PC_CollisionHandler : Script
{
    private Collider TargetCollider;

    public override void OnStart()
    {
        TargetCollider = Actor as Collider;
        TargetCollider.TriggerEnter += OnTriggerEnter;
    }

    private void OnTriggerEnter(PhysicsColliderActor actor)
    {
        if (actor.Name == "PlayerController") return; // don't detect my parent character controller
        TargetCollider.ClosestPoint(actor.Position, out Vector3 result);
        Debug.Log(result.ToString());
    }
}

This gives you an idea of what you have hit and where the nearest point was (not sure how robust this is for large awkward shapes as I guess it is just to the actor position, but it might be enough to build a force vector). So in theory you can do some more checks and apply some forces, if appropriate, to make it move away. Maybe there is a way of getting the collision point between two colliders… I could have looked harder :slight_smile:

I could not figure a way of getting the collision data directly from the character controller (Unity style).

I was surprised that the character controller does not just push the non-kinematic rigidbodies out of the way. Although I did find that my controller would stop a rolling ball, but then walk up and over it. If yours is actually getting moved by the ball I wonder how you are moving the ball - are you constantly resetting its velocity?

As an aside, I could not see an equivalent of the Unity MovePosition for moving kinematic rigidbodies, which makes it very hard to have any confidence in their collision detection… perhaps a fix for this is already baked in and transform movement is safe. I don’t know, I haven’t tested and I’m running out of enthusiasm to look :smiley:

Good luck, I need to do some other stuff today, but I’ll try and drop in next week. Have fun!

1 Like

Thanks for your ideas and code.
I thought so too, that to achieve my goal I need to be creative.
I guess built-in features are not good enough.

One thing about CharacterController though,
just like my pics in previous post, it behaves differently from a Kinematic RigidBody.

  • For the rolling sphere, I just put it on a static collider Slope, and let it roll by itself
    (the sphere is a Non-Kinematic RigidBody with Gravity enabled)
    So I don’t give any external forces by code or whatever manually

  • What I can think of what causes this is,
    a Kinematic RigidBody has inifinite mass, while CharacterController has zero mass?
    That’s why it is easily moved by non-kinematic RigidBody

    CharacterController VS non-kinematic RigidBody
    characontrol_01_

Kinematic RigidBody VS non-Kinematic RIgidBody
kinematic_01_

  • Since you told me that a CharacterController is basically just an extended version of Kinematic RigidBody, then do you think that this result is wrong?
    And if it is, we should post a git issue so that the dev can fix it!

That’s strange, in my very limited testing the N-K RB just bumped into the controller and rolled away (mine was smaller and slower than yours). I don’t think it is the rigidbody physics doing this: as soon as we talk about infinite or zero mass you can see that F (force) = m (mass) a (acceleration) becomes meaningless. It is also interesting that your CC does not translate, it just rises up as if climbing over the ball - making me think this is some sort of collider or step processing.

It may be worth doing some testing with adjusting the CC properties: Contact Offset, Slope Limit and Step Offset

You can see here a summary of the CC: Character Controllers — NVIDIA PhysX SDK 3.4.0 Documentation “The PhysX CCT is a kinematic controller.” Don’t just believe me :smiley:

Have you tried testing with: CharacterControllerPro Update! Documentation and Bug Fixes! I’m not sure if he has added any extra code for RB interaction, but it might be a nice sanity test just to see if it replicates your problems. I’ll tag @Spectrix in case he has any thoughts on this.

Actually I DID!
I downloaded the project from Git and test it in Flax 1.6 → the result is the same
Same conditions with my personal project :

  • Slope = static collider
  • Rolling Sphere = non-kinematic rigidbody + gravity enabled
  • The robot = CharacterController (obviously)
    characontrolpro_test_

Well, I think that just leaves you with coding your own solutions. Sorry I don’t have any more to offer. :frowning:

Thanks, I’m fine with coding my own code.
What I wanted to ask if do you think this behaviour is correct or not?
If it is then we’re done here.
Otherwise, I will post a git issue so that the dev can fix this.

Posted git issue here:

I’m not so sure it’s a bug. I agree that the collision does not look great with the ball, but I think this is more why people end up creating / modifying controllers to fit their game environment. Imagine a scenario where a wedge is slid under the character, then you expect them to step up and over it. And because we aren’t really using physics to interact with the character controller, it is hard to determine the best course of action based on the collider shapes / sizes.

I’m sure it would be a real benefit to have more options to handle these interactions in different ways , i.e. a more sophisticated character controller, which would definitely be an asset to Flax. But, imho, for now that is probably more of a community led development than something the engine developers will want to spend time on.

1 Like

I understand what you said about each user should have a different approach when creating their game.

But what I am trying to do here, is to set a standard point in Flax.
If the standard in most of game engines are “CharacterController behaves exactly the same like Kinematic RigidBody”
then I am just making suggestions "Hey maybe Flax should follow these standards? "
Because people will expect most engines to behave like that.

However, if they choose to leave the CharacterController as it is, because Flax is different than Unity, etc
It is also okay.
Maybe they can even give a better solution, like a parameter to allow user to set how the CharacterController reacts, a checkbox to behave similiarly to Kinematic RigidBody or not for example.

My point is not to force the dev to do things my way,
I just point inconvenience or things I don’t think is right in the engine,
and hopefully if many users including the devs feel that way, they may or may not change the direction of the feature.

1 Like

Just to add to this list: I notice that the Documents state “Kinematic rigidbodies are incompatible with CCD”, but my experience shows that the collision between a K-RB and a character collider was far more stable with CCD enabled on the K-RB.

In this case I may end up building my own solution. CharacterControllers shouldn’t really be able to modify the physical state of anything in the world on their own,

since they’re kinematic.

If you want to add this functionality, I can immediately think of two options that may or may not work. One would be to add custom RB interaction to the CC. On the face of it, this seems like it shouldn’t be super difficult. Just add the CC’s velocity as an impulse/force to any RBs it contacts. (Would have to use RayCasts/SphereCasts/CapsuleCasts to accomplish the detection.)

Edit: Or maybe the CollisionEnter method would work

Another option is to attach a RigidBody to the CharacterController, lock it’s X and Z rotation, and set it as a child of the CharacterController. Add it’s own collider, and put it on a different layer compared to the CC, but one that can still interact with the world.

In terms of detecting collisions with non-Character objects, that sounds like something that can be done with CheckBox easily enough. You can even specify a custom collision mask so only certain map objects are detected. I honestly haven’t played with the trigger system enough to give you any definite answers, but these are just a few ideas I would try.

The reason for this awkward sphere movement is likely because the CharacterController is trying to reach the highest point on the sphere, likely due to an increased step offset?

I was researching Unreal’s CharacterMovementComponent awhile back and was reverse engineering a whole bunch of stuff. I can’t show you any of the code, but it’s really interesting how they solved some common movement problems. I was going to create a character controller that uses some of their ideas, but when I asked Epic if I could publish it, since the code was loosely similar to theirs, I didn’t get a response. :skull:

Anyways, my point is that that awkward sphere movement is because the character has no platform attachment. This is rather easy to solve, if you’d like me to write up on it. (C# != C++, and Flax API != UnrealAPI, so I would see no harm in doing so.)

CharcaterControllerPro is more of a very simple tech demo than an actual asset made to be used in a finished game. It’s nothing like KCC in Unity or CMC in Unreal for example. If the community would like to start building such an asset, I would be glad to assist, but this is starting to get off-topic.

You might be right on this, however setting StepOffset to 0 does not change the result. The character will still move above the Sphere.
For my implementation to work around this, I use a Non-Kinematic RigidBody, instead of Flax’s default CharacterController as a base and add my own custom scripts to make it work like a CharacterController.
So luckily that can be a solution to my problem, but it means that I will never use the default CharacterController :sweat_smile:

That will be great if you can show me how to do that please.

How strange! The only other thing I can think of that might be causing it is that the minimum slope angle allows the character to slide up the sphere. What happens if you make the sphere bigger?

I’ll write a seperate topic about this.

1 Like

Bigger sphere = Nothing changes
rb_big

Also, setting SlopeLimit from 0 to 89(Max value) gave the same result