#if UNITY_EDITOR
|
|
using System;
|
|
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using System.IO;
|
|
using System.Runtime.Serialization;
|
|
using LuaFramework;
|
|
using LuaInterface;
|
|
using UnityEngine;
|
|
using UnityEngine.SceneManagement;
|
|
using UnityEngine.Video;
|
|
|
|
public class ResourceManagerEx : ILocalResLoader
|
|
{
|
|
ResourceManager mgr;
|
|
FilePathRuleInfo pathRules;
|
|
Dictionary<string,float> resLoadedTime;
|
|
Dictionary<string,string> cachePaths;
|
|
string rulePath = Application.dataPath + "/FilePathRule.json";
|
|
string cacheFilePath = Application.dataPath + "/FilePathCache.txt";
|
|
|
|
public void Init(ResourceManager mgr)
|
|
{
|
|
this.mgr = mgr;
|
|
resLoadedTime = new Dictionary<string,float>();
|
|
if (File.Exists(rulePath))
|
|
{
|
|
var infoContent = File.ReadAllText(rulePath);
|
|
pathRules = JsonUtility.FromJson<FilePathRuleInfo>(infoContent);
|
|
}
|
|
if (AppConst.IsUseLocalPathCache)
|
|
{
|
|
cachePaths = new Dictionary<string,string>();
|
|
if (File.Exists(cacheFilePath))
|
|
{
|
|
var infoContent = File.ReadAllLines(cacheFilePath);
|
|
foreach (var item in infoContent)
|
|
{
|
|
var kvParts = item.Split(',');
|
|
cachePaths.Add(kvParts[0], kvParts[1]);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
public void OnDestroy()
|
|
{
|
|
if (AppConst.IsUseLocalPathCache)
|
|
{
|
|
List<string> cacheList = new List<string>();
|
|
foreach (var item in cachePaths)
|
|
{
|
|
cacheList.Add(item.Key+","+item.Value);
|
|
}
|
|
File.WriteAllLines(cacheFilePath, cacheList.ToArray());
|
|
}
|
|
}
|
|
|
|
public bool Load(string abName, string[] assetNames, Type type, Action<UnityEngine.Object[]> action = null, LuaFunction func = null, uint level = 0)
|
|
{
|
|
if (assetNames.Length==0)
|
|
return false;
|
|
if (abName.EndsWith(AppConst.ExtName))
|
|
abName = abName.Substring(0, abName.Length-AppConst.ExtName.Length);
|
|
assetNames = HandleMultipleRes(assetNames);
|
|
if (assetNames.Length > 1)
|
|
{
|
|
//同时加载多个文件
|
|
LoadMultipleAssetsInLocal(abName, assetNames, type, action, func, level);
|
|
return true;
|
|
}
|
|
var filePath = GetRealPath(abName, assetNames[0], type);
|
|
if (filePath == "")
|
|
return false;
|
|
mgr.StartCoroutine(LoadAssetInLocal(filePath, abName, assetNames[0], type, action, func));
|
|
return true;
|
|
}
|
|
|
|
IEnumerator LoadAssetInLocal(string filePath, string abName, string resName, Type type, Action<UnityEngine.Object[]> action = null, LuaFunction func = null)
|
|
{
|
|
//如果之前已经加载过的话就不用等到下一帧才加载成功
|
|
var hasLoaded = resLoadedTime.ContainsKey(filePath.ToLowerInvariant());
|
|
if (!hasLoaded)
|
|
yield return new WaitForSeconds(0.01f);
|
|
UnityEngine.Object res = UnityEditor.AssetDatabase.LoadAssetAtPath(filePath, type);
|
|
if (res != null)
|
|
{
|
|
if (resLoadedTime.ContainsKey(filePath.ToLowerInvariant()))
|
|
resLoadedTime[filePath.ToLowerInvariant()] = Time.time;
|
|
else
|
|
resLoadedTime.Add(filePath.ToLowerInvariant(), Time.time);
|
|
if (func != null)
|
|
{
|
|
List<UnityEngine.Object> list = new List<UnityEngine.Object>();
|
|
list.Add(res);
|
|
object[] args = new object[] { list.ToArray() };
|
|
func.Call(args);
|
|
func.Dispose();
|
|
func = null;
|
|
}
|
|
else if (action != null)
|
|
{
|
|
List<UnityEngine.Object> list = new List<UnityEngine.Object>();
|
|
list.Add(res);
|
|
UnityEngine.Object[] args = list.ToArray();
|
|
action(args);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
Debug.Log("ResourceManagerEx:LoadAssetInLocal Error:cannot find file:" + filePath+" ab:"+abName+" res:"+resName);
|
|
}
|
|
yield return null;
|
|
}
|
|
|
|
void LoadMultipleAssetsInLocal(string abName, string[] assetNames, Type type, Action<UnityEngine.Object[]> action = null, LuaFunction func = null, uint level = 0)
|
|
{
|
|
List<UnityEngine.Object> list = new List<UnityEngine.Object>();
|
|
foreach (var resName in assetNames)
|
|
{
|
|
var filePath = GetRealPath(abName, resName, type);
|
|
UnityEngine.Object res = UnityEditor.AssetDatabase.LoadAssetAtPath(filePath, type);
|
|
// Debug.Log("LoadMultipleAssetsInLocal res : "+(res!=null)+" file:"+filePath+" ab:"+abName+" res:"+resName);
|
|
list.Add(res);//不管是否为null都要放进去
|
|
if (res != null)
|
|
{
|
|
if (resLoadedTime.ContainsKey(filePath.ToLowerInvariant()))
|
|
resLoadedTime[filePath.ToLowerInvariant()] = Time.time;
|
|
else
|
|
resLoadedTime.Add(filePath.ToLowerInvariant(), Time.time);
|
|
}
|
|
else
|
|
{
|
|
Debug.Log("ResourceManagerEx:LoadMultipleAssetsInLocal Error:cannot find file:" + filePath+" ab:"+abName+" res:"+resName);
|
|
}
|
|
}
|
|
if (func != null)
|
|
{
|
|
object[] args = new object[] { list.ToArray() };
|
|
func.Call(args);
|
|
func.Dispose();
|
|
func = null;
|
|
}
|
|
else if (action != null)
|
|
{
|
|
UnityEngine.Object[] args = list.ToArray();
|
|
action(args);
|
|
}
|
|
}
|
|
|
|
//因为传入的assetNames可能是{"1.png,2.png","3.png","4.png"},注意1和2是连在一起的,所以需要转化为单独元素的列表:{"1.png","2.png","3.png","4.png"}
|
|
string[] HandleMultipleRes(string[] assetNames)
|
|
{
|
|
var hasMultiResInOne = false;
|
|
foreach (var names in assetNames)
|
|
{
|
|
if (names.IndexOf(',')!=-1)
|
|
{
|
|
hasMultiResInOne = true;
|
|
break;
|
|
}
|
|
}
|
|
if (hasMultiResInOne)
|
|
{
|
|
List<string> realResList = new List<string>();
|
|
foreach (var names in assetNames)
|
|
{
|
|
if (names.IndexOf(',')!=-1)
|
|
{
|
|
var parts = names.Split(',');
|
|
foreach (var part in parts)
|
|
{
|
|
realResList.Add(part);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
realResList.Add(names);
|
|
}
|
|
}
|
|
assetNames = realResList.ToArray();
|
|
}
|
|
return assetNames;
|
|
}
|
|
|
|
private static string GetIconFilePathInDeep(string path, string[] abNames, string spriteName)
|
|
{
|
|
if (System.IO.Directory.Exists(path))
|
|
{
|
|
System.IO.DirectoryInfo direction = new System.IO.DirectoryInfo(path);
|
|
System.IO.DirectoryInfo[] sub_directions = direction.GetDirectories();
|
|
foreach (var dir in sub_directions)
|
|
{
|
|
string try_dir_path = path + dir.Name + "/";
|
|
string result = try_dir_path + spriteName;
|
|
if (dir.Name == abNames[1])
|
|
{
|
|
System.IO.DirectoryInfo try_dir = new System.IO.DirectoryInfo(try_dir_path);
|
|
System.IO.FileInfo[] files = try_dir.GetFiles("*", System.IO.SearchOption.AllDirectories);
|
|
for (int i = 0; i < files.Length; i++)
|
|
{
|
|
if (files[i].Name == (spriteName))
|
|
{
|
|
path = files[i].FullName;
|
|
return path;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
result = GetIconFilePathInDeep(try_dir_path, abNames, spriteName);
|
|
if (result != "")
|
|
return result;
|
|
}
|
|
}
|
|
}
|
|
return "";
|
|
}
|
|
|
|
static List<string> NoTextureFolder = new List<string> { "alphasingle", "alphaCommon", "alphaMain" };
|
|
private string GetRealPath(string abName, string resName, Type type)
|
|
{
|
|
string path = "";
|
|
do
|
|
{
|
|
var cacheKey = (abName+":"+resName).ToLowerInvariant();
|
|
// Debug.Log("cachePaths.ContainsKey(cacheKey) : "+cachePaths.ContainsKey(cacheKey)+" key:"+cacheKey);
|
|
if (AppConst.IsUseLocalPathCache && cachePaths.ContainsKey(cacheKey))
|
|
{
|
|
path = cachePaths[cacheKey];
|
|
break;
|
|
}
|
|
var dotIndex = resName.IndexOf('.');
|
|
if (dotIndex != -1)
|
|
resName = resName.Substring(0, dotIndex);
|
|
path = SearchInUI(abName, resName);
|
|
if (path != "")
|
|
break;
|
|
path = SearchByRules(abName, resName);
|
|
if (path != "")
|
|
break;
|
|
path = SearchInIcon(abName, resName);
|
|
if (path != "")
|
|
break;
|
|
if (AppConst.UseLocalResource >= 2)
|
|
{
|
|
//这一步将从整个项目资源目录进行搜索,会很卡的,建议发现找不到资源时在FilePathRule.json文件增加搜索规则
|
|
path = SearchInAll(abName, resName, type);
|
|
if (path != "")
|
|
break;
|
|
}
|
|
} while (false);
|
|
var isFileExist = File.Exists(path);
|
|
// Debug.Log("load local file failed : "+"isFileExist: "+isFileExist+" abName:"+abName+" res:"+assetNames[0]+" guess file:"+filePath);
|
|
if (!isFileExist)
|
|
{
|
|
if (AppConst.PrintLoadLocalRes >= 1)
|
|
{
|
|
var isPrintStack = AppConst.PrintLoadLocalRes >= 2;
|
|
string printContent = "load local file failed : "+"abName:"+abName+" res:"+resName+" guess file:"+path;
|
|
if (isPrintStack)
|
|
printContent += new System.Diagnostics.StackTrace().ToString();
|
|
Debug.Log(printContent);
|
|
}
|
|
path = "";
|
|
}
|
|
if (path.IndexOf(':')!=-1)
|
|
{
|
|
path = path.Replace('\\', '/');
|
|
path = UnityEditor.FileUtil.GetProjectRelativePath(path);
|
|
}
|
|
if (AppConst.IsUseLocalPathCache)
|
|
{
|
|
if (File.Exists(path))
|
|
{
|
|
var cacheKey = (abName+":"+resName).ToLowerInvariant();
|
|
// if (cachePaths.ContainsKey(cacheKey))
|
|
cachePaths[cacheKey] = path;
|
|
// else
|
|
// cachePaths.Add(cacheKey, path);
|
|
}
|
|
}
|
|
return path;
|
|
}
|
|
|
|
private string SearchByRules(string abName, string resName)
|
|
{
|
|
foreach (var rule in pathRules.Rules)
|
|
{
|
|
if (rule.Type == "StartsWith")
|
|
{
|
|
if (abName.StartsWith(rule.Key))
|
|
{
|
|
foreach (var testPath in rule.Paths)
|
|
{
|
|
var realPath = string.Format(testPath, resName);
|
|
if (File.Exists(realPath))
|
|
return realPath;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return "";
|
|
}
|
|
|
|
private string SearchInAll(string abName, string resName, Type type)
|
|
{
|
|
string typeName = GetTypeName(type);
|
|
string findFilter = resName;
|
|
if (typeName != "")
|
|
findFilter += " t:" + typeName;
|
|
string[] guids = UnityEditor.AssetDatabase.FindAssets(findFilter);
|
|
var retNum = guids.Length;
|
|
// Debug.Log(" findFilter : "+findFilter+" retNum:"+retNum+" typeName:"+typeName);
|
|
if (retNum == 1)
|
|
{
|
|
return UnityEditor.AssetDatabase.GUIDToAssetPath(guids[0]);
|
|
}
|
|
if (retNum > 1)
|
|
{
|
|
foreach (var retPathUID in guids)
|
|
{
|
|
var retPath = UnityEditor.AssetDatabase.GUIDToAssetPath(retPathUID);
|
|
// Debug.Log(retPath+" isEndWith:"+retPath.EndsWith(resName+"."+typeName.ToLowerInvariant()));
|
|
var fileSubffix = GetTypeFileSubffix(type);
|
|
if (retPath.ToLowerInvariant().EndsWith((resName+fileSubffix).ToLowerInvariant()))
|
|
return retPath;
|
|
}
|
|
}
|
|
return "";
|
|
}
|
|
|
|
private string GetTypeName(Type type)
|
|
{
|
|
if (type == typeof(GameObject))
|
|
return "Prefab";
|
|
else if (type == typeof(Sprite))
|
|
return "Sprite";
|
|
else if (type == typeof(Texture))
|
|
return "Texture";
|
|
else if (type == typeof(Mesh))
|
|
return "Mesh";
|
|
else if (type == typeof(Shader))
|
|
return "Shader";
|
|
else if (type == typeof(Scene))
|
|
return "Scene";
|
|
else if (type == typeof(Font))
|
|
return "Font";
|
|
else if (type == typeof(Material))
|
|
return "Material";
|
|
else if (type == typeof(AudioClip))
|
|
return "AudioClip";
|
|
return "";
|
|
}
|
|
|
|
private string GetTypeFileSubffix(Type type)
|
|
{
|
|
if (type == typeof(GameObject))
|
|
return ".prefab";
|
|
else if (type == typeof(Sprite))
|
|
return ".png";
|
|
else if (type == typeof(Texture))
|
|
return ".jpg";
|
|
else if (type == typeof(Mesh))
|
|
return ".fbx";
|
|
else if (type == typeof(Shader))
|
|
return ".shader";
|
|
else if (type == typeof(Scene))
|
|
return ".scene";
|
|
else if (type == typeof(Font))
|
|
return ".fnt";
|
|
else if (type == typeof(Material))
|
|
return ".mat";
|
|
else if (type == typeof(AudioClip))
|
|
return ".ogg";
|
|
return "";
|
|
}
|
|
|
|
private string SearchInIcon(string abName, string resName)
|
|
{
|
|
if (abName.StartsWith("icon_"))
|
|
{
|
|
string[] path_fix = abName.Split('_');
|
|
if (path_fix.Length >= 2)
|
|
{
|
|
string try_path = "Assets/LuaFramework/AssetBundleRes/iconjpg/" + resName;
|
|
if (!resName.EndsWith("jpg"))
|
|
try_path += ".jpg";
|
|
//Debug.Log("iconjpg try_path : "+try_path);
|
|
if (File.Exists(try_path))
|
|
{
|
|
return try_path;
|
|
}
|
|
else
|
|
{
|
|
string folder_str = path_fix[1];
|
|
try_path = "Assets/LuaFramework/AssetBundleRes/icon/" + folder_str + "/" + resName;
|
|
if (!resName.EndsWith(".png"))
|
|
resName += ".png";
|
|
//Debug.Log("icon try_path : "+try_path);
|
|
if (File.Exists(try_path))
|
|
{
|
|
return try_path;
|
|
}
|
|
else
|
|
{
|
|
try_path = "Assets/LuaFramework/AssetBundleRes/icon/" + folder_str + "/necessaryBg/" + resName;
|
|
if (!resName.EndsWith(".png"))
|
|
resName += ".png";
|
|
if (File.Exists(try_path))
|
|
{
|
|
return try_path;
|
|
}
|
|
else
|
|
{
|
|
try_path = GetIconFilePathInDeep("Assets/LuaFramework/AssetBundleRes/icon/", path_fix, resName);
|
|
if (try_path != "")
|
|
{
|
|
if (try_path.IndexOf(':') != -1)
|
|
try_path = UnityEditor.FileUtil.GetProjectRelativePath(try_path);
|
|
return try_path;
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|
|
}
|
|
}
|
|
return "";
|
|
}
|
|
|
|
private string SearchInUI(string abName, string resName)
|
|
{
|
|
string path = "";
|
|
bool is_no_texture_folder = false;
|
|
foreach (var item in NoTextureFolder)
|
|
{
|
|
if (abName.StartsWith(item))
|
|
{
|
|
is_no_texture_folder = true;
|
|
path = "Assets/LuaFramework/AssetBundleRes/ui/" + item + "/" + resName + ".png";
|
|
//Debug.Log("NoTextureFolder abName:"+abName+" resName:"+resName+" path:"+path);
|
|
return path;
|
|
}
|
|
}
|
|
if (!is_no_texture_folder)
|
|
{
|
|
if (abName.EndsWith("_asset"))
|
|
{
|
|
string folder_name = abName.Substring(0, abName.Length - 6);
|
|
string folder_path = "Assets/LuaFramework/AssetBundleRes/ui/" + folder_name + "/texture/";
|
|
path = folder_path + resName;
|
|
if (File.Exists(path + ".png"))
|
|
{
|
|
return path + ".png";
|
|
}
|
|
else if (File.Exists(path + ".jpg"))
|
|
{
|
|
return path + ".jpg";
|
|
}
|
|
else
|
|
{
|
|
if (Directory.Exists(folder_path))
|
|
{
|
|
DirectoryInfo direction = new DirectoryInfo(folder_path);
|
|
FileInfo[] files = direction.GetFiles("*", SearchOption.AllDirectories);
|
|
for (int i = 0; i < files.Length; i++)
|
|
{
|
|
// if (files[i].Name.StartsWith(resName))
|
|
if (files[i].Name == (resName+".png"))
|
|
{
|
|
path = files[i].FullName;
|
|
return path;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
string folder_path = "Assets/LuaFramework/AssetBundleRes/ui/" + abName + "/prefab/";
|
|
path = folder_path + resName + ".prefab";
|
|
if (File.Exists(path))
|
|
return path;
|
|
}
|
|
}
|
|
return "";
|
|
}
|
|
}
|
|
|
|
[Serializable]
|
|
public class FilePathRule
|
|
{
|
|
public string Type;
|
|
public string Key;
|
|
public List<string> Paths;
|
|
}
|
|
|
|
[Serializable]
|
|
public class FilePathRuleInfo
|
|
{
|
|
public List<FilePathRule> Rules;
|
|
}
|
|
|
|
#endif
|