18 子 2D卡牌客户端搭建 / 2D卡牌客户端搭建 备注: 1.资源加载统一入口 2.创建组件层级改为UI
12个文件已修改
3个文件已删除
1539 ■■■■ 已修改文件
Main/Component/UI/Effect/EffectMgr.cs 20 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/Core/ResModule/GameObjectPoolManager.cs 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/Core/SFX/SFXPlayUtility.cs 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/Manager/ResManager.cs 110 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/Message.meta 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/ResModule/GameObjectPoolManager.cs 637 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/ResModule/GameObjectPoolManager.cs.meta 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/ResModule/UILoader.cs 402 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/KnapSack/Logic/CommonGetItemWin.cs 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/Login/LoginWin.cs 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/Message/ImgAnalysis.cs 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/UI/LoadingWin.cs 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/UI/UIBase.cs 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/UI/UIManager.cs 213 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/Utility/MaterialUtility.cs 72 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/Component/UI/Effect/EffectMgr.cs
@@ -6,7 +6,14 @@
{
    public UIEffectBehaviour GetUIEffect(int id, bool _destroy = false)
    {
        var _prefab = ResManager.Instance.LoadAsset<GameObject>("UIEffect", id.ToString());
        EffectConfig effectCfg = EffectConfig.Get(id);
        if (null == effectCfg)
        {
            return null;
        }
        var _prefab = ResManager.Instance.LoadAsset<GameObject>("UIEffect/" + effectCfg.packageName, effectCfg.fxName);
        if (_prefab == null)
        {
            return null;
@@ -106,12 +113,19 @@
    public void RecyleUIEffect(int id, GameObject _effectObj)
    {
        var _prefab = ResManager.Instance.LoadAsset<GameObject>("UIEffect", id.ToString());
        _effectObj.SetActive(false);
        EffectConfig effectCfg = EffectConfig.Get(id);
        if (null == effectCfg)
        {
            return;
        }
        var _prefab = ResManager.Instance.LoadAsset<GameObject>("UIEffect/" + effectCfg.packageName, effectCfg.fxName);
        if (_prefab == null)
        {
            return;
        }
        GameObjectPoolManager.GameObjectPool _pool = GameObjectPoolManager.Instance.RequestPool(_prefab);
        if (_pool != null)
        {
Main/Core/ResModule/GameObjectPoolManager.cs
@@ -371,7 +371,8 @@
            if (!string.IsNullOrEmpty(assetBundleName) && !string.IsNullOrEmpty(assetName))
            {
                ResManager.Instance.UnloadAsset(assetBundleName);
                ResManager.Instance.UnloadAsset(assetBundleName, assetName);
                ResManager.Instance.UnloadAssetBundle(assetBundleName, true, false);
            }
        }
Main/Core/SFX/SFXPlayUtility.cs
@@ -237,8 +237,14 @@
    private SFXController Create(int id)
    {
        GameObject _prefab = ResManager.Instance.LoadAsset<GameObject>("UIEffect", id.ToString());
        EffectConfig effectCfg = EffectConfig.Get(id);
        if (null == effectCfg)
        {
            return null;
        }
        var _prefab = ResManager.Instance.LoadAsset<GameObject>("UIEffect/" + effectCfg.packageName, effectCfg.fxName);
        if (_prefab == null)
        {
            return null;
Main/Manager/ResManager.cs
@@ -7,6 +7,8 @@
using LitJson;
using System.IO;
using UnityEngine.Networking;
using UnityEngine.Video;
#if UNITY_EDITOR
using UnityEditor;
@@ -61,6 +63,19 @@
        }
    }
    
    private static readonly Dictionary<Type, string> fileExtensionDict = new Dictionary<Type, string>()
    {
        {typeof(GameObject), "prefab"},
        {typeof(Sprite), "png"},
        {typeof(Texture2D), "png"},
        {typeof(Shader), "shader"},
        {typeof(TextAsset), "txt"},
        {typeof(AudioClip), "wav"},
        {typeof(Font), "ttf"},
        {typeof(Material), "mat"},
        {typeof(VideoClip), "mp4"},
        {typeof(SpriteAtlas), "spriteatlasv2"},
    };
    public void Init()
@@ -75,22 +90,8 @@
    
    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";
        if (fileExtensionDict.TryGetValue(type, out string extension))
            return "." + extension;
        else
        {
            Debug.LogErrorFormat("GetExtension() => 不支持的资源类型: {0}.", type.Name);
@@ -125,32 +126,34 @@
    public T LoadAsset<T> (string directory, string name) where T : UnityEngine.Object
    {
        T asset = null;
        //  特殊处理 因为有一层图集的关系 directory要传入的应该是atlas的名字
        if (typeof(T) == typeof(Sprite))
        {
            return LoadSprite(directory, name) as T;
        }
        return LoadAssetInternal<T>(directory, name);
    }
    private T LoadAssetInternal<T>(string directory, string name) where T : UnityEngine.Object
    {
        T asset = null;
        var path = string.Concat($"Assets/ResourcesOut/{directory}/{name}", GetExtension(typeof(T))).Replace("//", "/");
        if (AssetSource.uiFromEditor)
        {
#if UNITY_EDITOR
        var path = string.Concat($"Assets/ResourcesOut/{directory}/{name}", GetExtension(typeof(T)));
        //  找不到文件时,尝试在内部继续找
        if (!File.Exists(path))
        {
            path = GetRelativePath(FindFilePath(directory, name + GetExtension(typeof(T))));
            if (string.IsNullOrEmpty(path))
            {
                Debug.LogErrorFormat("LoadAsset() => 加载不到资源: {1} {0}." + path, name, directory);
                return asset;
            }
        }
        asset = UnityEditor.AssetDatabase.LoadAssetAtPath<T>(path);
#else
        //TODO YYL ASSET BUNDLE部分要重写处理一下
        if (prefabBundle == null)
        {
            // string _path = GetAssetFilePath("builtin/prefabs");
            string _path = GetAssetFilePath($"builtin/{directory}");
            prefabBundle = AssetBundle.LoadFromFile(_path);
        }
        asset = prefabBundle.LoadAsset(name) as t;
            asset = UnityEditor.AssetDatabase.LoadAssetAtPath<T>(path);
#endif
        }
        else
        {
            var assetInfo = new AssetInfo(directory.ToLower(), name.ToLower());
            asset = AssetBundleUtility.Instance.Sync_LoadAsset(assetInfo, typeof(T)) as T;
        }
        if (asset == null)
        {
            Debug.LogErrorFormat("LoadAsset() => 加载不到资源: {0}.", name);
@@ -159,11 +162,30 @@
        return asset;
    }
    public void UnloadAsset(string assetBundleName)
    private Sprite LoadSprite(string atlasName, string spriteName)
    {
#if !UNITY_EDITOR
        SpriteAtlas atlas = LoadAsset<SpriteAtlas>("Sprite", atlasName);
        return atlas.GetSprite(spriteName);
#else
        //  编辑器下可以直接加载没啥问题
        return LoadAssetInternal<Sprite>("Sprite/" + atlasName, spriteName);
#endif
    }
    public void UnloadAsset(string assetBundleName, string assetName)
    {
        if (AssetSource.uiFromEditor)
            return;
        AssetBundleUtility.Instance.UnloadAsset(assetBundleName, assetName);
    }
    public void UnloadAssetBundle(string assetBundleName, bool unloadAllLoadedObjects, bool includeDependenice)
    {
        if (AssetSource.uiFromEditor)
            return;
        AssetBundleUtility.Instance.UnloadAssetBundle(assetBundleName, unloadAllLoadedObjects, includeDependenice);
    }
    public string GetAssetFilePath(string _assetKey)
Main/Message.meta
File was deleted
Main/ResModule/GameObjectPoolManager.cs
File was deleted
Main/ResModule/GameObjectPoolManager.cs.meta
File was deleted
Main/ResModule/UILoader.cs
@@ -7,368 +7,56 @@
using UnityEngine.U2D;
// public class UILoader
// {
//     readonly static string PREFAB_EXTERSION = ".prefab";
//     readonly static string SPRITE_EXTERSION = ".png";
//     readonly static string Spriteatlas_EXTERSION = ".spriteatlasv2";
public class UILoader
{
    public static GameObject LoadWindow(string name)
    {
        return ResManager.Instance.LoadAsset<GameObject>("UI", name);
    }
//     public static GameObject LoadWindow(string name)
//     {
//         GameObject window = null;
//         if (AssetSource.uiFromEditor)
//         {
// #if UNITY_EDITOR
//             var isPriority = false;//PriorityWindowConfig.Get().priorityWindows.Contains(name);
    public static GameObject LoadPrefab(string _name)
    {
        return ResManager.Instance.LoadAsset<GameObject>("Prefab", _name);
    }
//             var path = StringUtility.Contact(ResourcesPath.ResourcesOutAssetPath,
//                                                                 isPriority ? ResourcesPath.UI_PRIORITYWINDOW_SUFFIX : ResourcesPath.UI_WINDOW_SUFFIX, "/",
//                                                                 name,
//                                                                 PREFAB_EXTERSION);
    public static void UnLoadPrefab(string _assetName)
    {
        ResManager.Instance.UnloadAsset("Prefab", _assetName);
    }
//             window = UnityEditor.AssetDatabase.LoadAssetAtPath<GameObject>(path);
// #endif
//         }
//         else
//         {
//             // var isPriority = PriorityWindowConfig.Get().priorityWindows.Contains(name);
//             var bundleName = "ui/window";
    public static Sprite LoadSprite(string _iconKey)
    {
        var iconConfig = IconConfig.Get(_iconKey);
        if (iconConfig == null)
        {
            return null;
        }
//             var assetInfo = new AssetInfo(bundleName, name);
        return LoadSprite(iconConfig.folder, iconConfig.sprite);
    }
//             window = AssetBundleUtility.Instance.Sync_LoadAsset(assetInfo) as GameObject;
//         }
    public static Sprite LoadSprite(string _folder, string _file)
    {
        return ResManager.Instance.LoadAsset<Sprite>("Sprite/" + _folder, _file);
    }
//         if (window == null)
//         {
//             Debug.LogErrorFormat("UILoader.LoadWindow() => 加载不到资源: {0}.", name);
//         }
    public static void UnLoadSprite(string _iconKey)
    {
        var iconConfig = IconConfig.Get(_iconKey);
        if (iconConfig != null)
        {
            var bundleName = StringUtility.Contact("Sprite/", iconConfig.folder);
            ResManager.Instance.UnloadAsset(bundleName, iconConfig.sprite);
        }
    }
//         return window;
//     }
    public static Font LoadFont(string _fontName)
    {
        return ResManager.Instance.LoadAsset<Font>("Font", _fontName);
    }
//     public static void LoadWindowAsync(string _name, Action<bool, UnityEngine.Object> _callBack)
//     {
//         GameObject window = null;
//         if (AssetSource.uiFromEditor)
//         {
// #if UNITY_EDITOR
//             var isPriority = PriorityWindowConfig.Get().priorityWindows.Contains(_name);
//             var path = StringUtility.Contact(ResourcesPath.ResourcesOutAssetPath,
//                                                                isPriority ? ResourcesPath.UI_PRIORITYWINDOW_SUFFIX : ResourcesPath.UI_WINDOW_SUFFIX, "/",
//                                                                _name,
//                                                                PREFAB_EXTERSION);
//             window = UnityEditor.AssetDatabase.LoadAssetAtPath<GameObject>(path);
//             if (_callBack != null)
//             {
//                 _callBack(window != null, window);
//             }
// #endif
//         }
//         else
//         {
//             var isPriority = PriorityWindowConfig.Get().priorityWindows.Contains(_name);
//             var bundleName = isPriority ? StringUtility.Contact("ui/prioritywindow/", _name) : "ui/window";
//             var assetInfo = new AssetInfo(bundleName, _name);
//             AssetBundleUtility.Instance.Co_LoadAsset(assetInfo, _callBack);
//         }
//     }
//     public static void UnLoadWindowAsset(string _assetName)
//     {
//         if (!AssetSource.uiFromEditor)
//         {
//             var isPriority = PriorityWindowConfig.Get().priorityWindows.Contains(_assetName);
//             var bundleName = isPriority ? StringUtility.Contact("ui/prioritywindow/", _assetName) : "ui/window";
//             AssetBundleUtility.Instance.UnloadAsset(bundleName, _assetName);
//         }
//     }
//     public static void UnLoadPriorityWindow(string windowName)
//     {
//         if (!AssetSource.uiFromEditor)
//         {
//             var assetBundleName = StringUtility.Contact("ui/prioritywindow/", windowName.ToLower());
//             AssetBundleUtility.Instance.UnloadAssetBundle(assetBundleName, true, false);
//             switch (windowName)
//             {
//                 case "LoginWin":
//                     AssetBundleUtility.Instance.UnloadAssetBundle("ui/sprite/login", true, false);
//                     break;
//                 case "SelectRoleWin":
//                 case "CreateRoleWin":
//                     AssetBundleUtility.Instance.UnloadAssetBundle("ui/sprite/createrole", true, false);
//                     break;
//             }
//         }
//     }
//     public static GameObject LoadPrefab(string _name)
//     {
//         GameObject prefab = null;
//         if (AssetSource.uiFromEditor)
//         {
// #if UNITY_EDITOR
//             var path = StringUtility.Contact(ResourcesPath.ResourcesOutAssetPath,
//                                                                    ResourcesPath.UI_PREFAB_SUFFIX, "/",
//                                                                    _name,
//                                                                    PREFAB_EXTERSION);
//             prefab = UnityEditor.AssetDatabase.LoadAssetAtPath<GameObject>(path);
// #endif
//         }
//         else
//         {
//             var bundleName = ResourcesPath.UI_PREFAB_SUFFIX.ToLower();
//             var assetInfo = new AssetInfo(bundleName, _name);
//             prefab = AssetBundleUtility.Instance.Sync_LoadAsset(assetInfo) as GameObject;
//         }
//         if (prefab == null)
//         {
//             Debug.LogErrorFormat("UILoader.LoadPrefab() => 加载不到资源: {0}.", _name);
//         }
//         return prefab;
//     }
//     public static void UnLoadPrefab(string _assetName)
//     {
//         if (!AssetSource.uiFromEditor)
//         {
//             AssetBundleUtility.Instance.UnloadAsset("ui/prefab", _assetName);
//         }
//     }
//     public static Sprite LoadSprite(string _iconKey)
//     {
//         var iconConfig = IconConfig.Get(_iconKey);
//         if (iconConfig == null)
//         {
//             return null;
//         }
//         return LoadSprite(iconConfig.folder, iconConfig.sprite);
//     }
//     public static Sprite LoadSprite(string _folder, string _file)
//     {
//         var folder = _folder;
//         var file = _file;
//         Sprite sprite = null;
//         if (AssetSource.uiFromEditor)
//         {
// #if UNITY_EDITOR
//             var relativePath = folder;
//             var rootPath = ResourcesPath.UI_SPRITE_SUFFIX;
//             var path = StringUtility.Contact(ResourcesPath.ResourcesOutAssetPath,
//                                                                  rootPath, "/",
//                                                                  relativePath,
//                                                                  Spriteatlas_EXTERSION);
//             var spriteAtlas = UnityEditor.AssetDatabase.LoadAssetAtPath<SpriteAtlas>(path);
//             sprite = spriteAtlas.GetSprite(file);
// #endif
//         }
//         else
//         {
//             var bundleName = StringUtility.Contact("ui/sprite/", folder.ToLower());
//             //var assetInfo = new AssetInfo(bundleName, folder);
//             //var spriteAtlas = AssetBundleUtility.Instance.Sync_LoadAsset(assetInfo, typeof(SpriteAtlas)) as SpriteAtlas;
//             //sprite = spriteAtlas?.GetSprite(_file);
//             var assetInfo = new AssetInfo(bundleName, file);
//             sprite = AssetBundleUtility.Instance.Sync_LoadAsset(assetInfo, typeof(Sprite)) as Sprite;
//         }
//         if (sprite == null)
//         {
//             Debug.LogErrorFormat("UILoader.LoadSprite() => 加载不到资源: {0}.", file);
//         }
//         return sprite;
//     }
//     public static void UnLoadSprite(string _iconKey)
//     {
//         if (!AssetSource.uiFromEditor)
//         {
//             var iconConfig = IconConfig.Get(_iconKey);
//             if (iconConfig != null)
//             {
//                 var bundleName = StringUtility.Contact("ui/sprite/", iconConfig.folder.ToLower());
//                 AssetBundleUtility.Instance.UnloadAsset(bundleName, iconConfig.sprite);
//             }
//         }
//     }
//     public static Font LoadFont(string _fontName)
//     {
//         Font font = null;
//         if (AssetSource.uiFromEditor)
//         {
// #if UNITY_EDITOR
//             var rootPath = ResourcesPath.UI_FONT_SUFFIX;
//             var path = StringUtility.Contact(ResourcesPath.ResourcesOutAssetPath, rootPath, "/", _fontName, ".ttf");
//             font = UnityEditor.AssetDatabase.LoadAssetAtPath<Font>(path);
// #endif
//         }
//         else
//         {
//             var assetInfo = new AssetInfo("ui/font", _fontName);
//             font = AssetBundleUtility.Instance.Sync_LoadAsset(assetInfo, typeof(Font)) as Font;
//         }
//         if (font == null)
//         {
//             Debug.LogErrorFormat("UILoader.LoadFont() => 加载不到资源: {0}.", _fontName);
//         }
//         return font;
//     }
//     public static void UnLoadFont(string _fontName)
//     {
//         if (!AssetSource.uiFromEditor)
//         {
//             AssetBundleUtility.Instance.UnloadAsset("ui/font", _fontName);
//         }
//     }
//     public static GameObject LoadTreasure(string folder, string name)
//     {
//         GameObject prefab = null;
//         if (AssetSource.uiFromEditor)
//         {
// #if UNITY_EDITOR
//             var path = StringUtility.Contact(ResourcesPath.ResourcesOutAssetPath,
//                                                                    "UI/Treasure/", folder, "/",
//                                                                    name,
//                                                                    PREFAB_EXTERSION);
//             prefab = UnityEditor.AssetDatabase.LoadAssetAtPath<GameObject>(path);
// #endif
//         }
//         else
//         {
//             var bundleName = StringUtility.Contact("ui/treasure/", folder).ToLower();
//             var assetInfo = new AssetInfo(bundleName, name);
//             prefab = AssetBundleUtility.Instance.Sync_LoadAsset(assetInfo) as GameObject;
//         }
//         if (prefab == null)
//         {
//             Debug.LogErrorFormat("UILoader.LoadPrefab() => 加载不到资源: {0}.", name);
//         }
//         return prefab;
//     }
//     public static void UnLoadTreasure(string folder, string _assetName)
//     {
//         if (!AssetSource.uiFromEditor)
//         {
//             AssetBundleUtility.Instance.UnloadAsset(StringUtility.Contact("ui/treasure/", folder).ToLower(), _assetName);
//         }
//     }
//     public static GameObject LoadFaqi(string pathName, string name)
//     {
//         GameObject prefab = null;
//         if (AssetSource.uiFromEditor)
//         {
// #if UNITY_EDITOR
//             var path = StringUtility.Contact(ResourcesPath.ResourcesOutAssetPath,
//                                                                    //"UI/Treasure/", folder, "/",
//                                                                    pathName,
//                                                                    name,
//                                                                    PREFAB_EXTERSION);
//             prefab = UnityEditor.AssetDatabase.LoadAssetAtPath<GameObject>(path);
// #endif
//         }
//         else
//         {
//             var bundleName = pathName; //StringUtility.Contact("ui/treasure/", folder).ToLower();
//             var assetInfo = new AssetInfo(bundleName, name);
//             prefab = AssetBundleUtility.Instance.Sync_LoadAsset(assetInfo) as GameObject;
//         }
//         if (prefab == null)
//         {
//             Debug.LogErrorFormat("UILoader.LoadFaqi() => 加载不到资源: {0}.", name);
//         }
//         return prefab;
//     }
//     public static GameObject LoadGodWeapon(string _name)
//     {
//         GameObject prefab = null;
//         if (AssetSource.uiFromEditor)
//         {
// #if UNITY_EDITOR
//             var path = StringUtility.Contact(ResourcesPath.ResourcesOutAssetPath,
//                                                                    "UI/GodWeapon/",
//                                                                    _name,
//                                                                    PREFAB_EXTERSION);
//             prefab = UnityEditor.AssetDatabase.LoadAssetAtPath<GameObject>(path);
// #endif
//         }
//         else
//         {
//             var bundleName = "ui/godweapon";
//             var assetInfo = new AssetInfo(bundleName, _name);
//             prefab = AssetBundleUtility.Instance.Sync_LoadAsset(assetInfo) as GameObject;
//         }
//         if (prefab == null)
//         {
//             Debug.LogErrorFormat("UILoader.LoadGodWeapon() => 加载不到资源: {0}.", _name);
//         }
//         return prefab;
//     }
//     public static GameObject LoadBossShow(string _name)
//     {
//         GameObject prefab = null;
//         if (AssetSource.uiFromEditor)
//         {
// #if UNITY_EDITOR
//             var path = StringUtility.Contact(ResourcesPath.ResourcesOutAssetPath,
//                                                                    "UI/BossShow/",
//                                                                    _name,
//                                                                    PREFAB_EXTERSION);
//             prefab = UnityEditor.AssetDatabase.LoadAssetAtPath<GameObject>(path);
// #endif
//         }
//         else
//         {
//             var bundleName = "ui/bossshow";
//             var assetInfo = new AssetInfo(bundleName, _name);
//             prefab = AssetBundleUtility.Instance.Sync_LoadAsset(assetInfo) as GameObject;
//         }
//         if (prefab == null)
//         {
//             Debug.LogErrorFormat("UILoader.LoadBossShow() => 加载不到资源: {0}.", _name);
//         }
//         return prefab;
//     }
// }
    public static void UnLoadFont(string _fontName)
    {
        ResManager.Instance.UnloadAsset("Font", _fontName);
    }
}
Main/System/KnapSack/Logic/CommonGetItemWin.cs
@@ -21,19 +21,6 @@
            sureBtn.SetListener(() => UIManager.Instance.CloseWindow<CommonGetItemWin>());
        }
        public override void HandleOpen()
        {
            base.HandleOpen();
            Debug.Log("打开通用获得物品窗口");
            Refresh();
        }
        public override void HandleClose()
        {
            base.HandleClose();
            Debug.Log("关闭通用获得物品窗口");
        }
        public override void Refresh()
        {
            base.Refresh();
@@ -42,6 +29,7 @@
        protected override void OnPreOpen()
        {
            Refresh();
            ItemLogicUtility.Instance.OnGetItemShowEvent += OnGetItemShowEvent;
            scroller.OnRefreshCell += OnRefreshCell;
            desc.SetActive(!string.IsNullOrEmpty(ItemLogicUtility.Instance.getItemInfo));
Main/System/Login/LoginWin.cs
@@ -79,9 +79,9 @@
        });
    }
    public override void HandleOpen()
    protected override void OnPreOpen()
    {
        base.HandleOpen();
        base.OnPreOpen();
        Debug.Log("打开登录窗口");
@@ -102,9 +102,9 @@
        });
    }
    public override void HandleClose()
    protected override void OnPreClose()
    {
        base.HandleClose();
        base.OnPreClose();
        Debug.Log("关闭登录窗口");
        ServerListCenter.Instance.serverSelectEvent -= OnServerChange;
        ServerListCenter.Instance.onServerListRefreshEvent -= OnServerListRefresh;
Main/System/Message/ImgAnalysis.cs
@@ -189,8 +189,7 @@
        if (presentImgInfo.IsFace) return;
        if (IconConfig.isInit)
        {
            presentImgInfo.sprite = ResManager.Instance.LoadAsset<Sprite>("Sprite", presentImgInfo.spriteName);
            // presentImgInfo.sprite = UILoader.LoadSprite(presentImgInfo.spriteName);
            presentImgInfo.sprite = UILoader.LoadSprite(presentImgInfo.spriteName);
        }
        if (presentImgInfo.sprite != null)
Main/UI/LoadingWin.cs
@@ -23,16 +23,16 @@
        progressText = transform.Find("Text_Progress").GetComponent<Text>();
    }
    public override void HandleOpen()
    protected override void OnPreOpen()
    {
        base.HandleOpen();
        base.OnPreOpen();
        currentProgress = targetProgress = 0;
        Refresh();
    }
    public override void HandleClose()
    protected override void OnPreClose()
    {
        base.HandleClose();
        base.OnPreClose();
    }
    public override void Refresh()
Main/UI/UIBase.cs
@@ -209,7 +209,7 @@
    }
    // 打开UI
    public virtual void HandleOpen()
    public void HandleOpen()
    {
        OnPreOpen();
        // 如果正在播放动画,先停止
@@ -228,7 +228,7 @@
    }
    // 关闭UI - 修改后的方法
    public virtual void HandleClose()
    public void HandleClose()
    {
        // 如果已经在关闭过程中,直接返回
        if (isClosing) return;
@@ -272,7 +272,7 @@
    public virtual void CloseWindow()
    {
        UIManager.Instance.CloseWindow(this);
        UIManager.Instance.CloseWindow(this, false);
    }
    // 刷新UI
@@ -309,22 +309,29 @@
    /// <param name="autoDestroy">是否自动销毁,默认为true</param>
    /// <param name="destroyDelay">自动销毁延迟时间,默认为5秒</param>
    /// <returns>特效游戏对象</returns>
    public async UniTask<GameObject> PlayUIEffect(string effectName, Transform parent = null, bool autoDestroy = true, float destroyDelay = 5f)
    public async UniTask<GameObject> PlayUIEffect(int id, Transform parent = null, bool autoDestroy = true, float destroyDelay = 5f)
    {
        // 使用默认值
        if (parent == null) parent = transform;
        
        EffectConfig effectCfg = EffectConfig.Get(id);
        if (null == effectCfg)
        {
            return null;
        }
        // 加载特效资源
        GameObject effectPrefab = ResManager.Instance.LoadAsset<GameObject>("UIEffect", effectName);
        var effectPrefab = ResManager.Instance.LoadAsset<GameObject>("UIEffect/" + effectCfg.packageName, effectCfg.fxName);
        if (effectPrefab == null)
        {
            Debug.LogError($"加载UI特效失败: {effectName}");
            Debug.LogError($"加载UI特效失败: {effectCfg.packageName}");
            return null;
        }
        
        // 实例化特效
        GameObject effectObj = Instantiate(effectPrefab, parent);
        effectObj.name = $"Effect_{effectName}";
        effectObj.name = $"Effect_{effectCfg.packageName}";
        
        // 添加特效穿透阻挡器
        EffectPenetrationBlocker blocker = effectObj.AddComponent<EffectPenetrationBlocker>();
Main/UI/UIManager.cs
@@ -31,6 +31,9 @@
    // UI字典,存储所有已加载的UI,键为UI名称,值为UI实例
    private Dictionary<string, List<UIBase>> uiDict = new Dictionary<string, List<UIBase>>();
    
    // 存储关闭但未销毁的UI,键为UI名称,值为UI实例
    private Dictionary<string, List<UIBase>> closedUIDict = new Dictionary<string, List<UIBase>>();
    // UI栈,用于管理UI的显示顺序
    private Stack<UIBase> uiStack = new Stack<UIBase>();
    
@@ -91,56 +94,33 @@
        // 如果场景中没有UI根节点,则创建一个
        if (root == null)
        {
            root = new GameObject("UIRoot");
            // 添加DontDestroyOnLoad组件,确保UI根节点在场景切换时不被销毁
            GameObject.DontDestroyOnLoad(root);
            // 创建各层级节点
            GameObject staticNode = new GameObject("Static");
            GameObject bottomNode = new GameObject("Bottom");
            GameObject midNode = new GameObject("Mid");
            GameObject topNode = new GameObject("Top");
            GameObject systemNode = new GameObject("System");
            // 设置父节点
            staticNode.transform.SetParent(root.transform, false);
            bottomNode.transform.SetParent(root.transform, false);
            midNode.transform.SetParent(root.transform, false);
            topNode.transform.SetParent(root.transform, false);
            systemNode.transform.SetParent(root.transform, false);
            root = GameObject.Instantiate(BuiltInLoader.LoadPrefab("UIRoot"));
            if (root == null)
            {
                Debug.LogError("无法找到UI根节点");
                return;
            }
            // 添加DontDestroyOnLoad组件,确保UI根节点在场景切换时不被销毁
            GameObject.DontDestroyOnLoad(root);
        }
        uiRoot = root.transform;
        uiRoot.position = Vector3.zero;
        // 初始化各层级的Transform
        staticTrans = uiRoot.Find("Static");
        bottomTrans = uiRoot.Find("Bottom");
        midTrans = uiRoot.Find("Middle");
        topTrans = uiRoot.Find("Top");
        systemTrans = uiRoot.Find("System");
        // // 添加基础Canvas
        // Canvas rootCanvas = root.AddComponent<Canvas>();
        // rootCanvas.renderMode = RenderMode.ScreenSpaceOverlay;
        // rootCanvas.sortingOrder = 0;
        // // 添加CanvasScaler
        // UnityEngine.UI.CanvasScaler scaler = root.AddComponent<UnityEngine.UI.CanvasScaler>();
        // scaler.uiScaleMode = UnityEngine.UI.CanvasScaler.ScaleMode.ScaleWithScreenSize;
        // scaler.referenceResolution = new Vector2(1920, 1080);
        // scaler.screenMatchMode = UnityEngine.UI.CanvasScaler.ScreenMatchMode.MatchWidthOrHeight;
        // scaler.matchWidthOrHeight = 1.0f;
        // // 添加GraphicRaycaster
        // root.AddComponent<UnityEngine.UI.GraphicRaycaster>();
        layerTransformCache.Clear();
        layerTransformCache.Add(UILayer.Static, staticTrans);
        layerTransformCache.Add(UILayer.Bottom, bottomTrans);
        layerTransformCache.Add(UILayer.Mid, midTrans);
        layerTransformCache.Add(UILayer.Top, topTrans);
        layerTransformCache.Add(UILayer.System, systemTrans);
    }
    
    #endregion
@@ -370,13 +350,13 @@
    public void CheckAndCloseIdleUI()
    {
        // 如果没有UI,直接返回
        if (uiDict.Count == 0)
        if (uiDict.Count == 0 && closedUIDict.Count == 0)
            return;
            
        // 创建需要关闭的UI列表
        List<UIBase> uiToClose = new List<UIBase>();
        
        // 遍历所有UI
        // 遍历所有活跃UI
        foreach (var uiList in uiDict.Values)
        {
            foreach (var ui in uiList)
@@ -385,6 +365,9 @@
                if (ui.isPersistent)
                    continue;
                    
                if (ui.IsActive())
                    continue;
                // 计算UI空闲的回合数
                int idleRounds = currentRound - ui.lastUsedRound;
                
@@ -396,13 +379,53 @@
            }
        }
        
        // 关闭所有需要关闭的UI
        // 遍历所有关闭的UI
        List<string> emptyKeys = new List<string>();
        foreach (var kvp in closedUIDict)
        {
            string uiName = kvp.Key;
            List<UIBase> uiList = kvp.Value;
            List<UIBase> uiToRemove = new List<UIBase>();
            foreach (var ui in uiList)
            {
                // 计算UI空闲的回合数
                int idleRounds = currentRound - ui.lastUsedRound;
                // 如果空闲回合数超过最大空闲回合数,添加到关闭列表
                if (idleRounds > ui.maxIdleRounds)
                {
                    uiToClose.Add(ui);
                    uiToRemove.Add(ui);
                }
            }
            // 从关闭列表中移除需要销毁的UI
            foreach (var ui in uiToRemove)
            {
                uiList.Remove(ui);
            }
            // 如果列表为空,记录需要从字典中移除的键
            if (uiList.Count == 0)
            {
                emptyKeys.Add(uiName);
            }
        }
        // 从字典中移除空列表
        foreach (var key in emptyKeys)
        {
            closedUIDict.Remove(key);
        }
        // 销毁所有需要关闭的UI
        foreach (var ui in uiToClose)
        {
            // 记录日志
            Debug.Log($"关闭长时间未使用的UI: {ui.uiName}, 空闲回合数: {currentRound - ui.lastUsedRound}");
            // 关闭UI
            CloseWindow(ui);
            Debug.Log($"销毁长时间未使用的UI: {ui.uiName}, 空闲回合数: {currentRound - ui.lastUsedRound}");
            // 销毁UI对象
            GameObject.Destroy(ui.gameObject);
        }
    }
    
@@ -525,8 +548,80 @@
        // 获取UI类型名称
        string uiName = typeof(T).Name;
  
        // Debug.LogError("打开ui " + uiName);
        // 优先从closedUIDict中获取
        if (closedUIDict.TryGetValue(uiName, out List<UIBase> closedUIList) && closedUIList.Count > 0)
        {
            T recycledUI = closedUIList[0] as T;
            closedUIList.RemoveAt(0);
            if (closedUIList.Count == 0)
            {
                closedUIDict.Remove(uiName);
            }
            recycledUI.gameObject.SetActive(true);
            // 自动设置父级UI(如果未指定且支持父子关系)
            if (parentUI == null && recycledUI.supportParentChildRelation && uiStack.Count > 0)
            {
                // 获取栈顶UI
                UIBase topUI = uiStack.Peek();
                // 如果栈顶UI也支持父子关系且不是主UI,则将其设为父级
                if (topUI != null && topUI.supportParentChildRelation && !topUI.isMainUI)
                {
                    parentUI = topUI;
                }
            }
            // 设置父级UI
            if (parentUI != null && recycledUI.supportParentChildRelation && !parentUI.isMainUI)
            {
                // 设置父子关系
                recycledUI.parentUI = parentUI;
                if (parentUI.childrenUI == null)
                {
                    // 初始化父级UI的子UI列表
                    parentUI.childrenUI = new List<UIBase>();
                }
                // 添加到父级UI的子UI列表
                parentUI.childrenUI.Add(recycledUI);
            }
            // 更新回合数
            currentRound++;
            // 设置UI的最后使用回合数
            recycledUI.lastUsedRound = currentRound;
            // 更新父级UI的回合数
            UpdateParentUIRounds(recycledUI);
            // 将UI添加到字典中
            if (!uiDict.ContainsKey(uiName))
            {
                // 如果字典中不存在该类型的UI,创建新列表
                uiDict[uiName] = new List<UIBase>();
            }
            // 添加到UI列表
            uiDict[uiName].Add(recycledUI);
            // 将UI添加到栈中
            uiStack.Push(recycledUI);
            // 更新UI排序顺序
            UpdateUISortingOrder();
            // 打开UI
            recycledUI.HandleOpen();
            OnOpenWindow?.Invoke(recycledUI);
            // 检查并关闭长时间未使用的UI
            CheckAndCloseIdleUI();
            return recycledUI;
        }
        // 如果closedUIDict中没有可用的UI实例,则加载新的UI资源
        // Debug.LogError("打开ui " + uiName);
        // 加载UI资源
        T ui = LoadUIResource<T>(uiName);
@@ -601,16 +696,16 @@
    /// <summary>
    /// 关闭UI
    /// </summary>
    public void CloseWindow<T>() where T : UIBase
    public void CloseWindow<T>(bool destroy = false) where T : UIBase
    {
        // 获取UI类型名称
        string uiName = typeof(T).Name;
        
        CloseWindow(uiName);
        CloseWindow(uiName, destroy);
        
    }
    public void CloseWindow(string uiName)
    public void CloseWindow(string uiName, bool destroy = false)
    {
        // 检查UI是否存在
        if (!uiDict.ContainsKey(uiName) || uiDict[uiName].Count == 0)
@@ -624,13 +719,13 @@
        UIBase ui = uiDict[uiName][0];
        
        // 关闭UI
        CloseWindow(ui);
        CloseWindow(ui, destroy);
    }
    
    /// <summary>
    /// 关闭指定的UI实例
    /// </summary>
    public void CloseWindow(UIBase ui)
    public void CloseWindow(UIBase ui, bool destroy = false)
    {
        // 检查UI是否为空
        if (ui == null)
@@ -654,7 +749,7 @@
        foreach (var childUI in childrenUI)
        {
            // 关闭子UI
            CloseWindow(childUI);
            CloseWindow(childUI, destroy);
        }
        
        // 从栈中移除UI
@@ -699,8 +794,23 @@
        ui.HandleClose();
        OnCloseWindow?.Invoke(ui);
        
        // 销毁UI对象
        GameObject.Destroy(ui.gameObject);
        if (destroy)
        {
            // 销毁UI对象
            GameObject.Destroy(ui.gameObject);
        }
        else
        {
            // 添加到closedUIDict
            if (!closedUIDict.ContainsKey(uiName))
            {
                closedUIDict[uiName] = new List<UIBase>();
            }
            closedUIDict[uiName].Add(ui);
            // 隐藏UI
            ui.gameObject.SetActive(false);
        }
        
        // 更新UI排序顺序
        UpdateUISortingOrder();
@@ -729,7 +839,7 @@
        foreach (var ui in uiListCopy)
        {
            // 关闭UI实例
            CloseWindow(ui);
            CloseWindow(ui, false);
        }
    }
    
@@ -746,12 +856,13 @@
        foreach (var ui in uiArray)
        {
            // 关闭UI
            CloseWindow(ui);
            CloseWindow(ui, true);
        }
        
        // 清空UI字典和栈
        uiDict.Clear();
        uiStack.Clear();
        closedUIDict.Clear();
    }
    
    /// <summary>
