For example, always calling “transform.position” as opposed to “Vector3 pos = transform.position” then calling pos.
Which is more efficient?
For example, always calling “transform.position” as opposed to “Vector3 pos = transform.position” then calling pos.
Which is more efficient?
In the .net world, the unwritten rule (actually it may be written - I just don’t know where) is that accessing a property or field (transform.position) is trivial, so you don’t need to cache the result. Accessing a method (anything with parenthesis after it, something like transform.GetChild(0)) might have performance implications and could warrant caching locally if you have to use the result multiple times.
Of course, the compiler doesn’t enforce this, so it’s trivially easy to violate this rule. I’ve seen it in bad production code where an expensive database call is executed in the getter of a property. Assuming that the Unity team didn’t do anything silly like that, I usually go with the rule of thumb:
If it’s a property or field, don’t cache. If it’s a method result, cache (if using multiple times).
Sometimes I’ll cache a property or field if it’s two or three fields/properties deep (object.propA.fieldB) just to save on some typing, though.
Though I would recommend to cache anything that requires GetComponent
Unity did do something silly. .transform, .rigidbody, .camera, and all of those other helper properties are really hiding a call to GetComponent. GetComponent is not cheap. So grabbing the individual values is trivial, but grabbing the components itself can be expensive. If you need the same component multiple times a frame then cache the reference.
The hope is that this will be fixed in Unity 5.
In the case of transform, GetComponent is only used on the first call to the property when the backing field is null - which makes sense because a GameObject can’t exist without a Transform whereas it could gain or lose other components throughout its lifecycle.
Are you sure? If this is the case then go ahead and used .transform. My understanding was this was planned, but not yet introduced. I could be totally wrong.
Pretty sure.
That being said - someone did do a benchmark sometime ago and found that accessing a cached reference to transform was faster than hitting the property directly. So if you’re using it a lot then, for the time being, it seems to make sense to still cache it. (We do)
Well, all the helper properties are eliminated (except for transform), so yes I guess that’s “fixed”.
And yes manually caching transform is still faster, last I checked. It’s really only a concern if you access it a lot though (and “a lot” means way more than just a few times per frame).
–Eric
I’m actually kinda glad they are removed in 5 since I can just cache my own that way, and not have to worry about my name clashing with the transform provided by the monobehaviouer
The ‘transform’ property is staying around, its only all the other ones that are leaving.
For sure removing them was the right move, since it was always seemingly random which components got shortcuts and which didn’t. It also seemed to make people unclear on how Unity actually works, but if you have to use GetComponent for everything except Transform, then that should help clarify the component architecture.
–Eric
Ya well even with transform things are a little different now anyways since we got 2 different kinds of transform now.
That’s a good point actually. I wonder how Unity guarantees that GetComponent doesn’t return a RectTransform accidentally.
Well they are 2 different types, from what I seen you have to explicty getcomponent the RectTransform. Just using go.transform won’t get it.
It’s OOP. A RectTransform is a Transform.
I think the main benefit of removing them was reducing dependencies inside the engine. It allows smaller builds for platforms where this really matters, like webGL. If you don’t use anything from the physics engine, the physics engine won’t be added to your build.
Not necessarily. Because a RectTransform is a Transform and therefore fulfills the generic type check.
What I said seems silly in retrospect. I didn’t realize the two components were mutually exclusive. (I haven’t used the new UI yet).
That being said - does the transform property give you back the RectTransform for GameObjects that have it?
This gets you the RectTransform. The RectTransform inherits from Transform. Its basic OOP and polymorphism
RectTransform myRectTransform = (RectTransform)transform;
Yeah - I know how inheritance works ![]()
I was asking if this is how the property actually behaved because it’s not explicitly documented as such. And oddly enough, the documentation caveats with “or null if none is attached” which is actually impossible…
And to take it even one step further. Since Transform implements IEnumerable consider:
foreach (Transform t in transform)
{
// could t be a RectTransform?
}
Subsequently - does it have any impact on Transform.GetChild()?
Valid points. My exploration so far indicates that it works exactly as the inheritance structure would lead you to believe. GetChild, enumeration and so forth will all return Transfroms for both Transforms and RectTransforms. You can treat these a Transforms without any issues, or cast them to RectTransforms.
4.6 does suffer from significant lack of effort on the documentation side.