出于本答案的目的:
- “物”指角色、武器和射弹。
- “包裹”指的是组合关系,当我说一个对象包裹另一个对象时,意味着它将它作为一个组件。
一般的答案是会使用资源。更具体地说,您将使用自定义资源和场景。
场景堆栈
我将从场景堆栈开始,因为这是其中更清晰的部分。这些都是游戏源码中存在的场景:
- 资源:在其他软件中创建,具有网格、精灵、材质、着色器、骨骼、动画等。
- 道具/皮肤:包裹资产。添加碰撞器、骨骼附件和任何其他辅助节点。
- 特工/角色:包裹道具。添加行为(脚本)。角色控制器就是其中之一。
现在,如果你想改变它的行为方式,你需要一个不同的代理。如果你想改变它的外观,你需要一个不同的道具。
因此,可以有多个具有相同行为但不同外观的事物(由 prop 给出),并且可以有多个具有相同外观但不同行为的事物(由代理给出)。
场景与自定义资源的关系
然而,我上面描述的内容存在于场景树中。事物并不总是存在于场景树中(有时它们存在于菜单或库存容器中)。在那里您需要自定义资源。
将有两种自定义资源类,我将回到这一点......我在这里所说的可以适用于两者。
自定义资源类:
- 拥有您所需的有关该事物的数据的属性。
- Have
PackedScene
s 属性,它们可以实例化。
- 有一个方法来实例化
PackedScene
s,它还将实例的属性设置为自定义资源实例本身(这是依赖注入和控制反转的一种形式)。
因此,可以有多个具有相同行为但配置不同的事物(由自定义资源给出)。
有时自定义资源会引用多个PackedScene
s。以下是一些案例:
- 自定义资源还可以包括
PackedScene
在角色/代理内部实例化为道具/皮肤。
- 有时您需要多个选项来实例化场景树中的某个事物。例如,您可能有不同的
PackedScene
在装备时实例化武器,而不是在世界中掉落时实例化武器。
- 当角色由玩家控制时,您可能会使用一个代理/角色场景,而当角色是机器人时,您可能会使用另一个场景,尽管它们在概念上是相同的。
如果你不认为场景才是问题所在,那就更好了。自定义资源就是问题所在,而场景只是您在需要存在于场景树中时使用的包装器......并且您可能会在不同的场合使用不同的包装器。
当然,如果某些包装器是通用的,则不需要在自定义资源中配置属性。同样,自定义资源不需要具有实例化每种包装场景的方法......只需执行您实际需要的即可。
自定义资源栈
在实践中,您可能需要两种自定义资源类:
- 通用资源。它具有所有同类事物之间共有的所有数据。
- 具体资源。包装通用资源,并拥有特定事物所需的所有数据。
例如,一种通用资源可能代表一种武器模型,并且它具有弹药容量等内容。但游戏中可以有多种同型号的武器。特定资源代表其中一种武器,它具有诸如当前拥有的弹药量之类的信息。
您将希望通用资源具有PackedScene
代理/角色的,因为他们的行为都是相同的。但具体资源要有PackedScene
道具/皮肤的属性,因为每一个都可能被定制为看起来不同。
另外,您要注入到场景实例中的自定义资源是特定资源。这样,场景就可以访问所有数据(因为特定资源具有对通用资源的引用),并且可以控制特定数据(例如,它将更新其弹药数量)。您可能不想在运行时更改通用资源的数据。
此外,一般资源将probably作为资源文件存在于游戏源中。但特定的数据是在运行时创建的(您可以在保存游戏时保存它们的数据,当然也可以在加载游戏时重新创建它们)。事实上,您可能希望在通用资源脚本中包含一个方法来创建特定资源的实例。