Пример #1
0
        /// <summary>
        /// 同步加载
        /// </summary>
        /// <param name="path">AssetPathManager.Instance.GetStreamAssetDataPath("csv/csvList.csv")</param>
        /// <param name="callBack"></param>
        /// <param name="errorCallBack"></param>
        public static void LoadAsset(string path, Action <UnityWebRequest> callBack, Action <UnityWebRequest> errorCallBack = null)
        {
            Uri uri = new Uri(path);

            LDebug.LogWarning(" >路径: \n AbsoluteUri : " + uri.AbsoluteUri + " \n AbsolutePath: " + uri.AbsolutePath + " \n LocalPath: " + uri.LocalPath);
            using (UnityWebRequest uwr = UnityWebRequest.Get(uri))
            {
                uwr.timeout = 3;
                uwr.disposeUploadHandlerOnDispose      = true;
                uwr.disposeDownloadHandlerOnDispose    = true;
                uwr.disposeCertificateHandlerOnDispose = true;

                uwr.SendWebRequest();

                while (true)
                {
                    if (uwr.isHttpError || uwr.isNetworkError)
                    {
                        LDebug.LogError("  >Error: " + uwr.error + " " + uwr.url);
                        errorCallBack?.Invoke(uwr);
                        return;
                    }
                    else if (uwr.downloadProgress == 1)
                    {
                        LDebug.Log(" >Received: \n" + uwr.downloadHandler.text);
                        callBack?.Invoke(uwr);
                        return;
                    }
                }
            }
        }
Пример #2
0
        public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
        {
            EditorGUI.BeginChangeCheck();
            EditorGUI.PropertyField(position, property, label);

            //在必要时更新会刷新界面
            SetPropertyAttribute setProperty = attribute as SetPropertyAttribute;

            if (EditorGUI.EndChangeCheck())
            {
                //序列化的属性被修改时,实际变量值还是停留在原来的值上,知道ONGUI刷新。所以这里采用isDirty方式标记在其它所有OnGui事件全部完成后(比如Repaint)再更新对应变量
                setProperty.IsDirty = true;
            }
            else if (setProperty.IsDirty)
            {
                //这里需要查找这个变量真正的父属性节点
                object       parent = GetParentObjectOfProperty(property.propertyPath, property.serializedObject.targetObject);
                Type         type   = parent.GetType();
                PropertyInfo pi     = type.GetProperty(setProperty.Name);
                if (pi == null)
                {
                    LDebug.LogError("Invalid property name: " + setProperty.Name + "\nCheck your [SetProperty] attribute");
                }
                else
                {
                    pi.SetValue(parent, fieldInfo.GetValue(parent), null);
                }
                setProperty.IsDirty = false;
            }
        }
Пример #3
0
        /// <summary>
        /// 协程加载
        /// </summary>
        /// <param name="path">例如:AssetPathManager.Instance.GetStreamAssetDataPath("csv/csvList.csv")</param>
        /// <param name="callBack"></param>
        /// <param name="errorCallBack"></param>
        /// <returns></returns>
        public static IEnumerator ILoadAsset(string path, Action <string> callBack, Action <UnityWebRequest> errorCallBack = null)
        {
            Uri uri = new Uri(path);

            LDebug.LogWarning(" >路径: \n AbsoluteUri : " + uri.AbsoluteUri + " \n AbsolutePath: " + uri.AbsolutePath + " \n LocalPath: " + uri.LocalPath);
            using (UnityWebRequest uwr = UnityWebRequest.Get(uri))
            {
                uwr.timeout = 3;
                uwr.disposeUploadHandlerOnDispose      = true;
                uwr.disposeDownloadHandlerOnDispose    = true;
                uwr.disposeCertificateHandlerOnDispose = true;

                yield return(uwr.SendWebRequest());

                if (uwr.isNetworkError || uwr.isHttpError)
                {
                    LDebug.LogError("  >Error: " + uwr.error);
                    errorCallBack?.Invoke(uwr);
                }
                else
                {
                    callBack?.Invoke(uwr.downloadHandler.text);
                    //LDebug.Log( " >Received: \n" + uwr.downloadHandler.text );
                }
            }
        }
Пример #4
0
        public void Install()
        {
            _allRegisterUIDict  = new Dictionary <string, string>();
            _stackCurrentUI     = new Stack <BaseUI>();
            _dictLoadedAllUIs   = new Dictionary <string, BaseUI>();
            _dictCurrentShowUIs = new Dictionary <string, BaseUI>();

            TransRoot   = GameObject.FindGameObjectWithTag(UISysDefine.SYS_TAG_ROOTCANVAS).transform;
            TransNormal = UnityHelper.FindTheChildNode(TransRoot, UISysDefine.SYS_TAG_NORMALCANVAS);
            TransFixed  = UnityHelper.FindTheChildNode(TransRoot, UISysDefine.SYS_TAG_FIXEDCANVAS);
            TransPopUp  = UnityHelper.FindTheChildNode(TransRoot, UISysDefine.SYS_TAG_POPUPCANVAS);
            TransGlobal = UnityHelper.FindTheChildNode(TransRoot, UISysDefine.SYS_TAG_GLOBALCANVAS);

            RectransRoot   = TransRoot.GetComponent <RectTransform>();
            RectransNormal = TransNormal.GetComponent <RectTransform>();
            RectransFixed  = TransFixed.GetComponent <RectTransform>();
            RectransPopUp  = TransPopUp.GetComponent <RectTransform>();
            RectransGlobal = TransGlobal.GetComponent <RectTransform>();

            _fadeImage = UnityHelper.FindTheChildNode(TransGlobal, "Image_fadeBG").GetComponent <Image>();

            try
            {
                if (_fadeImage == null)
                {
                    LDebug.LogWarning("Image_fadeBG 未定义");
                }
                else if (!_fadeImage.gameObject.activeInHierarchy)
                {
                    LDebug.LogWarning("Image_fadeBG 未启用");
                }

                _fadeImage.raycastTarget = false;
                _fadeImage.gameObject.SetActive(true);
            }
            catch (Exception e)
            {
                LDebug.LogError("Image_fadeBG 错误");
            }

            //Mask蒙版初始化
            var ss = UIMaskManager.Instance;

            UICam        = UnityHelper.FindTheChildNode(TransRoot, "UICamera").GetComponent <Camera>();
            CanvasScaler = TransRoot.GetComponent <CanvasScaler>();
            GameObject.DontDestroyOnLoad(TransRoot.gameObject);

            AssemblyReflection();
        }
