If you think up a situation where you can’t see a solution without bidirectional reference, I’ll be probably able to make it singular directional reference.
For example, in GUI, a button invokes a function on some object. However, said object has no need to know what invoked that function. Thus, there’s no need for the object to hold a “back reference” to the button. A lot of function work this way.
The other thing to keep in mind is that you don’t need to establish all reference at design time. For example, if you’re making a car, it could look like it is sensible to assign references to Wheels at design time, BUT, instead of doing that you can simply make Car look for Wheels when it is activated and assign roles automatically.
One practical example, where you might THINK that you need back reference is a GUI where buttons are being enabled/disabled. Because in this case it might make sense to have one button disable another, and so on. In this case, you can do this:
- Make a class akin to OptionMenuGUIManager, and make it root.
- Make a state machine Enum corresponding to each page of GUI.
- Make some sort of “OptionMenuPage” class which would have indicate in which state of menu it will be activated, set it for relevant elements, and assign this component as option menu panel
- Upon startup of OptionMenuGUIManager, find all OptionMenuPage components and store them in a list, dictionary or anythign else. When option menu state changes, have OptionMenuGUIManager enable/disable relevant components.
In this case, each button will only need to know reference to OptionMenuGUIManager.
But. Even that reference is not necessary. Because you can find OptionMenuGUIManager at runtime using GetComponentInParent funciton.
So, there’s no real need to specify any connection by dragging components in this case, and all relationships can be established automatically.
Basically, in simpler terms, if you have a Car with Wheels attached to it, you might think that it is a good idea to store reference to Wheels in a Car, and references to Car in a Wheel. But those references can be found automacially.
Car can find its Wheels using GetComponentsInChildren, and Wheels can find their car using GetComponentInParent.
This can be done within Awake/OnEnable then said values can be cached, and it won’t be necessary to call those functions repeatedly.
Obviously you should be using templated version of those funcitons…