Let's say, that we have the following components:
Direction, which contains direction the object moves:
public class Direction : MonoBehaviour
{
[SerializeField]
private float angle = 0.0f;
public float Angle
{
get
{
return angle;
}
set
{
angle = value;
}
}
}
DirectionVisualizer, which visualizes this direction in form of a sphere:
[RequireComponent(typeof(Direction))]
public class DirectionVisualization : MonoBehaviour
{
private const float Radius = 2.0f;
private GameObject sphere;
private void PositionSphere()
{
Direction direction = GetComponent<Direction>();
float angle = direction.Angle;
Vector3 position = transform.position + new Vector3(
Radius * Mathf.Sin(angle * Mathf.PI / 180.0f),
0.0f,
Radius * Mathf.Cos(angle * Mathf.PI / 180.0f));
sphere.transform.position = position;
}
// Use this for initialization
void Start () {
sphere = GameObject.CreatePrimitive(PrimitiveType.Sphere);
sphere.transform.localScale = new Vector3(1.0f, 1.0f, 1.0f);
PositionSphere();
}
// Update is called once per frame
void Update () {
}
}
The relation above represents simplified model I'm having in my game - a component is used to visualize a set of parameters contained in other component(s).
Now I'd like the sphere to be automatically positioned basing on the angle field in Direction component without explicitly notifying DirectionVisualization, like:
var direction = someObj.GetComponent<Direction>();
direction.Angle = 25; // DirectionVisualization reacts automatically here
The simplest solution is to position sphere frame by frame, but I know, that Angle will change very infrequently and such solution would have dramatic impact on performance (in my game this visualization is a lot more complex).
I might do that by merging Direction and DirectionVisualization classes, such that I can handle Angle property setter, but that's a very ugly solution directly against SRR principle. So it's a no-go.
Other solution would be to create an event in Direction component and subscribe to it from within the DirectionVisualization component. But that raises following concerns:
- If
DirectionVisualizationis destroyed, the event handler will keep it alive (I should probably detach the event handler whenDirectionVisualizationis destroyed?) - When
DirectionVisualizationis added to object, it should subscribe toDirection's event - What should happen if DirectionVisualization is added to object, which does not (yet) have Direction component? Is there a way to detect adding Direction component, such that DirectionVisualization might subscribe to the event?
- What happens if
Directioncomponent is destroyed? How DirectionVisualization should behave? Is there way to detect it?
Is there a better way to handle notifications between components than one I proposed?