File was renamed from Assets/Launch/Manager/ResManager.cs |
| | |
| | | using UnityEngine;
|
| | | using System.Collections;
|
| | | using System.Collections.Generic;
|
| | | using Cysharp.Threading.Tasks;
|
| | | using System;
|
| | | using UnityEngine.U2D;
|
| | | using LitJson;
|
| | | using System.IO;
|
| | | using UnityEngine.Networking;
|
| | |
|
| | | #if UNITY_EDITOR
|
| | | using UnityEditor;
|
| | | #endif
|
| | |
|
| | | using LaunchCommon;
|
| | |
|
| | | public class ResManager : Singleton<ResManager>
|
| | | {
|
| | | |
| | |
|
| | | //不下载时本地安卓测试路径
|
| | | public string assetBundlesPath = Application.dataPath + "/../AssetBundles/Android/";
|
| | | public static string bytesFolderName = "logicbytes/";
|
| | | public string StreamingAssetPath
|
| | | {
|
| | | get
|
| | | {
|
| | | return ResourcesPath.Instance.StreamingAssetPath;
|
| | | }
|
| | | }
|
| | | public string ExternalStorePath |
| | | {
|
| | | get
|
| | | {
|
| | | return ResourcesPath.Instance.ExternalStorePath;
|
| | | }
|
| | | }
|
| | |
|
| | | //用于editor 下的资源路径
|
| | | public string ResourcesOutPath |
| | | {
|
| | | get
|
| | | {
|
| | | return ResourcesPath.ResourcesOutPath;
|
| | | }
|
| | | }
|
| | |
|
| | | public string CONFIG_FODLER
|
| | | {
|
| | | get
|
| | | {
|
| | | return ResourcesPath.CONFIG_FODLER;
|
| | | }
|
| | | }
|
| | |
|
| | | public string ResourcesOutAssetPath
|
| | | {
|
| | | get
|
| | | {
|
| | | return ResourcesPath.ResourcesOutAssetPath;
|
| | | }
|
| | | }
|
| | |
|
| | | public bool isPCTestDownLoad = false;
|
| | |
|
| | | public static readonly string[] VERSION_URL = new string[] {
|
| | | "http://gamecenter.secondworld.net.cn:11000/center/appversion_new.php/?"};
|
| | |
|
| | | public int debugBranch { get; private set; }
|
| | |
|
| | | private int urlIndex = 0;
|
| | |
|
| | | private string versionUrl;
|
| | |
|
| | | public VersionInfo versionInfo { get; private set; }
|
| | |
|
| | | private static LoadDllStep m_step;
|
| | |
|
| | | public static LoadDllStep step
|
| | | {
|
| | | get { return m_step; }
|
| | | set
|
| | | {
|
| | | m_step = value;
|
| | | Debug.Log("LoadDllStep:" + m_step);
|
| | | }
|
| | | }
|
| | |
|
| | | string assetBytesUrl;
|
| | |
|
| | | //从网络获取的资源版本信息
|
| | | public Dictionary<string, AssetVersion> assetVersions = new Dictionary<string, AssetVersion>();
|
| | |
|
| | | //本地LogicBytes文件和 assetVersions 比较是否需要下载
|
| | | public Dictionary<string, AssetVersion> localAssetVersions = new Dictionary<string, AssetVersion>();
|
| | |
|
| | | public static string versionUrlResult { get; private set; }
|
| | |
|
| | | /// <summary>
|
| | | /// 语言的ID,用于区分下载资源
|
| | | /// </summary>
|
| | | /// <value></value>
|
| | | public static string Id
|
| | | {
|
| | | get
|
| | | {
|
| | | var config = InitialFunctionConfig.Get("Language").Numerical1;
|
| | | if (string.IsNullOrEmpty(config))
|
| | | return "";
|
| | | return LocalSave.GetString("LANGUAGE_ID1");
|
| | | }
|
| | | set
|
| | | {
|
| | | LocalSave.SetString("LANGUAGE_ID1", value);
|
| | | }
|
| | | }
|
| | |
|
| | | //默认路径不附加地址,Id不为空时附加Id
|
| | | public static string fixPath
|
| | | {
|
| | | get
|
| | | {
|
| | | if (string.IsNullOrEmpty(Id))
|
| | | return "";
|
| | | return string.Format("/{0}", Id);
|
| | | }
|
| | | }
|
| | |
|
| | | private AssetBundle spriteBundle = null; //需要卸载
|
| | | private AssetBundle prefabBundle = null; //需要卸载
|
| | | private SpriteAtlas spriteAtlas = null;
|
| | |
|
| | | public void Init()
|
| | | {
|
| | | if (LocalSave.GetString("#@#BrancH") != string.Empty)
|
| | | {
|
| | | int tmpbranch;
|
| | | int.TryParse(LocalSave.GetString("#@#BrancH").Substring(1), out tmpbranch);
|
| | | if (tmpbranch != 0)
|
| | | debugBranch = tmpbranch;
|
| | | }
|
| | |
|
| | | var parentDirectory = Directory.GetParent(Application.persistentDataPath);
|
| | | if (File.Exists(parentDirectory + "/Debug"))
|
| | | {
|
| | | var content = File.ReadAllText(parentDirectory + "/Debug");
|
| | | if (!string.IsNullOrEmpty(content))
|
| | | {
|
| | | var json = JsonMapper.ToObject<DebugBranch>(File.ReadAllText(parentDirectory + "/Debug"));
|
| | | debugBranch = json.branch;
|
| | | }
|
| | | }
|
| | |
|
| | | Clock.Init();
|
| | | Debug.Log("ResManager.Init");
|
| | | }
|
| | |
|
| | | public void Release()
|
| | | {
|
| | | spriteBundle?.Unload(true); //true完全卸载,更新后重新加载
|
| | | prefabBundle?.Unload(true);
|
| | | assetVersions = null;
|
| | | localAssetVersions = null;
|
| | | spriteAtlas = null;
|
| | | Debug.Log("提前ResManager.Release资源");
|
| | | }
|
| | |
|
| | | public void RequestVersionCheck()
|
| | | {
|
| | | var versionConfig = VersionConfigEx.Get();
|
| | | var tables = new Dictionary<string, string>();
|
| | | tables["channel"] = versionConfig.appId;
|
| | | tables["versioncode"] = versionConfig.version;
|
| | | if (versionConfig.branch != 0)
|
| | | {
|
| | | tables["branch"] = versionConfig.branch.ToString();
|
| | | }
|
| | |
|
| | | tables["game"] = versionConfig.gameId;
|
| | |
|
| | | var url = string.Concat(VERSION_URL[urlIndex % VERSION_URL.Length], HttpRequest.HashtablaToString(tables));
|
| | |
|
| | | urlIndex++;
|
| | | versionUrl = url;
|
| | | Debug.Log("http地址:versionUrl " + url);
|
| | | HttpRequest.Instance.RequestHttpGet(url, HttpRequest.defaultHttpContentType, 1, OnVersionCheckResult);
|
| | | }
|
| | |
|
| | | private void OnVersionCheckResult(bool _ok, string _result)
|
| | | {
|
| | | if (_ok)
|
| | | {
|
| | | versionUrlResult = _result.Replace("{}", "null");
|
| | | versionInfo = JsonMapper.ToObject<VersionInfo>(versionUrlResult);
|
| | |
|
| | | if (VersionConfigEx.Get().assetAccess == VersionConfigEx.InstalledAsset.IngoreDownLoad)
|
| | | {
|
| | | assetVersions = localAssetVersions;
|
| | | step = LoadDllStep.ReadBytes;
|
| | | return;
|
| | | }
|
| | | step = LoadDllStep.PrepareDownLoad;
|
| | | }
|
| | | else
|
| | | {
|
| | | Debug.Log("http 数据通讯: VersionUtility:" + versionUrl + " result:" + versionUrlResult);
|
| | | Clock.AlarmAt(DateTime.Now + new TimeSpan(TimeSpan.TicksPerSecond), RequestVersionCheck);
|
| | | }
|
| | | }
|
| | |
|
| | | public string GetAssetFilePath(string _assetKey)
|
| | | {
|
| | | var path = Path.Combine(ExternalStorePath, _assetKey);
|
| | | if (!File.Exists(path))
|
| | | {
|
| | | path = Path.Combine(StreamingAssetPath, _assetKey);
|
| | | }
|
| | |
|
| | | return path;
|
| | | }
|
| | |
|
| | | public Sprite LoadSprite(string name)
|
| | | {
|
| | | Sprite sprite = null;
|
| | | #if UNITY_EDITOR
|
| | | // if (excludePngs.Contains(StringUtility.Contact(name, ".png")))
|
| | | // {
|
| | | // var path = StringUtility.Contact("Assets/ResourcesOut/BuiltIn/Sprites/", name, ".png");
|
| | | // sprite = UnityEditor.AssetDatabase.LoadAssetAtPath<Sprite>(path);
|
| | | // }
|
| | | // else
|
| | | // {
|
| | | var spriteAtlas = UnityEditor.AssetDatabase.LoadAssetAtPath<SpriteAtlas>("Assets/ResourcesOut/BuiltIn/Sprites/sprites.spriteatlasv2");
|
| | | sprite = spriteAtlas.GetSprite(name);
|
| | | // }
|
| | |
|
| | | #else
|
| | | if (spriteBundle == null)
|
| | | {
|
| | | string _path = GetAssetFilePath("builtin/sprites");
|
| | | spriteBundle = AssetBundle.LoadFromFile(_path);
|
| | | }
|
| | |
|
| | | sprite = spriteBundle.LoadAsset(name, typeof(Sprite)) as Sprite;
|
| | | #endif
|
| | | if (sprite == null)
|
| | | {
|
| | | Debug.LogErrorFormat("LoadSprite() => 加载不到资源: {0}.", name);
|
| | | }
|
| | |
|
| | | return sprite;
|
| | | }
|
| | |
|
| | | public GameObject LoadBuiltInPrefab(string name)
|
| | | {
|
| | | GameObject prefab = null;
|
| | | #if UNITY_EDITOR
|
| | | var path = string.Concat("Assets/ResourcesOut/BuiltIn/Prefabs/", name, ".prefab");
|
| | | prefab = UnityEditor.AssetDatabase.LoadAssetAtPath<GameObject>(path);
|
| | | #else
|
| | | if (prefabBundle == null)
|
| | | {
|
| | | string _path = GetAssetFilePath("builtin/prefabs");
|
| | | prefabBundle = AssetBundle.LoadFromFile(_path);
|
| | | }
|
| | | prefab = prefabBundle.LoadAsset(name) as GameObject;
|
| | | #endif
|
| | | if (prefab == null)
|
| | | {
|
| | | Debug.LogErrorFormat("LoadBuiltInPrefab() => 加载不到资源: {0}.", name);
|
| | | }
|
| | |
|
| | | return prefab;
|
| | | }
|
| | | |
| | | private string GetExtension(Type type)
|
| | | {
|
| | | if (type == typeof(GameObject))
|
| | | return ".prefab";
|
| | | else if (type == typeof(Sprite))
|
| | | return ".png";
|
| | | else if (type == typeof(Texture2D))
|
| | | return ".png";
|
| | | else if (type == typeof(Shader))
|
| | | return ".shader";
|
| | | else if (type == typeof(TextAsset))
|
| | | return ".txt";
|
| | | else if (type == typeof(AudioClip))
|
| | | return ".wav";
|
| | | else if (type == typeof(Font))
|
| | | return ".ttf";
|
| | | else if (type == typeof(Material))
|
| | | return ".mat";
|
| | | else
|
| | | {
|
| | | Debug.LogErrorFormat("GetExtension() => 不支持的资源类型: {0}.", type.Name);
|
| | | return "";
|
| | | }
|
| | | }
|
| | |
|
| | | public T LoadAsset<T> (string directory, string name) where T : UnityEngine.Object
|
| | | {
|
| | | T asset = null;
|
| | | #if UNITY_EDITOR
|
| | | var path = string.Concat($"Assets/ResourcesOut/{directory}/{name}", GetExtension(typeof(T)));
|
| | | asset = UnityEditor.AssetDatabase.LoadAssetAtPath<T>(path);
|
| | | #else
|
| | | if (prefabBundle == null)
|
| | | {
|
| | | // string _path = GetAssetFilePath("builtin/prefabs");
|
| | | string _path = GetAssetFilePath($"builtin/{directory}");
|
| | | prefabBundle = AssetBundle.LoadFromFile(_path);
|
| | | }
|
| | | asset = prefabBundle.LoadAsset(name) as t;
|
| | | #endif
|
| | | if (asset == null)
|
| | | {
|
| | | Debug.LogErrorFormat("LoadBuiltInPrefab() => 加载不到资源: {0}.", name);
|
| | | }
|
| | |
|
| | | return asset;
|
| | | }
|
| | |
|
| | |
|
| | | public void InitDefaultLanguage()
|
| | | {
|
| | | var config = InitialFunctionConfig.Get("Language").Numerical1;
|
| | | Debug.LogFormat("系统语言:{0} {1}", Application.systemLanguage, config);
|
| | | if (string.IsNullOrEmpty(config))
|
| | | return;
|
| | | var id = LocalSave.GetString("LANGUAGE_ID1");
|
| | | if (!string.IsNullOrEmpty(id))
|
| | | return;
|
| | |
|
| | | switch (Application.systemLanguage)
|
| | | {
|
| | | case SystemLanguage.Chinese:
|
| | | case SystemLanguage.ChineseSimplified:
|
| | | case SystemLanguage.ChineseTraditional:
|
| | | {
|
| | | id = "zh";
|
| | | break;
|
| | | }
|
| | | }
|
| | | var json = JsonMapper.ToObject(config);
|
| | | if (json.Keys.Contains(id))
|
| | | Id = id;
|
| | | else
|
| | | {
|
| | | //开启的情况下必须要有个默认值
|
| | | Id = InitialFunctionConfig.Get("Language").Numerical2;
|
| | | }
|
| | | }
|
| | | |
| | | //LogicBytes文件的MD5信息
|
| | | public void RequestLogicBytes()
|
| | | {
|
| | | var remoteURL = string.Concat(versionInfo.GetResourcesURL(VersionConfigEx.Get().branch), fixPath, "/logicbytes.txt");
|
| | | //var localURL = string.Concat(.ExternalStorePath, "/logicbytes.txt");
|
| | | assetBytesUrl = remoteURL;
|
| | | Debug.Log("http地址:logicbytesUrl " + assetBytesUrl);
|
| | | //HttpRequest.Instance.RequestHttpGet(assetBytesUrl, HttpRequest.defaultHttpContentType, 3, OnGetAssetVersionFile);
|
| | | HttpRequest.Instance.UnityWebRequestGet(assetBytesUrl, 5, OnGetAssetVersionFile);
|
| | | }
|
| | |
|
| | | private void OnGetAssetVersionFile(bool _ok, string _result)
|
| | | {
|
| | | Debug.LogFormat("RequestLogicBytes文件结果:时间 {0},结果 {1}, 文件大小 {2}", DateTime.Now, _ok, _result.Length);
|
| | | if (_ok)
|
| | | {
|
| | | UpdateAssetVersions(_result);
|
| | | step = LoadDllStep.DownLoad;
|
| | | }
|
| | | else
|
| | | {
|
| | | Debug.Log("http 数据通讯: RequestLogicBytes:" + assetBytesUrl + " result:" + _result);
|
| | | Clock.AlarmAt(DateTime.Now + new TimeSpan(TimeSpan.TicksPerSecond * 3), RequestLogicBytes);
|
| | | }
|
| | | }
|
| | |
|
| | | public Dictionary<string, AssetVersion> UpdateAssetVersions(string _assetVersionFile)
|
| | | {
|
| | | var lines = _assetVersionFile.Split(new string[] { FileExtersion.lineSplit }, StringSplitOptions.RemoveEmptyEntries);
|
| | | assetVersions.Clear();
|
| | | for (int i = 0; i < lines.Length; i++)
|
| | | {
|
| | | var assetVersion = new AssetVersion(lines[i]);
|
| | | assetVersions[assetVersion.relativePath] = assetVersion;
|
| | | }
|
| | | return assetVersions;
|
| | | }
|
| | |
|
| | | //读表 使用UnityWebRequest 考虑安卓环境
|
| | | private async UniTask ReadText(string table, Action<bool, string> OnComplete = null, string filePath = "")
|
| | | {
|
| | | var path = string.Empty;
|
| | | string content = string.Empty;
|
| | | bool result = false;
|
| | | if (filePath != "")
|
| | | {
|
| | | path = Path.Combine(filePath + $"{table}.txt");
|
| | | }
|
| | | else
|
| | | {
|
| | | #if UNITY_EDITOR
|
| | | path = CONFIG_FODLER + $"/{table}.txt";
|
| | | #else
|
| | | path = GetAssetFilePath($"config/{table}.txt");
|
| | | #endif
|
| | | }
|
| | | if (!path.Contains("file:"))
|
| | | {
|
| | | //ExternalStorePath 路径需要添加
|
| | | path = "file://" + path;
|
| | | }
|
| | | Debug.LogFormat("ReadText() => path: {0}", path);
|
| | | UnityWebRequest www = UnityWebRequest.Get(path);
|
| | | await www.SendWebRequest();
|
| | |
|
| | | #if UNITY_2020_1_OR_NEWER
|
| | | if (www.result != UnityWebRequest.Result.Success)
|
| | | {
|
| | | Debug.Log(www.error);
|
| | | OnComplete(result, content);
|
| | | }
|
| | | #else
|
| | | if (www.isHttpError || www.isNetworkError)
|
| | | {
|
| | | Debug.Log(www.error);
|
| | | OnComplete(result, content);
|
| | | }
|
| | | #endif
|
| | | else
|
| | | {
|
| | | content = www.downloadHandler.text;
|
| | | Debug.Log($"table:{table} size:{content.Length}");
|
| | | result = true;
|
| | | OnComplete(result, content);
|
| | | }
|
| | |
|
| | | }
|
| | |
|
| | | public async void InitTable(Action OnComplete = null)
|
| | | {
|
| | | await ReadText("InitialFunction", (isOK, value) =>
|
| | | {
|
| | | if (isOK)
|
| | | {
|
| | | InitialFunctionConfig.Init(value);
|
| | | OnComplete();
|
| | | }
|
| | | else
|
| | | {
|
| | | Debug.LogError("InitTable InitialFunctionConfig error");
|
| | | }
|
| | | });
|
| | | if (isPCTestDownLoad || Application.isMobilePlatform)
|
| | | {
|
| | | //读取的一定是StreamingAssetPath路径
|
| | | await ReadText("logicbytes", (isOK, value) =>
|
| | | {
|
| | | if (isOK)
|
| | | InitLocalLogicbytes(value);
|
| | | else
|
| | | Debug.LogWarning("InitTable logicbytes error");
|
| | | }, StreamingAssetPath);
|
| | | }
|
| | | }
|
| | |
|
| | | //随包安装的资源不同平台不一定可以获取FileInfo,所以需要下载一个文件来获取资源的MD5信息
|
| | | //该文件在打包时生成 记录随包的所有资源的信息
|
| | | //该文件记录的资源在包中肯定存在,所以不用去取指定的资源文件获得FileInfo 计算MD5
|
| | | //随包LogicBytes文件的MD5信息 用于下载对比
|
| | | void InitLocalLogicbytes(string content)
|
| | | {
|
| | | using (StringReader reader = new StringReader(content))
|
| | | {
|
| | | string line;
|
| | | while ((line = reader.ReadLine()) != null)
|
| | | {
|
| | | try
|
| | | {
|
| | | var assetVersion = new AssetVersion(line);
|
| | | assetVersion.localValid = true;
|
| | | localAssetVersions[assetVersion.relativePath] = assetVersion;
|
| | | }
|
| | | catch (System.Exception ex)
|
| | | {
|
| | | Debug.LogError(ex);
|
| | | }
|
| | | }
|
| | | }
|
| | | |
| | | }
|
| | |
|
| | | public void UnloadAsset(string assetBundleName)
|
| | | {
|
| | | |
| | | }
|
| | |
|
| | | public class VersionInfo
|
| | | {
|
| | | public JsonData notice_flag;
|
| | | public JsonData resource_url; //这里只用到这个取下载地址
|
| | | public string ResourceAward;
|
| | | public int downAsset = 1;
|
| | | public string downUrl;
|
| | | public int VersionCount;
|
| | |
|
| | |
|
| | | public string GetResourcesURL(int _branch)
|
| | | {
|
| | | if (resource_url != null)
|
| | | {
|
| | | return resource_url[_branch.ToString()].ToString();
|
| | | }
|
| | | else
|
| | | {
|
| | | return string.Empty;
|
| | | }
|
| | | }
|
| | |
|
| | | }
|
| | |
|
| | | public class DebugBranch
|
| | | {
|
| | | public int branch = -1;
|
| | | }
|
| | |
|
| | | public enum LoadDllStep
|
| | | {
|
| | | None,
|
| | | Wait, //每个阶段的等待时间 比如在下载中就处于等待状态,完成后再进入下一个阶段
|
| | | RequestVersion,
|
| | | PrepareDownLoad,
|
| | | DownLoad,
|
| | | ReadBytes,
|
| | | Completed,
|
| | | }
|
| | |
|
| | |
|
| | | using UnityEngine; |
| | | using System.Collections; |
| | | using System.Collections.Generic; |
| | | using Cysharp.Threading.Tasks; |
| | | using System; |
| | | using UnityEngine.U2D; |
| | | using LitJson; |
| | | using System.IO; |
| | | using UnityEngine.Networking; |
| | | |
| | | #if UNITY_EDITOR |
| | | using UnityEditor; |
| | | #endif |
| | | |
| | | using LaunchCommon; |
| | | |
| | | |
| | | // 热更新前的代码 |
| | | |
| | | public class LocalResManager : Singleton<LocalResManager> |
| | | { |
| | | //不下载时本地安卓测试路径 |
| | | public string assetBundlesPath = Application.dataPath + "/../AssetBundles/Android/"; |
| | | public static string bytesFolderName = "logicbytes/"; |
| | | public string StreamingAssetPath |
| | | { |
| | | get |
| | | { |
| | | return ResourcesPath.Instance.StreamingAssetPath; |
| | | } |
| | | } |
| | | public string ExternalStorePath |
| | | { |
| | | get |
| | | { |
| | | return ResourcesPath.Instance.ExternalStorePath; |
| | | } |
| | | } |
| | | |
| | | //用于editor 下的资源路径 |
| | | public string ResourcesOutPath |
| | | { |
| | | get |
| | | { |
| | | return ResourcesPath.ResourcesOutPath; |
| | | } |
| | | } |
| | | |
| | | public string CONFIG_FODLER |
| | | { |
| | | get |
| | | { |
| | | return ResourcesPath.CONFIG_FODLER; |
| | | } |
| | | } |
| | | |
| | | public string ResourcesOutAssetPath |
| | | { |
| | | get |
| | | { |
| | | return ResourcesPath.ResourcesOutAssetPath; |
| | | } |
| | | } |
| | | |
| | | public bool isPCTestDownLoad = false; |
| | | |
| | | public static readonly string[] VERSION_URL = new string[] { |
| | | "http://gamecenter.secondworld.net.cn:11000/center/appversion_new.php/?"}; |
| | | |
| | | public int debugBranch { get; private set; } |
| | | |
| | | private int urlIndex = 0; |
| | | |
| | | private string versionUrl; |
| | | |
| | | public VersionInfo versionInfo { get; private set; } |
| | | |
| | | private static LoadDllStep m_step; |
| | | |
| | | public static LoadDllStep step |
| | | { |
| | | get { return m_step; } |
| | | set |
| | | { |
| | | m_step = value; |
| | | Debug.Log("LoadDllStep:" + m_step); |
| | | } |
| | | } |
| | | |
| | | string assetBytesUrl; |
| | | |
| | | //从网络获取的资源版本信息 |
| | | public Dictionary<string, AssetVersion> assetVersions = new Dictionary<string, AssetVersion>(); |
| | | |
| | | //本地LogicBytes文件和 assetVersions 比较是否需要下载 |
| | | public Dictionary<string, AssetVersion> localAssetVersions = new Dictionary<string, AssetVersion>(); |
| | | |
| | | public static string versionUrlResult { get; private set; } |
| | | |
| | | /// <summary> |
| | | /// 语言的ID,用于区分下载资源 |
| | | /// </summary> |
| | | /// <value></value> |
| | | public static string Id |
| | | { |
| | | get |
| | | { |
| | | var config = InitialFunctionConfig.Get("Language").Numerical1; |
| | | if (string.IsNullOrEmpty(config)) |
| | | return ""; |
| | | return LocalSave.GetString("LANGUAGE_ID1"); |
| | | } |
| | | set |
| | | { |
| | | LocalSave.SetString("LANGUAGE_ID1", value); |
| | | } |
| | | } |
| | | |
| | | //默认路径不附加地址,Id不为空时附加Id |
| | | public static string fixPath |
| | | { |
| | | get |
| | | { |
| | | if (string.IsNullOrEmpty(Id)) |
| | | return ""; |
| | | return string.Format("/{0}", Id); |
| | | } |
| | | } |
| | | |
| | | private AssetBundle spriteBundle = null; //需要卸载 |
| | | private AssetBundle prefabBundle = null; //需要卸载 |
| | | private SpriteAtlas spriteAtlas = null; |
| | | |
| | | public void Init() |
| | | { |
| | | if (LocalSave.GetString("#@#BrancH") != string.Empty) |
| | | { |
| | | int tmpbranch; |
| | | int.TryParse(LocalSave.GetString("#@#BrancH").Substring(1), out tmpbranch); |
| | | if (tmpbranch != 0) |
| | | debugBranch = tmpbranch; |
| | | } |
| | | |
| | | var parentDirectory = Directory.GetParent(Application.persistentDataPath); |
| | | if (File.Exists(parentDirectory + "/Debug")) |
| | | { |
| | | var content = File.ReadAllText(parentDirectory + "/Debug"); |
| | | if (!string.IsNullOrEmpty(content)) |
| | | { |
| | | var json = JsonMapper.ToObject<DebugBranch>(File.ReadAllText(parentDirectory + "/Debug")); |
| | | debugBranch = json.branch; |
| | | } |
| | | } |
| | | |
| | | Clock.Init(); |
| | | Debug.Log("LocalResManager.Init"); |
| | | } |
| | | |
| | | public void Release() |
| | | { |
| | | spriteBundle?.Unload(true); //true完全卸载,更新后重新加载 |
| | | prefabBundle?.Unload(true); |
| | | assetVersions = null; |
| | | localAssetVersions = null; |
| | | spriteAtlas = null; |
| | | Debug.Log("提前ResManager.Release资源"); |
| | | } |
| | | |
| | | public void RequestVersionCheck() |
| | | { |
| | | var versionConfig = VersionConfigEx.Get(); |
| | | var tables = new Dictionary<string, string>(); |
| | | tables["channel"] = versionConfig.appId; |
| | | tables["versioncode"] = versionConfig.version; |
| | | if (versionConfig.branch != 0) |
| | | { |
| | | tables["branch"] = versionConfig.branch.ToString(); |
| | | } |
| | | |
| | | tables["game"] = versionConfig.gameId; |
| | | |
| | | var url = string.Concat(VERSION_URL[urlIndex % VERSION_URL.Length], HttpRequest.HashtablaToString(tables)); |
| | | |
| | | urlIndex++; |
| | | versionUrl = url; |
| | | Debug.Log("http地址:versionUrl " + url); |
| | | HttpRequest.Instance.RequestHttpGet(url, HttpRequest.defaultHttpContentType, 1, OnVersionCheckResult); |
| | | } |
| | | |
| | | private void OnVersionCheckResult(bool _ok, string _result) |
| | | { |
| | | if (_ok) |
| | | { |
| | | versionUrlResult = _result.Replace("{}", "null"); |
| | | versionInfo = JsonMapper.ToObject<VersionInfo>(versionUrlResult); |
| | | |
| | | if (VersionConfigEx.Get().assetAccess == VersionConfigEx.InstalledAsset.IngoreDownLoad) |
| | | { |
| | | assetVersions = localAssetVersions; |
| | | step = LoadDllStep.ReadBytes; |
| | | return; |
| | | } |
| | | step = LoadDllStep.PrepareDownLoad; |
| | | } |
| | | else |
| | | { |
| | | Debug.Log("http 数据通讯: VersionUtility:" + versionUrl + " result:" + versionUrlResult); |
| | | Clock.AlarmAt(DateTime.Now + new TimeSpan(TimeSpan.TicksPerSecond), RequestVersionCheck); |
| | | } |
| | | } |
| | | |
| | | public string GetAssetFilePath(string _assetKey) |
| | | { |
| | | var path = Path.Combine(ExternalStorePath, _assetKey); |
| | | if (!File.Exists(path)) |
| | | { |
| | | path = Path.Combine(StreamingAssetPath, _assetKey); |
| | | } |
| | | |
| | | return path; |
| | | } |
| | | |
| | | public Sprite LoadSprite(string name) |
| | | { |
| | | Sprite sprite = null; |
| | | #if UNITY_EDITOR |
| | | // if (excludePngs.Contains(StringUtility.Contact(name, ".png"))) |
| | | // { |
| | | // var path = StringUtility.Contact("Assets/ResourcesOut/BuiltIn/Sprites/", name, ".png"); |
| | | // sprite = UnityEditor.AssetDatabase.LoadAssetAtPath<Sprite>(path); |
| | | // } |
| | | // else |
| | | // { |
| | | var spriteAtlas = UnityEditor.AssetDatabase.LoadAssetAtPath<SpriteAtlas>("Assets/ResourcesOut/BuiltIn/Sprites/sprites.spriteatlasv2"); |
| | | sprite = spriteAtlas.GetSprite(name); |
| | | // } |
| | | |
| | | #else |
| | | if (spriteBundle == null) |
| | | { |
| | | string _path = GetAssetFilePath("builtin/sprites"); |
| | | spriteBundle = AssetBundle.LoadFromFile(_path); |
| | | } |
| | | |
| | | sprite = spriteBundle.LoadAsset(name, typeof(Sprite)) as Sprite; |
| | | #endif |
| | | if (sprite == null) |
| | | { |
| | | Debug.LogErrorFormat("LoadSprite() => 加载不到资源: {0}.", name); |
| | | } |
| | | |
| | | return sprite; |
| | | } |
| | | |
| | | public GameObject LoadBuiltInPrefab(string name) |
| | | { |
| | | GameObject prefab = null; |
| | | #if UNITY_EDITOR |
| | | var path = string.Concat("Assets/ResourcesOut/BuiltIn/Prefabs/", name, ".prefab"); |
| | | prefab = UnityEditor.AssetDatabase.LoadAssetAtPath<GameObject>(path); |
| | | #else |
| | | if (prefabBundle == null) |
| | | { |
| | | string _path = GetAssetFilePath("builtin/prefabs"); |
| | | prefabBundle = AssetBundle.LoadFromFile(_path); |
| | | } |
| | | prefab = prefabBundle.LoadAsset(name) as GameObject; |
| | | #endif |
| | | if (prefab == null) |
| | | { |
| | | Debug.LogErrorFormat("LoadBuiltInPrefab() => 加载不到资源: {0}.", name); |
| | | } |
| | | |
| | | return prefab; |
| | | } |
| | | |
| | | |
| | | public void InitDefaultLanguage() |
| | | { |
| | | var config = InitialFunctionConfig.Get("Language").Numerical1; |
| | | Debug.LogFormat("系统语言:{0} {1}", Application.systemLanguage, config); |
| | | if (string.IsNullOrEmpty(config)) |
| | | return; |
| | | var id = LocalSave.GetString("LANGUAGE_ID1"); |
| | | if (!string.IsNullOrEmpty(id)) |
| | | return; |
| | | |
| | | switch (Application.systemLanguage) |
| | | { |
| | | case SystemLanguage.Chinese: |
| | | case SystemLanguage.ChineseSimplified: |
| | | case SystemLanguage.ChineseTraditional: |
| | | { |
| | | id = "zh"; |
| | | break; |
| | | } |
| | | } |
| | | var json = JsonMapper.ToObject(config); |
| | | if (json.Keys.Contains(id)) |
| | | Id = id; |
| | | else |
| | | { |
| | | //开启的情况下必须要有个默认值 |
| | | Id = InitialFunctionConfig.Get("Language").Numerical2; |
| | | } |
| | | } |
| | | |
| | | //LogicBytes文件的MD5信息 |
| | | public void RequestLogicBytes() |
| | | { |
| | | var remoteURL = string.Concat(versionInfo.GetResourcesURL(VersionConfigEx.Get().branch), fixPath, "/logicbytes.txt"); |
| | | //var localURL = string.Concat(.ExternalStorePath, "/logicbytes.txt"); |
| | | assetBytesUrl = remoteURL; |
| | | Debug.Log("http地址:logicbytesUrl " + assetBytesUrl); |
| | | //HttpRequest.Instance.RequestHttpGet(assetBytesUrl, HttpRequest.defaultHttpContentType, 3, OnGetAssetVersionFile); |
| | | HttpRequest.Instance.UnityWebRequestGet(assetBytesUrl, 5, OnGetAssetVersionFile); |
| | | } |
| | | |
| | | private void OnGetAssetVersionFile(bool _ok, string _result) |
| | | { |
| | | Debug.LogFormat("RequestLogicBytes文件结果:时间 {0},结果 {1}, 文件大小 {2}", DateTime.Now, _ok, _result.Length); |
| | | if (_ok) |
| | | { |
| | | UpdateAssetVersions(_result); |
| | | step = LoadDllStep.DownLoad; |
| | | } |
| | | else |
| | | { |
| | | Debug.Log("http 数据通讯: RequestLogicBytes:" + assetBytesUrl + " result:" + _result); |
| | | Clock.AlarmAt(DateTime.Now + new TimeSpan(TimeSpan.TicksPerSecond * 3), RequestLogicBytes); |
| | | } |
| | | } |
| | | |
| | | public Dictionary<string, AssetVersion> UpdateAssetVersions(string _assetVersionFile) |
| | | { |
| | | var lines = _assetVersionFile.Split(new string[] { FileExtersion.lineSplit }, StringSplitOptions.RemoveEmptyEntries); |
| | | assetVersions.Clear(); |
| | | for (int i = 0; i < lines.Length; i++) |
| | | { |
| | | var assetVersion = new AssetVersion(lines[i]); |
| | | assetVersions[assetVersion.relativePath] = assetVersion; |
| | | } |
| | | return assetVersions; |
| | | } |
| | | |
| | | //读表 使用UnityWebRequest 考虑安卓环境 |
| | | private async UniTask ReadText(string table, Action<bool, string> OnComplete = null, string filePath = "") |
| | | { |
| | | var path = string.Empty; |
| | | string content = string.Empty; |
| | | bool result = false; |
| | | if (filePath != "") |
| | | { |
| | | path = Path.Combine(filePath + $"{table}.txt"); |
| | | } |
| | | else |
| | | { |
| | | #if UNITY_EDITOR |
| | | path = CONFIG_FODLER + $"/{table}.txt"; |
| | | #else |
| | | path = GetAssetFilePath($"config/{table}.txt"); |
| | | #endif |
| | | } |
| | | if (!path.Contains("file:")) |
| | | { |
| | | //ExternalStorePath 路径需要添加 |
| | | path = "file://" + path; |
| | | } |
| | | Debug.LogFormat("ReadText() => path: {0}", path); |
| | | UnityWebRequest www = UnityWebRequest.Get(path); |
| | | await www.SendWebRequest(); |
| | | |
| | | #if UNITY_2020_1_OR_NEWER |
| | | if (www.result != UnityWebRequest.Result.Success) |
| | | { |
| | | Debug.Log(www.error); |
| | | OnComplete(result, content); |
| | | } |
| | | #else |
| | | if (www.isHttpError || www.isNetworkError) |
| | | { |
| | | Debug.Log(www.error); |
| | | OnComplete(result, content); |
| | | } |
| | | #endif |
| | | else |
| | | { |
| | | content = www.downloadHandler.text; |
| | | Debug.Log($"table:{table} size:{content.Length}"); |
| | | result = true; |
| | | OnComplete(result, content); |
| | | } |
| | | |
| | | } |
| | | |
| | | public async void InitTable(Action OnComplete = null) |
| | | { |
| | | await ReadText("InitialFunction", (isOK, value) => |
| | | { |
| | | if (isOK) |
| | | { |
| | | InitialFunctionConfig.Init(value); |
| | | OnComplete(); |
| | | } |
| | | else |
| | | { |
| | | Debug.LogError("InitTable InitialFunctionConfig error"); |
| | | } |
| | | }); |
| | | if (isPCTestDownLoad || Application.isMobilePlatform) |
| | | { |
| | | //读取的一定是StreamingAssetPath路径 |
| | | await ReadText("logicbytes", (isOK, value) => |
| | | { |
| | | if (isOK) |
| | | InitLocalLogicbytes(value); |
| | | else |
| | | Debug.LogWarning("InitTable logicbytes error"); |
| | | }, StreamingAssetPath); |
| | | } |
| | | } |
| | | |
| | | //随包安装的资源不同平台不一定可以获取FileInfo,所以需要下载一个文件来获取资源的MD5信息 |
| | | //该文件在打包时生成 记录随包的所有资源的信息 |
| | | //该文件记录的资源在包中肯定存在,所以不用去取指定的资源文件获得FileInfo 计算MD5 |
| | | //随包LogicBytes文件的MD5信息 用于下载对比 |
| | | void InitLocalLogicbytes(string content) |
| | | { |
| | | using (StringReader reader = new StringReader(content)) |
| | | { |
| | | string line; |
| | | while ((line = reader.ReadLine()) != null) |
| | | { |
| | | try |
| | | { |
| | | var assetVersion = new AssetVersion(line); |
| | | assetVersion.localValid = true; |
| | | localAssetVersions[assetVersion.relativePath] = assetVersion; |
| | | } |
| | | catch (System.Exception ex) |
| | | { |
| | | Debug.LogError(ex); |
| | | } |
| | | } |
| | | } |
| | | |
| | | } |
| | | |
| | | public class VersionInfo |
| | | { |
| | | public JsonData notice_flag; |
| | | public JsonData resource_url; //这里只用到这个取下载地址 |
| | | public string ResourceAward; |
| | | public int downAsset = 1; |
| | | public string downUrl; |
| | | public int VersionCount; |
| | | |
| | | |
| | | public string GetResourcesURL(int _branch) |
| | | { |
| | | if (resource_url != null) |
| | | { |
| | | return resource_url[_branch.ToString()].ToString(); |
| | | } |
| | | else |
| | | { |
| | | return string.Empty; |
| | | } |
| | | } |
| | | |
| | | } |
| | | |
| | | public class DebugBranch |
| | | { |
| | | public int branch = -1; |
| | | } |
| | | |
| | | public enum LoadDllStep |
| | | { |
| | | None, |
| | | Wait, //每个阶段的等待时间 比如在下载中就处于等待状态,完成后再进入下一个阶段 |
| | | RequestVersion, |
| | | PrepareDownLoad, |
| | | DownLoad, |
| | | ReadBytes, |
| | | Completed, |
| | | } |
| | | } |