Hey, cheers for reading. I’ve got two questions, one leading on from the other:
Question One) Do you know of an elegant way to declare object instance data without using constructors? Unity doesn’t like constructors. If you have five enemies for example, and you want to set their stats individually (Name, speed, power etc.), with constructors you’d simply declare them as arguments. In Unity, the inspector allows you to do this with pre-existing objects, to bypass the constructor arguments approach, but it’s not clean. Why? Because some variables that control the behavior of the object should not be public!
Question Two) Why does the inspector only allow the editing of public members by default? I realize that it is to do with serialization, and the fact that the serializer only serializes public members unless explicitly told otherwise, but why approach it like this? Why is the inspector tied into serialization? I’m assuming its entirely to do with the technical problems involved, which is fair enough, but it would be nice.
The reason it is a problem is because the scope of my member variables has nothing to do with how I want to declare them. Another example: I have a float that should be hidden, that denotes how often the object should spawn. It is only ever used by other scripts inside an accessor function, which uses it inside an equation. With the Inspector, whenever I look at the class, I see this variable that shouldn’t be there!
Cheers for the help, question one is more important to me. Curious to see how you structure your code.
Question One:
Unity recommends not using the Constructor when your object / class is inheriting from Monobehaviour. Reason being is that your de-serialized data may be overwritten, and it may be overwritten in a very unpredictable way, leading to very odd behavior that is going to be hard to debug and track down. Awake() and Start() were made to replace the constructor, and the best place that you could initialize your values is going to be Awake(), as in relevance it is the closest to the constructor call in terms of call ordering.
I still use the constructor plenty in classes that have absolutely no need to inherit from Monobehavior, and I have no problems whatsoever. You may also want to consider looking into ScriptableObjects, as they are used for objects that do not need to inherit from Monobehavior, but can also be serialized by Unity without extra work from you.
Question Two:
In terms of design, I don’t see why they wouldn’t make any other choice than what is currently implemented in Unity. Being able to edit non public variables in the inspector from an architecture stand point for a software engineer is very poor. If you’re needing to edit non-public variables in a visual IDE way, then you’re doing something wrong in terms of your design. Even so, if you have public variables that need to be visible by other classes when being instantiated, you can simply set the System.nonserializable flag above the public member so Unity doesn’t serialize it and messes up your initialized values through code.
In terms of seeing what you need to, and not seeing what you don’t, I personally think everything works out fine in Unity as long as you know certain attribute flags to use when appropriate, as well as knowing the Unity way of structuring your code and when to do what with what Unity provides, such as the ScriptableObject feature.
During development, it’s also simple as going to the upper right corner of the inspector winder and changing it’s status to Debug instead of Normal to see all the variables that you can’t normally, makes life simple. From a design standpoint, the inspector really is there in terms for a software engineer to DEBUG. I typically will only design my public variables to be there for use by Designers, not mainly myself.
And in terms of structuring code, you’ll have to be a little more specific. Do you mean design patterns?