Search Unity

Feedback Is it really that hard to give the possibility to extend Colliders?

Discussion in 'Editor & General Support' started by Eugenio, Jul 27, 2020.

  1. Eugenio

    Eugenio

    Joined:
    Mar 21, 2013
    Posts:
    197
    Hello !! :)
    I would actually like to ask this question to someone from Unity Technologies: is it really that complicated/bad to give the possibility to extend the Collider classes?

    Let me explain: I created a Killable system in which collisions happens only between specific layers and specific MonoBehaviours so to try to optimize all the physics interactions that happen in my game.
    The only really annoying thing, is that I need to use a GetComponent<Killable>() on the parameter that the OnCollision/OnTrigger functions are giving me back on anything that can kill something:
    Code (CSharp):
    1. public class Projectile
    2. {
    3.     // lots of cool stuff...
    4.  
    5.     public void OnCollisionEnter(Collision coll)
    6.     {
    7.        Killable k = coll.GetComponent<Killable>();
    8.        if (k != null)
    9.        {
    10.           k.ApplyDamage();
    11.        }
    12.     }
    13. }
    Extending Colliders script would give me the possibility to do something like:
    Code (CSharp):
    1. public class KillableBoxCollider : BoxCollider
    2. {
    3.     [Header("Killable Fields")]
    4.     [SerializeField]
    5.     private Killable _killable = null;
    6.  
    7.     public Killable Killable { get { return _killable; } }
    8. }
    therefore I will have a new Projectile class
    Code (CSharp):
    1. public class Projectile
    2. {
    3.     // lots of cool stuff...
    4.  
    5.     public void OnCollisionEnter(Collision coll)
    6.     {
    7.        (coll.collider as KillableBoxCollider).Killable.ApplyDamage();
    8.     }
    9. }
    This example shows the potential of what it could be done to optimize a bit the interactions between game entities.

    Obviously, this is me dreaming about stuff. If anyone has a better solution, or there is already a way to make this but differently, please, let me know.
    In the case extending Colliders is not possible/not a good idea/something else, please, let me know also because I would like to understand the reasons !! :)

    Many many thanks.
     
  2. PraetorBlue

    PraetorBlue

    Joined:
    Dec 13, 2012
    Posts:
    7,909
    The colliders are all implemented in C++, probably complicating the idea of overriding them. Anyway what's the huge benefit of what you're proposing? Performance? Have you profiled your game and found GetComponent to be a real performance issue? You could achieve the same or better performance with a Dictionary<Collider, Killable> I'd guess.
     
  3. Eugenio

    Eugenio

    Joined:
    Mar 21, 2013
    Posts:
    197
    Thanks for the answer.

    Well, at the moment performances are not a huge issue, but I have a lot of small killable objects in the game and trigger projectiles that can pierce multiple enemies before to finish their lifecycle. I'm planning to increment the number of killables and projectiles, therefore, I was thinking about any possibility to improve performances.
    To be honest, I'm also thinking about ECS (therefore DOTS)...

    What do you mean with Dictionary<Collider, Killable>? Like having a cache somewhere that relates all the instances in the scene? If this is the case, yes, it could work especially if associated with a pooling system.
    Obviously this will have an impact on the memory footprint... but I suppose memory/performances is a never ending battle.

    I'm actually curious to know why do you think the Dictionary could provide better performances rather than a direct reference cached in an extended Collider.

    Again, many thanks !! :)
     
  4. PraetorBlue

    PraetorBlue

    Joined:
    Dec 13, 2012
    Posts:
    7,909
    Watch out for premature optimization.

    What's more expensive in C#? Casting an object or doing a Dictionary lookup? I have no idea but I'd say they are both very fast.
     
  5. Eugenio

    Eugenio

    Joined:
    Mar 21, 2013
    Posts:
    197
    By the way, I'm not entirely sure that the C++ implementation of the physics engine can be a blocker this time: in my opinion, the Collider components that are used in the inspector are C# proxies of the C++ classes.
    This means that adding the possibility to define a layer on top of those wrappers that doesn't pretend to modify the implementation of the C++ physics but it's just meant to be as a customizable container used only in the custom C# layer implemented by the user of the Unity Engine, shouldn't cause that much of a trouble.

    I may appreciate that Colliders are NOT MonoBehaviour but special Unity Components that you can still attach to a GameObject... and maybe this is why there is not the possibility to extend and use them.
     
    tonytopper likes this.
  6. Eugenio

    Eugenio

    Joined:
    Mar 21, 2013
    Posts:
    197
    This is actually very true :) but I'm not able to see if there will be an improvement on performances because there is no way to test this at the moment.

    That's very true... but, if you think about it, the cast is not going to be a conversion, at least in this case, because the Collider is actually of the type I'm trying to cast to. I think, in this case, it should be very fast, as you mentioned.
     
  7. PraetorBlue

    PraetorBlue

    Joined:
    Dec 13, 2012
    Posts:
    7,909
    I wonder if Unity stores components in a fixed order array/list at runtime (as it seems from the inspector in the editor). They could then potentially provide an unsafe, but very fast
    GetComponentAtIndex(int index)
    method which you could cast the result of. In most cases you could know that your Killable script is at component index 2 for example. This is quite fragile obviously but I could see the benefits of it.
     
    adamgolden likes this.
  8. Eugenio

    Eugenio

    Joined:
    Mar 21, 2013
    Posts:
    197
    In my opinion this can hugely increase the risks of bugs.

    Moreover, I noticed that, sometimes, the order of the components on a prefab is different from its instance in the scene, especially with the new prefab in prefabs feature.
    I know this could sound odd, but follow this example: I had an FBX imported in Unity. I then created a prefab with my own logic, adding the FBX under a Mesh sub-transform. I had to add some components to the instance of the FBX in my prefab and this is where things went, not wrong, but they were incoherent. The FBX instance visually similar to a prefab inside a prefab BUT it is not possible to add additional components to the FBX because is not a real prefab.
    Rearranging the additional components added to the FBX inside the prefab, will not apply properly, therefore, you could see a random order between what was on the original FBX and what has been newly added.
    In order to fix all of these incoherences, you should create another prefab with the content of the FBX and then use this prefab in the other prefab.

    Obviously this is an edge case and it sounds very confusing but I don't really know how to express this in a better way :D
     
    PraetorBlue likes this.
  9. msfredb7

    msfredb7

    Joined:
    Nov 1, 2012
    Posts:
    163
    Unless you have tens of thousands of collisions every frame, I doubt GetComponent will cause an issue. It's the intended way to go. Even if it was possible to extend the Collider class, I'd advise against it. Composition > Inheritance.

    If you really do have performance issues, DOTS could be a solution to look into.
     
    PraetorBlue likes this.
  10. PraetorBlue

    PraetorBlue

    Joined:
    Dec 13, 2012
    Posts:
    7,909
    Oh I agree completely, such a method would be a really good way to kick yourself in the ass with bugs in all sorts of really obvious and not-so-obvious ways. I didn't even think about prefabs-in-prefabs and prefab overrides etc.. That's a real headache. Still, I could see it being useful for some really narrow performance-sensitive situation. Though as some other posters have mentioned, maybe that's when you explore ECS/DOTS.