#Constructors

when is a Constructor needed?

Constructors (C# Programming Guide)

2 Likes

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.

1 Like

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. :slight_smile:

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 :slight_smile:

1 Like

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

1 Like

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. :slight_smile:

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.

3 Likes

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.

2 Likes

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