2D游戏中,通过FragmentManager创建Fragment对象池,生成碎片的时候从池中取出,然后因为碎片的图不一样就需要创建的时候动态传进来,现在遇到的问题是这样做一旦生成碎片过多draw call导致帧数下降,除了每个不同的碎片创建单独的预制体还有其他办法吗?
碎片管理器 FragmentManager.ts
import { _decorator, Component, instantiate, Node, Prefab, randomRange, Sprite, SpriteFrame, Vec3 } from 'cc';
import { Game } from '../Game/Game';
import { Fragment } from './Fragment';
import { ObjectPool } from '../Services/ObjectPool';
const { ccclass, property } = _decorator;
@ccclass('FragmentManager')
export class FragmentManager extends Component {
@property(Prefab) fragmentPrefab: Prefab;
private fragmentPool: ObjectPool<Node> = null;
private static instance: FragmentManager;
public static get Instance(): FragmentManager {
return this.instance;
}
protected onLoad(): void {
this.initPool();
FragmentManager.instance = this;
}
private initPool() {
this.fragmentPool = new ObjectPool<Node>(() => {
return instantiate(this.fragmentPrefab);
}, 200, "Fragment");
}
createFragments(position: Vec3, fragmentSpriteFrames: Array<SpriteFrame>) {
fragmentSpriteFrames.forEach(spriteFrame => {
const fragmentNode = this.fragmentPool.get();
const fragment = fragmentNode.getComponent(Fragment);
fragmentNode.active = true;
fragmentNode.setPosition(position);
fragmentNode.parent = Game.Instance.Floor;
// 设置碎片的精灵帧
const sprite = fragmentNode.getComponent(Sprite);
if (sprite) {
sprite.spriteFrame = spriteFrame;
}
// 设置碎片的随机大小和初始化参数
const scale = randomRange(0.95, 1.25);
fragmentNode.setScale(scale, scale, scale);
fragment?.initFragment(position);
});
}
public recycleFragment(fragmentNode: Node) {
fragmentNode.getComponent(Fragment)?.reset();
this.fragmentPool.put(fragmentNode);
}
}
碎片挂载的脚本 Fragment
import { _decorator, Component, instantiate, Node, Prefab, randomRange, Sprite, SpriteFrame, Vec3 } from 'cc';
import { Game } from '../Game/Game';
import { Fragment } from './Fragment';
import { ObjectPool } from '../Services/ObjectPool';
const { ccclass, property } = _decorator;
@ccclass('FragmentManager')
export class FragmentManager extends Component {
@property(Prefab) fragmentPrefab: Prefab;
private fragmentPool: ObjectPool<Node> = null;
private static instance: FragmentManager;
public static get Instance(): FragmentManager {
return this.instance;
}
protected onLoad(): void {
this.initPool();
FragmentManager.instance = this;
}
private initPool() {
this.fragmentPool = new ObjectPool<Node>(() => {
return instantiate(this.fragmentPrefab);
}, 200, "Fragment");
}
createFragments(position: Vec3, fragmentSpriteFrames: Array<SpriteFrame>) {
fragmentSpriteFrames.forEach(spriteFrame => {
const fragmentNode = this.fragmentPool.get();
const fragment = fragmentNode.getComponent(Fragment);
fragmentNode.active = true;
fragmentNode.setPosition(position);
fragmentNode.parent = Game.Instance.Floor;
// 设置碎片的精灵帧
const sprite = fragmentNode.getComponent(Sprite);
if (sprite) {
sprite.spriteFrame = spriteFrame; // fragmentSpriteFrames 都是来自于同一个图集中的图片,这里设置spriteFrame 是否导致Draw Call 增加呢?
}
// 设置碎片的随机大小和初始化参数
const scale = randomRange(0.95, 1.25);
fragmentNode.setScale(scale, scale, scale);
fragment?.initFragment(position);
});
}
public recycleFragment(fragmentNode: Node) {
fragmentNode.getComponent(Fragment)?.reset();
this.fragmentPool.put(fragmentNode);
}
}