Search Unity

Does collision track up through children?

Discussion in 'Scripting' started by Marscaleb, May 11, 2019.

  1. Marscaleb

    Marscaleb

    Joined:
    Jan 7, 2014
    Posts:
    1,037
    At the end of my day I came across a grievous bug. I had been testing an explosion attack that the player can drop, and it most had been working. But I want this to move with the player, not just drop in place. So I added a "parent" to the instantiate function that creates the explosion so that it would be parented to the player. However, after just this change, the player now "gets hit" by whatever the explosion touches, which actually kills the player.

    I can't see how this would happen, unless my player's code is checking collisions from colliders in its children. Is this how Unity works? That is, is that what happens? And if so, is there any way I can disable this feature so that a child's colliders will only trigger collisions within itself?
     
  2. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    38,752
    I'm not sure of the heuristic but yeah, something like "passing messages upwards" happens.

    One possibility is if you have a Rigidbody for your player at its root, you could add an isKinematic Rigidbody further down, and I speculate that RB might even "soak up" the rising collision message(s). Give it a try.

    Another way might be to leave the bomb as a root object, but put an isKinematic Rigidbody on it and add a FixedJoint so they move together as one under player control. If the FixedJoint is on the bomb, when it blows up the linkage will quietly go away.

    https://docs.unity3d.com/Manual/class-FixedJoint.html
     
  3. You're creating compound collider. Please read the manual for implications.

    Your best course of action I think if you write a small script which updates this position to match it comparing to the player and not put them under the same root object.
     
  4. Marscaleb

    Marscaleb

    Joined:
    Jan 7, 2014
    Posts:
    1,037
    That's what I'm afraid of; this effect is only going to exist for a mere matter of frames, so it seem absurd to go to such lengths as to track the player with additional code when this thing will barely ever exist at all. Once would think there should just be a way to have the object's movement be relative to another object but without compounding the the colliders.
     
  5. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    38,752
    Not sure where your reasoning is going with the "only going to exist for a mere matter of frames." If you want to be on the moon for two or three milliseconds, that doesn't mean you do so without a spaceship and a space suit.

    Luckily there already is, and I listed the first two that came to mind above, and then a @Lurking-Ninja snuck up and added another idea. I'm sorry if these ideas seem "absurd to go to such lengths" but well, software engineering can seem absurd at times, particularly to the uninitiated.

    Good luck in your search for a solution!
     
    hippocoder likes this.
  6. hippocoder

    hippocoder

    Digital Ape

    Joined:
    Apr 11, 2010
    Posts:
    29,723
    A compound collider exists as a single collider though. That's not absurd, it's you instructing Unity to create a single collider by putting the rigidbody only on the root, as per instructions. There's a ton of elegant ways of do what you want if you want.

    Try not to change the entire world to fit the wrong design - the explosion really shouldn't be parented to begin with but simply have a tiny bit of code to follow it's target.

    For example you could emulate child behaviour with:
    1. playerTransform.InverseTransformPoint(explosionSpawnPosition) will convert the explosion spawn position in world space to the local space of the player. Store this value as explosionAnchor.
    2. Every frame in LateUpdate the explosion is moved to the specific position as if it was a child with transform.position = playerTransform.TransformPoint(explosionAnchor);
    This will respect rotations, offsets and so on just as if it was a child.
     
    Lurking-Ninja and Kurt-Dekker like this.
  7. Marscaleb

    Marscaleb

    Joined:
    Jan 7, 2014
    Posts:
    1,037
    What's really bugging me about the whole thing is just trying to keep my code running as efficient as possible. Cut out as many unnecessary cycles and variables as I can. Theoretically, if I can piggyback off of the engine code that the game runs anyway, then my game is going to run a little more efficiently than if I run scripts that try to replicate the data and processes that are already being done in the engine.
    Hence why originally tried to create the explosion as a child of the player, so all the update stuff that happens behind the curtain will move the explosion automatically.

    Tracking the player means I have to find the player and then store that reference. Since this is an event that could be called ad hoc in the middle of gameplay, "find with tag" would be too expensive to call, so I need to have the player send its own reference to the explosion rather than having the explosion find the player. This can't be done with one line, so I have the player script create a local variable to store a reference to the explosion when it gets instantiated, and then an additional command send the player's reference to the explosion.
    Plus an extra cycle or two in the explosion to update it's position, but that would have to happen anyway.

    Now it's not that any of that is too much work or any such thing, but it did add a slight amount of overhead to the program that I was hoping I could avoid by using what the engine was already doing. But it looks like I was wrong.
    Of course, this one effect isn't going to break my game's ability to run on someone's machine, but that's just the level of diligence we ought to be applying to all of our code. Find the most efficient way for it to run.

    Thank you all for the information and suggestions.
    (Now if only I could figure out why some objects aren't getting hit by this explosion...)
     
  8. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    38,752
    I would recommend instead keeping your code running as efficiently as necessary. That goal is actually achievable, unlike the 'as efficient as possible' goal. But... your engineering effort and time is your own to spend.
     
    hippocoder likes this.
  9. hippocoder

    hippocoder

    Digital Ape

    Joined:
    Apr 11, 2010
    Posts:
    29,723
    Yeah, and it's not efficient as possible to parent and unparent things in Unity, that's actually quite a slow operation :D And if efficient as possible was truly the goal, this project would be in DOTS (ECS).
     
    Kurt-Dekker likes this.
  10. Marscaleb

    Marscaleb

    Joined:
    Jan 7, 2014
    Posts:
    1,037
    Good to know!