Пример #5
0
    private void BuyFailEventHandler(BuyFailReason obj)
    {
        switch (obj)
        {
        case BuyFailReason.NotInit:
            LDebug.LogError("Purchase Fail->Purchase not initialized");
            break;

        case BuyFailReason.ProductError:
            LDebug.LogError("Purchase Fail->Not purchasing product, not found or not available");
            break;

        case BuyFailReason.Other:
            LDebug.LogError("Purchase Fail->Other");
            break;
        }
        BuyFailEvent?.Invoke(obj);
    }
Пример #6
0
        public IEnumerator HotFixExecute()
        {
            LDebug.Log("开始检测更新:" + CONFIG_NAME);
            //1、下载最新的资源配置信息
            bool   canGoFurther   = true;
            string wrongFileName  = string.Empty;
            string localContent   = null;
            string remoteFilePath = CONFIG_NAME;

            //发送下载XX文件事件
            MsgManager.Instance.Broadcast(InternalEvent.HANDLING_REMOTE_RES, new MsgArgs(remoteFilePath, InternalEvent.RemoteStatus.Download));

            string localFilePath = AssetPathManager.Instance.GetPersistentDataPath(remoteFilePath, false);

            //2、根据本地是否存在资源配置信息,如果不存在,则视为远程更新流程不执行
            if (DocumentAccessor.IsExists(localFilePath))
            {
                string remoteContent  = null;
                byte[] contentByteArr = null;

                LDebug.Log("Remote update..." + FrameworkConfig.Instance.RemoteUrlConfig + "/" + remoteFilePath + " 开始读取", LogColor.yellow);
                //远程主配置文件获取
                yield return(DocumentAccessor.ILoadAsset(FrameworkConfig.Instance.RemoteUrlConfig + remoteFilePath, callBack: (UnityWebRequest e) =>
                {
                    LDebug.Log("Remote update..." + remoteFilePath + "读取完成", LogColor.yellow);
                    remoteContent = e.downloadHandler.text;
                    contentByteArr = e.downloadHandler.data;
                },
                                                         errorCallBack: (UnityWebRequest e) =>
                {
                    LDebug.LogError("Remote Error..." + e + ": " + remoteFilePath);
                    if (!string.IsNullOrEmpty(e.error))
                    {
                        canGoFurther = false; return;
                    }
                }));


                //因为加载出问题导致无法继续时,目前先使用中断后续步骤,并弹窗提醒的方式搞
                if (!canGoFurther)
                {
                    MsgManager.Instance.Broadcast(InternalEvent.REMOTE_UPDATE_ERROR, new MsgArgs(remoteContent, remoteFilePath));
                    yield break;
                }


                //本地主配置文件获取
                DocumentAccessor.LoadAsset(localFilePath, (string e) => { localContent = e; });


                ////本地配置表默认全更新。
                //string[] str = remoteContent.Split( "\r\n".ToCharArray(), StringSplitOptions.RemoveEmptyEntries );
                //string[] localFileContent = localContent.Split( "\r\n".ToCharArray(), StringSplitOptions.RemoveEmptyEntries );
                //var toDelete = localFileContent.Where( a => !str.Contains( a ) );

                //foreach ( var item in toDelete )
                //{
                //    FileInfo fileInfo = new FileInfo( AssetPathManager.Instance.GetPersistentDataPath( item, false ) );
                //    if ( fileInfo.Exists ) fileInfo.Delete();
                //    LDebug.Log( ">>>Delete " + item, LogColor.red );
                //    LDebug.Log( ">>>Delete Result " + DocumentAccessor.IsExists( AssetPathManager.Instance.GetPersistentDataPath( item, false ) ), LogColor.red );
                //}

                //for ( int w = 0; w < str.Length; w++ )
                //{
                //    LDebug.Log( "Remote update..." + str[ w ] + "开始读取" );
                //    yield return DocumentAccessor.ILoadAsset( FrameworkConfig.Instance.RemoteUrlConfig + str[ w ], ( UnityWebRequest e ) =>
                //    {
                //        LDebug.Log( "Remote update..." + str[ w ] + "读取完成", LogColor.yellow );
                //        DocumentAccessor.SaveAsset2LocalFile( AssetPathManager.Instance.GetPersistentDataPath( str[ w ], false ), e.downloadHandler.data );
                //    } );
                //}

                ////更新文档
                //DocumentAccessor.SaveAsset2LocalFile( localFilePath, contentByteArr );
                //LDebug.Log( "检测更新完成:" + CONFIG_NAME );

                //本地配置表默认增量更新。修改为增量更新后,后续的逻辑跟HOTFIXAB是一样的
                Dictionary <string, ABVersion> remoteABVersionsDic = ResolveABContent(remoteContent);
                Dictionary <string, ABVersion> localABVersionsDic  = ResolveABContent(localContent);

                //需要删除的对象
                var toDelete = localABVersionsDic.Where(a => !remoteABVersionsDic.ContainsKey(a.Key));
                foreach (var item in toDelete)
                {
                    FileInfo fileInfo = new FileInfo(AssetPathManager.Instance.GetPersistentDataPath(item.Key, false));
                    if (fileInfo.Exists)
                    {
                        fileInfo.Delete();
                    }
                    LDebug.Log(">>>Delete " + item.Key, LogColor.red);
                    LDebug.Log(">>>Delete Result " + DocumentAccessor.IsExists(AssetPathManager.Instance.GetPersistentDataPath(item.Key, false)), LogColor.red);
                }

                //需要更新的对象:可以根据需求拓展对version的使用规则。
                //默认是更新版本号更高或者新增加的对象。
                var toUpdate = remoteABVersionsDic.Where(a => !localABVersionsDic.ContainsKey(a.Key) || a.Value.Version > localABVersionsDic[a.Key].Version);
                foreach (var item in toUpdate)
                {
                    LDebug.Log("Remote update..." + FrameworkConfig.Instance.RemoteUrlConfig + "/" + item.Key + " 开始读取", LogColor.yellow);
                    yield return(DocumentAccessor.ILoadAsset(FrameworkConfig.Instance.RemoteUrlConfig + "/" + item.Key, (UnityWebRequest e) =>
                    {
                        LDebug.Log("Remote update..." + item.Key + "读取完成", LogColor.yellow);
                        DocumentAccessor.SaveAsset2LocalFile(AssetPathManager.Instance.GetPersistentDataPath(item.Key, false), e.downloadHandler.data);
                    }, (e) =>
                    {
                        LDebug.LogError("Remote Error..." + e + ": " + remoteFilePath);
                        if (!string.IsNullOrEmpty(e.error))
                        {
                            canGoFurther = false; wrongFileName = item.Key; return;
                        }
                    }));

                    // 因为加载出问题导致无法继续时,目前先使用中断后续步骤,并弹窗提醒的方式搞
                    if (!canGoFurther)
                    {
                        break;
                    }
                }

                // 因为加载出问题导致无法继续时,目前先使用中断后续步骤,并弹窗提醒的方式搞
                if (!canGoFurther)
                {
                    LDebug.LogError("Remote Update Abort..." + wrongFileName + " : " + remoteFilePath);
                    MsgManager.Instance.Broadcast(InternalEvent.REMOTE_UPDATE_ERROR, new MsgArgs(remoteContent, remoteFilePath, wrongFileName));
                    yield break;
                }

                //更新文档
                DocumentAccessor.SaveAsset2LocalFile(localFilePath, contentByteArr);
                LDebug.Log("检测更新完成:" + CONFIG_NAME);
            }
        }
