- Home /
is there a monobehaviour method guaranteed to get called before I can call getter / setters for custom properties?
Basically, I have a script that goes along the lines of:
public class EdgeCasting : MonoBehaviour {
private LineRenderer edgeRenderer;
private Vector3 _edgeOrigin;
private bool nextNodeCreationInProgress = false;
public Vector3 edgeOrigin {
get {
return _edgeOrigin;
}
set {
_edgeOrigin = value;
edgeRenderer.SetPosition(0, _edgeOrigin);
}
}
void Start() {
edgeRenderer = transform.Find("Edge").GetComponent();
}
...
I noticed that if (from another object) I instantiate the prefab to which this script is attached and then try to set the edgeOrigin property, like so:
newEdge = (EdgeCasting)((GameObject)Instantiate(Resources.Load("Edge"), transform.position, Quaternion.identity)).GetComponent<EdgeCasting>();
newEdge.edgeOrigin = transform.position;
newEdge's edgeRenderer is not yet initialized / assigned by the time I try to set it indirectly thru the edgeOrigin property. I assumed Start() was a sort of monobehaviour "constructor" if you will and so it was guaranteed to be called before one was able to manipulate a script instance. I guess I was wrong. So, is there any way to make sure any private members are initialized before being able to start accessing properties in the script / class? I mean other than making the renderer a public property and manually assigning it before using edgeOrigin.
If your LineRenderer is part of your prefab, you can make your edgeRenderer variable public (or add the SerializeField attribute) and link the LineRenderer in the inspector. That way the variable is set automatically when the object is Instantiated.
Answer by whydoidoit · Apr 23, 2013 at 07:24 AM
You need to use Awake() as if it were a parameterless constructor.
Note that Awake does not run on Prefabs until they are instantiated, but you can call functions on your scripts on Prefabs (a generally bad idea unless you have some specific purpose in mind).
right, my guess was that Awake or Start would be "sort of" constructors.However, you say that Awake() does not get called on prefabs but at least through Resources.Instantiate() both Awake() and Start() are being called for each instantiation. Still, like my question states, if I instantiate and try to set the edgeOrigin property, the renderer is still null.. Like, my call to the accessor seems to happen immediately before Awake() and Start(). If after the first Update() I try to re-access or set the property, then the renderer is already set.
Awake is called before the Instantiate method returns. Start is called the next frame before Update. So Awake is called before you have the chance to access your properties unless you access them from the class constructor itself...
@Bunny83 yes I just tested this out myself, If in my above code I move the initialization of the renderer from Start() to Awake() it does work just fine. Now, why did @whydoidoit say Awake() is not run on prefabs? Like I said, it DOES run on a prefab instantiated through Instantiate()
Don't mixup Prafabs with instances of Prefabs ;)
This is like a picture of a car can't drive, a real car can ;)
Yeah I mean that a prefab (not an instance) appears to be a real "thing" - you can set variables on it and call methods - but it is not really alive - it's not connected to real Unity objects. You can use this to preinitialize a prefab before instantiating it (and then the prefabs Awake call would have any variables you'd set available as it ran).
Your answer
Follow this Question
Related Questions
The name 'Joystick' does not denote a valid type ('not found') 2 Answers
Distribute terrain in zones 3 Answers
Multiple Cars not working 1 Answer
Player lives script help 1 Answer