Search Unity

It it possible to "inject" collisions?

Discussion in 'Physics for ECS' started by CookieStealer2, Mar 15, 2021.

  1. CookieStealer2

    CookieStealer2

    Joined:
    Jun 25, 2018
    Posts:
    119
    Hi,

    I'm aware that we can inject jobs between the various physics phases to modify data. This is a very useful feature but I also think it would be nice if we could add data. For example to fake a collision between two entities which are not actually colliding. From my understanding this is not possible with the current API, but maybe I'm missing something.

    Can I get a confirmation on this? Thanks!
     
  2. milos85miki

    milos85miki

    Joined:
    Nov 29, 2019
    Posts:
    197
    Hi @CookieStealer2 , could you please share some details about the use case (is it for character controller, a car or something else and why exactly is it needed)?
    Also, at which point in frame would you want to add the new contacts (before/after or during the simulation)?

    Would adding a special sphere/plane with filters to collide just with specific body help?
     
    CookieStealer2 likes this.
  3. CookieStealer2

    CookieStealer2

    Joined:
    Jun 25, 2018
    Posts:
    119
    1) I'm working on an unusual type of character controller, which is a bit like a one wheeled car with suspension. The goal is to have a character that can walk up on steps without getting stuck, respond naturally when absorbing a jump impact and able to interact with physics.

    So currently the torso of the character is a dynamic capsule which is being held up by a force, the standforce. This force represents the force of the characters legs and is calculated with the information from a downwards spherecast. This way when I walk over a step the cast hit distance is reduced and so the force increased and the character climbs up the step.

    But in some cases, for example when the ground is too steep (wall), I want to stop the character from walking up. In my current setup if the ground is too steep I apply a slipforce which is calculated assuming there is no friction between feet and ground: so slipforce = the normal force at the feet + gravity force (add the vectors and you'll see that the force points downward along the ground). The slipforce stops me from walking up the wall and instead slide down, but as soon as I touch the flat ground again the character tries to walk up again (if I keep holding forward button) and so the process repeats. The problem is that eventually the spherecast starts to quickly alternate between hitting ground/wall, resulting in alternating sliding/move forces and jittery motion. I want to avoid this somehow. Ideally the character should stop before hitting the wall (if the velocity is low enough?). I figured that adding a constraint into the physics solver (a collision) might solve it, but I'm not exactly sure how that collision would be defined to achieve the desired effect.

    If we think of this scenario but the character is just a simple dynamic ball without any spherecasts shenanigans. It only has a constant force towards the wall (sloped) when it is on the flat ground. If the solver is doing a good job, eventually the ball will settle right next to the wall, it wouldn't continuously alternate between rolling down and accelerating on the ground. This is what I want to achieve but for my character controller.

    2) The collisions would probably be injected before/after the physics simulation if they would be based on the spherecast which is queried before physics.

    3) Creating a plane/sphere might be an option but wouldn't that involve creating an entity and so cause a sync point if I want it to happen before physics?

    Perhaps there are other ways to solve my problem rather than inject collisions, but I wanted to see what options I had available.
     
  4. CookieStealer2

    CookieStealer2

    Joined:
    Jun 25, 2018
    Posts:
    119
    This will help to understand the scenario.
     
    PhilSA likes this.
  5. milos85miki

    milos85miki

    Joined:
    Nov 29, 2019
    Posts:
    197
    Thanks, I see the problem now. Have you maybe tried to do a raycast in movement direction, from a point between the 2 capsule vertices (height from lower vertex should depend on the height of steps you want to support)?
    Hopefully attached picture will clarify my proposal.
    char_caps_raycast_fwd.png
    Also tagging @petarmHavok , who knows much more about character controllers than I do.
     
  6. Alex33333333

    Alex33333333

    Joined:
    Jan 3, 2017
    Posts:
    11
    Hi, milos85miki
    Perhaps I would agree that such a function could be useful. My case is a vehicle system. (As you know already :)) I'm working on a fairly large project and most likely flexibility would be useful. So far, this is just speculation, because I haven't done any deep research.
    We plan to calculate the physics of a thousand or two vehicles on the server. Personally, I prefer such an algorithm:

    1. Turn off all collisions on the wheels.
    2. Cast collider to the ground from each wheel.
    3. Get hit point/s and inject fake contact/s using this hit point/s.
    4. Run a job to calculate collision event details and use them for further calculations.

    Steve has already suggested good options. I haven't done any tests yet. But at first glance, it would be more convenient to manually add collisions instead of spawning fake colliders under the wheels. And theoretically fake contacts would be more performant, as we would execute less code. But again, it is just an early assumption and i can’t tell exactly will we need this feature in the future. But from my experience: it is always better to have more flexibility, especially when you are dealing with difficult tasks.
     
    Last edited: Mar 16, 2021
    CookieStealer2 likes this.
  7. CookieStealer2

    CookieStealer2

    Joined:
    Jun 25, 2018
    Posts:
    119
    Sure, but then what do I do with the hit information? Like I said before I would only like to stop the capsule if it would end up in the jittery alternating state I showed. It should still be possible to jump into the wall and slide down.
     
  8. petarmHavok

    petarmHavok

    Joined:
    Nov 20, 2018
    Posts:
    461
    Yeah this is unfortunately not possible at the moment. The reason is that the whole multithreading architecture needs to know about all the pairs in advance, so that there are no race conditions.

    Usually, special types of bodies (like characters and vehicles) are not dynamic bodies, but kinematic, and you drive/collide them on your own. The reason is that these bodies are just too important to be treated the same as regular physics bodies. Also, they often have special movement logic that doesn't respect physics laws (capsule not tumbling over).

    In our character controller sample you can see how it all looks like. And we have a special solver for that that you can give extra planes. That's what we did for steep slopes. Would you like to take a look and let me know if that fits your needs perhaps? It's actually only 2 functions - CheckSupport() and CollideAndIntegrate().
     
  9. CookieStealer2

    CookieStealer2

    Joined:
    Jun 25, 2018
    Posts:
    119
    I'll take a look. Thanks!
     
  10. steveeHavok

    steveeHavok

    Joined:
    Mar 19, 2019
    Posts:
    481
    For the Character Controller use-case, you could try a pencil shape instead of the capsule. The capsule is faster but for a hero body like the main character it might be worth it.
    upload_2021-3-23_10-27-25.png
    The point on the top minimizes bodies sitting on your head :)
    The 'pencil point' at the bottom can dictate max step height and max slope within the shape itself.
    The slope on the bottom also gives a fixed angle against the supporting surface rather than the curved surface from the capsule.
     
    petarmHavok likes this.
  11. CookieStealer2

    CookieStealer2

    Joined:
    Jun 25, 2018
    Posts:
    119
    Interesting, but I assume then that I would have to modify the collision normals to not bump into the air when climbing a step?

    I have also looked into the character controller sample, but found it very complicated and the simplex solver I guess is more suited for kinematic character controllers.

    What I ended up doing to fix the problem was actually a bit like what milos originally suggested.
    First, if the player is on walkable ground, I cast a capsule to where the player will be the next frame and collect all hits. Then I process the hits; if a hit is on steep ground I remove any velocity towards that direction that would have caused the player to touch the steep ground, so the player is stopped right before collision. And so, if the player is walking on ground towards a wall he is stopped, but if he jumps into the wall, he is not stopped and instead the leg suspension absorbs the impact before sliding down and then finally getting stopped. It seems to work pretty good and will work as a solution for now.
     
    Last edited: Mar 30, 2021
  12. CookieStealer2

    CookieStealer2

    Joined:
    Jun 25, 2018
    Posts:
    119
    On second thought... maybe I'll need the simplex solver in cases like this: Capture2.PNG
     
    steveeHavok and petarmHavok like this.