昨天刚刚讲了Defold中的Collection Factory,与它比较相似的Collection Proxy组件也今天来讲一讲。Collection Proxy也是用于动态创建Collection。
Collection Proxy与Collection Factory的区别?
区别如下表所示:
特性 | Collection Proxy | Collection Factory |
---|---|---|
物理世界 | 完全独立,每个Collection Proxy的物理世界都是独立的。两个Collection Proxy中的物体就算位置在一起,也不会发生物理碰撞。 | 物理世界是同一个 |
资源加载 | 可通过load与async_load同步或异步加载资源,并经历load/async_load -> init -> enable -> disable -> final -> unload 向个生命周期阶段,并在load/async_load阶段发出proxy_loaded消息,在unlaod阶段发出proxy_unloaded消息。 | 可通过create与load方法进行同步或异步加载 |
输入交互 | 必须给Collection Proxy组件设置获取输入焦点,然后在Collection Proxy中的对象与组件才能获取输入交互。 | 无须特殊处理 |
典型场景 | 加载游戏关卡与独立场景等 | 向当前游戏世界中添加一个敌人小队或特效、奖励等 |
如何使用Collection Proxy?
Collection Proxy是一个组件,所以必须放到Game Object中。通过设置Collection属性指定要代理的Collection,如下图所示:

在上图中的Exclude属性,如果选中,那么在游戏打包时会排除内部包含的资源,而改为在运行时动态获取,这相关的知识会在后面讲到在线更新时提及。
Collection Proxy生命周期
Collection Proxy具有完整的生命周期,如下所示:
graph LR
load/async_load --> init --> enable --> disable --> final --> unload
load/async_load -.广播消息.-> proxy_loaded[/proxy_loaded/]
unload -.广播消息.-> proxy_unloaded[/proxy_unloaded/]
从上图可以看到Collection Proxy的完整生命周期,使用代码如下所示:
lua
function init(self)
-- 同步加载
msg.post("#collectionproxy", "load")
-- 异步加载
-- msg.post("#collectionproxy", "async_load")
end
function on_input(self, action_id, action)
-- 假设有一个按钮点击一下就发布一个 #collectionproxy 禁用的事件
if action_id == hash("proxy_finished") then
msg.post("#", "proxy_finished")
end
end
function on_message(self, message_id, message, sender)
if message_id == hash("proxy_loaded") then
-- 初始化Collection Proxy
msg.post('#collectionproxy', "init")
-- 生效Collection Proxy
msg.post("#collectionproxy", "enable")
-- 接收到proxy_finished事件
elseif message_id == hash("proxy_finished") then
-- 禁用Collection Proxy
msg.post("#collectionproxy", "disable")
-- 执行资源回收
msg.post("#collectionproxy", "final")
-- 卸载
msg.post("#collectionproxy", "unload")
elseif message_id == hash("proxy_unloaded") then
-- 已卸载完成
end
end
以上代码作为Collection Proxy 完整生命周期的演示,所Collection Proxy的交互都是通过msg.post消息系统通信。
最后的注意事项
- Collection Proxy之间的物理世界是隔离的,不同物理世界之间不会发生碰撞。
- Collection Proxy加载的资源是需要消耗内存的,如果存在非常大量的Collection Proxy加载,可以考虑一个优化游戏逻辑或使用在线更新。
- Collection Proxy必须要能获取得到输入焦点,其中包含的Game Object与组件才能获取焦点。