Пример #7
0
        /// <summary>
        /// Extracts the content from a .zip file inside an specific folder.
        /// </summary>
        /// <param name="fileZipPath">eg: AssetPathManager.Instance.GetStreamAssetDataPath("test.zip", false)</param>
        /// <param name="outputFolder">AssetPathManager.Instance.GetStreamAssetDataPath("", false)</param>
        /// <param name="password"></param>
        public static void ExtractZipContent(string fileZipPath, string outputFolder, string password = null)
        {
            ZipFile file = null;

            try
            {
                FileStream fs = File.OpenRead(fileZipPath);
                file = new ZipFile(fs);

                if (!string.IsNullOrEmpty(password))
                {
                    // AES encrypted entries are handled automatically
                    file.Password = password;
                }

                foreach (ZipEntry zipEntry in file)
                {
                    if (!zipEntry.IsFile)
                    {
                        // Ignore directories
                        continue;
                    }

                    string entryFileName = zipEntry.Name;
                    // to remove the folder from the entry:- entryFileName = Path.GetFileName(entryFileName);
                    // Optionally match entrynames against a selection list here to skip as desired.
                    // The unpacked length is available in the zipEntry.Size property.

                    // 4K is optimum
                    byte[] buffer    = new byte[4096];
                    Stream zipStream = file.GetInputStream(zipEntry);

                    // Manipulate the output filename here as desired.
                    string fullZipToPath = Path.Combine(outputFolder, entryFileName);
                    string directoryName = Path.GetDirectoryName(fullZipToPath);

                    if (directoryName.Length > 0)
                    {
                        Directory.CreateDirectory(directoryName);
                    }

                    // Unzip file in buffered chunks. This is just as fast as unpacking to a buffer the full size
                    // of the file, but does not waste memory.
                    // The "using" will close the stream even if an exception occurs.
                    using (FileStream streamWriter = File.Create(fullZipToPath))
                    {
                        StreamUtils.Copy(zipStream, streamWriter, buffer);
                    }
                }
            }
            catch (Exception e)
            {
                LDebug.LogError(" Zip Error >> " + e);
            }
            finally
            {
                if (file != null)
                {
                    file.IsStreamOwner = true; // Makes close also shut the underlying stream
                    file.Close();              // Ensure we release resources
                }
            }
        }