Main/Utility/MaterialUtility.cs
@@ -7,7 +7,7 @@
    public static Material GetDefaultSpriteGrayMaterial()
    {
        return ResManager.Instance.LoadAsset<Material>("Material", "SpriteGray");
        return ResManager.Instance.LoadAsset<Material>("Materials", "SpriteGray");
    }
    public static Material GetInstantiatedSpriteGrayMaterial()
@@ -18,12 +18,12 @@
    public static Material GetSmoothMaskGrayMaterial()
    {
        return ResManager.Instance.LoadAsset<Material>("Material", "SmoothMaskGray");
        return ResManager.Instance.LoadAsset<Material>("Materials", "SmoothMaskGray");
    }
    public static Material GetInstantiatedSpriteTwinkleMaterial()
    {
        var material = ResManager.Instance.LoadAsset<Material>("Material", "Flash");
        var material = ResManager.Instance.LoadAsset<Material>("Materials", "Flash");
        return new Material(material);
    }
@@ -32,14 +32,9 @@
        return UnityEngine.UI.Image.defaultGraphicMaterial;
    }
    public static Material GetUIBlurMaterial()
    {
        return ResManager.Instance.LoadAsset<Material>("Material", "GUIBlurMaterial");
    }
    public static Material GetGUIRenderTextureMaterial()
    {
        return ResManager.Instance.LoadAsset<Material>("Material", "UI_RenderTexture");
        return ResManager.Instance.LoadAsset<Material>("Materials", "UI_RenderTexture");
    }
    public static void SetRenderSortingOrder(this GameObject root, int sortingOrder, bool includeChildren)
