事件模型的五个组成部分
- 事件拥有者,事件发布者
- 事件
- 事件响应者,事件订阅者
- 事件响应函数,事件处理函数
- 订阅,注册
event简单实例
新建脚本EventTest2
,将五个模型写在代码头部
/// <summary>
/// 事件拥有者,事件发布者
/// 事件
/// 事件响应者,事件订阅者
/// 事件处理函数
/// 订阅,注册
/// </summary>
public class EventTest2 : MonoBehaviour
{
void Start()
{
}
}
新建事件拥有者,事件发布者
/// <summary>
/// 事件发布者
/// </summary>
public class PublishClass
{
}
新建事件
public class PublishClass
{
public event
}
发现需要一个委托类型,这个委托类型约束了事件传递能携带的数据类型,同样约束了事件订阅者处理函数所能接收的参数类型,这里我们随便指定一个类型
public class PublishClass
{
public delegate void PubEventHandler(string content); // 声明一个用于事件的委托类型,该委托类型可持有拥有一个参数没有返回值的方法
public event PubEventHandler Publish; // 声明一个事件
}
新建事件响应者,事件订阅者
/// <summary>
/// 事件响应者
/// </summary>
public class SubscribeClass
{
}
新建事件响应函数,事件处理函数,上面的委托类型已经约束了事件响应函数必须具备一个string类型的参数
public class SubscribeClass
{
/// <summary>
/// 事件处理函数
/// </summary>
/// <param name="content"></param>
public void DealFunction(string content)
{
Debug.Log("事件发布者发布了消息,参数是:" + content);
}
}
创建订阅关系,事件处理函数注册事件
public class EventTest2 : MonoBehaviour
{
void Start()
{
PublishClass pubEx = new PublishClass();
SubscribeClass subEx = new SubscribeClass();
pubEx.Publish += subEx.DealFunction;
}
}
这样事件模型的五个组成部分都写好了,触发pubEx.Publish
方法就会自动调用subEx.DealFunction
方法,下面来模拟一下事件的触发。注意事件必须由事件的拥有者、持有者触发,外部仅能订阅、注册,即调用事件的+=
和-=
方法
模拟事件触发条件,这里表示调用OnPublish
方法触发Publish
事件,模拟游戏中角色遭受攻击血量低于0触发死亡事件
public class PublishClass
{
public delegate void PubEventHandler(string content); // 声明一个用于事件的委托类型,该委托类型可持有拥有一个参数没有返回值的方法
public event PubEventHandler Publish; // 声明一个事件
public void OnPublish(string content) // 模拟事件的触发条件
{
if (Publish != null)
{
Publish(content);
}
}
}
模拟事件触发
public class EventTest2 : MonoBehaviour
{
void Start()
{
PublishClass pubEx = new PublishClass();
SubscribeClass subEx = new SubscribeClass();
pubEx.Publish += subEx.DealFunction;
pubEx.OnPublish("Hello,你好!"); // 事件触发
}
}
在unity中进行调试
可见,事件和事件处理函数已经成功触发
实例完整代码
/// 事件拥有者,事件发布者
/// 事件
/// 事件响应者,事件订阅者
/// 事件处理函数
/// 订阅,注册
/// </summary>
public class EventTest2 : MonoBehaviour
{
void Start()
{
PublishClass pubEx = new PublishClass();
SubscribeClass subEx = new SubscribeClass();
pubEx.Publish += subEx.DealFunction;
pubEx.OnPublish("Hello,你好!");
}
}
/// <summary>
/// 事件发布者
/// </summary>
public class PublishClass
{
public delegate void PubEventHandler(string content); // 声明一个用于事件的委托类型,该委托类型可持有拥有一个参数没有返回值的方法
public event PubEventHandler Publish; // 声明一个事件
public void OnPublish(string content) // 模拟事件的触发条件
{
if (Publish != null)
{
Publish(content);
}
}
}
/// <summary>
/// 事件响应者
/// </summary>
public class SubscribeClass
{
/// <summary>
/// 事件处理函数
/// </summary>
/// <param name="content"></param>
public void DealFunction(string content)
{
Debug.Log("事件发布者发布了消息,参数是:" + content);
}
}
事件的完整声明格式
public class PublishClass
{
public delegate void PubEventHandler(string content); // 声明一个用于事件的委托类型,该委托类型可持有拥有一个参数没有返回值的方法
private PubEventHandler m_PubEventHandler; // 委托字段
public event PubEventHandler Publish // 声明一个事件
{
add
{
m_PubEventHandler += value;
}
remove
{
m_PubEventHandler -= value;
}
}
public void OnPublish(string content) // 模拟事件的触发条件
{
if (m_PubEventHandler != null)
{
m_PubEventHandler(content);
}
}
}
事件与委托
- 事件不是委托字段,也不是特殊的委托
事件是委托字段的封装器,限制器,用于限制和保护委托字段,限制外界对委托字段的访问,只允许外界访问委托字段的+=
和-=
方法,类似于属性对字段的封装 - 事件基于委托
当事件被触发时,会调用订阅了该事件的事件响应者们的事件响应函数,而要记录、存储和引用这些事件响应函数只有委托字段可以做到,所以在声明事件时使用了委托类型