Cocos Create 3D 3.8 如何加载远程服务器模型FBX、GLB并解析显示到游戏

我的业务场景是需要将模型文件存放云服务器,然后动态根据数据库数据来加载到游戏中使用,同时可以给玩家用户也可以自行上传模型,经过平台审核没问题后,也可以渲染到游戏中来。

遇到的问题:

1.cocos不支持远程加载并解析文件
2.只支持AB包的形式,但很多时候我们并不喜欢重新打包
3.想过直接下载服务器的文件到本地,然后再用官方的API来解析,遇到各种问题,没法实现
4.论坛上有一个人2020年的时候提出过的方案,没法再实现
5.官方是否可以出版可以支持远程加载服务器上的模型、地形,这些很是必须的,总不太可能全部文件都打包放AB包,也适合不了需求,很多时候需要动态加载
6.个人觉得数据就是数据,代码就是代码,应该分开,数据应该可以动态加载,服务器一更新就可以使用,官方却只支持远程加载文本、JSON、图片,这些简单的文件,特殊的模型、地形图、这些也是必要的哇

cocos5
cocos6

期待官方回复,或者大家可以提出自己的想法和方案

个人觉得,小游戏可能定期更包没啥大问题,资源文件也不多,但面向大游戏,资源文件特别多,更新又频繁的话,肯定是需要放云服务器动态加载才是最好的,特别是数据和代码隔离思想一定要到位,而且官方既然都实现了对文本、JSON、图片这些资源的远程服务器加载了,为何不统一全部文件都实现?放AB包里真的不现实,实现不了动态数据

几个小时了,没人能回一下这个问题的解决方案吗?

fbx 应该是在拖入编辑器的时候动态解析了数据,直接使用肯定不行,毕竟不拖进去直接把fbx复制到文件夹是用不了的
可以看看能不能找到cocos的编辑器代码

看过,代码太多,改起来麻烦呢,如果官方完善的话,大家都可以用最好了

赞同,我现在做的游戏,期望远程加载tiledMap。结果不支持,现在在考虑咋实现呢

将资源做成bundle,打包的时候把这个远程包放服务器上【项目下的remote文件夹】,让引擎自己慢慢加载,我们代码上直接使用引擎提供的API来加载使用就好,反正我现在就这样做

fbx目录做成bundle怎样加载使用?

实现分两步:
1.远程加载服务器资源,在游戏主循环调用 GameBundleData.Instance.update();

export class GameBundleData extends Singleton {

   

    last_update_time:number = null; // 最后更新时间

    public update():void { // 检测更新资源包

        CF.delay(()=>{

            let con = false;

            if(this.last_update_time){

                let t = CFTime.timeStamp();

                if((t-this.last_update_time)/1000/60 >= 5){

                    //console.log('【游戏资源包数据】定时5分钟检测更新资源包触发...');

                    this.last_update_time = t;

                    con = true;

                }

            }else{

                this.last_update_time = CFTime.timeStamp();

                con = true;

            }

            if(con){

                CF.delay(()=>{

                    this.update_bundle();

                },0.001);

            }

        },0.001);

    }

   

    private update_bundle():void { // 更新资源包

        //读取服务器配置获取资源包版本信息

        //加载资源包

        Res.loadBundle('reslib','',(err,bundle)=>{

            if(err){

                return console.error(err);

            }

            if(bundle){

                Game.Instance._bundle_reslib = bundle;

            }

        });

    }

}

其中 Game.Instance._bundle_reslib 为 Game文件中的全局变量 _bundle_reslib:AssetManager.Bundle = null; // 资源包对象 reslib

2.自己写工具加载模型到游戏里 工具文件名为 Res

public static loadBundle(name:string,version:string,cb?: (err:Error | null, bundle?: AssetManager.Bundle)=>void) {
    assetManager.loadBundle(name,{version:version},cb);
}

public static instBundlePrefab3d(bundle: AssetManager.Bundle, root:Node | undefined = undefined, pos:Vec3 = Vec3.ZERO, path: string, cb?: (err:Error | null, asset?: Node)=>void) {

    Res.loadBundlePrefab(bundle,path,(err,asset)=>{

        if(CF.isNull(asset)){

            console.error('通过服务器实例3D模型 - 资源为空 : ',path);

            return;

        }

        cb(err,Res.inst3d(asset,root,pos));

    });

}

public static loadBundlePrefab(bundle: AssetManager.Bundle,path:string,cb?: (err:Error | null, asset?: Prefab)=>void) {

    bundle.load(path,Prefab,cb);

}

public static inst3d(asset: Prefab, root:Node | undefined = undefined,  pos:Vec3 = Vec3.ZERO) : Node {

    try {

        if (CF.isNull(asset)) {

            return null;

        }

        const instObj = instantiate(asset);

        if (root) {

            instObj.setParent(root);

        } else {

            director.getScene().addChild(instObj);

        }

        instObj.setWorldPosition(pos);

        instObj.setScale(Vec3.ONE);

        return instObj;

    } catch (error) {

        console.error('实例模型异常对象:',asset);

        console.error('实例模型异常:',error);

    }

    return null;

}

调用示例

Res.instBundlePrefab3d(Game.Instance._bundle_reslib,Game.Instance._objects_pool_node,new Vec3(p.x, p.y, p.z),resid,(err,asset)=>{

    if(asset){
		 // 实现你的业务逻辑
	}
});

其中 Game.Instance._objects_pool_node 为 Game文件中定义的全局变量 _objects_pool_node:Node | null | undefined; // 对象池节点 作为对象池

在Game文件初始化的时候执行
this._objects_pool_node = find('Main/objects_pool'); // 获取对象池节点对象
this._objects_pool_node.addComponent(ExitPointerLock);// 绑定支持锁定退出逻辑

非常同意,毕竟我是用cc做大型手游的,热更,远程加载真的很需要!

也可以读取模型的网格bin+json,蒙皮节点数据,骨骼json,动画bin+json;这四种数据合一起就可以组成cocos可以显示的蒙皮模型数据了,而静态模型只用要到网格数据就可以了。

也可以直接用插件: glTFLoader (cocos.com)

1赞