有个更简单方案,你试试
import { AssetManager } from ‘cc’;
import { _decorator, assetManager, Component, Node, path } from ‘cc’;
export class LoadWebZipBundleItem{
public url:string
public bundle:AssetManager.Bundle
public data:any
public bundleName:string
public isLoading:boolean=false
private _progress?:(prv:number,loaded:number,total:number)=>void
private _complete?:(bundle:AssetManager.Bundle,data:any)=>void
private _totalProgress:number=0
reset(){
this._progress=null
this._complete=null
this.data=null
this.bundle?.releaseUnusedAssets()
this.bundle=null
this.isLoading=false
}
async startLoad(url: string,value:any,progress?:(prv:number,loaded:number,total:number)=>void,complete?:(bundle:AssetManager.Bundle,data:any)=>void){
this.url=url
this.data=value
this.isLoading=true
let bundleVersion:string=value && value.bundleVersion
this.bundleName=value && value.bundleName || ""
let rate:number=0.5
if(this.bundleName.length > 0){
rate=0.001
}
this._progress=progress
this._complete=complete
if(value && value.version){
this.url+="?version="+value.version
}
let bundleData:ArrayBuffer = await this.downloadBundle(this.url,(prv:number,loaded:number,total:number)=>{
this._totalProgress = prv * rate
this._progress && this._progress(this._totalProgress,loaded,total)
})
let res:any = await this.loadBundleFromMemory(bundleData,(prv:number,loaded:number,total:number)=>{
let prvv:number=prv * rate * 0.1
if(this._totalProgress >= 1.0)this._totalProgress=1
else this._totalProgress+=prvv
this._progress && this._progress(this._totalProgress,loaded,total)
})
if(this.bundleName.length > 0){
this.bundle = await this.loadBundle(this.bundleName,{version:bundleVersion},(prv:number,finished: number, total: number, item: AssetManager.RequestItem)=>{
let prvv:number=finished * rate * 0.1
if(this._totalProgress >= 1.0)this._totalProgress=1
else this._totalProgress+=prvv
this._progress && this._progress(this._totalProgress,finished,total)
})
this._complete && this._complete(this.bundle,this.data)
}else{
this._complete && this._complete(null,this.data)
}
}
/**
* 模拟下载Bundle数据
*/
private downloadBundle(url: string,progress?:(prv:number,loaded:number,total:number)=>void): Promise<ArrayBuffer> {
return new Promise((resolve, reject) => {
const xhr:XMLHttpRequest = new XMLHttpRequest();
xhr.responseType = 'arraybuffer';
xhr.open('GET', url, true);
xhr.onprogress=(event:ProgressEvent)=>{
if(event.lengthComputable){
var percentComplete :number= event.loaded / event.total;
progress && progress(percentComplete,event.loaded,event.total)
}
}
xhr.onreadystatechange=()=>{
if (xhr.readyState == 4 && xhr.status === 200) {
resolve(xhr.response);
}
}
xhr.onerror = () => reject(new Error('网络错误'));
xhr.send();
});
}
/**
* zip内存解压数据
* @param bundleName
* @param bundleData
* @returns
*/
private loadBundleFromMemory(bundleData: ArrayBuffer,progress?:(prv:number,loaded:number,total:number)=>void):Promise<any>{
return new Promise(async resolve=>{
let jsZip:JSZip=new JSZip()
let zipFile:JSZip = await jsZip.loadAsync(bundleData)
let keys = Object.keys(zipFile.files);
let index:number=0
let count:number=0
for (let i = 0; i < keys.length; i++) if(!zipFile.files[keys[i]].dir)count++
for (let i = 0; i < keys.length; i++) {
let key = keys[i];
let ext:string=key.substring(key.lastIndexOf(".")+1,key.length)
let data = zipFile.files[key];
if(data.dir)continue
let asyncType:any = "blob";
let blob:any = await data.async(asyncType)
let imgUrl:string = URL.createObjectURL(blob);
assetManager.loadRemote(imgUrl,{ext:ext},(err: Error | null, data:any)=>{
index++
if(err){
console.error(`资源加载失败 -> ${err.message}`)
return
}
if(index >= count){
resolve(data)
}else{
var percentComplete=index / count
progress && progress(percentComplete,index,count)
}
})
}
})
}
/**
* 加载bundle
* @param bundleName
* @param options
* @returns
*/
loadBundle(bundleName:string,options?:any,progress?:(prv:number,finished: number, total: number, item: AssetManager.RequestItem)=>void):Promise<AssetManager.Bundle>{
return new Promise(resolve=>{
let version:string = options && options.version
assetManager.loadBundle(bundleName,{version:version},(err1:Error,bundle:AssetManager.Bundle)=>{
this.bundle=err1 ? null : bundle
if(this.bundle){
this.bundle.loadDir("/",(finished: number, total: number, item: AssetManager.RequestItem)=>{
const prv:number = parseFloat((finished / total).toFixed(2))
progress && progress(prv,finished,total,item)
},(error1:Error,data1:any)=>{
resolve(error1!=null ? null : data1)
})
}else{
resolve(err1!=null ? null : bundle)
}
})
})
}
}
直接这样加载显示
ZipWebLoader.getInstance().loadWebZipBundle(remoteZipUrl,{bundleName:“20011”},(prv:number,loaded:number,total:number)=>{
console.log("prv -> ",prv)
},async (bundle:any)=>{
console.log("load bundle complete ")
await Sleep(5000)
director.loadScene("20011",(error: null | Error, scene?: Scene)=>{
// if(!error)director.runScene(scene)
let persistNode:Node=window["UIManager"].getInstance().root
if(persistNode && persistNode.isValid){
persistNode.active=false
}
})
})