- Home /
Unity getter properties
Hello, Community! I'm reading this article: http://docs.unity3d.com/Manual/MobileOptimisation.html There is such phrase: "FindObjectsOfType (and Unity getter properties in general)" in this manual.
I can't understand what is Unity getter properties? May be anybody exactly knows? Thanks in advance.
Answer by MartinCA · Mar 12, 2015 at 11:16 PM
Getters and setters are a general name for methods which handle getting and setting (bet you didn't expect that!) values from and to fields.
In C#, getters and setters are implemented as a syntactic feature, which allows you to abstract the field.
i.e. all of the following are functionally identical.
// A
public string name { get; set; }
// B
public string name { get { return _name; } set { _name = value }
private string _name;
// C
private string _name
public string GetName(){ return _name; }
public void SetName( string name ){ _name = name; }
Also, if you're using Visual Studio or MonoDevelop, properties (fields accessed using getters and setters) are usually denoted with a special icon which is neither a variable nor a method.
What this means basically is that it's easy to mistake a function call for an assignment - consider this:
myobject.age = 15
Is this an assignment operation? a method call? it can be either, depending on wether age is a variable or a property.
Going back to the context of Unity, what this means is that some of the getters defined in the Unity API are basically wrappers for more expensive lookup methods. MonoBehavior.rigidbody, .transform, .camera, etc all basically wrap a GetComponent() call and are not cached values.
So basically, what this means is that if you have this piece of code:
void Update()
{
rigidbody.AddForce( force );
}
You're basically calling GetComponent() on every update, since rigidbody is a getter which returns the result of GetComponent. Those lookups are more expensive than simply storing a reference, hence the manual suggests you should be aware of such scenarios.
The best thing to do is to cache a reference to components you need to look up often - however, it's important to keep in mind that if you do store your own references you need to be aware of their lifecycle and validity.
an example for such pitfall:
private Rigidbody m_cachedRigidbody
void Awake()
{
// Let's assume there's no rigidbody attached on awake
m_cachedRigidbody = GetComponent< Rigidbody >()
}
void Start()
{
AddComponent< Rigidbody >();
}
void Update()
{
// This is valid since at the time the lookup is executed a Rigidbody component exists
rigidbody.AddForce( force );
// This will throw a null reference exception, since there was no rigidbody attached when we stored the result of GetComponent< Rigidbody >() so m_cachedRigidbody is actually null
m_cachedRigidbody.AddForce( force );
}
How do you think, this getters are such more expensive than GetComponent()? It seems only a few redundant operations.
The issue here is not that getters are more expensive than GetComponent, because getters ARE essentially calls to GetComponent.
It's that GetComponent is more expensive that accessing a stored field.
Accessing a field has a time complexity of O(1), whereas usually the best case of search methods has a time complexity of O(n) - this depends on the implementation of the search algorithm.
Additionally, method calls add a small overhead.
Essentially, the best practice would be to store the results of GetComponent calls you use often and access the cached value. Also, I believe in Unity5 those convenience getters were removed altogether (atleast I recall that being the discussion).
Basically, what you'd want to do is this:
private Rigidbody m_rigidbody;
void Awake()
{
m_rigidbody = GetComponent< Rigidbody >()
}
void Update()
{
// Since we're modifying the rigidbody often, it's best to use a cached value.
m_rigidbody.AddForce( f );
}
One super important thing to keep in $$anonymous$$d though, is that all of these are micro optimizations. $$anonymous$$ost likely you will not even be able to see the impact of these changes. If you're working on optimizing a game, it's best to put your effort into optimizing the rendering performance since 99% of the time that's the bottleneck.
Answer by NoseKills · Mar 12, 2015 at 10:46 PM
I believe it basically means all methods in Unity that get a list of objects or an object from the scene by name/type/tag/component etc. where the only way to find those objects is to (internally, hidden from the user) loop through a set of objects/components and check if they meet the given criteria.
This would include especially such as GameObject.FindGameObjectsWithTag
, Object.FindObjectsOfType
and GameObject.Find
and to certain extent GameObject.GetComponent
and Transform.Find
.
Of course the structure of you objects/scne also affect this