Defold引擎中关于CollectionProxy的使用

昨天刚刚讲了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消息系统通信。

最后的注意事项

  1. Collection Proxy之间的物理世界是隔离的,不同物理世界之间不会发生碰撞。
  2. Collection Proxy加载的资源是需要消耗内存的,如果存在非常大量的Collection Proxy加载,可以考虑一个优化游戏逻辑或使用在线更新。
  3. Collection Proxy必须要能获取得到输入焦点,其中包含的Game Object与组件才能获取焦点。
相关推荐
源猿人2 小时前
企业级文件浏览系统的Vue实现:架构设计与最佳实践
前端·javascript·数据可视化
xw53 小时前
uni-app中v-if使用”异常”
前端·uni-app
!win !3 小时前
uni-app中v-if使用”异常”
前端·uni-app
IT_陈寒3 小时前
Java 性能优化:5个被低估的JVM参数让你的应用吞吐量提升50%
前端·人工智能·后端
南囝coding3 小时前
《独立开发者精选工具》第 018 期
前端·后端
小桥风满袖4 小时前
极简三分钟ES6 - ES9中for await of
前端·javascript
半花4 小时前
i18n国际语言化配置
前端
编程贝多芬4 小时前
Promise 的场景和最佳实践
前端·javascript