Пример #8
0
    void OnGUI()
    {
        //必选项:类名
        GUILayout.Label("脚本类名(UI+类名) 例如:UIMain");
        uiScriptsName = EditorGUILayout.TextField(uiScriptsName);

        //选填
        GUILayout.Label("类说明,建议写UI界面类型,例如:主界面");
        uiSummary = EditorGUILayout.TextField(uiSummary);

        uiNodeType    = ( UINodeTypeEnum )EditorGUILayout.EnumPopup("挂载节点", uiNodeType);
        uiShowMode    = ( UIShowModeEnum )EditorGUILayout.EnumPopup("窗体显示方式", uiShowMode);
        uiTransparent = ( UITransparentEnum )EditorGUILayout.EnumPopup("窗体背后的遮罩透明度", uiTransparent);

        EditorGUILayout.Space();

        //勾选项
        useOnEnable_OnDisable = EditorGUILayout.Toggle("OnEnable/OnDisable", useOnEnable_OnDisable);
        useDefaultExitBtn     = EditorGUILayout.Toggle("退出按钮", useDefaultExitBtn);
        if (useDefaultExitBtn)
        {
            useOnEnable_OnDisable = useDefaultExitBtn ? true : EditorGUILayout.Toggle("启用OnEnable/OnDisable", useOnEnable_OnDisable);
        }
        useAnimRoot = EditorGUILayout.Toggle("动画控制器", useAnimRoot);
        if (useAnimRoot)
        {
            animStartID = EditorGUILayout.TextField("    弹出动画ID", animStartID);
            animCloseID = EditorGUILayout.TextField("    关闭动画ID", animCloseID);
        }

        EditorGUILayout.Space();

        using (new BackgroundColorScope(Color.green))
        {
            if (GUILayout.Button("创建脚本+UI预制件+注册绑定", GUILayout.Height(40)))
            {
                _saveLocalFileInfo = new FileInfo(Application.dataPath + "/Editor/" + GlobalEditorSetting.JSON_FILE_NAME);

                if (CheckClassNameValid())
                {
                    isDirty = true;

                    EditorUtility.DisplayProgressBar("生成UI模块", "", 1f);

                    //CS 脚本
                    UICreateParse cs        = new UICreateParse();
                    string        csOutPath = Application.dataPath + "/Scripts/UI";
                    if (!FrameworkConfig.Instance.UseHotFixMode)
                    {
                        csOutPath = Application.dataPath + "/Scripts/UI";
                    }
                    else
                    {
                        csOutPath = Application.dataPath + "/Scripts/ILRuntime/HotFixLogic/UI";
                    }
                    EditorMenuExtention.CreateCSFile(csOutPath, uiScriptsName + ".cs", cs.CreateCS(this));
                    AssetDatabase.Refresh();

                    //预制件
                    newCanvas            = new GameObject("Canvas_" + uiScriptsName.Substring(2), typeof(Canvas)).GetComponent <Canvas>();
                    newCanvas.renderMode = RenderMode.ScreenSpaceOverlay;

                    var canvasScaler = newCanvas.gameObject.AddComponent <CanvasScaler>();
                    canvasScaler.uiScaleMode = CanvasScaler.ScaleMode.ConstantPixelSize;

                    var graphics = newCanvas.gameObject.AddComponent <GraphicRaycaster>();
                    graphics.ignoreReversedGraphics = true;
                    graphics.blockingObjects        = GraphicRaycaster.BlockingObjects.None;

                    GameObject animTrans = new GameObject("Container_Anim", typeof(RectTransform));
                    animTrans.transform.SetParent(newCanvas.transform);
                    var recTrans = animTrans.GetComponent <RectTransform>();
                    recTrans.sizeDelta                = Vector2.zero;
                    recTrans.anchorMin                = Vector2.zero;
                    recTrans.anchorMax                = Vector2.one;
                    recTrans.anchoredPosition         = Vector2.zero;
                    animTrans.transform.localPosition = Vector3.zero;
                    animTrans.transform.localScale    = Vector3.one;

                    if (useAnimRoot)
                    {
                        //DOTEEN插件未集成在编辑器库中,引出到库外部使用
                        CreateAnimationComponentEvent?.Invoke(animTrans, animStartID, animCloseID);
                    }

                    if (useDefaultExitBtn)
                    {
                        GameObject btnExit = new GameObject("Btn_Exit", typeof(RectTransform));
                        btnExit.AddComponent <CanvasRenderer>();
                        btnExit.AddComponent <Image>().maskable = false;
                        btnExit.AddComponent <Button>();
                        btnExit.transform.SetParent(animTrans.transform);
                        btnExit.transform.localPosition = Vector3.zero;
                        btnExit.transform.localScale    = Vector3.one;
                    }

                    //Layer设定
                    ChangeUILayer(newCanvas.transform, "UI");

                    //预制件自注册
                    RigisterUIPath(uiScriptsName);

                    AssetDatabase.Refresh();
                }
                else
                {
                    EditorUtility.DisplayDialog("类名错误", "类名应该不为空、空格,并且以UI开头", "哦");
                }
            }
        }

        EditorGUILayout.Space();

        using (new BackgroundColorScope(Color.green))
        {
            if (GUILayout.Button("仅创建脚本", GUILayout.Height(40)))
            {
                _saveLocalFileInfo = new FileInfo(Application.dataPath + "/Editor/" + GlobalEditorSetting.JSON_FILE_NAME);

                if (CheckClassNameValid())
                {
                    //CS 脚本
                    UICreateParse cs        = new UICreateParse();
                    string        csOutPath = Application.dataPath + "/Scripts/UI";

                    if (!FrameworkConfig.Instance.UseHotFixMode)
                    {
                        csOutPath = Application.dataPath + "/Scripts/UI";
                    }
                    else
                    {
                        csOutPath = Application.dataPath + "/Scripts/ILRuntime/HotFixLogic/UI";
                    }


                    EditorMenuExtention.CreateCSFile(csOutPath, uiScriptsName + ".cs", cs.CreateCS(this));
                    AssetDatabase.Refresh();
                }
                else
                {
                    EditorUtility.DisplayDialog("类名错误", "类名应该不为空、空格,并且以UI开头", "哦");
                }
            }
        }

        EditorGUILayout.Space();

        using (new BackgroundColorScope(Color.yellow))
        {
            if (GUILayout.Button("更新UI配置", GUILayout.Height(40)))
            {
                _saveLocalFileInfo = new FileInfo(Application.dataPath + "/Editor/" + GlobalEditorSetting.JSON_FILE_NAME);

                //============JSON文件取出============//
                ResPathTemplate rpt = null;
                //如果文件存在,则读取解析为存储类,写入相关数据条后写入JSON并保存
                if (DocumentAccessor.IsExists(Application.dataPath + "/Editor/" + GlobalEditorSetting.JSON_FILE_NAME))
                {
                    var content = DocumentAccessor.ReadFile(Application.dataPath + "/Editor/" + GlobalEditorSetting.JSON_FILE_NAME);

                    rpt = JsonMapper.ToObject <ResPathTemplate>(content);
                }
                //如果文件不存在,则新建存储类,并保存相关的数据,然后写入JSON并保存
                else
                {
                    rpt = new ResPathTemplate();
                }
                //=================================//

                //每次都重新写入ResPath
                Dictionary <string, string> resPathSumList = new Dictionary <string, string>();
                foreach (var item in rpt.UI)
                {
                    var sum = item.Value.Split('|');
                    if (sum.Length > 1 && !string.IsNullOrEmpty(sum[1]))
                    {
                        resPathSumList.Add(item.Key.ToUpper(), sum[1]);
                    }
                }
                rpt.UI.Clear();

                //============存入UI配置============//

                List <string> allResourcesPath = new List <string>();
                RecursionAction("Assets", allResourcesPath);

                foreach (var childPath in allResourcesPath)
                {
                    DirectoryInfo folder = new DirectoryInfo("Assets" + childPath + "/" + GlobalEditorSetting.UI_PREFAB_PATH);

                    if (!folder.Exists)
                    {
                        continue;
                    }

                    foreach (FileInfo file in folder.GetFiles())
                    {
                        string ss = file.Extension.ToUpper();
                        if (ss.Contains(".PREFAB") && file.FullName.Contains("Canvas"))
                        {
                            var result = file.Name.Split('.')[0];
                            var key    = "UI" + result.Split('_')[1].ToUpper();
                            rpt.UI.Add(key, GlobalEditorSetting.UI_PREFAB_PATH + result);

                            if (resPathSumList.ContainsKey(key))
                            {
                                rpt.UI[key] += "|" + resPathSumList[key];
                            }
                        }
                    }
                }

                //=================================//

                //============JSON文件存入============//
                using (StreamWriter sw = _saveLocalFileInfo.CreateText())
                {
                    var result = JsonMapper.ToJson(rpt);
                    sw.Write(result);
                }
                //=================================//

                //============更新并保存CS============//
                //更新并保存CS
                ResPathParse rpp = new ResPathParse();

                if (!FrameworkConfig.Instance.UseHotFixMode)
                {
                    EditorMenuExtention.CreateCSFile(Application.dataPath + "/Scripts", GlobalEditorSetting.OUTPUT_RESPATH, rpp.CreateCS(rpt));
                }
                else
                {
                    EditorMenuExtention.CreateCSFile(Application.dataPath + "/Scripts/ILRuntime/HotFixLogic", GlobalEditorSetting.OUTPUT_RESPATH, rpp.CreateCS(rpt));
                }

                AssetDatabase.Refresh();
            }
        }

        //汇总编译
        while (isDirty && !EditorApplication.isCompiling)
        {
            isDirty = false;

            EditorUtility.ClearProgressBar();
            LDebug.Log(" 成功生成UI预制件! ");

            if (!FrameworkConfig.Instance.UseHotFixMode)
            {
                //反射生成脚本组件
                var asmb = System.Reflection.Assembly.Load("Assembly-CSharp");
                var t    = asmb.GetType("Assets.Scripts.UI." + uiScriptsName);
                if (null != t)
                {
                    newCanvas.gameObject.AddComponent(t);
                }
                else
                {
                    LDebug.LogError("UI脚本绑定失败");
                }
            }

            string localPath = "Assets/Resources/" + GlobalEditorSetting.UI_PREFAB_PATH + newCanvas.gameObject.name + ".prefab";
            //预防重名
            localPath = AssetDatabase.GenerateUniqueAssetPath(localPath);
            PrefabUtility.SaveAsPrefabAssetAndConnect(newCanvas.gameObject, localPath, InteractionMode.UserAction);

            AssetDatabase.Refresh();
        }
    }
