I’d like to get some input from you on a common practice in Unity.
This being wiring things up in the Editor. When I first started using Unity I thought it was quite empowering the way we can easily drag n drop references from one component to another.
However, in the back of my mind I had this nagging thought that I was doing something I really shouldn’t be doing… basically hard-wiring dependencies. The only difference is I was doing it visually instead of programmatically.
I think we all know that too much of this kind of thing causes problems down the road.
I think the visual nature of the process makes it so many people don’t consider it the same as if they were hard-wiring inside their code. Kind of the same way many people use the common pattern of setting up a Delegate / EventHandler in code and then use the .SomeEventSubscriptionMethod += SendEventNotificationsToThisMethod pattern thinking they are actually making their code more loosely coupled when in reality this is not loosely coupled. How can it be? This pattern has one class explicitly registering itself to an Event on another class and to do that it must first have a reference to the other class. There is some flexibility in the pattern in that multiple classes can register and receive the notifications but that is another story. The proper way to decouple it IMO is to just create a completely separate EventManager class and have all publishers and subscribers use that one class. Now there is a single explicit connection used by all other classes. Of course, in Unity I suppose the SendMessage may be ideal for decoupling.
Anyway, I digress…
Let’s use a basic example of setting a camera to follow a player. Making the camera a child of the player works. But that is too simple so let’s say the camera is following a pinball. Can’t simply be a child because the camera would roll as the ball rolls.
There are always a number of different ways to do things and there are alternatives to wiring things up in the Editor.
One way would be to simply use GameObject.Find(“Player”).GetComponent in a Camera script to automatically find and set the reference of the player’s transform.
Another (kind of insane) way would be for the Camera script to have a public method that accepts a transform and in a script on the player have it locate the camera, get a reference to the attached camera script and then call the method to pass over the player’s transform. The camera script receives the transform and stores it.
The Unity messaging system could be used in the same way to allow a player script to send its transform over to the Camera.
A custom Notification Class could be used to do the same thing.
And so forth. Many different ways. With pros and cons to each. For Unity I think a good way is probably the first approach described above… simply make use of the Find() method in a camera script. However, it is obviously not completely decoupled. There is a dependency. A requirement. Simply changing the name of the GameObject from Player to Hero would cause the code to fail and the reference would not be set. Same for passing to a camera where the camera name has changed.
So, in this case relying on some kind of Messaging / Notification system OR simply wiring it up in the Editor actually are the more robust solutions. The issue I see with hard-wiring up references in the Editor is it can turn a project into a mess of spaghetti where you end up looking around… “where in hell is this set up?!” Is it in the code? Is it in the Editor? This is particularly a pain point when dealing with projects someone else created such as Assets from the store.
Reason for all of this is that I plan on very slowly getting back into Unity and focusing on each thing like this one at a time to find a best pattern before going forward. I already did that a lot previously but I will revisit and evaluate the options just to be sure.
So this all leads me to my question…
How do the rest of you feel about such things… do you just wire up references in the Editor not giving it a second thought or do you strive to decouple things more by using code to set up these references such as using some kind of Messaging system or possibly even a single class containing all of the Editor hard-wired references?