当前位置:   article > 正文

Unity 观察者模式(实例详解)

Unity 观察者模式(实例详解)

简介

Unity中实现观察者模式,我们可以创建一个Subject(目标/主题)类,它负责维护订阅者列表,并且当其状态改变时通知所有观察者。下面通过5个代码示例来详细展示如何在Unity C#脚本中应用观察者模式:

示例1 - 简单的文本更新通知

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

// 观察者接口
public interface IObserver
{
    void OnUpdate(string message);
}

// 被观察者接口
public interface IObservable
{
    void Register(IObserver observer);
    void Remove(IObserver observer);
    void NotifyObservers(string message);
}

// 具体的被观察者类
public class TextDisplay : MonoBehaviour, IObservable
{
    private List<IObserver> observers = new List<IObserver>();

    public void Register(IObserver observer)
    {
        observers.Add(observer);
    }

    public void Remove(IObserver observer)
    {
        observers.Remove(observer);
    }

    public void NotifyObservers(string message)
    {
        foreach (var observer in observers)
        {
            observer.OnUpdate(message);
        }
    }

    // 模拟状态改变
    public void UpdateText(string newText)
    {
        Debug.Log("Text has been updated to: " + newText);
        NotifyObservers(newText);
    }
}

// 具体的观察者类
public class ConsoleLogger : MonoBehaviour, IObserver
{
    public void OnUpdate(string message)
    {
        Debug.Log("Console Logger received update: " + message);
    }
}

// 使用示例
public class GameManager : MonoBehaviour
{
    public TextDisplay display;
    public ConsoleLogger logger;

    void Start()
    {
        display.Register(logger);
        display.UpdateText("Hello, World!");
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69

示例2 - 多观察者监听游戏分数变化

public interface IScoreObserver : IObserver
{
    void OnScoreChanged(int newScore);
}

public class ScoreManager : MonoBehaviour, IObservable
{
    private List<IScoreObserver> scoreObservers = new List<IScoreObserver>();

    public void Register(IScoreObserver observer)
    {
        scoreObservers.Add(observer);
    }

    public void Remove(IScoreObserver observer)
    {
        scoreObservers.Remove(observer);
    }

    public void NotifyScoreObservers(int newScore)
    {
        foreach (var observer in scoreObservers)
        {
            observer.OnScoreChanged(newScore);
        }
    }

    public void IncreaseScore(int points)
    {
        int currentScore = GetTotalScore(); // 假设这是一个获取当前分数的方法
        int newScore = currentScore + points;
        SetTotalScore(newScore); // 假设这是一个设置总分数的方法
        NotifyScoreObservers(newScore);
    }
}

public class ScoreUI : MonoBehaviour, IScoreObserver
{
    public void OnScoreChanged(int newScore)
    {
        GetComponent<Text>().text = "Score: " + newScore;
    }
}

public class HighScoreTracker : MonoBehaviour, IScoreObserver
{
    public void OnScoreChanged(int newScore)
    {
        if (newScore > PlayerPrefs.GetInt("HighScore"))
        {
            PlayerPrefs.SetInt("HighScore", newScore);
        }
    }
}

// 使用示例
public class GameInitializer : MonoBehaviour
{
    public ScoreManager scoreManager;
    public ScoreUI scoreUI;
    public HighScoreTracker highScoreTracker;

    void Start()
    {
        scoreManager.Register(scoreUI);
        scoreManager.Register(highScoreTracker);
        // 游戏过程中调用scoreManager.IncreaseScore()增加分数
    }
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70

示例3 - 事件系统实现观察者模式

using UnityEngine.Events;

public class SubjectWithEvent : MonoBehaviour
{
    public UnityEvent<string> OnTextUpdated;

    public void UpdateText(string newText)
    {
        Debug.Log("Text has been updated to: " + newText);
        OnTextUpdated.Invoke(newText);
    }
}

public class ObserverUsingEvent : MonoBehaviour
{
    public SubjectWithEvent subject;

    void Start()
    {
        subject.OnTextUpdated.AddListener(OnTextUpdatedHandler);
    }

    void OnDestroy()
    {
        subject.OnTextUpdated.RemoveListener(OnTextUpdatedHandler);
    }

    void OnTextUpdatedHandler(string message)
    {
        Debug.Log("Received text update: " + message);
    }
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33

示例4 - 泛型观察者和可序列化的事件系统

[System.Serializable]
public class GenericEvent<T> : UnityEvent<T>
{
}

public class ObservableGeneric<T> : MonoBehaviour
{
    public GenericEvent<T> OnStateChanged;

    public T State { get; private set; }

    public void ChangeState(T newState)
    {
        State = newState;
        OnStateChanged?.Invoke(newState);
    }
}

public class ObserverForGeneric<T> : MonoBehaviour
{
    public ObservableGeneric<T> observable;

    public void Awake()
    {
        observable.OnStateChanged.AddListener(StateChangedHandler);
    }

    public void OnDestroy()
    {
        observable.OnStateChanged.RemoveListener(StateChangedHandler);
    }

    void StateChangedHandler(T newState)
    {
        Debug.Log($"New state received: {newState}");
    }
}

// 使用示例
public class ExampleUsage : MonoBehaviour
{
    public ObservableGeneric<int> healthObservable;
    public ObserverForGeneric<int> healthObserver;

    void Start()
    {
        healthObserver.observable = healthObservable;
    }
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50

示例5 - 使用C#委托简化版

public class SimpleObservable
{
    public delegate void MessageEventHandler(string message);

    public event MessageEventHandler OnMessageEvent;

    public void SendMessage(string message)
    {
        OnMessageEvent?.Invoke(message);
    }
}

public class SimpleObserver : MonoBehaviour
{
    public SimpleObservable observable;

    void Start()
    {
        observable.OnMessageEvent += HandleMessageEvent;
    }

    void OnDestroy()
    {
        observable.OnMessageEvent -= HandleMessageEvent;
    }

    void HandleMessageEvent(string message)
    {
        Debug.Log("Received message: " + message);
    }
}

// 使用示例
public class SimpleExample : MonoBehaviour
{
    public SimpleObservable messageSource;
    public SimpleObserver messageRecipient;

    void Start()
    {
        messageRecipient.observable = messageSource;
        messageSource.SendMessage("Hello from the Observable");
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44

以上每个示例都展示了观察者模式的基本原理:当被观察者的状态发生改变时,它会通知所有已注册的观察者进行相应的响应或更新操作。

python推荐学习汇总连接:
50个开发必备的Python经典脚本(1-10)

50个开发必备的Python经典脚本(11-20)

50个开发必备的Python经典脚本(21-30)

50个开发必备的Python经典脚本(31-40)

50个开发必备的Python经典脚本(41-50)
————————————————

​最后我们放松一下眼睛
在这里插入图片描述

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/不正经/article/detail/92745
推荐阅读
相关标签
  

闽ICP备14008679号