我们在Test文件夹中新建一个场景,命名为NewAPITest。

Global事件

在同文件夹内新建一个脚本,命名为GlobalEventExample

  1. 直接使用TypeEventSystem.Global获取实例
  2. 使用IOnEvent<T>泛型接口,指定监听类型,此接口会自动使用Global注册监听
  3. 使用IOnEvent<T>泛型接口,监听多个类型时,需要在<>内单独指定
  4. 可以在QFrameworkOnGlobalEventExtension静态拓展声明里添加Send Event方法,不过要注意不要和CanSendEventExtension重名了
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
using UnityEngine;

namespace QFrameWork.Example
{
public class GlobalEventExample : MonoBehaviour,
IOnEvent<GlobalEventExample.GlobalEventB>,
IOnEvent<GlobalEventExample.GlobalEventC>
{
public struct GlobalEventA { }
public struct GlobalEventB { }
public struct GlobalEventC { }
void Start()
{
TypeEventSystem.Global.Register<GlobalEventA>(OnGlobalEventA)
.UnregisterWhenGameObjectDestroyed(gameObject);
this.RegisterEvent<GlobalEventB>()
.UnregisterWhenGameObjectDestroyed(gameObject);
this.RegisterEvent<GlobalEventC>()
.UnregisterWhenGameObjectDestroyed(gameObject);
}
private void OnDestroy()
{
//this.UnregisterEvent<GlobalEventB>();
//this.UnregisterEvent<GlobalEventC>();
}
void Update()
{
if (Input.GetMouseButtonDown(0))
{
TypeEventSystem.Global.Send<GlobalEventA>();
}
if (Input.GetMouseButtonDown(1))
{
TypeEventSystem.Global.Send<GlobalEventB>();
}
if (Input.GetMouseButtonDown(2))
{
TypeEventSystem.Global.Send<GlobalEventC>();
}
if (Input.GetKeyDown(KeyCode.X))
{
Destroy(gameObject);
}
}
private void OnGlobalEventA(GlobalEventA globalEventA)
{
Debug.Log(globalEventA.ToString());
}

public void OnEvent(GlobalEventB globalEventB)
{
Debug.Log(globalEventB.ToString());
}
public void OnEvent(GlobalEventC globalEventC)
{
Debug.Log(globalEventC.ToString());
}
}
}

BindableProperty新增API

在同文件夹内新建一个脚本,命名为BindablePropertyExample

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
using UnityEngine;

namespace QFrameWork.Example
{
public class BindablePropertyExample : MonoBehaviour
{
private BindableProperty<int> Age = new BindableProperty<int>(10);
private BindableProperty<int> Counter = new BindableProperty<int>();

void Start()
{
Age.Register(age =>
{
Debug.Log(age);

Counter.Value = 10 * age;
}).UnregisterWhenGameObjectDestroyed(gameObject);
//使用RegisterWithInitValue,传入的方法会优先调用一次,然后再注入Register方法中
Counter.RegisterWithInitValue(value =>
{
Debug.Log(value);
}).UnregisterWhenGameObjectDestroyed(gameObject);
}

void Update()
{
if (Input.GetMouseButtonDown(0))
{
Age.Value++;
if (Age == 15)//隐式转换,显式为:(int)Age == 15
{
Debug.Log("Got it!");
}
}
}
}
}

结果

如果我们在BindableProperty的源码中添加新的隐式转换

1
2
3
4
public static implicit operator BindableProperty<T>(T value)
{
return new BindableProperty<T>(value);
}

那么新的BindableProperty的声明可以这样写

1
private BindableProperty<int> Age = 10;//10隐式转换,显式为(BindableProperty)10

但是这会造成一个问题,如果我们修改Age的值,写成Age++并不会报错,但是不写成Age.Value++就不会触发监听。

?为什么写成Age++不会报错呢?这是因为系统会自动计算BindableProperty<T> BindableProperty<T>.operator++(BindableProperty<T> value)这样做肯定不行,因为返回的BindableProperty肯定会丢失监听

拓展:让BindableProperty可以被序列化

BindableProperty本身不支持被序列化,如果想序列化它让让它在编辑器中显示,可以包装一下它:

新建一个IntProperty

1
2
3
4
5
6
7
8
9
10
11
12
13
[Serializable]
public class IntProperty : BindableProperty<int>
{
public IntProperty(int value = 0) : base(value){}//注意在子类构造中调用父类构造的写法
}
[Serializable]
public class BindableProperty<T>
{
//...
[SerializeField]
private T mValue = default(T);
//...
}

但是并不建议这么做