赞
踩
保证一个类只有一个实例,且具有全局访问点,一般用作管理器,下面是用静态变量实现的单例
- /// <summary>
- /// 单例基类
- /// </summary>
-
- //<summary>:这个标签是用于代码文档生成工具的,通常在编写代码时会用来描述代码的功能、用途等。在这里,它说明下面的代码是一个单例基类。
-
- public class Singleton<T> where T : new()
- {
- static T instance;
-
- public static T Instance
- {
- get
- {
- if (instance == null)
- {
- instance = new T();
- }
- return instance;
- }
-
- }
- }
解释代码:
public class Singleton<T> where T : new()
:这是一个泛型类定义,命名为 Singleton,其中 T 是一个类型参数。where T : new()
这部分表示 T 必须有一个无参数的公共构造函数,因为在后面的代码中会使用 new T()
来创建 T 类型的实例。泛型就是不知道具体是什么类型,就用T占位字符先表示,所以之后的代码逻辑,不管什么类型的参数,都执行相同的代码逻辑
static T instance;
:这是一个静态字段,用来保存单例实例。因为它是静态的,所以所有使用该类的实例将共享这个字段。
public static T Instance { get { ... } }
:这是一个静态属性,用来获取单例实例。通过这个属性可以访问单例对象。
get
:这是属性的访问器,用来获取属性值。在这个访问器中,如果实例还没有被创建,它会通过 new T()
来创建一个新的实例,并将其赋值给 instance
,然后返回该实例。如果实例已经存在,它直接返回已有的实例。
这样设计的好处是,无论使用何种类型,只需要继承这个泛型基类,就可以轻松地创建对应类型的单例。
其他类转换为单例,ShopMgr是商店管理器,继承Singleton就转换为单例
- class ShopMgr : Singleton<ShopMgr>
- {
- //具体逻辑
- }
观察者模式定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新,主要用于解耦代码
这里使用一个简单的事件管理器来演示逻辑
- using System.Collections;
- using System.Collections.Generic;
- using UnityEngine;
-
- public class EventManager : Singleton<EventManager>
- {
- public delegate void EventCallBack(object param);// 事件回调函数
- // 事件字典
- Dictionary<int, List<EventCallBack>> mDictEvent = new Dictionary<int, List<EventCallBack>>();
-
- /// <summary>
- /// 添加事件监听
- /// </summary>
- public void AddEvent(int eventId, EventCallBack callBack)
- {
- if(!mDictEvent.ContainsKey(eventId))
- {
- mDictEvent.Add(eventId,new List<EventCallBack>());
- }
- if(!mDictEvent[eventId].Contains(callBack))
- {
- mDictEvent[eventId].Add(callBack);
- }
- else
- {
- Debug.LogWarning("Repeat Add Event CallBack,EventId = " + eventId + ",CallBack = " + callBack.ToString());
- }
- }
-
- /// <summary>
- /// 删除事件监听
- /// </summary>
- public void DelEvent(int eventId, EventCallBack callBack)
- {
- if(!mDictEvent.ContainsKey(eventId))
- {
- return;
- }
- if(!mDictEvent[eventId].Contains(callBack))
- {
- return;
- }
- mDictEvent[eventId].Remove(callBack);
-
- // 如果回调都被移除了 那么key也从字典移除
- if (mDictEvent[eventId].Count < 1)
- {
- mDictEvent.Remove(eventId);
- }
-
- }
-
- /// <summary>
- /// 通知事件
- /// </summary>
- public void NotifyEvent(int eventId,object param)
- {
- if(mDictEvent.ContainsKey(eventId))
- {
- foreach(var callback in mDictEvent[eventId])
- {
- callback(param);
- }
- }
- }
- }
解释代码:
这段代码定义了一个名为 EventManager 的类,它继承了之前我们提到的泛型单例模式的基类。让我解释每一部分的含义:
using System.Collections;
和 using System.Collections.Generic;
:这两行是命名空间的引用,用于在代码中使用集合类和泛型集合类。
using UnityEngine;
:这行引用了 Unity 引擎的命名空间,使得代码可以使用 Unity 的 API。
public class EventManager : Singleton<EventManager>
:这是一个类定义,它继承了之前定义的 Singleton 泛型基类,并指定了泛型参数为 EventManager 自身。这意味着 EventManager 类将作为单例使用。
public delegate void EventCallBack(object param);
:这行定义了一个委托类型 EventCallBack,它表示一个事件回调函数,参数为 object 类型。
Dictionary<int, List<EventCallBack>> mDictEvent = new Dictionary<int, List<EventCallBack>>();
:这是一个字典类型的字段,用于存储事件和对应的事件回调函数列表。键为整数类型(事件ID),值为事件回调函数列表。这个字典用于管理事件和事件回调函数之间的关系。
public void AddEvent(int eventId, EventCallBack callBack)
:这是一个公共方法,用于添加事件监听。它接受两个参数,一个是事件ID,另一个是事件回调函数。它首先检查是否已存在该事件ID对应的回调函数列表,如果不存在,则创建一个新的列表,并将回调函数添加到列表中。如果已存在列表,则只需将回调函数添加到列表中。
public void DelEvent(int eventId, EventCallBack callBack)
:这是一个公共方法,用于删除事件监听。它接受两个参数,一个是事件ID,另一个是要删除的事件回调函数。它首先检查是否存在该事件ID对应的回调函数列表,如果不存在,则直接返回。如果存在列表,则检查回调函数是否在列表中,如果在,则将其从列表中移除。如果移除后列表为空,则将事件ID从字典中移除。
public void NotifyEvent(int eventId, object param)
:这是一个公共方法,用于通知事件。它接受两个参数,一个是事件ID,另一个是要传递给事件回调函数的参数。它首先检查是否存在该事件ID对应的回调函数列表,如果存在,则遍历列表,并依次调用每个回调函数,并将参数传递给它们。
通过这段代码,你可以方便地在 Unity 中管理事件和事件回调函数,实现事件的订阅、发布和取消订阅功能。
定义商店刷新事件的id:
- public class EventId
- {
- public static int OnShopDataChange = 1; //商店数据变化时触发
- public static int OnGoldChange = 2; //金币变化时触发
- }
以UI界面的刷新为例,打开商店UI时监听商店数据变化,关闭时移除监听
- public class ShopUI
- {
- private void RegisterEvent()//打开商店
- {
- EventManager.Instance.AddEvent(EventId.OnShopDataChange, OnDataChange);
- //添加:商店数据变化时,商店UI的刷新事件
- EventManager.Instance.AddEvent(EventId.OnGoldChange, OnDataChange);
- }
-
- private void UnRegisterEvent()//关闭商店
- {
- EventManager.Instance.DelEvent(EventId.OnShopDataChange, OnDataChange);
- EventManager.Instance.DelEvent(EventId.OnGoldChange, OnDataChange);
- }
-
- private void OnDataChange(object param)//只要商店数据变化就会触发
- {
- //刷新UI的具体逻辑
- }
- }
当商店的数据变化或者金币变化时,就会触发对应的事件,刷新商店的UI
- class ShopMgr : Singleton<ShopMgr>
- {
- private void OnDataChange()
- {
- EventManager.Instance.NotifyEvent(EventId.OnShopDataChange, null);
- }
- }
-
- class ItemMgr : Singleton<ItemMgr>
- {
- private void OnDataChange()
- {
- EventManager.Instance.NotifyEvent(EventId.OnGoldChange, null);
- }
- }
通常用于创建单一的对象类型
定义道具基类及其子类
- using UnityEngine;
-
- public abstract class ItemBase
- {
- protected string name;
-
- public virtual void Use()
- {
- Debug.Log("使用了" + name);
- }
- }
-
- public class HealthPotion : ItemBase
- {
- public HealthPotion()
- {
- name = "生命药水";
- }
-
- public override void Use()
- {
- base.Use();
- //具体的使用逻辑
- Debug.Log("恢复了100点生命");
- }
- }
-
- public class ManaPotion : ItemBase
- {
- public ManaPotion()
- {
- name = "魔法药水";
- }
-
- public override void Use()
- {
- base.Use();
- //具体的使用逻辑
- Debug.Log("恢复了100点魔法");
- }
- }
-
- public class SpeedBoost : ItemBase
- {
- public SpeedBoost()
- {
- name = "加速药剂";
- }
-
- public override void Use()
- {
- base.Use();
- //具体的使用逻辑
- Debug.Log("增加了移动速度");
- }
- }
解释代码:
这段代码定义了一个简单的物品系统,其中包括一个抽象基类 ItemBase
和三个具体的物品类 HealthPotion
、ManaPotion
和 SpeedBoost
。让我逐个解释每个部分的含义:
using UnityEngine;
:这是 Unity 引擎的命名空间引用,使得代码可以使用 Unity 的 API。
public abstract class ItemBase
:这是一个抽象基类的定义,命名为 ItemBase
。抽象类是不能直接实例化的,它定义了一个通用的物品模板,其中包含了物品的基本属性和行为。
protected string name;
:这是一个受保护的字符串字段,用于存储物品的名称。由于它是受保护的,所以只能在 ItemBase
类及其派生类中访问。
public virtual void Use()
:这是一个公共的虚拟方法,用于执行物品的使用操作。在基类中,这个方法的实现只是简单地输出一个使用信息,其中包含物品的名称。因为它被声明为虚拟方法,所以它可以在派生类中被重写。
public class HealthPotion : ItemBase
:这是一个具体的物品类 HealthPotion
的定义,它继承自 ItemBase
基类。它代表了一种生命药水物品。
public HealthPotion()
:这是 HealthPotion
类的构造函数,它初始化了物品的名称为 "生命药水"。
public override void Use()
:这是对基类中的虚拟方法 Use()
的重写。在 HealthPotion
类中,除了调用基类方法输出使用信息外,还增加了具体的使用逻辑,即恢复了100点生命。
public class ManaPotion : ItemBase
和 public class SpeedBoost : ItemBase
:这两个类与 HealthPotion
类的结构和功能类似,分别代表了魔法药水和加速药剂物品。它们也都继承自 ItemBase
基类,并在构造函数中初始化了物品的名称,并重写了 Use()
方法,实现了各自的使用逻辑。
通过这样的设计,你可以轻松地扩展物品系统,添加新的物品类,并根据需要定义不同的使用行为。
- public class ItemFactory
- {
- public static ItemBase CreateItem(string itemName)
- {
- ItemBase item = null;
- switch (itemName)
- {
- case "Health_Potion":
- item = new HealthPotion();
- break;
- case "Mana_Potion":
- item = new ManaPotion();
- break;
- case "Speed_Boost":
- item = new SpeedBoost();
- break;
- }
- return item;
- }
- }
游戏中通过ItemFactory创建并使用道具,只能创建ItemBase类型的对象
- //创建并使用生命药水
- ItemBase healthPotion = ItemFactory.CreateItem("Health_Potion");
- healthPotion.Use();
-
- //创建并使用加速药剂
- ItemBase speedBoost = ItemFactory.CreateItem("Speed_Boost");
- speedBoost.Use();
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。