Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Unity 4.5: 2D Colliders + Rotation Change

Discussion in '2D' started by Yukichu, May 30, 2014.

  1. Yukichu

    Yukichu

    Joined:
    Apr 2, 2013
    Posts:
    420
    So.... Unity 4.5 Physics Updates has done... ahem... interesting things.

    4.3.4 = 2D collider attached to an object. Rotate object on X axis. Since collider is 2D, it does not rotate. It completely ignores rotation since it exists in a 2D world.

    4.5 = 2D collider attached to object. Rotate object on X axis. Collider2D will 'shrink' to a relative size as if the object were actually rotating, albeit still 2D 'flat'. At 90 degrees X, collider is infinitely thin since you're looking at a 2D object 'plane' in a manner of speaking, and will actually not trigger collisions at all.

    Funny. Completely new behavior. Looks like all colliders will get their own gameobjects now.

    Also... it seems to have fixed the inconsistent behavior of previous Physics2D where if you interpolated collision on a rigidbody, you absolutely could not rotate the Z axis of a transform that had a Collider2D attached.

    So, perhaps before I go redoing a ton of stuff, I should ask - is this the new expected behavior, or is this an oversight?

    To Test: Create gameobject. Attach 2D collider. Rotate X. Watch it shrink in scene view. At 90X, it's effectively "gone". Doesn't even have to be running.

    Haven't created a bug because... I don't know if it is a bug.
     
  2. golonko

    golonko

    Joined:
    Nov 6, 2012
    Posts:
    13
    For me this is a major issue which i can't solve at the moment...
    I posted about this yesterday(link)
     
  3. layola

    layola

    Joined:
    Aug 6, 2013
    Posts:
    94
    I got the same problem ,may be it's not bug just improve
    I have to rollback to 4.3.4 at the moment .
    another problem :
    the editor camera can not show the 2d collider in same case .or it's far away from the base object .
     
  4. Yukichu

    Yukichu

    Joined:
    Apr 2, 2013
    Posts:
    420
    I searched for other people's posts first, must've missed yours.

    Yep, totally bunked up things for me.

    My solution was to create a parent object that has the collider on it, and rotate the child, put animations on the child, etc. Completely annoying. Waiting on a response as to whether this is new-normal-behavior or new-incorrect-behavior so I can change everything or not.
     
  5. Fubeca

    Fubeca

    Joined:
    Jul 21, 2013
    Posts:
    41
    Okay, so it's not just me. I'll try to the parent gameobject with the collider and rotate the child. This has borked my project pretty hardcore, but I want to know if it's "by design" (thus making it necessary for me to redo my whole project), or "oopsie! sorry for that" and get fixed in a hurry..
     
  6. Yukichu

    Yukichu

    Joined:
    Apr 2, 2013
    Posts:
    420
    Yes yes... I'd like an official reply on this too. Hrm, time to find someone to send this thread
     
  7. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    11,321
    Sorry for the delay in replying.

    This was an intended change that was requested many times however, in hindsight it may be better to provide a rotation on X/Y as an option in 2D physics settings. It'd be possible to get that out in a fairly short duration, maybe as a patch release.

    To be clear however, you guys are talking about only transforming the centroid of the collider only and not transforming the collider vertex right?
     
    Last edited: Jun 3, 2014
  8. golonko

    golonko

    Joined:
    Nov 6, 2012
    Posts:
    13
    I'm not doing any vertex transformations.
    As stated in the other post all i do is add a collider2D to a 3D object with a rigidbody2D and then rotate the object's transform to fix the facing direction of the model.
     
  9. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    11,321
    I understand what you are doing but it seems you understood my question. My question was to confirm that you/others only want the centroid of the collider to be transformed and not the the vertex of the colliders (box/edge/polygon). In a simple case (yours) where you rotate around X/Y on the GO that contains the collider in question then the centroid doesn't move however this isn't the case when rotating about X/Y in the parent hierarchy.

    In 4.5, not only is the centroid of the collider rotated but also the vertex of the edge and box/polygon.
     
  10. Yukichu

    Yukichu

    Joined:
    Apr 2, 2013
    Posts:
    420
    Err... Centroid is a new word to me, so I may be incorrect in my statements but...

    Yes, an option for the X/Y rotation to only affect the centroid (center/pivot?) and not the vertex/edges would be nice. However... considering Box2D was originally implemented on solely the Z-plane... I now see that allowing this would (or could) allow you to have X/Z as the 'overhead' for a game, rather than X/Y.

    Considering Box2D was implemented as such in 4.something-or-other to be X/Y only, we of course built our games to accomodate. It would be nice to simply have a checkbox in the project physics2D section to restrict vertex rotations for X, Y and Z... as I could see similiar issues with an X/Z overhead, rotating Z, and everything being wonky.

    I will happily wait for this option to be implemented in a patch release. Kind of stinks that existing projects basically broke due to this as it was working with the current implementation of Box2D. Just, err... not a criticism, more of a want... considering lots of existing projects broke... a patch release would be the most ideal situation.
     
  11. Fubeca

    Fubeca

    Joined:
    Jul 21, 2013
    Posts:
    41
    Yes, I'd like an option to have it only rotate on the centroid of collider, and not reshape the collider's vertices. (Like it did in 4.3). I want to be able to use 3d models in a 2d game, purchasing them out of the asset store and plopping them in and not worrying about learning how to use blender right now. One thing at a time. :) The concept of my game would be to difficult for a player to play in 3d, so I need it in 2d, and I really like the 3d models I've purchased for it.
     
  12. Yukichu

    Yukichu

    Joined:
    Apr 2, 2013
    Posts:
    420
    Well, looks like this didn't make it into 4.5.1. Hoping it gets in the next patch.
     
  13. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    11,321
    The fix went into the first patch to 4.5.1 which should be out fairly soon.
     
    keely and Yukichu like this.
  14. Yukichu

    Yukichu

    Joined:
    Apr 2, 2013
    Posts:
    420
    Awesome, thanks for the heads-up!
     
  15. golonko

    golonko

    Joined:
    Nov 6, 2012
    Posts:
    13
    You mean 4.5.1p1, and not the currently available 4.5.1f3 ?
    Because i can't see the fix anywhere in f3...
     
  16. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    11,321
    Yes, I said the first patch for 4.5.1 i.e. p1 which should be out soon.
     
  17. golonko

    golonko

    Joined:
    Nov 6, 2012
    Posts:
    13
    Could you elaborate a bit about how this was fixed?
    I've got 4.5.1p1 and still cant find a way to keep my 2D colliders facing the camera
     
  18. Yukichu

    Yukichu

    Joined:
    Apr 2, 2013
    Posts:
    420
    I installed 4.5.1p1 as well and could not find options for changing this. I presume it didn't make it into this patch release?
     
  19. Yukichu

    Yukichu

    Joined:
    Apr 2, 2013
    Posts:
    420
    *cough* Any news on this?
     
  20. golonko

    golonko

    Joined:
    Nov 6, 2012
    Posts:
    13
    Anybody?
    I would love to not feel ignored...
     
  21. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    11,321
    Sorry, this didn't make it into the patch releases. This will be provided as an option in 2D physics settings. Unfortunately, at the moment, I cannot give you a fixed release date or specific patch release it will get into it. I will of course do so when I know myself.
     
  22. golonko

    golonko

    Joined:
    Nov 6, 2012
    Posts:
    13
    heh..
    I installed the new 4.5.1p2...
    And now I am kindly being informed that the collider will not be created due to it's rotation.

    Now i see your reply MelvMay...
    At least it's SOME feedback ;-)
    Could you give us a hint as to how to work around this issue?
     
  23. Yukichu

    Yukichu

    Joined:
    Apr 2, 2013
    Posts:
    420
    The work around for me was to put the collider on a different gameobject, generally the parent. Move the parent's position, and the texture,sprite,whatever child you apply the rotation.

    Unfortunately, I don't want to go back and change this for uh... a lot of objects and code... so I'm waiting for the patch.

    Melv, thanks for the update. Please let us know when you have more information!
     
  24. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    11,321
    Yes, I changed it so that you are at least informed when the reorientated collider breaks Box2Ds constraints for size, area etc. This was a quick informative measure and more preferable than spamming the console however yes, being able to select whether the 2D colliders are transformed in 3D space or not is the solution moving forward. I'm actually looking at a couple of extra options in 2D settings. The first is to select 3D or 2D transformation for 2D colliders. The second is whether to not create the collider if it exceeds Box2Ds constraints (what happens now) or simply clamp those constraints (if possible) meaning it won't necessarily be the size you specify but may be clamped at some lower bound. For instance, creating a crazy small box (perhaps in one axis as some do instead of using the edge-collider) will be clamped so that it doesn't exceed either the size or area bounds. This would also work if you were rotating the colliders in 3D space.

    For 4.3 equivalent, you'd simply select 2D transform in your physics settings and it'd behave as it did before.
     
  25. Yukichu

    Yukichu

    Joined:
    Apr 2, 2013
    Posts:
    420
    Sounds excellent. Looking forward to it. Please let us know when it's scheduled with some certainty to be added.
     
  26. Fubeca

    Fubeca

    Joined:
    Jul 21, 2013
    Posts:
    41
    K, I'm still completely broken on my primary 3d model in my game that I want my 2d colliders to move with the model. And what you describe would all of a sudden make everything work again.
     
  27. Fubeca

    Fubeca

    Joined:
    Jul 21, 2013
    Posts:
    41
    I finally gave up on waiting for the alleged fix after a month of multiple patches and a new point release and I messed around with it some more.

    I created a new root non-rotated gameObject for this model and moved the rigidbody2d and scripts up one level to it. Everything works great when I rewrite the script to rotate the new child gameObject's transform instead of the transform that the rigidBody2d is on (which used to be one and the same).

    So it breaks if you have the rigidBody2d on a rotated gameObject, and doesn't break if you put it on a non-rotated rigidBody2 gameObject with descendent rotated gameObjects. I really don't understand why this works this way, because it seems to be very inconsistent to me. It seems that any rotation should act exactly the same since it's the exact same game object that's being rotated, and it's still attached to the rigidBody2d indirectly, including the colliders that are in those same child gameObjects. (The only thing that changed was an extra gameObject root that contains the script and moving the rigidBody2d there.)

    This works for me, but I'm worried that this is a "Bug", and will be "Fixed", thus breaking me again.
     
  28. golonko

    golonko

    Joined:
    Nov 6, 2012
    Posts:
    13
    It seems like the issue is partially fixed now (checked in 4.5.2f1)
    Partially because it seems like only non-trigger colliders have been fixed. And because in the gizmo wireframe of the collider is still rotated.
    The collisions do work as they should. So even though you can't see your collider (as it's visually rotated), the objects will collide as if the collider was not rotated.

    It does not work on triggers (at least when it comes to raycasting a touch point). So if you have a rotated trigger collider, you will not be able to use it as a touch area.

    This behaviour is somewhat acceptable, as i can put the touch areas into a child and only rotate these.

    But still, it is pretty annoying!
     
  29. Yukichu

    Yukichu

    Joined:
    Apr 2, 2013
    Posts:
    420
    Ugh. Half-fixed isn't fixed. Was hoping there would be a toggle somewhere to make everyone happy.
     
  30. Yukichu

    Yukichu

    Joined:
    Apr 2, 2013
    Posts:
    420
    Hoping to bring this to the forefront, as it's still an issue.
     
  31. SpacemanBoots

    SpacemanBoots

    Joined:
    Nov 27, 2012
    Posts:
    32
    That's actually the behavior I'm looking for.


    I can't seem to find anything... Did this make it in or was the other implementation removed?
     
  32. Fubeca

    Fubeca

    Joined:
    Jul 21, 2013
    Posts:
    41
    It's not in there yet. I've been anxiously watching each patch. I think they forgot about this issue.
     
  33. SpacemanBoots

    SpacemanBoots

    Joined:
    Nov 27, 2012
    Posts:
    32
    Well there must be something in the works. Right now it's displaying the collider as if by the 4.5 behavior, but physically interacting in the 4.3.4 way. Which is very confusing to work with when rotation is used. I would call it broken to be honest.

    @MelvMay Could you give us an update on the matter?
     
  34. Fubeca

    Fubeca

    Joined:
    Jul 21, 2013
    Posts:
    41
    Yeah. I've had to scrap my use of all 3d models and just use 2d placeholders until it's fixed. I originally understood that a fix would be coming soon (3 months ago), but I've about given up on that. I'm getting the vibe that it won't be happening at all and that I need to figure out how to convert all the 3d models and their many animations I'm using to 2d. The results I've had on my more important ones so far have been lackluster (I am NOT an artist, thus the reason I've spent a few thousand $ on the asset store for assets). I need a reliable way to do it, and I haven't spent the time to get them consistent yet.

    I was really excited when I found that I could use 3d and 2d in the same scene with an orthographic camera. It didn't even occur to me that it was not something they intended to support, and would get removed in a major point release, until after I'd spent months going down that road. I had not been concerned when I purchased assets whether they were 2d or 3d, and am going to have to deal with that if I want to finish and ship my game some time this year.
     
  35. Yukichu

    Yukichu

    Joined:
    Apr 2, 2013
    Posts:
    420
    *cricket chirp* PM'd MelvMay a few days back, hoping he'd respond. Just some info would be great, even if it's "this is more work than we expected and it's on the back burner, etc" or ... something.
     
  36. matthuston

    matthuston

    Joined:
    Sep 29, 2009
    Posts:
    14
    I am also curious about this change / fix.
     
  37. golonko

    golonko

    Joined:
    Nov 6, 2012
    Posts:
    13
    It is becoming increasingly annoying.
    I just came around on another incarnation of this issue.
    I got animations for my character and was trying to use mecanim for everything, but found out that rigidbody2d attached to an object prevents all rotations around Y axis.
    So if i have a character walking from left to right and wanted to use a turning animation where he was rotating around Y to face left... the system strips all Y rotation components from the animation and the result is far less than satisfying. great job guys!
     
  38. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    11,321
    I've just pushed a change to 4.5.5p1 (not released yet) that corrects rotations for 2D colliders under full 3D transform rotation. Previously, rotating X/Y in combination to Z would cause bad geometry under certain rotations.

    I am also now looking into (read that as trying to get this into the 4.5 patch-release cycle) being able to select whether you want the collider geometry transformed at all. By this I mean all colliders that are comprised of vertice i.e. BoxCollider2D, EdgeCollider2D & PolygonCollider2D. This would effectively mean you can choose whether (say) rotating in the X axis actually rotates the BoxCollider2D geometry or not. If not, they would stay aligned on the X/Y plane.

    Obviously the above change doesn't change the fact that you should avoid rotating physics objects using the transform (performance penalty) but it now does work correctly and is obviously great in-editor.
     
  39. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    11,321
    I'll try my best to get the ability to turn-off this rotation into the same patch release, time allowing.
     
  40. Fubeca

    Fubeca

    Joined:
    Jul 21, 2013
    Posts:
    41
    What's the correct way to rotate them?
     
  41. Pyrian

    Pyrian

    Joined:
    Mar 27, 2014
    Posts:
    301
    In the Z-axis using Physics calls, presumably.
     
  42. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    11,321
    The short answer is to use the MovePosition/MoveRotation methods on Rigidbody2D.

    The longer answer:
    The correct way to rotate a Rigidbody2D is to let it move using its own angular velocity after all, the whole point is to let the simulation actually simulate. That way it can avoid collider overlaps and correct calculate collision responses as well as maintain contacts efficiently. If you want to take direct control and reposition it or set a specific angle by setting the transform, you're interrupting that process and warping it immediately to another position/orientation. The physics system then has to regenerate contacts and attempt to resolve overlaps if you do this.

    The Rigidbody2D has MovePosition and MoveRotation methods (same as 3D Rigidbody) that perform this action but in a way that is compatible with the simulation. It does this by calculating the required velocity to move the object to that position/angle during the next physics update. It does not just reposition/reorientate it as changing the transform does.

    The main thing is to know that without a Rigidbody2D (or Rigidbody) then you assume full control of position/orientation using the Transform component however when you add either of these components, you're effectively saying that you're handing over control of the position/orientation to the Rigidbody component and that you'll change the position/orientation indirectly by going through the Rigidbody and letting it do its stuff. It effectively becomes a proxy to the transform and should be treated that way.

    The exception to this is a kinematic body which is designed to be repositioned like this. A dynamic body however should be left to do its thing.

    Of course, Unity lets you do whatever you like and we're honor bound to maintain contact callbacks (etc) but behind the scenes you're causing more work to happen.

    Hope that helps.
     
  43. Fubeca

    Fubeca

    Joined:
    Jul 21, 2013
    Posts:
    41
    Thank you for the explanation. Good to learn this stuff. I know that somewhere I've made some bad assumptions, and just built on top of them. I'm clearly misusing things, and that's obviously why I'm running into issues. (I still need the way to flip left and right since MoveRotation just makes it move upsidedown, but it's progress.) Is the Unity documentation intended to be read start to finish? I haven't tried it yet, but I've gone through quite a few tutorials and read several books, but those are always very arbitrary and never seem to cover what *I* want to do. For a hobbyist, I've invested a lot of money into Unity Pro and assets (somewhere around 8k at this point), so I'm genuinely interested and invested in learning how this works.

    I'm hoping you can point me in a better direction, or at least have the "O Ho!" moment that you can show me the error of my ways. (And share how bad this customer story is around the water cooler.) Here's an overview of what I'm doing and and why I'm doing it.

    I'm using a bunch of 3d models (that I've purchased in the asset store) in 2d, with an orthographic camera. I'm treating all my 3d stuff as 2d (by using 2d colliders and triggers), but arranging them in Z position the same way all the 2d tutorials do with the 2d sprites to get things to layer correctly. I don't think this part in and of itself is what is causing the issues. My idea was that I'd just put 2d colliders around my 3d objects and everything would be good. Since 2d colliders didn't rotate at the time I came up with this, it was working great. Right after I got all of this working, the update that made them rotate, and broke this, came out.

    Now the part that I think is causing issues. At some point while I was working on this, Unity introduced the feature that made Triggers cascade up the gameobject tree to a script attached to a RigidBody. Prior to that release, I'd put scripts on each of the nodes that needed to pass this information up and didn't even need the rigid body. However, to make that work, I needed the RigidBody. I wasn't actually doing anything in 3d, so I have a RigidBody2d component on the common parent game object node even though it is a 3d model. At the time, I was doing everything with Triggers and didn't really have any Colliders anyways, so I just set the Kinematic option so that I was controlling everything with the gameobject, and it really isn't colliding with anything anyways because it's mostly Triggers.

    So when the update came out that rotated Trigger2d colliders that were attached to the same transform, that's when things broke. I do have a couple of actual colliders (instead of triggers) on the game objects to keep things above my terrain and within the camera area, but it's the triggers that I'm concerned about getting working because those are what I'm using the most (and the colliders are working fine now that I've adapted). Honestly, the triggers are working okay at this point, too, now that I've adapted everything. But I've clearly gone the wrong direction somewhere.

    If it weren't for the darn animations on the 3d models, I'd just switch completely to 2d (which is what I did for some ballistae I had serious issues with after the trigger issue started). And even if I do that, I still want to understand where I went wildly astray, and how I should have done it instead.
     
  44. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    11,321
    If I follow you, there are at least two things that are standing in your way (please correct me if I get this wrong):

    1) Callbacks on Rigidbody2D and not the Collider2D.
    So this isn't the case. Callbacks get sent to the collider and then to the connected rigidbody (if it exists) so you get both but the collider always gets it. From your statement you seem to be indicating that you added a rigidbody only so you could get these callbacks but I'm concerned about your use-case here; a collider without a rigidbody becomes static i.e. it's designed to never be moved and there's a pretty heavy performance penalty for doing so (don't do this). Technically, behind the scenes, when you don't add a rigidbody component, I attach the collider to a common rigid-body set to be static known as the ground-body. All colliders without a rigidbody component get added to this. This saves having to add rigidbody components for all your static colliders (which tend to dominate any scene) therefore make for a better workflow but just as important, it means that Box2D doesn't have to iterate hundreds/thousands of static bodies during integration which (for the most part) it ignores. Finally I'll add that for 2D physics, there's absolutely no difference between a collider that is marked as a trigger or not. Obviously there's a difference between it causing a collision response and the callback we issue but in Box2D you simply set the (fixture) to be a trigger (just a flag) so it's more of a mode of a collider (fixture). My point being that there's no difference specifically in how we handle triggers against how we handle non-triggers. I've seen so many reports saying (say) kinematic triggers don't do this or static non-triggers do this but the reality is that there's no difference (at a core level) in how we handle triggers versus non-triggers. The callbacks are dealt with equally, we just report each under a difference callback name i.e. OnCollider2D or OnTrigger2D.

    2) Colliders being Transformed in both X & Y rotations in addition to Z.
    This was changed as it was a big source of reported 'bugs' i.e. users expected the transformation to take place. As I mentioned above. I'll add an option to turn this off if required. The biggest thing you can encounter with this kind of transformation is that you create a 2D collider that fails Box2Ds checks which are essential either that the total 2D area of the collider becomes too small to create and/or two vertices of the collider are too close (obviously excludes the CircleCollider2D). When vertices are too close, one of them gets removed. If enough get removed and you end up with <3 then the shape cannot be created. A change in 4.5 was for me to add one of two warnings that appear on each collider. The first is to warn that no physics shape was created at all because of the verification process above. The second is that *some* of the physics shapes were not created as can be the case with the PolygonCollider2D that is essentially a compound physics collider (it generates potentially lots of shapes).


    Did I cover what you were raising? Was I off-base? Hopefully not too much techno-blurb.
     
  45. Fubeca

    Fubeca

    Joined:
    Jul 21, 2013
    Posts:
    41
    Thank you for your insights, and I really appreciate the time you're spending to help me get this. I think I follow what you're saying (and will read it a few more times when I get home from work tonight). I have rigidbody2d on all the gameobjects that move (although I think that is only coincidentally, so I really appreciate the additional information), but they have child game objects that also have colliders.

    My current 3d model that I want as my character is now rearranged to work within the current 2d framework, but I'm concerned about the colliders I've added. In order to work within the current 2d framework, my dragon is now arranged this way:

    DragonContainer (Character Controller, RigidBody2d, other scripts, etc)
    -> Dragon (Animator)
    ->->Dragon Mesh
    ->->bones tree for the animator. On some of the bones I have added BoxCollider2D components so that the trigger colliders move with the animation.
    ->->Senses (which has children with sense trigger colliders)

    I re-arranged it this way because I found that if I do any rotation above or on the RigidBody2d level, it rotates all the child colliders. However, if I rotate below that point (and have my 2d colliders added below where I've already done the rotation) then they don't rotate. I'm not sure if this is by design, and that's why I'm anxiously awaiting the flag to turn off the rotation in case that ends up getting changed, too, and then breaks the workaround I've found.

    My new big concern based on what you've just told me is this: are these child BoxCollider2D components that I've put on the bones considered static? Because they're definitely moving. A lot. I think I'd make the collider mistake regardless whether on this or any other project (2d or 3d), so I'm interested in knowing if colliders attached to descendents of an object with a rigidbody are considered static or not. I would think that they wouldn't be static, since from what I'm understanding the rigidbody component basically says "I'm going to be moving", but I just want to confirm.

    For the other things, I need to go through and see where I'm using RigidBody components on things that really should be static. I know I am using it on things that aren't moving and therefore shouldn't have it (based on the insight you have provided) above. I was having issues with things not triggering until I added it, but I'm going to dig in and find out why that's the case.

    Honestly, I think I just need to figure out how to convert the 3d dragon model and the animations I want into 2d. Because a lot of the issues I'm running into are from trying to mix the two. :) My attempts to do something simple like a ballista and catapult have left something to be desired.
     
  46. Pyrian

    Pyrian

    Joined:
    Mar 27, 2014
    Posts:
    301
    I, too, would appreciate knowing the cost and/or best practice of moving a child collider with respect to its parent Rigidbody2D, such as with an animation. Is that expensive? Is there a better way to do it (e.g. using separate Rigidbody2D's and joints)?
     
  47. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    11,321
    I'll give you the extended response here because there's a lot going on behind the scenes that we have to do to fit-in with the behaviour that's expected by Unity. When I refer to this I'm specifically referring to the component set-up and the transform hierarchy that existed before 2D physics did. This isn't always the best to how Box2D wants to work either!

    > My new big concern based on what you've just told me is this: are these child BoxCollider2D components that I've put on the bones considered static?
    No, from your hierarchy description they wouldn't. Here's what happens; when a collider is added it checks to see if a rigidbody component exists on the same game-object or on any of the parent game-objects in the hierarchy. This is the behaviour inherited from 3D physics. If a rigid-body does exist then the first one it discovers as it searches 'up' the transform hierarchy will be the one it connects to and from then on it lives in the 'space' of that rigid-body i.e. when the rigid-body moves, it moves with it at no cost. If one doesn't exist then the collider is static and is (behind the scenes) connected to the hidden static ground-body that lives at the world origin (0,0).

    Obviously it's the rigid-body itself that is set to be either dynamic or kinematic therefore any attached colliders are effectively known as dynamic/kinematic but in reality, it's the rigid-body that is but because the colliders are attached to it, they become one and the same with the rigid-body controlling position/orientation and the colliders controlling behaviour i.e. collision-detection.

    A dynamic rigid-body means that it controls the transform dynamically as it reacts to physics collisions and you should not reposition the rigid-body by changing transforms if you can avoid it. Kinematic is designed so that you can reposition it at a much lower penalty.

    Hope your with me so far. :)

    So let's lalk about rotation. There are two areas we're interested in; rigid-body and colliders. For rigid-body, when we rotate in Z we simply update the rigid-body position. We shouldn't really set the Z rotation because (if you think about it) we're transporting the Z from one position to another instantly (star trek transporter again) and this is again problematic because it can cause overlaps (penetration of colliders). If we rotate in X/Y then the rigid-body ignores it because it's a 2D rigid-body and has no concept of rotation in X/Y.

    Colliders however are a whole difference story! In real performance terms, repositioning the rigid-body doesn't actually 'move' the colliders because they live in the local-space of the rigid-body. What this means that a collider that lives in the local space at say (10,5) (let's assume this is the center of a circle-collider but could equally be a vertex on a box collider) is +10 on the world X and +5 on the world Y from wherever the rigid-body is positioned and when Z rotation is zero. When you rotate the rigid-body in Z, the collider doesn't actually move because again it lives in the Z rotation space of the rigid-body so assuming the Z is now 90-deg then the +10 on the local X becomes +10 on the world Y and the +5 on the local Y becomes -5 on the world X.

    When you rotate the transform in X/Y on a game-object that has a collider then we are in a difficult situation because, in the end, they are 2D colliders under a 3D transformation. So why don't we just ignore this? The main reason is that it is expected that colliders follow where other 3D objects are positioned i.e. if you have a 3D box then it is expected that the 2D collider at least stays centered where it is. Secondly, as has been shown by the sheer number of bug reports on the matter, that it is expected that the collider is transformed by the rotation in X/Y so that it tracks things that also rotate in 3D such as 2D sprites!

    But Box2D rigid-body and colliders don't have any concept of 3D transformations so what gives?

    This brings me nicely to Box2D and how we have to do things we'd rather not do (read that: performance penalties we have to pay because of the 'limitations' of Box2D).

    When we rotate in X/Y for a 2D collider, we have to transform the vertex-based geometry itself (circle-collider is excluded from this as it has no vertice). This means we then have to regenerate the Box2D fixture (collision shape). We have to do this because Box2D does not allow the alteration of the geometry on an existing fixture (collision shape). This is a performance penalty we have to pay. It's also a PITA because Box2D will then automatically delete contacts related to that collider so we have to jump through many hoops maintaining these contacts so that when we have regenerated the collision shape we connect-up the newly generated contacts.

    Note that when I say that the collider lives in the local-space of the rigid-body, this is easy to understand when the collider is on the same game-object as the rigid-body however when the collider is on a child or anywhere further 'down' the hierarchy then we have to transform the geometry appropriately as there are (potentially) a lot of transforms between the two. If any of those transforms change then again, the child collider or, and here's the pain, *any* child colliders need to be recalculated! Oh yes, don't touch transforms where you've got lots of 2D colliders spread across a deep hierarchy. For simpler colliders it isn't so bad really but if you use the polygon-collider which is a compound collider in the sense that it can create a potentially unlimited number of Box2D collision shapes then imagine having to regenerate all that geometry each time the transform changes!

    Note that this also applies to other aspects of the transform. If you change the scale (at all) then we have to recalculate the geometry which forces us to regenerate the collision shape in Box2D.

    The very nature and flexibility of Unity in its component-based approach means that the integration of a 2D physics system into a 3D system creates behaviour we have to implement but has a cost penalty.

    Box2D has been developed so that you set something up and from then on, for the most part, it's immutable. This includes collider (fixture) geometry and many other things related to the rigid-body and joints. Unity is written so that things are exposed as components which have lots of nice mutable properties; flexible but at odds.

    Some summary points:

    If you set-up a rigid-body/collider hierarchy and leave it running, only moving/rotating using the rigid-body MovePosition/MoveRotation and/or modifying the linear/angular velocity of the rigid-body then you'll get great performance.

    If you want to position the rigid-body itself using the transform then you should set it to be kinematic; don't leave it as dynamic.

    If you want to modify the collider positions/orientations then you're going to pay a penalty whatever you do as they are designed to live at a fixed 2D offset in the 2D local-space of the rigid-body they originally attached to. Colliders should only move because the rigid-body moved!! Remember, there is no such thing as a kinematic collider only a kinematic rigid-body. Saying a kinematic collider is like calling you a blue person because you're sitting in a blue car although to be fair, it's an understandable notion.

    If you never want a collider to move then make sure it lives in a game-object where there's no rigid-body and there's no rigid-body in any of its parents. If you reparent it and there's a rigid-body there then it will attach to that and no longer be static.

    Whatever you do, don't ever, ever think about repositioning/rotating a static collider.

    All of the above you *can* do because flexibility is the name of the Unity game however you can get stung. Also, some of these operations are *required* when you're editing. For instance you do want to move static colliders when you're designing your level and the editor simply does what you can do in your game i.e. move a static collider but of course, you shouldn't be doing that if possible!

    ---

    So I woke up early and wrote this while drinking my morning coffee so I kind of rambled on and on. Hopefully you can pick-out useful stuff from this and please feel free to ask if you need me to elaborate on anything specific,

    Hope this helps.
     
    Last edited: Oct 9, 2014
    hippocoder likes this.
  48. Fubeca

    Fubeca

    Joined:
    Jul 21, 2013
    Posts:
    41
    Thank you very much for the clarifications, and for spending the time to explain this. It helps immensely. I'm a bit surprised that I managed to follow all of it, too - although parts required re-reading a few times :). I now appreciate why the change was made, and it explains why I see what appeared to me to be weird behavior but really isn't. I'm a business programmer, so this whole "physics in my program" thing is pretty weird. :)

    I'm going to go revisit my whole project. I am doing some transform position changes manually that I need to figure out how to accommodate correctly, but thankfully there aren't very many of those. (I did see the performance drop significantly and tried to find other ways to deal with what I wanted to have happen.) The sad thing is that I've used MovePosition and MoveRotation in my 3d learning projects, and completely forgot about it when I started on this 2d project from scratch.

    Thanks again!
     
  49. Pyrian

    Pyrian

    Joined:
    Mar 27, 2014
    Posts:
    301
    So, what's the best practice if I want to animate a physic's objects colliders? No scaling or X/Y rotations; each collider remains the same, they're just moving in 2D with respect to their parent. Should I just bite the performance bullet and animate them with mechanim? Or should I make each component a separate Rigidbody2D with immobile joints (hinge joint with fixed angle, maybe?), and animate/move the anchor points?
     
  50. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    11,321
    @Pyrian: Not sure if I follow. Best practice in achieving what? If you mean what gives best performance then it's don't animate the transform if you've got physics components on a game-object and the same applies to the 2d physics component properties but if you need to (say) scale the object in your game then you obviously need to animate scale thus will take the performance hit. Just being aware of what it is doing should empower you. I'm certainly not trying to suggest you shouldn't do it, just don't do it if you don't need to.

    Joints are the same, if you animate the anchor points, then the joint needs to be recreated.

    Recreating joints have less of a performance hit then recreating a collider, more so as you compare a joint to say the PolygonCollider2D but if you're using joints to constrain position and you're constantly moving the joint anchor, note that it doesn't instantly move to that position but does so with a force that works over time.

    In the end, a majority of the properties of objects in the Box2D physics SDK were not mean to be animated; mainly for performance reasons but it's Unity so we are forced to allowed it.