此管理器主要用于加载Unity导出的资源,如3D场景,3D预制体等等。代码如下:
/**
* Unity导出资源管理器
*/
export default class ResMgr extends Laya.Script
{
private unityResMap = new Map(); //预制体字典:Map
public static Instance: ResMgr;
constructor()
{
super();
ResMgr.Instance = this;
}
//=====================================场景=======================================
/**
* 获取(.ls)类型预制体的完整路径
* @param sceneName 场景名称
*/
public GetSc3dPath(sceneName: string): string
{
return "res/Scenes/Conventional/" + sceneName + ".ls";
}
/**
* 加载并打开3D场景(.ls)
* @param sc3dName 3d场景名称
* @param caller 作用域
* @param callback 回调((sc3d:Laya.Scene3D)=>{})
*/
public OpenSc3D(sc3dName: string, caller: any, callback: Function=(sc3d?: Laya.Scene3D)=>{})
{
let sc3dResPath = this.GetSc3dPath(sc3dName);
Laya.Scene3D.load(sc3dResPath, Laya.Handler.create(caller, (sc3d: Laya.Scene3D)=>
{
sc3d.name=sc3dName;
Laya.stage.addChild(sc3d);
Laya.stage.setChildIndex(sc3d,0);
callback(sc3d);
}));
}
/**
* 销毁3d场景并清理场景资源
* @param sc3d 要清理的3d场景
* @param sc3dName 要清理的3d场景名称
*/
public Destoy3dScene(sc3d: Laya.Scene3D, sc3dName: string)
{
if(sc3d)
{
sc3d.destroy(true);
sc3d = null;
}
this.ClearRes(this.GetSc3dPath(sc3dName));
Laya.Resource.destroyUnusedResources();
}
//=====================================3D精灵=======================================
/**
* 获取(.lh)类型预制体的完整路径
* @param prefabName 预制体名称
*/
public GetPrefabPath(prefabName: string): string
{
return "res/Prefabs/Conventional/" + prefabName + ".lh";
}
/**
* 加载sp3d精灵,回调是对缓存中的资源进行操作
* @param sp3dName 资源名称
* @param caller 作用域
* @param callback 回调
*/
public LoadSp3d(sp3dName: string, caller: any, callback: Function=(sp3d:Laya.Sprite3D)=>{})
{
if (this.unityResMap.has(sp3dName))
{
let tempSp3d = this.unityResMap.get(sp3dName) as Laya.Sprite3D;
callback(tempSp3d);
}
else
{
Laya.Sprite3D.load(this.GetPrefabPath(sp3dName),Laya.Handler.create(caller,(sp3d:Laya.Sprite3D)=>
{
let realSp3d=sp3d.getChildAt(0)as Laya.Sprite3D;
this.unityResMap.set(sp3dName, realSp3d);
callback(realSp3d);
}));
}
}
/**
* 清理sp3d资源并在资源字典里移除
* @param sp3dName 预制资源名称
*/
public DestroySp3dRes(sp3dName: string)
{
if (!this.unityResMap.has(sp3dName))
return;
let sp3d=this.unityResMap.get(sp3dName)as Laya.Sprite3D;
sp3d.destroy(true);
sp3d = null;
this.ClearRes(this.GetPrefabPath(sp3dName));
this.unityResMap.delete(sp3dName);
Laya.Resource.destroyUnusedResources();
}
//=====================================材质Material=====================================
/**
* 加载贴图并设置Unlit材质
* @param skinnedMeshSp3d 节点
* @param textureResPath 地址
* @param caller 作用域
*/
public SetUnlitTexture(skinnedMeshSp3d:Laya.SkinnedMeshSprite3D,textureResPath:string,caller: any)
{
Laya.Texture2D.load(textureResPath, Laya.Handler.create(caller,function(tex:Laya.Texture2D)
{
let mat = new Laya.UnlitMaterial();
mat.albedoTexture = tex;
skinnedMeshSp3d.skinnedMeshRenderer.material = mat;
}));
}
/**
* 加载贴图并设置Standard材质
* @param skinnedMeshSp3d 节点
* @param textureResPath 地址
* @param caller 作用域
*/
public SetStandardTexture(skinnedMeshSp3d:Laya.SkinnedMeshSprite3D,textureResPath:string,caller: any)
{
Laya.Texture2D.load(textureResPath, Laya.Handler.create(caller,function(tex:Laya.Texture2D)
{
let mat = new Laya.PBRStandardMaterial();
mat.albedoTexture = tex;
skinnedMeshSp3d.skinnedMeshRenderer.material = mat;
}));
}
/**
* 设置天空盒子材质
* @param camera 摄像机
* @param mat 材质
*/
public SetSkyMat(camera: Laya.Camera, mat: Laya.Material)
{
let skyRenderer: Laya.SkyRenderer = camera.skyRenderer;
skyRenderer.mesh = Laya.SkyBox.instance;
skyRenderer.material = mat;
}
//=====================================加载多资源=====================================
/**
* 同时加载多个资源(不推荐使用,不方便资源管理)
* @param resArray 使用资源路径数组
* @param caller 作用域
* @param callback 加载资源完后的回调
*/
public LoadMultiRes(resArray: string[], caller: any, callback: Function)
{
Laya.loader.create(resArray, Laya.Handler.create(caller, callback));
}
/**
* 获取加载完多个资源后,资源缓存里的某个资源(必须在LoadMultiRes的回调中获取)
* @param resPath 资源路径
*/
public GetRes(resPath: string): any
{
return Laya.Loader.getRes(resPath);
}
//=====================================清理资源=======================================
/**
* 清理指定路径的资源(用于2d,3d预制体,场景,精灵,资源的清理)
* @param resPath 资源路径
*/
public ClearRes(resPath:string)
{
Laya.LoaderManager.prototype.clearRes(resPath);
}
/**
* 清理单个路径的贴图纹理资源,下次加载场景时会自动重新设置纹理(用于贴图文件的清理)
* @param texturePath 纹理路径
*/
public ClearTexture(texturePath:string)
{
Laya.LoaderManager.prototype.clearTextureRes(texturePath);
}
//=====================================其他=======================================
/**
* 打印字典
*/
public LogUnityResMapInfo() {
if (this.unityResMap.size==0||!this.unityResMap)
{
console.log("Map为空");
return;
}
console.log("Map长度:"+this.unityResMap.size);
for (let [key, value] of this.unityResMap)
{
console.log("key:", key, "===", "value:", value);
}
}
}
使用方法:
在导出Unity场景或预制体时,需要注意:需要在导出工具里要勾上,其他设置下的自定义导出根目录名,名称可以自定义,我这里场景使用的:“Scenes”,预制体使用的“Prefabs”。
这样导出资源的好处是可以覆盖重复资源,比如多个预制体或场景使用了同一个资源,那么使用这种方法导出就可以共用一个资源。
代码里在这两个方法修改路径名称,要和在Unity里导出工具设置的名称一致:
接下来是加载方法的使用:
打开3D场景:
ResMgr.Instance.OpenSc3D(“3D场景名称”, this, (sc3d: Laya.Scene3D) =>
{
//加载完3D场景后的回调
});
如果不使用3D场景了,需要对其进行销毁:
ResMgr.Instance.Destoy3dScene(“3D场景对象”,“3D场景名称”);
加载3D精灵:
ResMgr.Instance.LoadSp3d("3D精灵名称", this, (sp3d: Laya.Sprite3D) =>
{
//加载完3D精灵后的回调
});
代码里还有一些其他加载的方法,使用也比较简单,直接调用即可。
ResMgr管理器的初始化可以参考我以前的帖子,场景管理器。