Observer Design Pattern with Game Objects

I am trying to implement the Observer Design Pattern with game objects but I am not sure how to go about doing so. I’ve seen a lot of information on the Observer Design Pattern, but nothing that really relates to Unity or game development.

So basically what I am trying to do is have a game object as the subject, and have the other game objects/observers change color every 20 seconds based on a notification from the subject. How would I go about doing this? How can I get one game object to communicate with other game objects?

For starters, I have something like this, but I’m not sure if I am headed in the right direction with it:

public interface INotification
{
    void AddObjects(IObjects obj);
    void RemoveObjects(IObjects obj);
    void NotifyObjects(Color color);
}

public interface IObjects
{
    void ColorReceived(Color color);
}

This one isn’t finished:

public class SetObjects : INotification

    List<IObjects> lst = new List<IObjects>();

{
    public void AddObjects()
    {

    }

    public void RemoveObjects()
    {

    }

    public void NotifyObjects()
    {

    }

}

use c# events or unity events. it is based on observer design pattern

1 Like

As Gohan Said, Events is practically the Observer Pattern.

However just for academics sake. lets try and make one. When I think of the Observer Pattern I like to think of it as a newspaper route. With a publisher and a group of subscribers. And to help with future-proofing the pattern, instead of passing in a specific data type (like Color) I would create a custom data struct that would pass data to the subscribers (similar to how the container class PointerEventData holds all possible data that all Pointer handlers use). So if you make a specific subscriber that wants some special data the container struct can be expanded and the publisher can generate the new data, all without breaking all the other subscibers.

public struct SubscriptionData
{
  IPublisher publisher; //in case the subscriber might be following multiple publishers 
  Color retrivedColor;

  string newData; // some new data added later in the project
}

public interface IPublisher
{
   void Subscribe(ISubscriber subscriber);
   void UnSubscribe(ISubscriber subscriber);
}

public interface ISubscriber
{
  void Notify(SubscriptionData data);
}

then making a publisher should be pretty straightforward

public class Broadcaster : IPublisher
{
    // this data will be managed internally in various private functions
    SubscriptionData data;

    List<ISubscriber> subscribers = new List<ISubscriber>();



    public void Subscribe(ISubscriber subscriber)
    {
        if(subscribers.Contains(subscriber)
        {
            return;
        }

        subscribers.Add(subscriber);
    }



    public void UnSubscribe(ISubscriber subscriber)
    {
        if(!subscribers.Contains(subscriber)
        {
            return;
        }

        subscribers.Remove(subscriber);
    }



    //notice this is private. its not exposed to the interface since no external class
    // should be calling it
    private void NotifySubscribers()
    {

        for(int i=0; i<subscribers.Length;)
        {
            ISubscriber current = subscribers[i];

           

            if(current  == null || ReferenceEquals(current ,null) || current.Equals(null))
            {
                subscribers.Remove(subscriber);
            }
            else
            {
                current.Notify(data);
                i++;
            }
           
        }
    }



    //add all your other functions that would update the class's
    // internal state (i.e. the SubscriptionData struct)
}

The Observer pattern can have memleaks, since a subscriber could be disposed without unsubscribing. However you can take steps to automatically release these leaks, as I do in the NotifySuscribers. However this is lazy deallocation (potentials leak aren’t cleared until they are attempted to be accessed).

You could attempt more aggressive deallocation, but you’ll quickly find that those usually cause more headaches down the road than they solve. The best and proper way to handle this is to ensure that the subscribers properly unsubscribe themselves.

anywho, this should be plenty to get the gist of making an Observer pattern

Wow, thanks Joshua. It is starting to become clear to me now. One thing that I am unclear of, though, is how this works with game objects. Do I declare them in the script(s) to get them to work with it, or would I have to drag and drop with the list in the editor somehow? Thanks again.

There’s a number of ways you can pull it off. All depending on how coupled you want your code to be with the Broadcaster, however concretely accessing the Broadcaster class sort of defeats the purpose of the interface.

I just made a new thread, Code Design: Abstracting Singletons, where I used Extension Methods plus interfaces to keep my singletons decoupled from the rest of the project. give it a read, and you could see that you could make the Broadcaster implement a ISubSingleton interface (as defined in my thread) and allow your game objects to access the broadcaster instance only through the IPublisher interface

1 Like