@@ -67,67 +62,8 @@
                renderer.sortingOrder = sortingOrder;
            }
        }
    }
    static Shader m_HeroShader;
    static Shader m_PlayerShader;
    static Shader heroShader {
        get {
            if (m_HeroShader == null)
            {
                m_HeroShader = Shader.Find("Character/Character,Emission,Flow_Hero");
            }
            if (m_HeroShader == null)
            {
                m_HeroShader = Shader.Find("Character/Character, Emission,Flow_Hero");
            }
            return m_HeroShader;
        }
    }
    static Shader playerShader {
        get {
            if (m_PlayerShader == null)
            {
                m_PlayerShader = Shader.Find("Character/Character,Emission,Flow");
            }
            if (m_PlayerShader == null)
            {
                m_PlayerShader = Shader.Find("Character/Character, Emission,Flow");
            }
            return m_PlayerShader;
        }
    }
    public static void SwitchXrayShader(Material _material, bool _isHero)
    {
        if (_material == null)
        {
            return;
        }
        if (_isHero)
        {
            if (_material.shader.name != "Character/Character,Emission,Flow_Hero" && _material.shader.name != "Character/Character, Emission,Flow_Hero")
            {
                _material.shader = heroShader;
                _material.SetColor("_XRayColor", new Color32(0, 107, 255, 255));
            }
        }
        else
        {
            if (_material.shader.name != "Character/Character, Emission,Flow" && _material.shader.name != "Character/Character,Emission,Flow")
            {
                _material.shader = playerShader;
            }
        }
    }
}