Пример #9
0
        private void Awake()
        {
            // Make this GameObject immortal if the user requests it.
            if (this._dontDestroyOnLoad)
            {
                Object.DontDestroyOnLoad(this.gameObject);
            }

            this.group = this.transform;

            // Default name behavior will use the GameObject's name without "Pool" (if found)
            if (this.poolName == "")
            {
                // Automatically Remove "Pool" from names to allow users to name prefabs in a
                //   more development-friendly way. E.g. "EnemiesPool" becomes just "Enemies".
                //   Notes: This will return the original string if "Pool" isn't found.
                //          Do this once here, rather than a getter, to avoide string work
                this.poolName = this.group.name.Replace("Pool", "");
                this.poolName = this.poolName.Replace("(Clone)", "");
            }

            if (this.logMessages)
            {
                Debug.Log(string.Format("SpawnPool {0}: Initializing..", this.poolName));
            }

            // Only used on items defined in the Inspector
            for (int i = 0; i < this.perPrefabPoolOptions.Count; i++)
            {
                //if (this.perPrefabPoolOptions[i].prefab == null)
                //{
                //    Debug.LogWarning(string.Format("Initialization Warning: Pool '{0}' " +
                //              "contains a PrefabPool with no prefab reference. Skipping.",
                //               this.poolName));
                //    continue;
                //}

                //// Init the PrefabPool's GameObject cache because it can't do it.
                ////   This is only needed when created by the inspector because the constructor
                ////   won't be run.
                //this.perPrefabPoolOptions[i].inspectorInstanceConstructor();
                //this.CreatePrefabPool(this.perPrefabPoolOptions[i]);
                if (this.perPrefabPoolOptions[i].Pools == null)
                {
                    Debug.LogWarning(string.Format("Initialization Warning: Pool '{0}' " +
                                                   "contains a PrefabPool with no prefab reference. Skipping.",
                                                   this.poolName));
                    continue;
                }
                List <PrefabPool> sorts = this.perPrefabPoolOptions[i].Pools;
                for (int j = 0; j < sorts.Count; j++)
                {
                    try
                    {
                        sorts[j].inspectorInstanceConstructor();
                        this.CreatePrefabPool(sorts[j]);
                    }
                    catch (System.Exception)
                    {
                        LDebug.LogError(string.Format("==>对象池预制件丢失!  池类型:{0}  Index: {1}", this.perPrefabPoolOptions[i].SortSpawnName, i));
                        throw;
                    }
                }
            }

            //perPrefabPoolOptions.Clear();
            //perPrefabPoolOptions = null;
            // Add this SpawnPool to PoolManager for use. This is done last to lower the
            //   possibility of adding a badly init pool.
            PoolManager.Pools.Add(this);
        }
