123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112 |
- import { _decorator, Component, instantiate, Node, Prefab, Vec3 } from 'cc';
- const { ccclass, property } = _decorator;
- /**
- * 对象池管理器
- * 功能:
- * 1. 管理游戏对象的复用
- * 2. 减少频繁创建/销毁对象的性能开销
- * 3. 支持Prefab和Node两种类型的对象池
- */
- @ccclass('PoolManager')
- export class PoolManager extends Component {
- // 对象池存储(改为更准确的名称)
- private static _objectPools = new Map<string, Node[]>();
- /**
- * 从对象池获取节点(支持Prefab或Node)
- * @param prefab - Prefab资源或节点模板
- * @param parent - 可选父节点
- * @returns 可复用的节点实例
- */
- public static getNode(prefab: Prefab | Node, parent?: Node): Node {
- const poolKey = prefab instanceof Prefab ? prefab.data.name : prefab.name;
- let node: Node = null;
- //从对象池获取可用节点
- const pool = this._objectPools.get(poolKey);
- if(pool?.length > 0) {
- node = pool.pop();
- }else {
- node = instantiate(prefab) as Node;
- }
- //初始化节点状态
- if (node) {
- node.active = true;
- node.position = Vec3.ZERO;
- if(parent) {
- node.setParent(parent);
- }
- }
- return node;
- }
- /**
- * 通过名称从对象池获取节点
- * @param poolKey - 对象池键名
- * @param parent - 可选父节点
- * @returns 可复用的节点实例(如果没有则返回null)
- */
- public static getName(poolKey: string, parent?: Node): Node | null {
- const pool = this._objectPools.get(poolKey);
- const node = pool?.pop();
- if(node) {
- node.active = true;
- if(parent){
- node.setParent(parent);
- }
- }
- return node ?? null;
- }
- /**
- * 将节点回收到对象池
- * @param node - 要回收的节点
- */
- public static putNode(node: Node): void {
- if (!node?.isValid || !node) return;
- const poolKey = node.name;
- //清理节点状态
- node.removeFromParent();
- node.active = false;
- //存入对象池
- if(poolKey) {
- if(!this._objectPools.has(poolKey)) {
- this._objectPools.set(poolKey, []);
- }
- this._objectPools.get(poolKey).push(node);
- }else{//没有有效名称的节点直接销毁
- node.destroy();
- }
- }
- /**
- * 获取指定对象池的大小
- * @param poolKey - 对象池键名
- * @returns 对象池中可用节点的数量
- */
- public static getPoolSize(poolKey: string): number {
- return this._objectPools.get(poolKey)?.length ?? 0;
- }
- /**
- * 清空指定对象池
- * @param poolKey - 要清空的对象池键名
- */
- public static clearPool(poolKey: string): void {
- const pool = this._objectPools.get(poolKey);
- if (pool) {
- pool.forEach(node => node.destroy());
- this._objectPools.delete(poolKey);
- }
- }
- /**
- * 清空所有对象池
- */
- public static clearAll(): void {
- this._objectPools.forEach((pool, key) => {
- pool.forEach(node => node.destroy());
- });
- this._objectPools.clear();
- }
- }
|