源战役客户端
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

505 lines
18 KiB

#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