Пример #10
0
        public IEnumerator HotFixExecute()
        {
            //下载总表进行匹配更新
            bool   canGoFurther   = true;
            string localContent   = null;
            string wrongFileName  = string.Empty;
            string remoteFilePath = CONFIG_VERSION;
            string localFilePath  = AssetPathManager.Instance.GetPersistentDataPath(remoteFilePath, false);

            //发送下载XX文件事件
            MsgManager.Instance.Broadcast(InternalEvent.HANDLING_REMOTE_RES, new MsgArgs(remoteFilePath, InternalEvent.RemoteStatus.Download));

            //根据本地是否存在资源配置信息,如果不存在,则视为远程更新流程不执行
            if (DocumentAccessor.IsExists(localFilePath))
            {
                string remoteContent  = null;
                byte[] contentByteArr = null;

                //远程主配置文件获取
                LDebug.Log("Remote update..." + FrameworkConfig.Instance.RemoteUrlConfig + "/" + remoteFilePath + " 开始读取", LogColor.yellow);
                yield return(DocumentAccessor.ILoadAsset(FrameworkConfig.Instance.RemoteUrlConfig + remoteFilePath, callBack: (UnityWebRequest e) =>
                {
                    LDebug.Log("Remote update..." + remoteFilePath + "读取完成", LogColor.yellow);
                    remoteContent = e.downloadHandler.text;
                    contentByteArr = e.downloadHandler.data;
                },
                                                         errorCallBack: (UnityWebRequest e) =>
                {
                    LDebug.LogError("Remote Error..." + e + ": " + remoteFilePath);
                    if (!string.IsNullOrEmpty(e.error))
                    {
                        canGoFurther = false; return;
                    }
                }));

                // 因为加载出问题导致无法继续时,目前先使用中断后续步骤,并弹窗提醒的方式搞
                if (!canGoFurther)
                {
                    LDebug.LogError("Remote Update Abort..." + wrongFileName + " : " + remoteFilePath);
                    MsgManager.Instance.Broadcast(InternalEvent.REMOTE_UPDATE_ERROR, new MsgArgs(remoteContent, remoteFilePath, wrongFileName));
                    yield break;
                }

                //本地主配置文件获取
                DocumentAccessor.LoadAsset(localFilePath, (string e) => { localContent = e; });

                var remoteVersion = remoteContent.Split('=')[1];
                var localVersion  = localContent.Split('=')[1];
                if (remoteVersion != localVersion)
                {
                    //更新文档
                    DocumentAccessor.SaveAsset2LocalFile(localFilePath, contentByteArr);
                }
                else
                {
                    yield break;
                }
            }
            else
            {
                yield break;
            }

            //1、下载最新的资源配置信息
            //================DLL 运行库================//
            remoteFilePath = CONFIG_NAME;
            //发送下载XX文件事件
            MsgManager.Instance.Broadcast(InternalEvent.HANDLING_REMOTE_RES, new MsgArgs(remoteFilePath, InternalEvent.RemoteStatus.Download));

            localFilePath = AssetPathManager.Instance.GetPersistentDataPath(remoteFilePath, false);
            //2、根据本地是否存在资源配置信息,如果不存在,则视为远程更新流程不执行
            if (DocumentAccessor.IsExists(localFilePath))
            {
                string remoteContent  = null;
                byte[] contentByteArr = null;

                //远程主配置文件获取
                LDebug.Log("Remote update..." + FrameworkConfig.Instance.RemoteUrlConfig + "/" + remoteFilePath + " 开始读取", LogColor.yellow);
                yield return(DocumentAccessor.ILoadAsset(FrameworkConfig.Instance.RemoteUrlConfig + remoteFilePath, callBack: (UnityWebRequest e) =>
                {
                    LDebug.Log("Remote update..." + remoteFilePath + "读取完成", LogColor.yellow);
                    remoteContent = e.downloadHandler.text;
                    contentByteArr = e.downloadHandler.data;
                },
                                                         errorCallBack: (UnityWebRequest e) =>
                {
                    LDebug.LogError("Remote Error..." + e + ": " + remoteFilePath);
                    if (!string.IsNullOrEmpty(e.error))
                    {
                        canGoFurther = false; return;
                    }
                }));

                // 因为加载出问题导致无法继续时,目前先使用中断后续步骤,并弹窗提醒的方式搞
                if (!canGoFurther)
                {
                    LDebug.LogError("Remote Update Abort..." + wrongFileName + " : " + remoteFilePath);
                    MsgManager.Instance.Broadcast(InternalEvent.REMOTE_UPDATE_ERROR, new MsgArgs(remoteContent, remoteFilePath, wrongFileName));
                    yield break;
                }

                //本地主配置文件获取
                DocumentAccessor.LoadAsset(localFilePath, (string e) => { localContent = e; });

                //更新文档
                DocumentAccessor.SaveAsset2LocalFile(localFilePath, contentByteArr);
            }


            //================DLL 调试库================//
            if (!FrameworkConfig.Instance.showLog)
            {
                yield break;
            }

            remoteFilePath = CONFIG_NAME_PDB;
            localFilePath  = AssetPathManager.Instance.GetPersistentDataPath(remoteFilePath, false);

            //发送下载XX文件事件
            MsgManager.Instance.Broadcast(InternalEvent.HANDLING_REMOTE_RES, new MsgArgs(remoteFilePath, InternalEvent.RemoteStatus.Download));

            //2、根据本地是否存在资源配置信息,如果不存在,则视为远程更新流程不执行
            if (DocumentAccessor.IsExists(localFilePath))
            {
                string remoteContent  = null;
                byte[] contentByteArr = null;

                //远程主配置文件获取
                LDebug.Log("Remote update..." + FrameworkConfig.Instance.RemoteUrlConfig + "/" + remoteFilePath + " 开始读取", LogColor.yellow);
                yield return(DocumentAccessor.ILoadAsset(FrameworkConfig.Instance.RemoteUrlConfig + remoteFilePath, callBack: (UnityWebRequest e) =>
                {
                    LDebug.Log("Remote update..." + remoteFilePath + "读取完成", LogColor.yellow);
                    remoteContent = e.downloadHandler.text;
                    contentByteArr = e.downloadHandler.data;
                },
                                                         errorCallBack: (UnityWebRequest e) =>
                {
                    LDebug.LogError("Remote Error..." + e + ": " + remoteFilePath);
                    if (!string.IsNullOrEmpty(e.error))
                    {
                        canGoFurther = false; return;
                    }
                }));

                // 因为加载出问题导致无法继续时,目前先使用中断后续步骤,并弹窗提醒的方式搞
                if (!canGoFurther)
                {
                    LDebug.LogError("Remote Update Abort..." + wrongFileName + " : " + remoteFilePath);
                    MsgManager.Instance.Broadcast(InternalEvent.REMOTE_UPDATE_ERROR, new MsgArgs(remoteContent, remoteFilePath, wrongFileName));
                    yield break;
                }

                //本地主配置文件获取
                DocumentAccessor.LoadAsset(localFilePath, (string e) => { localContent = e; });

                //更新文档
                DocumentAccessor.SaveAsset2LocalFile(localFilePath, contentByteArr);
            }
        }
