Manuals
Manuals




This translation is community contributed and may not be up to date. We only maintain the English version of the documentation. Read this manual in English

集合工厂

集合工厂组件用于将存储在集合文件中的游戏对象组和层级结构生成到运行中的游戏中。

集合提供了一种强大的机制来创建可重用的模板,或称为Defold中的”预制件”。有关集合的概述,请参阅构建块文档。集合可以放置在编辑器中,也可以动态插入到您的游戏中。

使用集合工厂组件,您可以将集合文件的内容生成到游戏世界中。这类似于对集合内的所有游戏对象执行工厂生成,然后在对象之间构建父子层级关系。一个典型的用例是生成由多个游戏对象组成的敌人(例如,敌人+武器)。

生成集合

假设我们想要一个角色游戏对象和一个单独的盾牌游戏对象作为角色的子对象。我们在一个集合文件中构建游戏对象层级结构,并将其保存为”bean.collection”。

集合代理组件用于基于集合创建新的游戏世界,包括单独的物理世界。新世界通过新的套接字访问。当您向代理发送消息开始加载时,集合中包含的所有资产都通过代理加载。这使得它们对于例如在游戏中切换关卡非常有用。然而,新的游戏世界带来了相当多的开销,因此不要将它们用于少量内容的动态加载。有关更多信息,请参阅集合代理文档

Collection to spawn

然后,我们将集合工厂添加到一个游戏对象中,该游戏对象将负责生成,并将”bean.collection”设置为组件的原型

Collection factory

现在,生成bean和shield只需要调用collectionfactory.create()函数:

local bean_ids = collectionfactory.create("#bean_factory")

该函数接受5个参数:

url
应该生成新游戏对象组的集合工厂组件的id。
[position]
(可选)生成的游戏对象的世界位置。这应该是一个vector3。如果您不指定位置,对象将在集合工厂组件的位置生成。
[rotation]
(可选)新游戏对象的世界旋转。这应该是一个quat
[properties]
(可选)一个带有id-table对的Lua表,用于初始化生成的游戏对象。有关如何构造此表的信息,请参见下文。
[scale]
(可选)生成的游戏对象的缩放比例。缩放可以表示为一个number(大于0),它指定所有轴上的均匀缩放。您也可以提供一个vector3,其中每个组件指定相应轴上的缩放。

collectionfactory.create()将生成的游戏对象的标识作为表返回。表键将每个对象的集合本地id的哈希映射到每个对象的运行时id:

“bean”和”shield”之间的父子关系不会在返回的表中反映出来。这种关系仅存在于运行时场景图中,即对象如何一起变换。重新设置对象的父级永远不会改变其id。

local bean_ids = collectionfactory.create("#bean_factory")
go.set_scale(0.5, bean_ids[hash("/bean")])
pprint(bean_ids)
-- DEBUG:SCRIPT:
-- {
--   hash: [/shield] = hash: [/collection0/shield], -- <1>
--   hash: [/bean] = hash: [/collection0/bean],
-- }
  1. 添加了前缀/collection[N]/,其中[N]是一个计数器,以唯一标识每个实例:

属性

生成集合时,您可以通过构造一个表来将属性参数传递给每个游戏对象,其中键是对象id,值是包含要设置的脚本属性的表。

local props = {}
props[hash("/bean")] = { shield = false }
local ids = collectionfactory.create("#bean_factory", nil, nil, props)

假设”bean.collection”中的”bean”游戏对象定义了”shield”属性。脚本属性手册包含有关脚本属性的信息。

-- bean/controller.script
go.property("shield", true)

function init(self)
    if not self.shield then
        go.delete("shield")
    end     
end

工厂资源的动态加载

通过选中集合工厂属性中的动态加载复选框,引擎会推迟与工厂关联的资源的加载。

Load dynamically

取消选中该复选框时,引擎在加载集合工厂组件时加载原型资源,因此它们立即可用于生成。

选中该复选框时,您有两种使用选项:

同步加载
当您想要生成对象时调用collectionfactory.create()。这将同步加载资源,这可能会导致卡顿,然后生成新实例。
function init(self)
    -- 集合工厂父级集合加载时
    -- 集合工厂资源不会被加载. 调用 create 函数
    -- 会把资源进行同步加载.
    self.go_ids = collectionfactory.create("#collectionfactory")
end

function final(self)  
    -- 删掉游戏对象, 资源引用计数减少
    -- 本例中集合工厂资源也会被卸载
    -- 因为集合工厂组件不包含对资源的引用.
    go.delete(self.go_ids)

    -- 因为集合工厂组件不包含对资源的引用
    -- 所以对集合工厂调用 unload 没有意义
    collectionfactory.unload("#factory")
end
异步加载
调用collectionfactory.load()以异步方式显式加载资源。当资源准备好生成时,会收到一个回调。
function load_complete(self, url, result)
    -- 资源加载完成, 可以新建对象
    self.go_ids = collectionfactory.create(url)
end

function init(self)
    -- 集合工厂父级集合加载时
    -- 集合工厂资源不被加载. 调用 load 函数进行资源异步加载.
    collectionfactory.load("#factory", load_complete)
end

function final(self)
    -- 删掉游戏对象, 资源引用计数减少
    -- 本例中集合工厂资源不会被卸载
    -- 因为集合工厂组件包含对资源的引用.
    go.delete(self.go_ids)

    -- 调用 unload 函数, 集合工厂对资源引用被释放,
    -- 这样资源才会被卸载.
    collectionfactory.unload("#factory")
end

动态原型

可以通过选中集合工厂属性中的动态原型复选框来更改集合工厂可以创建的原型

Dynamic prototype

动态原型选项被选中时,集合工厂组件可以使用collectionfactory.set_prototype()函数更改原型。示例:

collectionfactory.unload("#factory") -- 卸载之前的资源
collectionfactory.set_prototype("#factory", "/main/levels/level1.collectionc")
local ids = collectionfactory.create("#factory")

当设置动态原型选项时,集合组件计数无法优化,拥有集合将使用game.project文件中的默认组件计数。