when is a Constructor needed?
When you want to assign variables and do things at the creation during âconstructionâ.
The easy answer is always. Though if you donât specify an empty constructor the compiler will add one automatically.
As for when to specify one explicitly. That depends on what you need from the class. If it is an object that needs access to other objects in order to function youâd normally instantiate them in the constructor, or require a reference to be added via constructor parameters.
Basically it works the same as the Awake function in Unity, where youâd normally also register those references needed for the MonoBehaviour to function. Remember though, that a constructor can not be used in a MonoBehaviour.
Sure it can. The problem is that constructors on UnityEngine Objects are run during editor-time, then can have effects that carry over when you hit the play button. There are very rare cases where you will want to use a constructor on a UnityEngine.Object.
Iâll disagree and also point out that you didnât actually mention what those cases are. ![]()
The big issue is that if you define a constructor that takes arguments then you also have to define a parameterless constructor so serialization continues to work. These constructors are called numerous times throughout the lifecycle of the editor, the biggest one being during code compiles. I ran into this issue when I absentmindedly put a call to the Steamworks API in the parameterless constructor of an object I had marked as serializable (mind you- not even a UnityEngine object derivative) and the editor vomited and died as soon as I did a code compile.
Your point is especially untrue in the case of MonoBehaviour specifically because MonoBehaviours are useless if not attached to a GameObject in a scene; so creating one via a constructor literally does nothing for you and can cause you a boatload of headaches. Thereâs a reason the editor spits warnings at you when you try to do it and that the API provides no mechanism to attach an already existing MonoBehaviour instance to a GameObject ![]()
True, about the parameterless constructorâŚIâd already made such a habit of parameterless constructors for serialization that I wasnât even imagining a case where somebody would try to put a constructor with parameters on a UnityEngine Object. You wouldnât create one by calling a constructor directly, but when a ScriptableObject or MonoBehaviour is instantiated, the constructor is called. This means that in rare cases, there are circumstances where using constructors on a UnityEngine Object is desirable.
I already mentioned the undesirable effects re: the editor and constructors. If you use them with that in mind, you can avoid the effects. Constructors arenât really intended to be used for heavy lifting, so you always need to be careful with your external calls anyway with them.
Argue all you want, but the fact of the matter is that I successfully use constructors on UnityEngine Objects, on a regular basis, with mindful use of them for certain things. For example, using a constructor to set a default value in a case where setting that value from a field initializer isnât possible (say, the initialization value isnât available at compile-time, like trying to initialize to Vector3.zero from a field initializer). You said that you canât use them on MonoBehaviours, and that is factually untrue, because I do use them.
Show me a valid use case. With code. Your vector example doesnât make sense to me because a vector with a default value is essentially Vector3.zero and zero is just a shortcut to new Vector3(0, 0, 0) anyway - which you could do in a field initializer. Thatâs also not anything you couldnât do in Awake.
Also note that Iâm not saying you canât - Iâm saying you shouldnât.
I gave you a valid case. Pay me, and Iâll write code to teach you. The vector example specifically may not make sense as a use case, but the actual statement that sometimes you want to initialize to a value not available at compile-time is true.
Sorry, got you confused with the person I responded to initially, you did in fact say you shouldnât. If you want to maintain that you âshouldâ never use constructors on serialized objects, thatâs your opinion and youâre welcome to it.
âŚor maybe donât be a condescending jerk?
And the reason this canât be done in Awake is?
Sorry, but you literally ordered me to write code for you, and the only person that can do that is somebody who is paying me for my time. I will try to be less of a condescending jerk about saying no next time.
This conversation has gotten messy, Iâm out. Youâve got my input, take it or leave it.
Who would have thought that youâd want to engage in a technical discussion when youâre voluntarily spending time on a programming forum. I asked you to back up your argument with an actual code example and you requested to be paid to prove your own pointâŚcool story.
In summation - donât use constructors on MonoBehaviours; youâre opening yourself up to a bunch of hurt with no notable gains.
If youâre rolling your own classes (inheriting from System.Object) then go crazy. @Boz0r has the right of it
Is certainly a valid opinion some people would have on the matter.
A great counter-opinion would include a concrete example where initialization could not occur in Awake and had to occur in a constructor. ![]()
A case where you need to have an object subscribe to an event when itâs made, while it is disabled, would be one. And then you shoot holes in it, and we debate about that, and this goes on. You have your opinion, youâre welcome to it, and Iâve validated it. I have mine, and itâs interesting that rather than accepting that there may be scenarios youâre unaware of where my opinion is valid, you will insult me and argue with me all day.
Somebody categorically stated that you can not use constructors on UnityEngine Objects, and I stated that you can, and now youâve moved the argument into âshouldâ territory. Should territory is not based entirely on fact, and may vary from programmer to programmer. I have had situations where I have decided to use constructors on MonoBehaviours, and they have worked well with me. You may have made a different choice, and that is fine. I donât have to work with you, I donât particularly care about your practices, and the only reason I continued this thread is because I hate to see somebody telling newbies that their opinion is fact.
How did I insult you? Itâs entirely possible that there are scenarios I havenât thought of - youâre just not adequately explaining what those scenarios actually are.
You mentioned a scenario involving defaulting a Vector3 field
To which I said that a Vector3 defaults to a zeroâd vector anyway and there was no reason you couldnât do that in Awake. And you acknowledged that when you replied with
SoâŚok weâre still at the point where we donât have a use case for doing initialization from a MonoBehaviour derived constructor.
Now you mention this
Which seems like it might genuinely be interesting but you didnât provide enough implementation information. Are you saying that you need to have a MonoBehaviour subscribe to an event when itâs added to a GameObject that is disabled? Iâm curious about why you would have disabled behaviours executing event based code when theyâre disabled (maybe to auto-magically turn themselves on?) and what effects that event subscription has during serialization in the editor. Also - how is the MonoBehaviour gathering the event it needs to subscribe to?
Um, when you called me a condescending jerk back there after demanding that I write code for you?
Iâm seriously not here to hold your hand through this. If you think itâs an interesting possible use-case, write a prototype and try it out. Iâm happy to throw out breadcrumbs, but I get paid for this stuff. If you like writing code for free to prove a point to strangers who are technically your competition, have fun getting brain-raped by your competition. I didnât respond to this thread for your benefit. Iâm out.
I get paid for it too so calm it down Biff.
I guess that just boils down a drastic different in point of view. I see that big title at the top that says Community and take that as the people who are here are genuinely interested in helping others, learning new things, and imparting knowledge based on their own experiences. Much of that involves discussions of a technical nature, something I guess you donât want to take part in because you see the members here as your competition (which really begs the question as to why youâre here in the first place). Iâd be keen to continue the conversation as I am interested in what youâre doing (and what everyone else here is doing) but if youâre afraid Iâm going to steal your free code and use it to âbrain rapeâ you then I guess Iâll stop beating a dead horse. Have a nice day man.
other thing to consider the question was asked in the context of someone just learning. Itâs easier to just say using constructors on a MB is not the best idea. Than have the OP try to use them on a MB before knowing the implications of it.
Guidelines and rules can help people learn, they just have to also learn that there is a time and place to sometimes break said rules.
Excellent points. If youâre advocating the usage of an anti-pattern then the impetus is on you to adequately explain when itâs practical to do so. In addition to the MSDN link provided earlier hereâs a snippet from the documentation on MonoBehaviour.Awake for anyone who comes across this thread later
https://docs.unity3d.com/ScriptReference/MonoBehaviour.Awake.html