UH4L11——热更新工程使用MonoBehaviour

热更新工程使用MonoBehaviour

ILRuntime中虽然支持跨域继承MonoBehaviour​,但是作者并不建议大家这样做
我们可以通过类似Lua热更中那样,在主工程中实现用于派发生命周期函数的的公共脚本
通过委托或事件达到生命周期函数的调用

ILRuntime不推荐直接使用MonoBehaviour

ILRuntime中支持在热更工程中跨域继承MonoBehaviour

  1. 注册跨域继承适配器
  2. 对泛型方法AddComponent​进行重定向(较为复杂)

但是,ILRuntime并不推荐通过跨域继承直接使用MonoBehaviour
推荐大家类似Lua中一样使用MonoBehaviour
在主工程中通过委托或事件的形式派发生命周期函数 到 热更中

主要原因:
MonoBehaviour​是一个很特殊的类,很多底层逻辑是在C++中处理的
比如其中public​字段的序列化,在Inspector窗口中显示的功能,
如果在热更工程中去写,底层C++逻辑无法获取到热更工程中C#相关的信息

派发生命周期函数的形式使用MonoBehaviour

在主工程中实现一个脚本,该脚本的主要目的就是派发MonoBehaviour​的声明周期函数供热更工程中使用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
using System;
using UnityEngine;

public class ILRuntimeMono : MonoBehaviour
{
public event Action awakeEvent;
public event Action startEvent;
public event Action updateEvent;

void Awake()
{
awakeEvent?.Invoke();
}

void Start()
{
startEvent?.Invoke();
}

void Update()
{
updateEvent?.Invoke();
}
}

热更新工程内:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public class ILRuntimeMain
{
public static void Main()
{
GameObject obj = new GameObject();
ILRuntimeMono mono = obj.AddComponent<ILRuntimeMono>();
mono.awakeEvent += () =>
{
Debug.Log("Awake");
};
mono.startEvent += () =>
{
Debug.Log("Start");
};
mono.updateEvent += () =>
{
Debug.Log("Update");
};
}
}

值得一提的是,Awake​是一个相对特殊的生命周期函数,它类似于构造函数,在脚本添加的时候就会自动执行
因此在挂载了脚本后,再向脚本对象添加Awake​要执行的委托,然后执行是做不到的

输出:image

如果想要模拟Awake​的效果,在挂载了脚本以后直接执行初始化逻辑即可,不需要额外声明事件并添加

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public static void Main()
{
GameObject obj = new GameObject();
ILRuntimeMono mono = obj.AddComponent<ILRuntimeMono>();
Debug.Log("Awake");
//mono.awakeEvent += () =>
//{
// Debug.Log("Awake");
//};
mono.startEvent += () =>
{
Debug.Log("Start");
};
mono.updateEvent += () =>
{
Debug.Log("Update");
};
}

输出:image