资源系统的组成部分
1. 资源收集
2. 资源标识
3. 资源加载/卸载
4. 资源依赖
5. 资源分组
6. 资源查找
7. 资源元数据管理
8. 资源重命名,重定位,删除
预备知识
资源系统会使用到前面我们说过的模块系统,需要监听模块系统的事件,比如模块的加载/卸载.
当收到某个模块加载的事件后,资源系统会及时的加载这个模块所需要的资源.
同样的在收到模块卸载事件后,卸载掉它所使用的资源.
这里需要注意的细节是资源系统的加载卸载操作是由模块系统的模块加载/卸载来触发的,具体的资源加载/卸载机制后面会讲到.
另外资源系统和许多Torque中的子系统一样,所使用的也是TAML进行操作.下面会用Xml格式的TAML文件做介绍,方便阅读.
导出方法
资源系统导出到脚本的方法,可以参照开源代码asset目录下文件后缀为_ScriptingBind.h的头文件进行了解.
什么是资源(Asset)?
(下面所有提到Asset的地方都有资源名字代替,也可以理解为资产,资本等,随意:))
资源是被用来定义一个能被Torque引擎识别的对象类型,并能够将其实例化.这个定义很抽象,但是也表明了资源能够做到任何你想做到的事情!
你可以将资源认为是组成游戏的基本元素,比如图像,音效,特效,动画等等...同样也可以是一个脚本,界面,玩家属性表等等...
总之只要一个对象能够正确的通过TAML配置呈现,并让引擎能够通过TAML进行创建实例和自动销毁,那么它就可以成为一个资源.
资源系统的整体结构是基于一个能够被明确定义的资源定义文件.这个资源定义文件使用TAML格式,并且明确指出了自己的资源类型.
资源系统维护了一个有效资源组成的数据库,有效资源是指那些被扫描到的单个的资源定义文件.
当一个资源被添加到数据库中,那么它就可以被执行加载,卸载,重命名,删除,移除等操作.
资源通常包括以下几个信息:
1. 资源的配置信息
2. 引用到的其他文件
3. 引用到的其他资源
资源的初步认识
下面先从C++继承关系上说明资源的类型和使用方法.
要创建一种新的资源类型,只需要从AssetBase类继承即可,这个类提供了资源的基本属性和访问资源的接口以及资源系统内部的通信机制.
当新的资源类型被创建,并不是必须要重新某些继承方法.
以ScriptAsset脚本资源为例,我们可以像下面一样简单的完成:
class ScriptAsset : public AssetBase
{
...
}
上面这种写法是被系统认可的,在资源定义文件可以如下:
<ScriptAsset
AssetName="HighScoreScript" />
我们创建的脚本资源类型并没有属性和方法,AssetName是继承于AssetBase,在资源定义文件中这个属性是强制定义的,必须有.
理论上你必须手动的加载资源,并且通过接口获取资源的实例,但实际上你什么都不用做,这都是资源系统的工作.
资源的申明
学习的第一步,明白资源是如何被资源系统所知道的非常重要.
如上所述,当一个模块被加载,资源系统监听到了加载事件并加载模块用到的资源,但是这一点是如何设定的呢?
考虑到性能问题,在配置的时候提供了一个小小的开关来让开发者自行选择是递归遍历还是指定加载.
为了这个目的,资源系统允许用户自己配置要扫描的路径,资源文件后缀名以及是否递归扫描,而资源的配置就在模块定义文件中,下面是一个常规的模块定义文件:
<ModuleDefinition
ModuleId="TruckToy"
VersionId="1"
Description="A monster truck toy."
Dependencies="ToyAssets=1"
Type="toy"
ToyCategoryIndex="5"
ScriptFile="main.cs"
CreateFunction="create"
DestroyFunction="destroy"/>
下面我们添加资源定义信息:
<ModuleDefinition
ModuleId="TruckToy"
VersionId="1"
Description="A monster truck toy."
Dependencies="ToyAssets=1"
Type="toy"
ToyCategoryIndex="5"
ScriptFile="main.cs"
CreateFunction="create"
DestroyFunction="destroy">
<DeclaredAssets
Path="assets"
Extension="asset.taml"
Recurse="true"/>
</ModuleDefinition>
DeclaredAssets为XML的节点名,class DeclaredAssets : public SimObject,它有三个属性可以设定,如上面说的.
这个节点是可以多个的,比如:
<ModuleDefinition
ModuleId="TruckToy"
VersionId="1"
Description="A monster truck toy."
Dependencies="ToyAssets=1"
Type="toy"
ToyCategoryIndex="5"
ScriptFile="main.cs"
CreateFunction="create"
DestroyFunction="destroy">
<DeclaredAssets
Path="EnemyAssets"
Extension="asset.taml"
Recurse="true"/>
<DeclaredAssets
Path="GuiAssets"
Extension="asset.taml"
Recurse="true"/>
</ModuleDefinition>
资源状态
在我们进入资源使用实战之前,还有一个需要了解的概念就是资源的状态.
三种状态:
1. Unknown(未知) // 也许是资源存在,但是没有指定扫描
2. Loaded(加载了) // 有模块在使用,当前有效
3. Unloaded(卸载了) // 扫描过存在,但是当前没有模块使用