Search Unity

Isolating separate collider at feet for grounding

Discussion in 'Physics' started by victus_maestro, Jul 19, 2019.

  1. victus_maestro

    victus_maestro

    Joined:
    Apr 21, 2019
    Posts:
    21
    Bonjour all, I apologize if this is a duplicate--I found no search results for it but I feel like this is something that has to have been asked before.

    In a video some time ago, I saw a recommendation to place a separate, slightly narrower collider at the feet, so that you could detect collisions with the ground without creating a "ground" tagged surface object for every platform.

    This sounds like a great solution, but the default action of colliders on children is to trigger the same action as the parent collider. I feel like there has to be some way to differentiate (perhaps in the collision data in OnCollisionEnter()), but I don't yet know it.

    If anyone can point me in the right direction to implement this, or if a different solution would be better, any tips would be much appreciated!
     
  2. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    11,497
    I'm not sure what that means. If you add a script on a GameObject with a collision/trigger callback you'll only get it for colliders on that GameObject and not colliders on a parent or other children.

    The confusing thing might be that you additionally get a callback on the GameObject that has the Rigidbody on it too which might be on the parent. If you keep that separated from the colliders you're interested in then there'll be no ambiguity.
     
    Last edited: Jul 19, 2019
  3. victus_maestro

    victus_maestro

    Joined:
    Apr 21, 2019
    Posts:
    21
    Thanks for the reply, @MelvMay. I probably poorly explained it. I tried doing this method before, but it didn't work...I wish I had kept the project I was testing it in, as that would have given better context. Essentially, however I had set it up, collision with any of the colliders ended up grounding the character, though that was probably an issue with my setup and not the system itself.

    I just seem to remember in researching a solution that someone mentioned that child colliders work as a multi-mesh complex hull for the parent. Admittedly, I may be misremembering or had misunderstood in the first place.

    So in this context, and with the goal of making implementation smooth and efficient, what is the best solution? Main collider on the GameObject and the feet on a child? I've heard that multiple collider components on a single GO are bad practice...is that true?

    Edit: Rereading your reply, it sounds like I should have it split into a separate GO for the sake of compartmentalizing that collider's behavior from that of the others.
     
  4. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    11,497
    Yes, it's called a compound collider but all it really means is that you can have multiple colliders attached to a parent Rigidbody (see here, also the note of "Note: Compound colliders return individual callbacks for each collider collision pair when using Collision Callbacks.")

    No and I'm not sure in what possible way it could be a bad practice. Maybe you read that someone had some particular problem on their project or that crazy numbers of primitive colliders were being used rather than a mesh (I've seen this done).

    In the end, due to the way the collision callbacks work in a script, the decision is based upon if you need a callback for a specific collider. If there's two on the same GameObject then the same callback will be used for both. This might be fine or, as in your case, it might produce ambiguity. If you must have a callback for that particular collider then relocating it onto a child GO makes no difference to physics but does mean it'll get its own callback.
     
  5. victus_maestro

    victus_maestro

    Joined:
    Apr 21, 2019
    Posts:
    21
    Ah, thank you, that clarifies things. That is definitely in line with the behavior I saw when I tried to implement it.

    So to be sure I understand, it sounds like for my implementation, I will want to add a child GO/collider and have a script attached to that GameObject with its own OnCollisionEnter function to flip the boolean I want. And the parent's RB will recognize it due to its position in the hierarchy?


    And as for the question of multiple colliders, I tracked down the source where I heard it and it was actually a blanket statement about duplicate components in general, which I thought was odd given that I know for a fact that multiple modular scripts are a common practice. But looking into it, the source was not authoritative and was most likely a "blind leading the blind" situation, or dependent on circumstances that weren't elaborated.

    Just goes to show, it's always better to come here first.
     
  6. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    11,497
    In short, yes. Any Collider (or Collider2D) type adding to a GameObject will attached to the Rigidbody (or Rigidbody2D) on the same GameObject or continue searching "up" the hiearchy until it reaches the root. Moving that attached Rigidbody moves the Collider. The hierarchy (Transforms) between the Rigidbody and the Collider determine it's relative pose between the body and collider. This allows creating compound set-ups of multiple collider types, all attached to the same Rigidbody. Ultimately though, you should only see the Rigidbody moving so colliders move relative to it.

    Sorry for the extra detail but it's all important.

    Good luck.
     
  7. victus_maestro

    victus_maestro

    Joined:
    Apr 21, 2019
    Posts:
    21
    To not leave this thread hanging, I just wanted to provide some resolution for people who may have been confused as I was.

    It took me a long time to understand the interplay between colliders, rigidbodies, and collision methods. This is what @MelvMay was trying to explain to me, but for some reason it took a while for it to click. Nonetheless, thanks for the patience and detailed responses!

    I definitely understand it better now, though it will take some more practice and experimentation. In short, my understanding is that I could have used child objects with references to the collision contacts array to determine the exact collider involved.

    While not my original plan, the method I used in the mean time is quite serviceable so I may keep it, and in the interest of giving ideas for future devs I'll note it here.

    I created a generic "proximity trigger" class. This class can be added to a child GameObject with a collider set to "trigger" and will generally just act as an "on/off" proximity sensor.

    When a collision is made by the player's main hull, it checks the value of a proximity trigger on the feet collider object. This child GO simply has a sphere collider slightly narrower than the player and moved down a fraction of a unit below the main collider. This allows the function to identify if the player is colliding with the ground or not.

    This is not a perfect system, but one advantage is that I can use the same generic sensors for the sides of the character to set triggers for wall jumps and the like as well. It may not work forever, but I haven't identified any issues with it for the moment.

    If I change it further, I'll post changes here for reference. But as always, comments/criticism are always welcome.
     
    MelvMay likes this.
  8. neilybod

    neilybod

    Joined:
    Apr 3, 2020
    Posts:
    2
    Just found your thread while googling and wanted to thank you both for providing some really useful info. So many blog examples and forum posts contains some real bad practice dev, but this really helped :)
     
  9. victus_maestro

    victus_maestro

    Joined:
    Apr 21, 2019
    Posts:
    21
    Glad it was of some use to you! I always get great insights from the other developers here. If you have any questions about specific implementations, I'll do my best to help!