Wzorzec projektowy Observer w Unity

Poniżej przykład prostej implementacji wzorca Obserwatora na podstawie Youtubera, który wrzuca nowy film i subskrybenta, który dostaje powiadomienie po wrzuceniu filmu.
W tym przykładzie, informacja poleci w świat po kliknięciu LMB.
W skrypcie Youtubera tworzymy taki event i jednocześnie sprawdzamy później czy ktokolwiek go nasłuchuje, ponieważ jeśli nikt nie będzie nasłuchiwał to nie ma sensu wysyłać komunikatu 😉
W skrypcie Subskrybenta subskrybujemy do tego eventu w metodzie OnEnable(), ale trzeba pamiętać by też odsubskrybować, gdy dany obiekt znika ze sceny i robimy to w metodzie OnDisable().

// Youtuber

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Youtuber : MonoBehaviour
{
    public static event Action NewVideo;

    private void Update()
    {
        if (Input.GetMouseButtonDown(1))
        {
            if (NewVideo != null)
            {
                NewVideo();
            }
            // Instrukcja poniżej zastępuje 4 powyższe więc warto jej użyć ;)
            //NewVideo?.Invoke();
        }
    }
}
// Subscriber

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Subscriber : MonoBehaviour
{
    private void OnEnable()
    {
        Youtuber.NewVideo += OpenYoutube;
    }

    private void OnDisable()
    {
        Youtuber.NewVideo -= OpenYoutube;   
    }

    void OpenYoutube()
    {
        Debug.Log("ok, let's watch a new movie");
    }

}

A teraz przykład w którym stworzymy powiadomienia z parametrem, aby zobaczyć do której playlisty został dodany nowy film.
Po kliknięciu LMB wyślemy informację, że wpadł film o Unity, a po kliknięciu RMB film o Blenderze.

// Youtuber

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Youtuber : MonoBehaviour
{
    public static event Action<string> NewVideo;

    private void Update()
    {
        if (Input.GetMouseButtonDown(0))
        {
            NewVideo?.Invoke("Unity");
        }
        else if (Input.GetMouseButtonDown(1))
        {
            NewVideo?.Invoke("Blender");
        }
    }
}
//Subscriber

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Subscriber : MonoBehaviour
{
    private void OnEnable()
    {
        Youtuber.NewVideo += OpenYoutube;
    }

    private void OnDisable()
    {
        Youtuber.NewVideo -= OpenYoutube;   
    }

    void OpenYoutube(string playlista)
    {
        Debug.Log($"Let's watch a new movie to learn more about {playlista}");
    }
}

Przykład wyświetlenia panelu z przyciskiem do otworzenia nowego filmu po otrzymaniu eventa

using System;
using UnityEngine;

public class Youtuber : MonoBehaviour
{
    public static event Action<string> NewVideo;

    void Update()
    {
        if (Input.GetMouseButtonDown(1))
        {
            NewVideo?.Invoke("https://www.youtube.com/watch?v=_f6gdsncpdY");
        }
    }
}
using UnityEngine;
using UnityEngine.UI;

public class Subscriber : MonoBehaviour
{
    [SerializeField] GameObject NewVideoPanel;
    [SerializeField] Button linkButton;

    private void OnEnable()
    {
        Youtuber.NewVideo += OnNewVideo;
    }

    private void OnDisable()
    {
        Youtuber.NewVideo -= OnNewVideo;
    }

    void OnNewVideo(string link)
    {
        linkButton.onClick.AddListener(()=> Application.OpenURL(link));
        NewVideoPanel.SetActive(true);
    }

    public void ClosePanel()
    {
        NewVideoPanel.SetActive(false);
    }
}
Scroll to Top