文章目录
- 简介
- 示例1 - 简单的文本更新通知
- 示例2 - 多观察者监听游戏分数变化
- 示例3 - 事件系统实现观察者模式
- 示例4 - 泛型观察者和可序列化的事件系统
- 示例5 - 使用C#委托简化版
简介
在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!");
}
}
示例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()增加分数
}
}
示例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);
}
}
示例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;
}
}
示例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");
}
}
以上每个示例都展示了观察者模式的基本原理:当被观察者的状态发生改变时,它会通知所有已注册的观察者进行相应的响应或更新操作。
python推荐学习汇总连接:
50个开发必备的Python经典脚本(1-10)
50个开发必备的Python经典脚本(11-20)
50个开发必备的Python经典脚本(21-30)
50个开发必备的Python经典脚本(31-40)
50个开发必备的Python经典脚本(41-50)
————————————————
最后我们放松一下眼睛