Skip to content
使用与动态加载资源

使用与动态加载资源

阅读本文大概需要 10 分钟

使用与加载资源的方式及示例

1.1 获取场景中已经存在的对象

函数:

getChildren() : Array<GameObject>

获取所有子物体()

推荐使用 asyncFind 替代

ts
let goList = this.gameObject.getChildren();
goList.forEach(element => {
    console.log(`${this.gameObject.name} | ${element.name}`);
});
let goList = this.gameObject.getChildren();
goList.forEach(element => {
    console.log(`${this.gameObject.name} | ${element.name}`);
});
getChildByName(name: string) : GameObject

根据名字获取子物体 ( 物体名字 )

ts
let childrenObj = this.gameObject.getChildByName("MyChildrenName");
let childrenObj = this.gameObject.getChildByName("MyChildrenName");
getChildByGameObjectId(gameObjectId: string) : GameObject

根据 GameObjectId 获取子物体 ( 物体 GameObjectId )

ts
let childrenObjByGameObjectId = this.gameObject.getChildByGameObjectId("MyChildrenGameObjectId");
let childrenObjByGameObjectId = this.gameObject.getChildByGameObjectId("MyChildrenGameObjectId");

静态函数:

find(gameObjectId: string) : GameObject

查找当前物体 ( 物体的 GameObjectId )

可查找所有继承自 GameObject 的对象

ts
//find GameObject
let goByfind = GameObject.findGameObjectById("GameObjectID");

//find Other Object eg.
let myTrigger = GameObject.findGameObjectById("TriggerObjID") as BoxTrigger;
//find GameObject
let goByfind = GameObject.findGameObjectById("GameObjectID");

//find Other Object eg.
let myTrigger = GameObject.findGameObjectById("TriggerObjID") as BoxTrigger;
asyncFindGameObjectById(gameObjectId: string) : Promise<GameObject>

异步查找当前物体 ( 物体的 GameObjectId )

可查找所有继承自 GameObject 的对象

ts
@Component
export default class GetObj extends Script {
    
    protected async OnStart(): Promise`<void>` {

       let goByAsyfind = await GameObject.asyncFindGameObjectById("GameObjectGameObjectId");

    }
    
}
@Component
export default class GetObj extends Script {
    
    protected async OnStart(): Promise`<void>` {

       let goByAsyfind = await GameObject.asyncFindGameObjectById("GameObjectGameObjectId");

    }
    
}

使用异步加载时,需要 await 修饰符,且将异步修饰符(async)包含至函数

findGameObjectsByName(name: string) : Array<GameObject>

通过名字查找所有物体 ( 物体名字 )

ts
@Component
export default class GetObj extends Script {
    
    protected OnStart(): void {

       let goListByName = GameObject.findGameObjectsByName("GameObjectsName");
       goListByName.forEach(element => {

           console.log(`${this.gameObject.name} | ${element.name} | ${element.gameObjectId}`);

       });

    }
    
}
@Component
export default class GetObj extends Script {
    
    protected OnStart(): void {

       let goListByName = GameObject.findGameObjectsByName("GameObjectsName");
       goListByName.forEach(element => {

           console.log(`${this.gameObject.name} | ${element.name} | ${element.gameObjectId}`);

       });

    }
    
}
findGameObjectByName(name: string) : GameObject

通过名字查找物体 ( 物体名字 )

返回第一个查找到的对象,如有多个同名对象,随机返回一个

ts
let goByName = GameObject.findGameObjectByName("GameObjectName");
let goByName = GameObject.findGameObjectByName("GameObjectName");
findGameObjectsByTag(InTag: string) : Array<GameObject>

通过自定义 Tag 获取 GameObject ( )

ts
@Component
export default class GetObj extends Script {
    
    protected OnStart(): void {

       let goListByTag = GameObject.findGameObjectsByTag("GameObjectsTag");
       goListByTag.forEach(element => {

           console.log(`${this.gameObject.name} | ${element.name} | ${element.getTag()}`);

       });

    }
    
}
@Component
export default class GetObj extends Script {
    
    protected OnStart(): void {

       let goListByTag = GameObject.findGameObjectsByTag("GameObjectsTag");
       goListByTag.forEach(element => {

           console.log(`${this.gameObject.name} | ${element.name} | ${element.getTag()}`);

       });

    }
    
}

1.2 克隆场景中已经存在的对象

clone() : GameObject

复制对象(返回对象 : GameObject)

ts
let goclone = this.gameObject.clone();
let goclone = this.gameObject.clone();

1.3 在场景中生成资源库内的对象

spawn(assetId: string, gameObjectInfo?: mw.GameObjectInfo) : GameObject

根据 AssetId 构造一个 GameObject ( 资源ID , GameObject信息 )

ts
@Component
export default class GetObj extends Script {

    /** 当脚本被实例后,会在第一帧更新前调用此函数 */
    protected OnStart(): void {

        //Create GameObject
        let assetGameObject = GameObject.spawn("AssetID");
        
        //Create Other Object eg.
        let effectObj = GameObject.spawn("EffectAssetID") as Effect;

    }

}
@Component
export default class GetObj extends Script {

    /** 当脚本被实例后,会在第一帧更新前调用此函数 */
    protected OnStart(): void {

        //Create GameObject
        let assetGameObject = GameObject.spawn("AssetID");
        
        //Create Other Object eg.
        let effectObj = GameObject.spawn("EffectAssetID") as Effect;

    }

}

使用spawn函数时,所需生成的资源 ID 需要拖入优先加载栏 或者 使用AssetUtil接口下载加载资源

接口使用方法如下,在脚本中添加即可

ts
AssetUtil.asyncDownloadAsset("").then((flag) => {
    if(flag) {
        // your code
    }
});
AssetUtil.asyncDownloadAsset("").then((flag) => {
    if(flag) {
        // your code
    }
});

1.4 在场景中生成预制体(Prefab)对象

使用与加载资源方式的区别

最本质的区别就是获取(Get)新建(New)

2.1 使用资源

1.1** 内所有函数的方式都是获取资源(Get)即为使用资源**

使用资源会将该对象的内存地址指向所使用的变量

不会产生新的内存消耗

2.2 加载资源

1.2**、1.31.4 内所有函数的方式都是新建资源(New)即为加载资源**

加载资源会向编辑器申请一块新的内存用来存储新的对象

无论是复制还是生成,都会产生新的内存消耗

建议将逻辑中需要频繁重复新建、销毁的对象做成对象池,避免内存的过多消耗

使用与加载资源时的注意事项

频繁创建、销毁对象时最好做一个对象池管理(例如子弹)

以减少程序内存与执行效率的开销

获取到的所有资源对象在使用前请进行判空处理,防止代码跑火车

需要动态创建的资源(资源库中的资源),需****要进行优先加载,否则对象的资源无法立即应用

补充:

方法一:可通过 AssetUtil.asyncDownloadAsset 的方式将资源异步加载到工程中

方法二:可以将需要动态加载的资源拖拽到优先加载中进行标记

同步与异步查找对象的使用方式建议(find & asyncFind)

在代码执行过程中

若逻辑的时序性比较重要,则建议使用异步加载

若不重要则使用同步加载

异步加载会使代码执行暂时阻塞,待加载完毕再执行剩余逻辑

异步加载案例:

场景一跳转至场景二时,我们可以使用 UI 遮挡场景加载的过程

使用异步加载等待反馈,待场景内所有资源加载完毕,再取消 UI 遮挡

同步加载案例:

当我们需要同时初始化很多资源,且资源并非及时使用的时候

我们可以使用同步加载,方便程序同时加载多个资源,加快进度