Cocos Creator资源自动释放之2.x和3.x版本的使用及区别
2.x
封装:
// 2.x
import { ccclass, menu, disallowMultiple } from 'cc';
// 定义 AutoReleaseAssets 类
@ccclass
@menu('资源管理/AutoReleaseAssets/自动释放资源')
@disallowMultiple
export class AutoReleaseAssets extends cc.Component {
// 存储动态资源的数组
private dynamicsAssets: cc.Asset[] = [];
/**
* 添加单个资源到自动释放列表
* @param _asset 要添加的资源
*/
public addAutoReleaseAsset(_asset: cc.Asset): void {
// 检查资源是否有效
if (cc.isValid(_asset)) {
// 增加资源引用计数
_asset.addRef();
// 将资源添加到动态资源数组
this.dynamicsAssets.push(_asset);
}
}
/**
* 添加多个资源到自动释放列表
* @param _assets 要添加的资源数组
*/
public addAutoReleaseAssets(_assets: cc.Asset[]): void {
// 遍历资源数组
for (const _asset of _assets) {
// 调用添加单个资源的方法
this.addAutoReleaseAsset(_asset);
}
}
/**
* 组件销毁时自动释放资源
*/
onDestroy(): void {
// 遍历动态资源数组
for (const asset of this.dynamicsAssets) {
// 检查资源是否有效
if (cc.isValid(asset)) {
// 减少资源引用计数
asset.decRef();
}
}
// 清空动态资源数组
this.dynamicsAssets = [];
}
}
// 为 cc.Component 原型添加扩展方法
declare global {
interface CCComponent {
addAutoReleaseAsset(_asset: cc.Asset): void;
addAutoReleaseAssets(_assets: cc.Asset[]): void;
}
}
cc.Component.prototype.addAutoReleaseAsset = function (_asset: cc.Asset): void {
// 获取节点上的 AutoReleaseAssets 组件
let autoReleaseComponent = this.node.getComponent(AutoReleaseAssets);
// 如果组件无效,则添加该组件
if (!cc.isValid(autoReleaseComponent)) {
autoReleaseComponent = this.node.addComponent(AutoReleaseAssets);
}
// 调用组件的添加单个资源方法
autoReleaseComponent.addAutoReleaseAsset(_asset);
};
cc.Component.prototype.addAutoReleaseAssets = function (_assets: cc.Asset[]): void {
// 获取节点上的 AutoReleaseAssets 组件
let autoReleaseComponent = this.node.getComponent(AutoReleaseAssets);
// 如果组件无效,则添加该组件
if (!cc.isValid(autoReleaseComponent)) {
autoReleaseComponent = this.node.addComponent(AutoReleaseAssets);
}
// 调用组件的添加多个资源方法
autoReleaseComponent.addAutoReleaseAssets(_assets);
};
使用:
import { _decorator, Component } from 'cc';
import { AutoReleaseAssets } from './path/to/AutoReleaseAssets'; // 根据实际路径调整
const { ccclass, property } = _decorator;
@ccclass('MyComponent')
export class MyComponent extends Component {
start() {
const resourcePaths = ['textures/myTexture1', 'textures/myTexture2'];
const assets: cc.Asset[] = [];
// 加载单个资源
cc.resources.load('textures/myTexture', cc.Texture2D, (err, texture: cc.Texture2D) => {
if (err) {
console.error('资源加载失败:', err);
return;
}
// 添加单个资源到自动释放列表
this.addAutoReleaseAsset(texture);
// 使用资源,例如设置精灵的纹理
const sprite = this.node.getComponent(cc.Sprite);
if (sprite) {
sprite.spriteFrame = new cc.SpriteFrame(texture);
}
});
// 批量加载资源
cc.resources.loadDir('textures', cc.Texture2D, (err, textures: cc.Texture2D[]) => {
if (err) {
console.error('资源加载失败:', err);
return;
}
// 将加载的资源添加到数组中
assets.push(...textures);
// 添加多个资源到自动释放列表
this.addAutoReleaseAssets(assets);
// 使用资源,例如设置多个精灵的纹理
const sprites = this.node.getComponentsInChildren(cc.Sprite);
for (let i = 0; i < sprites.length && i < textures.length; i++) {
sprites[i].spriteFrame = new cc.SpriteFrame(textures[i]);
}
});
}
}
3.x
封装
// AutoReleaseAssets.ts
import { _decorator, Component, Asset } from 'cc';
const { ccclass, menu, disallowMultiple } = _decorator;
@ccclass
@menu('资源管理/AutoReleaseAssets/自动释放资源')
@disallowMultiple
export class AutoReleaseAssets extends Component {
private dynamicsAssets: Asset[] = [];
/**
* 添加单个资源到自动释放列表
* @param _asset 要添加的资源
*/
public addAutoReleaseAsset(_asset: Asset): void {
if (_asset) {
_asset.addRef();
this.dynamicsAssets.push(_asset);
}
}
/**
* 添加多个资源到自动释放列表
* @param _assets 要添加的资源数组
*/
public addAutoReleaseAssets(_assets: Asset[]): void {
for (const _asset of _assets) {
this.addAutoReleaseAsset(_asset);
}
}
/**
* 组件销毁时自动释放资源
*/
onDestroy(): void {
for (const asset of this.dynamicsAssets) {
if (asset) {
asset.decRef();
}
}
this.dynamicsAssets = [];
}
}
// 为 Component 原型添加扩展方法
declare global {
interface Component {
addAutoReleaseAsset(_asset: Asset): void;
addAutoReleaseAssets(_assets: Asset[]): void;
}
}
Component.prototype.addAutoReleaseAsset = function (_asset: Asset): void {
let autoReleaseComponent = this.node.getComponent(AutoReleaseAssets);
if (!autoReleaseComponent) {
autoReleaseComponent = this.node.addComponent(AutoReleaseAssets);
}
autoReleaseComponent.addAutoReleaseAsset(_asset);
};
Component.prototype.addAutoReleaseAssets = function (_assets: Asset[]): void {
let autoReleaseComponent = this.node.getComponent(AutoReleaseAssets);
if (!autoReleaseComponent) {
autoReleaseComponent = this.node.addComponent(AutoReleaseAssets);
}
autoReleaseComponent.addAutoReleaseAssets(_assets);
};
使用
// MyComponent.ts
import { _decorator, Component, Sprite, SpriteFrame, resources, Texture2D } from 'cc';
import { AutoReleaseAssets } from './AutoReleaseAssets'; // 根据实际路径调整
const { ccclass } = _decorator;
@ccclass('MyComponent')
export class MyComponent extends Component {
start() {
// 加载单个资源
resources.load('textures/myTexture', Texture2D, (err, texture: Texture2D) => {
if (err) {
console.error('资源加载失败:', err);
return;
}
// 添加单个资源到自动释放列表
this.addAutoReleaseAsset(texture);
// 使用资源,例如设置精灵的纹理
const sprite = this.node.getComponent(Sprite);
if (sprite) {
sprite.spriteFrame = new SpriteFrame(texture);
}
});
// 加载多个资源
const resourcePaths = ['textures/myTexture1', 'textures/myTexture2'];
const assets: Texture2D[] = [];
resources.loadDir('textures', Texture2D, (err, textures: Texture2D[]) => {
if (err) {
console.error('资源加载失败:', err);
return;
}
// 将加载的资源添加到数组中
assets.push(...textures);
// 添加多个资源到自动释放列表
this.addAutoReleaseAssets(assets);
// 使用资源,例如设置多个精灵的纹理
const sprites = this.node.getComponentsInChildren(Sprite);
for (let i = 0; i < sprites.length && i < textures.length; i++) {
sprites[i].spriteFrame = new SpriteFrame(textures[i]);
}
});
}
}
说明
命名空间和导入方式:在 Cocos Creator 3.x 系列中,很多类和模块的导入方式有所不同,使用
import { ... } from 'cc' 来导入所需的类。
API 调整:cc.resources 现在变为 resources,可以直接从 cc 命名空间中导入使用。
cc.isValid 调整:在这个场景中,直接使用简单的真值判断(如 if (_asset))来检查资源是否有效,简化了代码。