Пример #11
0
        public IEnumerator HotFixExecute()
        {
            LDebug.Log("开始检测更新:" + CONFIG_NAME);
            //1、下载最新的资源配置信息
            bool   canGoFurther   = true;
            string localContent   = null;
            string wrongFileName  = string.Empty;
            string remoteFilePath = CONFIG_NAME;

            //发送下载XX文件事件
            MsgManager.Instance.Broadcast(InternalEvent.HANDLING_REMOTE_RES, new MsgArgs(remoteFilePath, InternalEvent.RemoteStatus.Download));

            string localFilePath = AssetPathManager.Instance.GetPersistentDataPath(remoteFilePath, false);

            //2、根据本地是否存在资源配置信息,如果不存在,则视为远程更新流程不执行
            if (DocumentAccessor.IsExists(localFilePath))
            {
                string remoteContent  = null;
                byte[] contentByteArr = null;

                //远程主配置文件获取
                LDebug.Log("Remote update..." + FrameworkConfig.Instance.RemoteUrlConfig + "/" + remoteFilePath + " 开始读取", LogColor.yellow);
                yield return(DocumentAccessor.ILoadAsset(FrameworkConfig.Instance.RemoteUrlConfig + remoteFilePath, callBack: (UnityWebRequest e) =>
                {
                    LDebug.Log("Remote update..." + remoteFilePath + "读取完成", LogColor.yellow);
                    remoteContent = e.downloadHandler.text;
                    contentByteArr = e.downloadHandler.data;
                },
                                                         errorCallBack: (UnityWebRequest e) =>
                {
                    LDebug.LogError("Remote Error..." + e + ": " + remoteFilePath);
                    if (!string.IsNullOrEmpty(e.error))
                    {
                        canGoFurther = false; return;
                    }
                }));

                //因为加载出问题导致无法继续时,目前先使用中断后续步骤,并弹窗提醒的方式搞
                if (!canGoFurther)
                {
                    MsgManager.Instance.Broadcast(InternalEvent.REMOTE_UPDATE_ERROR, new MsgArgs(remoteContent, remoteFilePath));
                    yield break;
                }

                //本地主配置文件获取
                DocumentAccessor.LoadAsset(localFilePath, (string e) => { localContent = e; });

                //AB资源默认增量更新
                Dictionary <string, ABVersion> remoteABVersionsDic = ResolveABContent(remoteContent);
                Dictionary <string, ABVersion> localABVersionsDic  = ResolveABContent(localContent);

                //需要删除的对象
                var toDelete = localABVersionsDic.Where(a => !remoteABVersionsDic.ContainsKey(a.Key));
                foreach (var item in toDelete)
                {
                    string opFile = $"{FrameworkConfig.Instance.ABFolderName}/{item.Key}";
                    if (FrameworkConfig.Instance.useZIP)
                    {
                        if (opFile.Contains(".manifest"))
                        {
                            continue;
                        }
                        opFile += ".zip";
                    }
                    FileInfo fileInfo = new FileInfo(AssetPathManager.Instance.GetPersistentDataPath(opFile, false));
                    if (fileInfo.Exists)
                    {
                        fileInfo.Delete();
                    }
                    LDebug.Log(">>>Delete " + item.Key, LogColor.red);
                    LDebug.Log(">>>Delete Result " + DocumentAccessor.IsExists(AssetPathManager.Instance.GetPersistentDataPath(opFile, false)), LogColor.red);
                }

                //需要更新的对象:可以根据需求拓展对version的使用规则。
                //默认是更新版本号更高或者新增加的对象。
                var toUpdate = remoteABVersionsDic.Where(a => !localABVersionsDic.ContainsKey(a.Key) || a.Value.Version > localABVersionsDic[a.Key].Version);
                foreach (var item in toUpdate)
                {
                    string opFile = $"{FrameworkConfig.Instance.ABFolderName}/{item.Key}";
                    if (FrameworkConfig.Instance.useZIP)
                    {
                        if (opFile.Contains(".manifest"))
                        {
                            continue;
                        }
                        opFile += ".zip";
                    }
                    LDebug.Log("Remote update..." + FrameworkConfig.Instance.RemoteUrlConfig + opFile + " 开始访问", LogColor.yellow);
                    yield return(DocumentAccessor.ILoadAsset(FrameworkConfig.Instance.RemoteUrlConfig + opFile, (UnityWebRequest e) =>
                    {
                        LDebug.Log("Remote update..." + FrameworkConfig.Instance.RemoteUrlConfig + "/" + item.Key + "访问完成", LogColor.yellow);
                        DocumentAccessor.SaveAsset2LocalFile(AssetPathManager.Instance.GetPersistentDataPath(opFile, false), e.downloadHandler.data);
                    }, (e) =>
                    {
                        LDebug.LogError("Remote Error..." + e + ": " + item.Key);
                        if (!string.IsNullOrEmpty(e.error))
                        {
                            canGoFurther = false; wrongFileName = item.Key; return;
                        }
                    }));

                    // 因为加载出问题导致无法继续时,目前先使用中断后续步骤,并弹窗提醒的方式搞
                    if (!canGoFurther)
                    {
                        break;
                    }
                }

                // 因为加载出问题导致无法继续时,目前先使用中断后续步骤,并弹窗提醒的方式搞
                if (!canGoFurther)
                {
                    LDebug.LogError("Remote Update Abort..." + wrongFileName + " : " + remoteFilePath);
                    MsgManager.Instance.Broadcast(InternalEvent.REMOTE_UPDATE_ERROR, new MsgArgs(remoteContent, remoteFilePath, wrongFileName));
                    yield break;
                }

                _toZipList = remoteABVersionsDic;

                //更新文档
                DocumentAccessor.SaveAsset2LocalFile(localFilePath, contentByteArr);
                LDebug.Log("检测更新完成:" + CONFIG_NAME);
            }
        }
Пример #12
0
        /// <summary>
        /// 加载指定名称UI
        /// 功能:
        /// 1、根据名称加载预制体
        /// 2、根据UI类型加载到不同节点下
        /// 3、隐藏创建的UI克隆体
        /// 4、把克隆体加入到所有窗体列表
        /// </summary>
        /// <param name="uiName">窗体名称</param>
        /// <returns></returns>
        private BaseUI LoadUI(string uiName)
        {
            //加载的UI预制体
            BaseUI     baseUI    = null;
            GameObject prefClone = null;

            //加载预制体
            if (!string.IsNullOrEmpty(uiName))
            {
                prefClone = LoadResourceFunc != null?LoadResourceFunc(uiName) : null;
            }
            if (prefClone == null)
            {
                throw new Exception("未指定UI预制件加载方法或UI预制件路径指定错误 ==>" + uiName);
            }
            prefClone = GameObject.Instantiate(prefClone);

            //设置父节点
            if (TransRoot != null && prefClone != null)
            {
                if (_allRegisterUIDict.ContainsKey(uiName))
                {
                    //获取Unity编辑器程序集
                    var assembly = Assembly.Load("Assembly-CSharp, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null");
                    if (FrameworkConfig.Instance.scriptEnvironment == RunEnvironment.DotNet || uiName.IndexOf("Canvas_Loading") != -1)
                    {
                        LDebug.Log(">>>>>UI Load Search Assembly " + assembly.FullName + "  :  " + _allRegisterUIDict[uiName]);
                        baseUI = ( BaseUI )assembly.CreateInstance(_allRegisterUIDict[uiName], true);
                    }
                    else if (FrameworkConfig.Instance.scriptEnvironment == RunEnvironment.ILRuntime)
                    {
                        //获取热更工程程序集
                        //借由反射现成方法,调取生成ILR内部实例,并返回结果
                        LDebug.Log(">>>> RunEnvironment.ILRuntime " + assembly.FullName);
                        var ssstype = assembly.GetType("Assets.Scripts.ILRScriptCall");
                        baseUI = ssstype.GetMethod("GetUITypeByThis").Invoke(null, new object[1] {
                            _allRegisterUIDict[uiName]
                        }) as BaseUI;
                    }
                    //========================//
                    //baseUI = Activator.CreateInstance( Type.GetType( _allRegisterUIDict[ uiName ], true, true ) ) as BaseUI;
                    baseUI.GameObjectInstance = prefClone;
                    baseUI.AssetsName         = uiName;
                    baseUI.IsInitOver         = true;
                    //========================//
                }

                if (baseUI == null)
                {
                    LDebug.LogError(uiName + "UI 脚本加载失败"); return(null);
                }

                baseUI.OnAwake();

                switch (baseUI.CurrentUIType.uiNodeType)
                {
                case UINodeTypeEnum.Normal:
                    prefClone.transform.SetParent(TransNormal, false);
                    break;

                case UINodeTypeEnum.Fixed:
                    prefClone.transform.SetParent(TransFixed, false);
                    break;

                case UINodeTypeEnum.PopUp:
                    prefClone.transform.SetParent(TransPopUp, false);
                    break;

                case UINodeTypeEnum.Global:
                    prefClone.transform.SetParent(TransGlobal, false);
                    break;

                default:
                    throw new Exception("未登记的UI类型--" + baseUI.CurrentUIType.uiShowMode);
                }

                baseUI.OnAdapter();

                //加入到所有窗体缓存中
                _dictLoadedAllUIs.Add(uiName, baseUI);
                return(baseUI);
            }
            return(null);
        }
