A Unity ID allows you to buy and/or subscribe to Unity products and services, shop in the Asset Store and participate
in the Unity community.
Calling all New Unity users! Join the Halloween Mods Showcase Challenge until October 31.
Discussion in 'Physics' started by Alan-Liu, Jan 20, 2017.
Should I make sure a rigidbody is on same GameObject or parent?
I don't think so.. anybody?
The question doesn't make sense really.
A Collider that's non-static but doesn't have a Rigidbody means that it's on a child GameObject and is implicitly attaching to a Rigidbody on a parent GameObject. That doesn't have a cost, nor did it ever.
The only thing that changed in 3D physics is moving a Static Collider i.e. a Collider that doesn't have a Rigidbody to attach to change to be far less expensive in 5.5.
Is it still slower than moving a non-static collider?
Sorry but your questions are too vague. I am even presuming you mean 3D physics and not 2D physics. How do you 'move' the collider? Do you set the Transform or using Rigidbody(2D).MovePosition? Why is this even an issue for you? Are you seeing some problem?
If you want to move a collider yourself instead of the physics system doing so and it to not respond to forces then add a Kinematic Rigidbody (IsKinematic=true). If you want the physics system to move it and it to respond to forces then use a Dynamic Rigidbody (IsKinematic=false). If you don't want the physics system to move it and you're not moving it and it not to respond to forces then use a Static Rigidbody (for 3D physics you just don't add a Rigidbody, in 2D you can explicitly set the bodyType).
It's not an issue, I'm just asking out of curiosity and I only had one question.
The profiler used to issue a warning, if I moved a gameobject (by setting the transform.position directly) that had a collider (I'm talking about 3D physics, which I thought was clear, since I quoted you talking about 3D physics), without a kinematic rigid body.
And since this was a thing that a lot of developers did (by mistake, or simply not knowing better), I believe this case was optimized (at least, that's what I remember reading on a Unity blogpost, please correct me if I'm wrong).
So to be more specific:
Is doing GameObject.transform.position = new Vector3(a,b,c); (assume a,b,c are random values) faster on a gameobject that has a collider and a rigidbody set to kinematic, or on a gameobject that just has a collider (at which point, I believe the collider is considered to be "static")?
From this blogpost: https://blogs.unity3d.com/2014/07/08/high-performance-physics-in-unity-5/
Which makes me think that moving a static collider and a rigidbody-less collider is now the same thing, which certainly wasn't the case in Unity 4. Is it? Or are there still differences?
I'm a 2D physics dev not a 3D one so I'm not sure on the exact improvement made. From what I understand, the overhead has been completely removed or the difference is negligible so they should be the same but it's a really easy thing to test with the profiler surely?
I will add finally that I see this kind of thing being asked all the time as if adding a Kinematic Rigidbody is something to be avoided or bad to do if you're explicitly moving a collider. It's what it is designed for. I think it stems from the (in my opinion) bad decision early on in Unity to allow not adding a Rigidbody to implicitly mean Static. Note this isn't some dig at you at all, just my observation that this implicit action raises needless question on what is a good way of doing things because yeah, less is better (not adding a component).
There have been tests, they were kinda inconclusive (but it seems they are now roughly in the same ballpark in terms of performance)
I'm adding rigidbodies when I intend to move colliders, so it's not an issue for me personally. It's a bit weird workflow though (which you seem to agree on).
The thing is, on the forums, there was a big push to educate people on this issue, since a lot of people did it wrong (in the Unity 4 era).
Then there was the blog post I posted above, which led people to believe, that for Unity 5, kinematic rigidbody or not, it's the same thing now, at least performance wise.
But then the manual ( https://docs.unity3d.com/Manual/CollidersOverview.html ) says
Which is the opposite. But then again, as a lot of things in the manual, it could just be very outdated.
So you can probably see why people are a bit confused as what the "best practice" is.
And to confuse things even further, it seems moving colliders without rigidbodies is actually much faster according to a quick test I just did.
Yeah, so, moving 1000 box colliders takes about 2.8ms, and if I attach a Kinematic Rigidbody on the parent object (or to all cubes individually, it makes no difference it seems), it needs around 27ms.
So maybe I'm doing something wrong, or the manual is flat out wrong, or there's a bug?
At this point, it's better to speak to a 3D physics dev such as Anthony Yakolev (@yant).
Can I have a look at your particular project with 2.8ms / 27ms difference?
In general, one is advised to have a RB on all the physics objects that are moved from scripts as otherwise some parts of the world might not get updated properly (example: a ball sleeping on a static box won't always be awaken if you remove the static box; a performance optimisation in the physics engine).
As for your earlier questions, we've had moving of static objects sped up significantly in Unity 5.0 https://blogs.unity3d.com/2014/07/08/high-performance-physics-in-unity-5/ that's why the performance warning was removed.
I submitted a bug report (as a documentation bug, since I really don't know if it's an actual bug, or if the docs are simply outdated). I had a repro scene attached with it. It's case 873057.
From the tests I've made, it seems like moving non-rigidbody colliders is now the fastest thing. It's faster than moving kinematic rigidbody colliders or non-kinematic rigidbody colliders.
This surprised me because it was kind of a well-known Unity thing that everytime you had to move colliders, it was better if they had rigidbodies, but apparently this isn't true anymore
@yant Any update on this?
Which is fine, btw. Having to add a rigidbody just to mark a collider as "non-static" was always kinda weird.
So it's good that it was changed. The thing is we don't know how exactly it was changed and the manual saying the complete opposite of what is happening isn't helping.
I'm not sure there's an actual bug here, the thing needed could be a complete rewrite of that section in the manual.
@AcidArrow What Unity version do you've used with your test?
I've tested it myself with 1000 moving cubes and got the same result (kinematic rigidbodies are slower) @ Unity 5.4.
I'm moving thousands of trigger colliders every frame ( using their transform )
I've had a kinematic rigidbody attached to every trigger, but I've tried removing it and the performance changed significantly ( from about 15 fps to 40 fps )
The player ( with a rigidbody ) is still able to collide with the triggers without any issues.
I wanted to know if this might introduce bugs or if some collisions might not be detected ?
maybe it can helps https://forum.unity.com/threads/2d-...overhead-if-they-have-animated-parent.635962/
@larex39 Thanks, but I think I have the opposite issue
removing the kinematic rigidbodies really enhances performance
Right now i'm just concerned of getting weird physics behavior since unity recommends adding rigidbodies to any trigger collider that moves
i found it is always bad idea to move coliders by their transforms, so instead of removing the kinematic rigid bodyes try to move them by rigidbody.movePosition and you should have better performance
Considering they are all triggers i think its fine. @slake_it
I also thought so but that is not true, if you are moving triggers you are moving coliders that means the physics is always involved, and they behave like static rigid bodyes without collision
look at this thread:
I was also moving lot of triggers and i thought there should be no physics involved, but there always is, but you can make it faster, as i wrote at the end of the thread
Let's not mix 2D and 3D physics, they are obviously completely difference systems. The "lower cost of moving static colliders" was a 3D physics (physx) thing and doesn't relate to 2D physics (Box2D) at all so let's talk about one or the other.
So for 2D physics only....
It makes zero difference if it's a trigger or not, just ignore that as it just controls if contacts are calculated during the simulation step.
Don't move colliders that are not attached to a Rigidbody2D as this causes (amongst other stuff) their geometry to be recalculated. Collider geometry lives in Rigidbody2D space so without one, the collider geometry is implicitly attached to the static ground-body that lives at the world origin so the collider "local space" geometry is actually also "world space" geometry therefore moving the collider causes this geometry to be recalculated.
Simple rule: Never, ever, ever move colliders. Always move bodies. This also includes moving the relative position of a collider to its body.
If you absolutely want a static collider to move (why? it's static! Use kinematic) then add a Rigidbody2D and set the body-type to static and move that. Zero collider recreation/recalculation in this case. You can even rotate that static body.
The title of "non-static-colliders-without-rigidbody-still-costs-in-unity" makes no sense.
Hope that helps.
Cool, I wish things were as clear for 3D physics as well.
To use Unity EventSystem with Sprites, as far I know, I need to attach colliders to Sprites in order to receive events like OnDrag, OnDrop, etc...
So, let's say I want to drag and drop Sprites. Then I need to add a 2D collider to get events. And I will move them (they are moving while dragging), so, do I need to add a Rigidbody although I don't need physics?
@MelvMay Thank you for the thorough breakdown. In my 2D game, I don't use a single RigidBody, but I do use BoxColliders/PolyColliders/etc. I then use Physics queries like RayCasts/CircleCast/etc, to detect collisions.
Because I don't have a single RigidBody in my scene, would I still see a performance benefit from adding Kinematic RigidBodies to all my moving objects with colliders?
See Point#2 above. Never do that for the reasons I stated.
Read MelvMay's answers for 2D physics.
For 3D physics it's an unknown, because after multiple threads, bug reports and repro cases, it's impossible to get a clear answer for Unity's 3d Physics.
The manual still says the same things, many years later, which to the best of my understanding, are 100% false.
From unity 5 its false, afaik.
Static colliders are very optimized and doesnt require rigidvodies.
A big difference between 3D (PhysX) and (2D) Box2D is that for 3D there's a transform between the body and the shapes (colliders) to allow for pose/scaling whereas in Box2D there isn't. All shapes (colliders) live directly in body-space so moving the collider relative to the body requires recalculations but in 2D you can add a Rigidbody2D set to static to stop this issue so it's a non-issue in 2D. But if you're going to move it then set it to Kinematic because yeah, not static.
"The manual still says the same things, many years later, which to the best of my understanding, are 100% false."
There is a bug in our tracking system about updating that manual page which claims moving static colliders in 3D will incur a high perf cost. It won't any longer, since Unity 5.0. This is currently assigned to the docs team.
How long has that been there? I remember reporting this ages ago.
In the meantime, could you please give a breakdown of what we should do in common use cases in 3D physics?
When should we use a kinematic Rigidbody?
Should we ever deliberately move a collider which does not have a Rigidbody attached?
Bonus question, since @MelvMay answered an equivalent for 2D:
Should articulated children of Rigidbodies have a Rigidbody and joint of their own?
1) when you want to make a dynamic object static for a little while (assuming*)
2) yes, since Unity 5 its a proper thing to do
3) i think it depends on what your trying to do
Well, sure, I also think I know what the answers to those things are. However, my answers are all based on what the documentation says and speculation / informal personal testing after we were told it had changed.
Some confirmation and detail would be great.