I’m building a simple strategy game and stumble on multiple problems with communication between components. So i have “Unit” object, “Camera” object and UI. The idea is that when you click on Unit, camera moves to its position and UI displays some text. My approach:
public class Unit : MB
{
public event Action OnSelected;
public void Select()
{
OnSelected?.Invoke(this);
}
}
Unit invokes delegate and passes self, so camera and UI can use its public fields
public class Camera : MB
{
private void OnEnable()
{
foreach (Unit unit in FindObjectsOfType<Unit>())
unit.OnSelected += MoveTo;
}
public void MoveTo(Unit unit) { // some code }
}
First problem comes from Camera. In order to subscribe i must search entire scene for all Units and then subscribe. But i can’t subscribe for new ones. In order to battle this i must implement some sort of spawner mechanics. But my code gets convoluted quickly and it still uses FindObjectsOfType<>. Something like this:
And i need two more methods to unsubscribe. Feels like too much for problem like this, and i need to write almost exactly the same code for UI component. Is there some sort of pattern that i don’t know of?
Second problem is that i want to reuse “MoveTo” camera method and pass Vector3 as its parameter. I can subscribe using lambda expression:
Regarding the second problem, you need a reference to the method you want to remove from the event. You’re creating a new method using the lambda expression that wraps around your MoveTo method. It either needs to be stored in a variable for later use or you should just make an ordinary method that will contain a call to MoveTo. I would make a method called OnUnitSelected or something like that.
Regarding the first problem, I can offer two solutions.
Simple solution
Make a static version of OnSelected event for the units. That could be used to catch the moment when any of the active units are selected.