Пример #13
0
        public static void CsvToCs()
        {
            Debug.Log("配置文件转化为代码  开始!");
            _csvListToBeRestored.Clear();
            string xlsxpath   = Application.dataPath + "/XLSX";
            string streampath = Application.dataPath + "/StreamingAssets";
            string csvOutPath = Application.dataPath + "/StreamingAssets/csv";
            string csOutPath  = Application.dataPath + "/Scripts/CSV";

            if (!FrameworkConfig.Instance.UseHotFixMode)
            {
                csOutPath = Application.dataPath + "/Scripts/CSV";
            }
            else
            {
                csOutPath = Application.dataPath + "/Scripts/ILRuntime/HotFixLogic/CSV";
            }
            DirectoryInfo theXMLFolder = new DirectoryInfo(xlsxpath);

            //文件列表
            //string listpath = Application.dataPath + "/StreamingAssets/csvList.txt";
            //FileStream fs = new FileStream( listpath, FileMode.Create );
            //StreamWriter listwriter = new StreamWriter( fs, new UTF8Encoding(false) );

            if (!Directory.Exists(csvOutPath))
            {
                Directory.CreateDirectory(csvOutPath);
            }
            if (!Directory.Exists(csOutPath))
            {
                Directory.CreateDirectory(csOutPath);
            }

            try
            {
                ConfigsNamesTemplate cnt = new ConfigsNamesTemplate();
                //对文件进行遍历
                foreach (var NextFile in theXMLFolder.GetFiles())
                {
                    if (Path.GetExtension(NextFile.Name) == ".xlsx" && !NextFile.Name.StartsWith("~$"))
                    {
                        LDebug.Log(" >表处理 : " + NextFile.Name);
                        FileStream stream  = NextFile.Open(FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
                        string     csvfile = XLSXTOCSV(stream);
                        CSVParser  cp      = new CSVParser();
                        CreateCSFile(csOutPath, NextFile.Name.Split('.')[0] + ".cs", cp.CreateCS(NextFile.Name.Split('.')[0], csvfile));
                        CreateCSVFile(csvOutPath + "/" + NextFile.Name.Split('.')[0] + ".csv", csvfile);
                        LDebug.Log(NextFile.Name.Split('.')[0] + "  文件生成成功!");

                        //这里固定取配置表第三行配置作为类型读取,如果需要修改配置表适配服务器(增加第四行),需要同步修改
                        CSVReader reader = new CSVReader(csvfile);
                        cnt.configsNameList.Add(NextFile.Name.Split('.')[0], reader.GetData(0, 2));
                        //listwriter.WriteLine( "csv/" + NextFile.Name.Split( '.' )[ 0 ] + ".csv" );
                        string str = "csv/" + NextFile.Name.Split('.')[0] + ".csv";
                        _csvListToBeRestored.Add(new ABVersion {
                            AbName = str, MD5 = LitFramework.Crypto.Crypto.md5.GetFileHash(csvOutPath + "/" + NextFile.Name.Split('.')[0] + ".csv"), Version = 1
                        });
                    }
                    else if (Path.GetExtension(NextFile.Name) == ".txt")
                    {
                        FileInfo fi = new FileInfo(csvOutPath + "/" + NextFile.Name);
                        if (fi.Exists)
                        {
                            fi.Delete();
                        }
                        NextFile.CopyTo(csvOutPath + "/" + NextFile.Name);
                        //listwriter.WriteLine( NextFile.Name );
                        _csvListToBeRestored.Add(new ABVersion {
                            AbName = NextFile.Name, MD5 = string.Empty, Version = 0
                        });
                    }
                }

                //遍历框架配置的额外后缀文件
                string[] extralFile = FrameworkConfig.Instance.configs_suffix.Split('|');
                foreach (var item in extralFile)
                {
                    if (item.Equals("csv"))
                    {
                        continue;
                    }

                    GetFiles(new DirectoryInfo(streampath), item, _csvListToBeRestored);
                }

                //============更新并保存CS============//
                ConfigsParse rpp = new ConfigsParse();

                if (!FrameworkConfig.Instance.UseHotFixMode)
                {
                    EditorMenuExtention.CreateCSFile(Application.dataPath + "/Scripts/Model/Const/", "Configs.cs", rpp.CreateCS(cnt));
                }
                else
                {
                    EditorMenuExtention.CreateCSFile(Application.dataPath + "/Scripts/ILRuntime/HotFixLogic/Model/Const/", "Configs.cs", rpp.CreateCS(cnt));
                }
            }
            catch (Exception e) { LDebug.LogError(e.Message); }
            finally
            {
                //加载本地文件,没有就创建完成。有则比对同名文件的MD5,不一样则version+1
                MatchCSVTotalFile(_csvListToBeRestored);

                //listwriter.Close();
                //listwriter.Dispose();
                //fs.Dispose();
#if UNITY_EDITOR
                AssetDatabase.Refresh();
#endif
            }
        }