设计模式
观察者模式:
点击查看代码
// 采用观察者模式实现,降低系统间耦合度
public static class EventHandle
{
// 事件定义(被观察者)
public static event Action<InventoryLocation, List<InventoryItem>> UpdateInventoryUI;
// 触发通知方法
public static void CallUpdateInventoryUI(InventoryLocation location, List<InventoryItem> list)
{
// ?. 操作符确保即使没有订阅者也不会引发异常
UpdateInventoryUI?.Invoke(location, list);
}
// 另一个事件示例
public static event Action<int, Vector3> InstantiateItemInScene;
public static void CallInstantiateItemInScene(int ID, Vector3 pos)
{
InstantiateItemInScene?.Invoke(ID, pos);
}
}
// 在InventoryUI.cs中订阅事件
private void OnEnable()
{
EventHandle.UpdateInventoryUI += OnUpdateInventoryUI; // 注册库存更新事件
}
private void OnDisable()
{
EventHandle.UpdateInventoryUI -= OnUpdateInventoryUI; // 取消注册库存更新事件
}
// 事件处理方法
private void OnUpdateInventoryUI(InventoryLocation location, List<InventoryItem> list)
{
// 处理UI更新逻辑
}
// 在InventoryManager.cs中触发事件
EventHandle.CallUpdateInventoryUI(InventoryLocation.Player, playerBag.itemList);
观察者模式的最大优势是实现了模块间的松耦合,比如在项目中,ItemManager和InventoryUI通过EventHandle通信,而不需要直接引用对方,这使得代码更加模块化和可维护。
点击查看代码
// 通用单例模式基类,确保一个类只有一个实例
// T: 继承该类的具体类型
public class Singleton<T> : MonoBehaviour
where T : Singleton<T>
{
// 静态实例,用于全局访问
private static T instance;
// 公共访问器,获取单例实例
public static T Instance
{
get => instance;
}
// 在对象初始化时确保只有一个实例存在
protected virtual void Awake()
{
// 如果已经存在实例,销毁当前对象
if (instance != null)
Destroy(gameObject);
else
// 否则将当前对象设为实例
instance = (T)this;
}
// 当对象被销毁时清理实例引用
protected virtual void OnDestroy()
{
// 在销毁时清理该对象相关的所有 tween
DOTween.Kill(this);
if (instance == this)
instance = null;
}
}
/// <summary>
/// 库存管理系统(单例模式)
/// 功能:
/// 1. 管理游戏内所有物品数据
/// 2. 提供物品信息的查询接口
/// 3. 处理物品的添加/移除逻辑
/// </summary>
public class InventoryManager : Singleton<InventoryManager>
{
[Header("物品数据")]
public ItemDataList_SO ItemDataList_SO;
[Header("背包数据")]
public InventoryBag_SO playerBag;
// 方法实现...
}
单例模式的使用示例
在代码中,您可以通过Instance静态属性访问单例实例,例如:
// 在SlotUI.cs中
InventoryManager.Instance.SwapItem(slotIndex, targetIndex);
// 在其他地方可以获取物品信息
var itemDetails = InventoryManager.Instance.GetItemDetails(itemID);
单例模式在游戏开发中的优势:
全局访问点:提供一个全局唯一的访问点,无需传递引用
状态共享:确保系统中只有一个状态实例,避免数据不一致
延迟初始化:资源可以在首次使用时才被创建
减少内存占用:避免创建多个相同功能的对象
在您的项目中,单例模式主要应用于需要全局访问的管理类,如库存管理系统,这是Unity游戏开发中的常见做法,特别适合那些在整个游戏生命周期中需要维护状态的系统。
Unity 的 SceneManager 类提供了方法来加载和卸载场景。可以使用 SceneManager.LoadScene 方法来切换场景,并在需要时管理对象的生命周期。
点击查看代码
public class SceneLoader : MonoBehaviour
{
public void LoadNewScene(string sceneName)
{
SceneManager.LoadScene(sceneName);
}
}
ScriptableObject 是一种轻量级的对象,可以在多个场景中共享数据。它们不会在场景切换时被销毁,适合存储游戏设置、配置或状态。
点击查看代码
[CreateAssetMenu(fileName = "GameSettings", menuName = "ScriptableObjects/GameSettings")]
public class GameSettings : ScriptableObject
{
public int playerHealth;
public float gameSpeed;
}
使用事件系统可以在不同的对象之间传递信息,而不需要直接引用。这样可以减少对象之间的耦合,便于管理对象的生命周期。
点击查看代码
public class EventManager : MonoBehaviour
{
public delegate void GameEvent();
public static event GameEvent OnGameStart;
public void StartGame()
{
OnGameStart?.Invoke();
}
}
对象池是一种设计模式,用于管理对象的创建和销毁,特别是在需要频繁创建和销毁对象的情况下(如子弹、敌人等)。通过重用对象,可以提高性能。
点击查看代码
public class ObjectPool : MonoBehaviour
{
public GameObject prefab;
private Queue<GameObject> pool = new Queue<GameObject>();
public GameObject GetObject()
{
if (pool.Count > 0)
{
return pool.Dequeue();
}
else
{
return Instantiate(prefab);
}
}
public void ReturnObject(GameObject obj)
{
obj.SetActive(false);
pool.Enqueue(obj);
}
}
使用状态模式可以管理游戏对象的不同状态,特别是在需要在不同状态之间切换时(如角色的行走、跳跃、攻击状态)。
点击查看代码
public interface IState
{
void Enter();
void Execute();
void Exit();
}
public class WalkingState : IState
{
public void Enter() { /* 进入行走状态 */ }
public void Execute() { /* 执行行走逻辑 */ }
public void Exit() { /* 退出行走状态 */ }
}
点击查看代码
namespace ZJHServer
{
// 定义可执行的无参数、无返回值的委托类型
// 用于向Execute方法传递要执行的代码块
public delegate void ExecuteDelegate();
// 线程安全的单例执行器
// 用于确保在多线程环境下,指定的代码块在任意时刻只被一个线程执行
// 结合了单例模式和线程同步机制,防止并发操作引起的数据竞争
public class SingleExecute
{
private static object ob = new object(); // 用于单例模式的线程锁对象
private static SingleExecute instance = null; // 单例实例,使用懒加载模式
// 单例访问器,使用双锁检测模式确保线程安全
// 所有线程将共享同一个SingleExecute实例
public static SingleExecute Instance
{
get
{
lock (ob) // 外部锁:确保线程安全
{
if (instance == null)
{
instance = new SingleExecute();
}
return instance;
}
}
}
private object objLock = new object(); // 用于Execute方法的互斥锁
private Mutex mutex = null; // 互斥量对象,提供更强的线程同步机制
// 构造函数,初始化互斥量
// 私有构造函数确保只能通过Instance属性创建实例
public SingleExecute()
{
mutex = new Mutex(); // 创建未命名的互斥量
}
// 线程安全地执行传入的委托方法
// 使用两层锁机制确保任意时刻只有一个线程在执行委托
//
// 应用场景:
// 1. 数据库操作等共享资源访问
// 2. 需要顺序执行且不允许并行的业务逻辑
// 3. 防止多线程导致的数据不一致问题
//
// 参数 executeDelegate: 要执行的委托方法
public void Execute(ExecuteDelegate executeDelegate)
{
lock (objLock) // 第一层锁:确保单线程进入
{
try
{
mutex.WaitOne(); // 第二层锁:等待互斥量
executeDelegate(); // 执行委托方法(临界区代码)
}
finally
{
mutex.ReleaseMutex(); // 确保释放互斥量,防止死锁
}
}
}
}
}

浙公网安备 33010602011771号