From 01b5728a890315e4dbe9aabf7225a7957171e1a5 Mon Sep 17 00:00:00 2001
From: yyl <yyl>
Date: 星期四, 07 五月 2026 18:00:36 +0800
Subject: [PATCH] webgl2

---
 Main/SDK/SDKAndroidImpl.cs.meta                 |   11 +
 Main/SDK/SDKWebGLImpl.cs                        |   68 ++++++
 Main/System/KnapSack/PackManager.cs             |   12 -
 Main/System/Tip/ScrollTip.cs                    |    3 
 Main/SDK/SDKBaseImpl.cs                         |   50 +++++
 Main/System/Login/LoginWin.cs                   |   34 +++
 Main/Core/NetworkPackage/GameNetSystem.cs       |    2 
 Main/SDK/SDKBaseImpl.cs.meta                    |   11 +
 Main/SDK/SDKWebGLImpl.cs.meta                   |   11 +
 Main/Core/NetworkPackage/Socket/ClientSocket.cs |   87 +++++++
 Main/System/Tip/ScrollTipDetail.cs              |   13 
 Main/SDK/SDKAndroidImpl.cs                      |  100 ++++++++++
 Main/System/Message/MessageWin.cs               |    9 
 Main/System/Login/LoginManager.cs               |   28 ++
 Main/System/Tip/ScrollTipWin.cs                 |    9 
 Main/SDK/SDKUtils.cs                            |  149 +++++---------
 16 files changed, 459 insertions(+), 138 deletions(-)

diff --git a/Main/Core/NetworkPackage/GameNetSystem.cs b/Main/Core/NetworkPackage/GameNetSystem.cs
index e43d534..e3033f9 100644
--- a/Main/Core/NetworkPackage/GameNetSystem.cs
+++ b/Main/Core/NetworkPackage/GameNetSystem.cs
@@ -118,6 +118,8 @@
             Debug.Log(ex);
         }
 
+        Debug.unityLogger.logEnabled = true;
+
         mainSocket = new ClientSocket(ServerType.Main);
         //  websocket鐨勬柇寮�閾炬帴闇�瑕佸鐞嗕竴涓�
         mainSocket.OnDisconnected = () =>
diff --git a/Main/Core/NetworkPackage/Socket/ClientSocket.cs b/Main/Core/NetworkPackage/Socket/ClientSocket.cs
index ae90b8d..9bc71b1 100644
--- a/Main/Core/NetworkPackage/Socket/ClientSocket.cs
+++ b/Main/Core/NetworkPackage/Socket/ClientSocket.cs
@@ -76,11 +76,13 @@
 
     public void Connect(string _ip, int _port, Action<bool> _onConnected)
     {
+        Debug.unityLogger.logEnabled = true;
         try
         {
             ip = _ip;
             port = _port;
             onConnected = _onConnected;
+            Debug.Log($"[ClientSocket][Connect] 灏濊瘯杩炴帴: ip={_ip}, port={_port}");
             //鐩墠娴嬭瘯鍒板紓姝ヤ袱涓棶棰�
             // 1. BeginGetHostAddresses 涓嶆槑鎯呭喌涓嬩細寰堜箙鎵嶅洖璋冿紝瀵艰嚧瑙﹀彂瓒呮椂
             // 2. 瓒呮椂鐨勬儏鍐典笅澶氭灏濊瘯鐧诲綍鍚庯紝浼氳Е鍙戝娆nGetHostAddresses锛屽鑷寸櫥褰曞紓甯�
@@ -96,29 +98,29 @@
             ipAddress = ipAddresses[0];
 #endif
 
-
+            Debug.Log($"[ClientSocket][Connect] 瑙f瀽鍒癷pAddress={ipAddress}, family={ipAddress.AddressFamily}");
             if (ipAddress.AddressFamily == AddressFamily.InterNetworkV6)
             {
-                Debug.Log("褰撳墠浣跨敤鐨勭綉缁�: IPV6");
+                Debug.Log("[ClientSocket][Connect] 褰撳墠浣跨敤鐨勭綉缁�: IPV6");
                 m_Socket = new Socket(AddressFamily.InterNetworkV6, SocketType.Stream, ProtocolType.Tcp);
             }
             else
             {
-                Debug.Log("褰撳墠浣跨敤鐨勭綉缁�: IPV4");
+                Debug.Log("[ClientSocket][Connect] 褰撳墠浣跨敤鐨勭綉缁�: IPV4");
                 m_Socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
             }
 
             var ipEndPoint = new IPEndPoint(ipAddress, port);
             if (ipEndPoint == null)
             {
-                Debug.Log("IpEndPoint is null");
+                Debug.LogError("[ClientSocket][Connect] IpEndPoint is null");
             }
 
             m_Socket.BeginConnect(ipEndPoint, new AsyncCallback(ConnectCallBack), null);
         }
         catch (Exception e)
         {
-            Debug.LogError(e.Message);
+            Debug.LogError($"[ClientSocket][Connect] 寮傚父: {e.Message}");
         }
 
 
@@ -154,12 +156,14 @@
     /// <param name="_result"></param>
     private void ConnectCallBack(IAsyncResult _result)
     {
+        Debug.unityLogger.logEnabled = true;
         if (!_result.IsCompleted)
         {
-            Debug.Log("閾炬帴瓒呮椂锛�");
+            Debug.LogError("[ClientSocket][ConnectCallBack] 閾炬帴瓒呮椂锛�");
             CloseConnect();
             if (onConnected != null)
             {
+                Debug.LogError("[ClientSocket][ConnectCallBack] onConnected(false) 瓒呮椂");
                 onConnected(false);
                 onConnected = null;
             }
@@ -170,11 +174,12 @@
             {
                 if (m_Socket != null && m_Socket.Connected)
                 {
-                    Debug.Log("纭鐨勯摼鎺ュ疄鐜�");
+                    Debug.Log("[ClientSocket][ConnectCallBack] 纭鐨勯摼鎺ュ疄鐜�");
                     OnConnectSuccess();
                 }
                 else
                 {
+                    Debug.LogError("[ClientSocket][ConnectCallBack] m_Socket涓簄ull鎴栨湭杩炴帴");
                     if (m_Socket != null)
                     {
                         m_Socket.Disconnect(true);
@@ -183,12 +188,13 @@
             }
             catch (System.Exception ex)
             {
-                Debug.Log(ex);
+                Debug.LogError($"[ClientSocket][ConnectCallBack] 寮傚父: {ex}");
             }
             finally
             {
                 if (onConnected != null)
                 {
+                    Debug.Log($"[ClientSocket][ConnectCallBack] onConnected({{0}})", m_Socket != null && m_Socket.Connected);
                     onConnected(m_Socket != null && m_Socket.Connected);
                     onConnected = null;
                 }
@@ -205,6 +211,8 @@
     public void CloseConnect()
     {
         Debug.Log("==== CloseConnect");
+        Debug.unityLogger.logEnabled = true;
+        Debug.Log("[ClientSocket][CloseConnect] ==== CloseConnect");
         try
         {
             isStopTreading = true;
@@ -242,6 +250,20 @@
     {
         if (m_packageThread != null)
         {
+            m_packageThread.Abort();
+            m_packageThread = null;
+        }
+
+        m_LastPackageTime = DateTime.Now;
+        m_packageThread = new Thread(new ThreadStart(ReceiveInfo)); // 鍚姩绾跨▼鎺ユ敹淇℃伅
+        m_packageThread.IsBackground = true;
+        m_packageThread.Start();
+        isStopTreading = false;
+        Debug.unityLogger.logEnabled = true;
+        Debug.Log("[ClientSocket][OnConnectSuccess] 杩炴帴鎴愬姛锛屽惎鍔ㄦ帴鏀剁嚎绋�");
+        if (m_packageThread != null)
+        {
+            Debug.LogWarning("[ClientSocket][OnConnectSuccess] m_packageThread宸插瓨鍦紝鍏圓bort");
             m_packageThread.Abort();
             m_packageThread = null;
         }
@@ -296,6 +318,51 @@
                 Debug.Log(e);
             }
         }
+        Debug.unityLogger.logEnabled = true;
+        Debug.Log("[ClientSocket][ReceiveInfo] 鎺ユ敹绾跨▼鍚姩");
+        while (!isStopTreading)
+        {
+            try
+            {
+                var shutdown = false;
+                if (!m_Socket.Connected)
+                {
+                    Debug.LogWarning("[ClientSocket][ReceiveInfo] m_Socket 宸叉柇寮�");
+                    shutdown = true;
+                }
+
+                if (!shutdown)
+                {
+                    var dataLength = m_Socket.Receive(bufferBytes);
+                    Debug.Log($"[ClientSocket][ReceiveInfo] 鏀跺埌鏁版嵁闀垮害: {dataLength}");
+                    if (dataLength <= 0)
+                    {
+                        Debug.LogWarning("[ClientSocket][ReceiveInfo] dataLength <= 0锛屽噯澶囨柇寮�");
+                        shutdown = true;
+                    }
+                    else
+                    {
+                        getBytesTotal += dataLength;
+                        var bytes = new byte[dataLength];
+                        Array.Copy(bufferBytes, 0, bytes, 0, dataLength);
+                        ReadInfo(bytes);
+                    }
+                }
+
+                if (shutdown)
+                {
+                    Debug.LogWarning("[ClientSocket][ReceiveInfo] shutdown=true锛屽叧闂璖ocket");
+                    isStopTreading = true;
+                    m_Socket.Shutdown(SocketShutdown.Both);
+                    m_Socket.Close();
+                }
+            }
+            catch (Exception e)
+            {
+                Debug.LogError($"[ClientSocket][ReceiveInfo] 寮傚父: {e}");
+            }
+        }
+        Debug.Log("[ClientSocket][ReceiveInfo] 鎺ユ敹绾跨▼閫�鍑�");
 
     }
 
@@ -312,6 +379,7 @@
             if (fragmentBytes != null && fragmentBytes.Length > 0)
             {
                 Array.Resize(ref fixBytes, vBytes.Length + fragmentBytes.Length);
+                Debug.Log($"[ClientSocket][ReadInfo] 瀛樺湪fragmentBytes, 闀垮害: {fragmentBytes.Length}");
                 Array.Copy(fragmentBytes, 0, fixBytes, 0, fragmentBytes.Length);
                 Array.Copy(vBytes, 0, fixBytes, fragmentBytes.Length, vBytes.Length);
             }
@@ -439,6 +507,7 @@
     
     public async void Connect(string _ip, int _port, Action<bool> _onConnected)
     {
+        Debug.unityLogger.logEnabled = true;
         ip = _ip;
         port = _port;
         onConnected = _onConnected;
@@ -597,7 +666,7 @@
     
     public async void CloseConnect()
     {
-        Debug.Log("[ClientSocket-WebSocket] ==== CloseConnect");
+        Debug.Log("[ClientSocket-WebSocket] ==== CloseConnect\n" + System.Environment.StackTrace);
         fragmentBytes = null;
         
         if (webSocket != null)
diff --git a/Main/SDK/SDKAndroidImpl.cs b/Main/SDK/SDKAndroidImpl.cs
new file mode 100644
index 0000000..f7740d0
--- /dev/null
+++ b/Main/SDK/SDKAndroidImpl.cs
@@ -0,0 +1,100 @@
+#if UNITY_ANDROID
+using UnityEngine;
+using LitJson;
+using System;
+
+/// <summary>
+/// Android骞冲彴SDK瀹炵幇锛岀户鎵縎DKBaseImpl銆�
+/// 閫氳繃AndroidJavaClass涓庡師鐢烻DK浜や簰銆�
+/// </summary>
+public class SDKAndroidImpl : SDKBaseImpl
+{
+    public SDKAndroidImpl(SDKUtils utils) : base(utils) { }
+
+    // -------------------------------------------------------
+    // 搴曞眰娑堟伅鍙戦�� 鈥斺�� 閫氳繃AndroidJavaClass璋冪敤鍘熺敓SDK
+    // -------------------------------------------------------
+    public override void SendToNative(string jsonStr)
+    {
+        if (VersionConfig.Get().appId == "sghy")
+        {
+            using (var sdk = new AndroidJavaClass("com.xssg.sdk.UnityMsgHandler"))
+                sdk.CallStatic("onUnityMessage", jsonStr);
+        }
+        else
+        {
+            using (var sdk = new AndroidJavaClass("com.wgyx.sdk.UnityMsgHandler"))
+                sdk.CallStatic("onUnityMessage", jsonStr);
+        }
+    }
+
+    // -------------------------------------------------------
+    // 鍒濆鍖� 鈥斺�� 妫�鏌ュ唴缃祫婧愭嫹璐濈姸鎬� + 鍚屾鍖匢D
+    // -------------------------------------------------------
+    public override void InitPlatform()
+    {
+        var savedVer = LocalSave.GetString("BuiltInAssetCopyCompleted_Android");
+        SDKUtils.builtinAssetCopyFinished = !string.IsNullOrEmpty(savedVer)
+            && VersionConfig.Get().version == savedVer;
+        SyncClientPackageID();
+    }
+
+    // -------------------------------------------------------
+    // SDK鐧诲綍 鈥斺�� 璧版甯稿師鐢烻DK娴佺▼
+    // -------------------------------------------------------
+    public override void FreePlatformLogin()
+    {
+        utils.SendSdkMessage(SDKUtils.CodeU2A.FreePlatformLogin);
+    }
+
+    // -------------------------------------------------------
+    // 璁惧淇℃伅 鈥斺�� Android鐗规湁锛歮ac/imei/totalMemory
+    // -------------------------------------------------------
+    public override void FillDeviceInfo(JsonData json)
+    {
+        utils.Device.macAddress = json["mac"].ToString();
+        utils.Device.imei = json["imei"] != null ? json["imei"].ToString() : utils.Device.uniqueID;
+        utils.Device.totalMemory = (int)json["memoryTotal"];
+    }
+
+    // -------------------------------------------------------
+    // 閫�鍑烘父鎴�
+    // -------------------------------------------------------
+    public override void ExitGame()
+    {
+        Application.Quit();
+    }
+
+    // -------------------------------------------------------
+    // Android涓撳睘锛氭潈闄� & 鍖匢D
+    // -------------------------------------------------------
+
+    public override void SyncClientPackageID()
+    {
+        utils.SendSdkMessage(SDKUtils.CodeU2A.ClientPackage,
+            json => json["clientPkgID"] = VersionConfig.Get().clientPackageFlag);
+    }
+
+    public override void RequestPermission(string permission, Action<string, int> callBack)
+    {
+        utils.RegisterPermissionCallback(callBack);
+        utils.SendSdkMessage(SDKUtils.CodeU2A.RequestPermission,
+            json => json["permission"] = permission);
+    }
+
+    public override void RequestPermissionStart()
+    {
+        utils.SendSdkMessage(SDKUtils.CodeU2A.RequestPermissionStart);
+    }
+
+    // -------------------------------------------------------
+    // 闈欐�佸伐鍏� 鈥斺�� 鑾峰彇Android搴旂敤涓婁笅鏂�
+    // -------------------------------------------------------
+    public static AndroidJavaObject GetApplicationContext()
+    {
+        using (var jc = new AndroidJavaClass("com.unity3d.player.UnityPlayer"))
+        using (var jo = jc.GetStatic<AndroidJavaObject>("currentActivity"))
+            return jo.Call<AndroidJavaObject>("getApplicationContext");
+    }
+}
+#endif
diff --git a/Main/SDK/SDKAndroidImpl.cs.meta b/Main/SDK/SDKAndroidImpl.cs.meta
new file mode 100644
index 0000000..404d332
--- /dev/null
+++ b/Main/SDK/SDKAndroidImpl.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: fad8ebe1b08b656489826bafdefb356f
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Main/SDK/SDKBaseImpl.cs b/Main/SDK/SDKBaseImpl.cs
new file mode 100644
index 0000000..4d3f349
--- /dev/null
+++ b/Main/SDK/SDKBaseImpl.cs
@@ -0,0 +1,50 @@
+using UnityEngine;
+using LitJson;
+using System;
+
+/// <summary>
+/// SDK骞冲彴瀹炵幇鐨勬娊璞″熀绫汇��
+/// 姣忎釜鐩爣骞冲彴锛圓ndroid銆乄ebGL绛夛級缁ф壙姝ょ被骞跺疄鐜板悇鑷殑閫昏緫銆�
+/// SDKUtils鎸佹湁涓�涓猄DKBaseImpl瀹炰緥锛屾墍鏈夊钩鍙板樊寮傚潎閫氳繃姝ゅ熀绫诲鎵樸��
+/// </summary>
+public abstract class SDKBaseImpl
+{
+    protected readonly SDKUtils utils;
+
+    protected SDKBaseImpl(SDKUtils utils)
+    {
+        this.utils = utils;
+    }
+
+    // -------------------------------------------------------
+    // 蹇呴』鐢卞瓙绫诲疄鐜扮殑骞冲彴鏍稿績鏂规硶
+    // -------------------------------------------------------
+
+    /// <summary>鍚戝钩鍙板師鐢烻DK鍙戦�丣SON娑堟伅</summary>
+    public abstract void SendToNative(string jsonStr);
+
+    /// <summary>骞冲彴鍒濆鍖栵紙妫�鏌ュ唴缃祫婧愭嫹璐濈姸鎬併�佸钩鍙扮壒鏈夎缃瓑锛�</summary>
+    public abstract void InitPlatform();
+
+    /// <summary>瑙﹀彂SDK璐﹀彿鐧诲綍娴佺▼</summary>
+    public abstract void FreePlatformLogin();
+
+    /// <summary>濉厖骞冲彴鐗规湁鐨勮澶囦俊鎭瓧娈碉紙濡侫ndroid鐨刴ac/imei绛夛級</summary>
+    public abstract void FillDeviceInfo(JsonData json);
+
+    /// <summary>閫�鍑烘父鎴忥紙鍚勫钩鍙拌涓轰笉鍚岋級</summary>
+    public abstract void ExitGame();
+
+    // -------------------------------------------------------
+    // 鍙�夐噸鍐欙紙榛樿绌哄疄鐜帮紝浠匒ndroid绛夊钩鍙伴渶瑕侊級
+    // -------------------------------------------------------
+
+    /// <summary>鍚屾瀹㈡埛绔寘ID鍒板師鐢烻DK</summary>
+    public virtual void SyncClientPackageID() { }
+
+    /// <summary>鍔ㄦ�佺敵璇峰崟涓潈闄�</summary>
+    public virtual void RequestPermission(string permission, Action<string, int> callBack) { }
+
+    /// <summary>鍚姩鏃舵壒閲忕敵璇锋潈闄愶紙鐢盨DK鍐冲畾绛栫暐锛�</summary>
+    public virtual void RequestPermissionStart() { }
+}
diff --git a/Main/SDK/SDKBaseImpl.cs.meta b/Main/SDK/SDKBaseImpl.cs.meta
new file mode 100644
index 0000000..c3a6752
--- /dev/null
+++ b/Main/SDK/SDKBaseImpl.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 75293dc3923823b408a427acffc9d6a8
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Main/SDK/SDKUtils.cs b/Main/SDK/SDKUtils.cs
index 2c5891b..9526253 100644
--- a/Main/SDK/SDKUtils.cs
+++ b/Main/SDK/SDKUtils.cs
@@ -66,7 +66,7 @@
     /// sdk鍒濆鍖栨槸鍚﹀畬鎴愭爣璇�
     /// 瀹㈡埛绔竴鑸渶瑕佺瓑寰呰繖涓�间负true鎵嶇户缁�昏緫
     /// </summary>
-    public bool InitFinished { get; private set; }
+    public bool InitFinished { get; set; }
 
     #region 鍩虹瀹氫箟涓庡洖璋�
 
@@ -106,7 +106,7 @@
     /// </summary>
     public UnityAction<NetworkReachability> OnNetworkStatusChanged;
 
-    public static bool builtinAssetCopyFinished { get; private set; }
+    public static bool builtinAssetCopyFinished { get; internal set; }
 
     /// <summary>
     /// 鏄惁宸茬粡灏哠treamingAsset鎷疯礉鑷崇洰鏍囪矾寰�
@@ -125,11 +125,24 @@
     #endregion
 
     #region 鑷敱sdk
-    public FP_LoginOk FreePlatformInfo { get; private set; }
+    public FP_LoginOk FreePlatformInfo { get; set; }
     #endregion
 
     private JsonData m_Json = new JsonData();
 
+    // 褰撳墠骞冲彴SDK瀹炵幇
+    private SDKBaseImpl m_impl;
+
+    private SDKBaseImpl CreateImpl()
+    {
+#if UNITY_ANDROID
+        return new SDKAndroidImpl(this);
+#elif UNITY_WEBGL
+        return new SDKWebGLImpl(this);
+#else
+        return null; // Editor/Standalone: SendMessageToSDK鍦‥ditor涓嬬洿鎺ヨ烦杩�
+#endif
+    }
 
     public void Init()
     {
@@ -155,22 +168,14 @@
         NetworkType = NetworkReachability.NotReachable;
         BatteryLevel = 100;
 
+        m_impl = CreateImpl();
+
 #if !UNITY_EDITOR
         if (InitFinished)
         {
             return;
         }
-#if UNITY_ANDROID
-        var builtinAssetsCopyFinishVersion = LocalSave.GetString("BuiltInAssetCopyCompleted_Android");
-        if (string.IsNullOrEmpty(builtinAssetsCopyFinishVersion))
-        {
-            builtinAssetCopyFinished = false;
-        }
-        else
-        {
-            builtinAssetCopyFinished = VersionConfig.Get().version == builtinAssetsCopyFinishVersion;
-        }
-#endif
+        m_impl?.InitPlatform();
 #if UNITY_IOS || UNITY_STANDALONE
         var builtinAssetsCopyFinishVersion = LocalSave.GetString("BuiltInAssetCopyCompleted_IOSorStandalone");
         if (string.IsNullOrEmpty(builtinAssetsCopyFinishVersion))
@@ -192,8 +197,6 @@
             AssetCopyFinished = VersionConfig.Get().version == assetsCopyFinishVersion;
         }
 
-#elif UNITY_ANDROID
-        SyncClientPackageID();
 #endif
 
         InitFinished = false;
@@ -320,41 +323,22 @@
         SendMessageToSDK(m_Json);
     }
 
-    public void SyncClientPackageID()
-    {
-#if UNITY_ANDROID
-        m_Json.Clear();
-        m_Json["code"] = CodeU2A.ClientPackage;
-        m_Json["clientPkgID"] = VersionConfig.Get().clientPackageFlag;
-        SendMessageToSDK(m_Json);
-#endif
-    }
-
-    //鐢宠Android 鏉冮檺
-    public void RequestAndroidPermission(string permission, Action<string, int> callBack)
-    {
-        onPermissionCallBack += callBack;
-        m_Json.Clear();
-        m_Json["code"] = CodeU2A.RequestPermission;
-        m_Json["permission"] = permission;
-        SendMessageToSDK(m_Json);
-    }
-
-    //鐢宠Android 鏉冮檺 鍚姩鏃�
-    public void RequestAndroidPermissionStart()
-    {
-        m_Json.Clear();
-        m_Json["code"] = CodeU2A.RequestPermissionStart;
-        SendMessageToSDK(m_Json);
-    }
-
-
     public void RequestSecretRule()
     {
         m_Json.Clear();
         m_Json["code"] = CodeU2A.RequestSecretRule;
         SendMessageToSDK(m_Json);
     }
+
+    /// <summary>鍚屾瀹㈡埛绔寘ID锛堝鎵樼粰骞冲彴瀹炵幇锛�</summary>
+    public void SyncClientPackageID() => m_impl?.SyncClientPackageID();
+
+    /// <summary>鍔ㄦ�佺敵璇稟ndroid鏉冮檺锛堥潪Android骞冲彴涓虹┖鎿嶄綔锛�</summary>
+    public void RequestAndroidPermission(string permission, Action<string, int> callBack)
+        => m_impl?.RequestPermission(permission, callBack);
+
+    /// <summary>鍚姩鏃舵壒閲忕敵璇锋潈闄愶紙闈濧ndroid骞冲彴涓虹┖鎿嶄綔锛�</summary>
+    public void RequestAndroidPermissionStart() => m_impl?.RequestPermissionStart();
 
 
 
@@ -379,17 +363,6 @@
 
     #region 澶勭悊涓嶴DK浜や簰鐨勫簳灞傛柟娉�
 
-    public static AndroidJavaObject GetApplicationContext()
-    {
-        using (AndroidJavaClass jc = new AndroidJavaClass("com.unity3d.player.UnityPlayer"))
-        {
-            using (AndroidJavaObject jo = jc.GetStatic<AndroidJavaObject>("currentActivity"))
-            {
-                return jo.Call<AndroidJavaObject>("getApplicationContext");
-            }
-        }
-    }
-
     public string GetSplicePackageID()
     {
         var _result = "default";
@@ -409,29 +382,28 @@
     private void SendMessageToSDK(JsonData json)
     {
 #if !UNITY_EDITOR
-#if UNITY_ANDROID
-        if (VersionConfig.Get().appId == "sghy")
-        {
-            using (AndroidJavaClass H2engineSDK = new AndroidJavaClass("com.xssg.sdk.UnityMsgHandler"))
-            {
-                H2engineSDK.CallStatic("onUnityMessage", json.ToJson());
-            }
-        }
-        else
-        {
-            using (AndroidJavaClass H2engineSDK = new AndroidJavaClass("com.wgyx.sdk.UnityMsgHandler"))
-            {
-                H2engineSDK.CallStatic("onUnityMessage", json.ToJson());
-            }
-        }
-#elif UNITY_IOS
-        AotSdkUtility.IOSUniyMessageHandle(json.ToJson());
-#elif UNITY_STANDALONE || UNITY_WEBGL
-        InitFinished=true;
+        var _jsonStr = json.ToJson();
+#if UNITY_IOS
+        AotSdkUtility.IOSUniyMessageHandle(_jsonStr);
+#else
+        m_impl?.SendToNative(_jsonStr);
 #endif
-        
 #endif
+    }
 
+    /// <summary>渚涘钩鍙板疄鐜扮被璋冪敤鐨勪究鎹峰彂鍖呮柟娉曪紙甯﹀彲閫塉SON濉厖锛�</summary>
+    internal void SendSdkMessage(int code, Action<JsonData> fillJson = null)
+    {
+        m_Json.Clear();
+        m_Json["code"] = code;
+        fillJson?.Invoke(m_Json);
+        SendMessageToSDK(m_Json);
+    }
+
+    /// <summary>渚涘钩鍙板疄鐜扮被娉ㄥ唽鏉冮檺鍥炶皟</summary>
+    internal void RegisterPermissionCallback(Action<string, int> callBack)
+    {
+        onPermissionCallBack += callBack;
     }
 
     public void HandleMsgWithSDK(string jsonString)
@@ -447,18 +419,7 @@
                 //Device.uniqueID = _json["unique_id"].ToString();
                 Device.androidID = _json["android_id"].ToString();// ios骞冲彴涓嬩负idfa
                 Device.userAgent = _json["userAgent"].ToString();
-#if UNITY_ANDROID
-                Device.macAddress = _json["mac"].ToString();
-                if (_json["imei"] != null)
-                {
-                    Device.imei = _json["imei"].ToString();
-                }
-                else
-                {
-                    Device.imei = Device.uniqueID;
-                }
-                Device.totalMemory = (int)_json["memoryTotal"];
-#endif
+                m_impl?.FillDeviceInfo(_json);
                 if (OnDeviceInfoChanged != null)
                 {
                     OnDeviceInfoChanged(Device);
@@ -644,11 +605,7 @@
                 // else
                 {
                     //榛樿閮芥槸閫�鍑烘父鎴�
-#if UNITY_WEBGL
-                    Application.OpenURL("about:blank");
-#else
-                    Application.Quit();
-#endif
+                    m_impl?.ExitGame();
                 }
                 break;
             case CodeA2U.GetAdAward:
@@ -746,7 +703,7 @@
         #endregion
     }
 
-    private static class CodeU2A
+    public static class CodeU2A
     {
         /**
          * 鎵ц璧勬簮鎷疯礉
@@ -930,9 +887,7 @@
     /// </summary>
     public void FreePlatformLogin()
     {
-        m_Json.Clear();
-        m_Json["code"] = CodeU2A.FreePlatformLogin;
-        SendMessageToSDK(m_Json);
+        m_impl?.FreePlatformLogin();
     }
 
 
diff --git a/Main/SDK/SDKWebGLImpl.cs b/Main/SDK/SDKWebGLImpl.cs
new file mode 100644
index 0000000..7c46d2e
--- /dev/null
+++ b/Main/SDK/SDKWebGLImpl.cs
@@ -0,0 +1,68 @@
+#if UNITY_WEBGL
+using UnityEngine;
+using LitJson;
+using System;
+
+/// <summary>
+/// WebGL骞冲彴SDK瀹炵幇锛岀户鎵縎DKBaseImpl銆�
+/// WebGL鏃犲師鐢烻DK灞傦紝鐧诲綍鐩存帴妯℃嫙鍥炶皟锛岄��鍑鸿烦杞┖鐧介〉銆�
+/// </summary>
+public class SDKWebGLImpl : SDKBaseImpl
+{
+    public SDKWebGLImpl(SDKUtils utils) : base(utils) { }
+
+    // -------------------------------------------------------
+    // 娑堟伅鍙戦�� 鈥斺�� WebGL鏃犲師鐢烻DK锛屾爣璁板垵濮嬪寲瀹屾垚鍗冲彲
+    // -------------------------------------------------------
+    public override void SendToNative(string jsonStr)
+    {
+        // WebGL鏃犲師鐢烻DK Bridge锛屾敹鍒扮涓�娆endToNative锛圛nit娑堟伅锛夊悗鏍囪瀹屾垚
+        utils.InitFinished = true;
+    }
+
+    // -------------------------------------------------------
+    // 鍒濆鍖� 鈥斺�� WebGL鏃犲唴缃祫婧愭嫹璐濇祦绋�
+    // -------------------------------------------------------
+    public override void InitPlatform()
+    {
+        // WebGL涓嶉渶瑕佸唴缃祫婧愭嫹璐濈姸鎬佹鏌�
+    }
+
+    // -------------------------------------------------------
+    // SDK鐧诲綍 鈥斺�� WebGL鐩存帴妯℃嫙鐧诲綍鎴愬姛鍥炶皟
+    // -------------------------------------------------------
+    public override void FreePlatformLogin()
+    {
+        Debug.Log("[SDKWebGLImpl] FreePlatformLogin: WebGL妯℃嫙鐧诲綍");
+
+        var info = new SDKUtils.FP_LoginOk
+        {
+            account      = "webgl_user",
+            token        = "111",          // 鍐呮祴鏈嶅厤瀵嗙害瀹氾紝涓� InterTest Password 涓�鑷�
+            qkUserName   = "webgl_user",
+            tokenExpire  = "9999999999",
+            accountID    = 0,
+            phone        = 0,
+        };
+
+        utils.FreePlatformInfo = info;
+        utils.onFreePlatformLoginOk?.Invoke(info);
+    }
+
+    // -------------------------------------------------------
+    // 璁惧淇℃伅 鈥斺�� WebGL鏃犵壒鏈夎澶囧瓧娈�
+    // -------------------------------------------------------
+    public override void FillDeviceInfo(JsonData json)
+    {
+        // WebGL涓嬫棤mac/imei绛夊瓧娈碉紝涓嶅仛棰濆濉厖
+    }
+
+    // -------------------------------------------------------
+    // 閫�鍑烘父鎴� 鈥斺�� WebGL璺宠浆绌虹櫧椤�
+    // -------------------------------------------------------
+    public override void ExitGame()
+    {
+        Application.OpenURL("about:blank");
+    }
+}
+#endif
diff --git a/Main/SDK/SDKWebGLImpl.cs.meta b/Main/SDK/SDKWebGLImpl.cs.meta
new file mode 100644
index 0000000..7e6fd81
--- /dev/null
+++ b/Main/SDK/SDKWebGLImpl.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: e46364c334945194eae43e4524adeb08
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Main/System/KnapSack/PackManager.cs b/Main/System/KnapSack/PackManager.cs
index 6c21ee8..cc19375 100644
--- a/Main/System/KnapSack/PackManager.cs
+++ b/Main/System/KnapSack/PackManager.cs
@@ -559,17 +559,9 @@
         }
     #endif
 
-        path = AssetVersionUtility.GetAssetFilePath($"Config/{name}.txt");
-
-        using var req = UnityEngine.Networking.UnityWebRequest.Get(path);
-        await req.SendWebRequest();
-
-        if (req.result != UnityEngine.Networking.UnityWebRequest.Result.Success)
-            throw new Exception($"LoadConfigIni failed: {req.error}");
-
-        return req.downloadHandler.text
-            .Split(new[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries);
+        return await ResManager.Instance.LoadConfigAsync(name + ".ini", false);
     }
+    
     public int GetCanBuyPackGirdCount(PackType type)
     {
         if (!PackMaxCountDict.ContainsKey((int)type))
diff --git a/Main/System/Login/LoginManager.cs b/Main/System/Login/LoginManager.cs
index 298f406..a0186d7 100644
--- a/Main/System/Login/LoginManager.cs
+++ b/Main/System/Login/LoginManager.cs
@@ -127,10 +127,12 @@
 
     public void AccountLogin(string _account, string _ip, int _port, int _gamePort)
     {
-        Debug.LogFormat("璐﹀彿鐧诲綍, account:{0} ; ip:{1} ; port:{2} ; gamePort:{3}", _account, _ip, _port, _gamePort);
+        Debug.unityLogger.logEnabled = true;
+        Debug.LogFormat("[LoginManager][AccountLogin] 璐﹀彿鐧诲綍, account:{0} ; ip:{1} ; port:{2} ; gamePort:{3}", _account, _ip, _port, _gamePort);
         isLogined = true;
         if (Application.internetReachability == NetworkReachability.NotReachable)
         {
+            Debug.LogError("[LoginManager][AccountLogin] 缃戠粶涓嶅彲杈撅紝寮瑰嚭鎻愮ず骞秗eturn");
             ConfirmCancel.ShowPopConfirm(
                 Language.Get("Mail101"),
                 Language.Get("L1116"),
@@ -141,6 +143,7 @@
 
         if (busy)
         {
+            Debug.LogWarning("[LoginManager][AccountLogin] busy涓簍rue锛岀洿鎺eturn");
             return;
         }
 
@@ -155,6 +158,7 @@
             portBuf = _port;
             gamePortBuf = _gamePort;
 
+            Debug.Log("[LoginManager][AccountLogin] 璋冪敤ConnectGameServer");
             ConnectGameServer(ipBuf, gamePortBuf);
 
             GameNetSystem.Instance.OnAccountLogin();
@@ -162,7 +166,7 @@
         }
         catch (Exception ex)
         {
-            Debug.Log(ex);
+            Debug.LogError($"[LoginManager][AccountLogin] 寮傚父: {ex}");
             busy = false;
         }
 
@@ -170,6 +174,8 @@
 
     public void AccountLogin(string _ip, int _port, int _gamePort)
     {
+        Debug.unityLogger.logEnabled = true;
+        Debug.LogError("[YLTEST] Account Login " + sdkLogined);
         if (sdkLogined)
         {
             AccountLogin(sdkLoginResult.account, _ip, _port, _gamePort);
@@ -204,10 +210,11 @@
 
     private void OnAccountLogin(bool _ok, string _result)
     {
+        Debug.unityLogger.logEnabled = true;
         if (!_ok)
         {
             busy = false;
-            Debug.LogError(_result);
+            Debug.LogError($"[LoginManager][OnAccountLogin] 鐧诲綍鍥炶皟澶辫触: {_result}");
             NetLinkWin.Hide();
             return;
         }
@@ -215,6 +222,7 @@
         if (string.IsNullOrEmpty(_result))
         {
             busy = false;
+            Debug.LogError("[LoginManager][OnAccountLogin] 鐧诲綍鍥炶皟_result涓虹┖锛屽脊鍑烘彁绀�");
             ServerTipDetails.DisplayNormalTip(Language.Get("L1117"));
             NetLinkWin.Hide();
             return;
@@ -225,6 +233,7 @@
         {
             if (stringSet.Length > 1)
             {
+                Debug.LogError($"[LoginManager][OnAccountLogin] 鐧诲綍鍥炶皟_result闈濷K锛屾彁绀�: {stringSet[1]}");
                 ServerTipDetails.DisplayNormalTip(stringSet[1]);
             }
 
@@ -236,11 +245,13 @@
         localSaveAccountName = accountBuf;
         try
         {
+            Debug.Log("[LoginManager][OnAccountLogin] 鐧诲綍鍥炶皟OK锛屽噯澶嘋onnectGameServer");
             ConnectGameServer(ipBuf, gamePortBuf);
         }
         catch (Exception ex)
         {
             busy = false;
+            Debug.LogError($"[LoginManager][OnAccountLogin] ConnectGameServer寮傚父: {ex}");
             Debug.Log(ex);
         }
     }
@@ -248,11 +259,15 @@
 
     void ConnectGameServer(string _ip, int _port)
     {
+        Debug.unityLogger.logEnabled = true;
+        Debug.LogError("[YLTEST] Connect Server " + _ip + ":" + _port);
         GameNetSystem.Instance.BeginConnectGameServer(_ip, _port, OnGameServerConnected);
     }
 
     private void OnGameServerConnected(bool ok)
     {
+        Debug.unityLogger.logEnabled = true;
+        Debug.LogError("[YLTEST] Connect Server result " + ok);
         if (ok)
         {
             GameNetSystem.Instance.SetIsWaitLogin(false);
@@ -386,7 +401,12 @@
     {
         GameNetSystem.Instance.SetIsWaitLogin(false);
         var send = new C0101_tagCPlayerLogin();
-        switch (VersionConfig.config.versionAuthority)
+        var authority = VersionConfig.config.versionAuthority;
+#if UNITY_WEBGL && !UNITY_EDITOR
+        // WebGL 骞冲彴娌℃湁鐪熷疄 SDK锛屽己鍒惰蛋 InterTest 鍒嗘敮锛堣处鍙�+瀵嗙爜锛夌櫥褰�
+        authority = VersionAuthority.InterTest;
+#endif
+        switch (authority)
         {
             case VersionAuthority.InterTest:
                 send.IDType = 1;
diff --git a/Main/System/Login/LoginWin.cs b/Main/System/Login/LoginWin.cs
index 35f7b46..8ca60c3 100644
--- a/Main/System/Login/LoginWin.cs
+++ b/Main/System/Login/LoginWin.cs
@@ -182,7 +182,7 @@
             var appId = VersionConfig.config.appId;
             var branch = VersionConfig.config.branch;
              m_ContainerAccount.SetActive(isGetServerList
-            && (VersionConfig.config.versionAuthority == VersionAuthority.InterTest || VersionConfig.config.isBanShu));
+            && (VersionConfig.config.versionAuthority == VersionAuthority.InterTest || VersionConfig.config.isBanShu || Application.platform == RuntimePlatform.WebGLPlayer));
         }).Forget();
 
         // m_UserHelp.SetActive(ContactConfig.GetConfig(appId, branch) != null);
@@ -275,18 +275,22 @@
         m_WaitServerList.SetActive(!ServerListCenter.Instance.serverListGot);
         m_ContainerEnterGame.SetActive(ServerListCenter.Instance.serverListGot);
         m_ContainerAccount.SetActive(ServerListCenter.Instance.serverListGot
-            && (VersionConfig.config.versionAuthority == VersionAuthority.InterTest || VersionConfig.config.isBanShu));
+            && (VersionConfig.config.versionAuthority == VersionAuthority.InterTest || VersionConfig.config.isBanShu || Application.platform == RuntimePlatform.WebGLPlayer));
     }
 
     protected virtual void EnterGame()
     {
+        Debug.unityLogger.logEnabled = true;
+        Debug.Log("[LoginWin][EnterGame] 鏂规硶杩涘叆");
         if (!checkRead.isOn)
         {
+            Debug.LogWarning("[LoginWin][EnterGame] 鐢ㄦ埛鏈嬀閫夊崗璁紝寮瑰嚭纭妗�");
             ConfirmCancel.ShowPopConfirm(Language.Get("agreementTitle"), Language.Get("agreementInfo"));
+            Debug.LogWarning("[LoginWin][EnterGame] return: 鏈嬀閫夊崗璁�");
             return;
         }
 
-
+        Debug.Log("[LoginWin][EnterGame] 鐢ㄦ埛宸插嬀閫夊崗璁紝鍑嗗闅愯棌娴獥骞惰皟鐢↙ogin()");
         SDKUtils.Instance.SendHideFloatWin();
 
         Login();
@@ -339,10 +343,13 @@
 
     protected void Login()
     {
+        Debug.unityLogger.logEnabled = true;
+        Debug.Log("[LoginWin][Login] 鏂规硶杩涘叆");
         var allow = false;
         if (DebugUtility.Instance.isWhiteListAccount)
         {
             allow = true;
+            Debug.Log("[LoginWin][Login] 鐧藉悕鍗曡处鍙凤紝鍏佽鐧诲綍");
         }
         else
         {
@@ -350,10 +357,12 @@
                 || ServerListCenter.Instance.currentServer.running_status == (int)ServerState.Predicted)
             {
                 allow = false;
+                Debug.LogWarning($"[LoginWin][Login] 褰撳墠鏈嶅姟鍣ㄧ姸鎬佷负 {ServerListCenter.Instance.currentServer.running_status}锛屼笉鍏佽鐧诲綍");
             }
             else
             {
                 allow = true;
+                Debug.Log("[LoginWin][Login] 鏈嶅姟鍣ㄧ姸鎬佸厑璁哥櫥褰�");
             }
         }
 
@@ -362,13 +371,15 @@
             switch ((ServerState)ServerListCenter.Instance.currentServer.running_status)
             {
                 case ServerState.Maintain:
+                    Debug.LogWarning("[LoginWin][Login] 鏈嶅姟鍣ㄧ淮鎶や腑锛屽脊鍑虹淮鎶ゆ彁绀�");
                     SysNotifyMgr.Instance.ShowTip("ServerDown");
                     break;
                 case ServerState.Predicted:
+                    Debug.LogWarning($"[LoginWin][Login] 鏈嶅姟鍣ㄦ湭寮�鏈嶏紝寮�鏈嶆椂闂�: {ServerListCenter.Instance.currentServer.start_date:yyyy-MM-dd HH:mm}");
                     SysNotifyMgr.Instance.ShowTip("ServerOpen", ServerListCenter.Instance.currentServer.start_date.ToString("yyyy-MM-dd HH:mm"));
                     break;
             }
-
+            Debug.LogWarning("[LoginWin][Login] return: 鏈嶅姟鍣ㄧ姸鎬佷笉鍏佽鐧诲綍");
             return;
         }
 
@@ -380,14 +391,29 @@
                 case VersionAuthority.InterTest:
                     if (string.IsNullOrEmpty(m_Account.text))
                     {
+                        Debug.LogWarning("[LoginWin][Login] 娴嬭瘯鏈嶈处鍙蜂负绌猴紝寮瑰嚭鎻愮ず");
                         ServerTipDetails.DisplayNormalTip(Language.Get("L1095"));
+                        Debug.LogWarning("[LoginWin][Login] return: 娴嬭瘯鏈嶈处鍙蜂负绌�");
                         return;
                     }
 
+                    Debug.Log($"[LoginWin][Login] 娴嬭瘯鏈嶈处鍙风櫥褰�: {m_Account.text}, IP: {m_ServerIP}, Port: {m_Port}, GamePort: {m_GamePort}");
                     LoginManager.Instance.AccountLogin(m_Account.text, m_ServerIP, m_Port, m_GamePort);
                     break;
                 case VersionAuthority.Release:
+#if UNITY_WEBGL
+                    if (string.IsNullOrEmpty(m_Account.text))
+                    {
+                        Debug.LogWarning("[LoginWin][Login] WebGL璐﹀彿涓虹┖锛屽脊鍑烘彁绀�");
+                        ServerTipDetails.DisplayNormalTip(Language.Get("L1095"));
+                        return;
+                    }
+                    Debug.Log($"[LoginWin][Login] WebGL璐﹀彿鐧诲綍: {m_Account.text}, IP: {m_ServerIP}, Port: {m_Port}, GamePort: {m_GamePort}");
+                    LoginManager.Instance.AccountLogin(m_Account.text, m_ServerIP, m_Port, m_GamePort);
+#else
+                    Debug.Log($"[LoginWin][Login] 姝e紡鏈嶈处鍙风櫥褰�: IP: {m_ServerIP}, Port: {m_Port}, GamePort: {m_GamePort}");
                     LoginManager.Instance.AccountLogin(m_ServerIP, m_Port, m_GamePort);
+#endif
                     break;
             }
 
diff --git a/Main/System/Message/MessageWin.cs b/Main/System/Message/MessageWin.cs
index 1b7fcfd..5a8224f 100644
--- a/Main/System/Message/MessageWin.cs
+++ b/Main/System/Message/MessageWin.cs
@@ -1,6 +1,7 @@
 using UnityEngine;
 using UnityEngine.UI;
 using DG.Tweening;
+using Cysharp.Threading.Tasks;
 
 using System.Text.RegularExpressions;
 
@@ -109,14 +110,6 @@
             OnGMOpen();
             ServerTipDetails.requireOpenGM = false;
         }
-    }
-
-    private void OnDisable()
-    {
-        m_ContainerNormalHint.SetActive(false);
-        m_ContainerChatHint.SetActive(false);
-        DisableServerTip();
-        StopAllCoroutines();
     }
 
     void CheckNormalHint()
diff --git a/Main/System/Tip/ScrollTip.cs b/Main/System/Tip/ScrollTip.cs
index 15d8410..d29bdfc 100644
--- a/Main/System/Tip/ScrollTip.cs
+++ b/Main/System/Tip/ScrollTip.cs
@@ -19,6 +19,9 @@
     
     public static void ShowTip(string tip, ArrayList infoList = null, int _order = 0)
     {
+        if (string.IsNullOrWhiteSpace(tip))
+            return;
+
         int range = Math.Min(m_Hints.Count, 10);
         int findCnt = 0;
         for (int i = 1; i <= range; i++)
diff --git a/Main/System/Tip/ScrollTipDetail.cs b/Main/System/Tip/ScrollTipDetail.cs
index 685e7ec..9c4ee8d 100644
--- a/Main/System/Tip/ScrollTipDetail.cs
+++ b/Main/System/Tip/ScrollTipDetail.cs
@@ -19,6 +19,7 @@
     private float m_TipShowTime;
     private float m_TipHideTime;
     private float m_TipDistance;
+    private Sequence _sequence;
 
     private void Awake()
     {
@@ -46,12 +47,12 @@
         pos = transform.localPosition;
         presentState = state;
         //LateUpdate 鏀规垚dotwweing
-        Sequence tween = DOTween.Sequence();;
-        tween.Append(transform.DOLocalMove(pos.SetY(pos.y + m_TipDistance), ScrollTip.tipMoveTime)).SetEase(Ease.Linear);
-        tween.AppendInterval(m_TipShowTime);
-        tween.Append(canvasGroup.DOFade(0, m_TipHideTime)).SetEase(Ease.Linear);
-        tween.Play();
-        tween.OnComplete(() =>
+        _sequence = DOTween.Sequence();
+        _sequence.Append(transform.DOLocalMove(pos.SetY(pos.y + m_TipDistance), ScrollTip.tipMoveTime).SetEase(Ease.Linear));
+        _sequence.AppendInterval(m_TipShowTime);
+        _sequence.Append(canvasGroup.DOFade(0, m_TipHideTime).SetEase(Ease.Linear));
+        _sequence.Play();
+        _sequence.OnComplete(() =>
         { 
             presentState = ScrollTip.ScrollTipState.None;
             ScrollTip.Release(this, false);
diff --git a/Main/System/Tip/ScrollTipWin.cs b/Main/System/Tip/ScrollTipWin.cs
index 5ddf2e2..9a825b0 100644
--- a/Main/System/Tip/ScrollTipWin.cs
+++ b/Main/System/Tip/ScrollTipWin.cs
@@ -113,6 +113,15 @@
             ScrollTipDetail tipDetail = await ScrollTip.Request();
             if (tipDetail != null)
             {
+                // 棣栨鐧诲綍鏃� pool 涓� null锛孯equest() 寮傛鍔犺浇棰勫埗浣撹�楁椂 >100ms銆�
+                // LoopTipReceiveEvent 姣� 100ms 閲嶅叆锛屽彲鑳藉凡鏈夊彟涓�娆¤皟鐢ㄥ厛娑堣�椾簡 m_Hints[0]銆�
+                // 鑻� await 杩斿洖鏃� m_Hints 宸茬┖锛屽繀椤诲皢 tipDetail 褰掕繕姹狅紝鍚﹀垯瀹冧細琚彃鍏� Canvas 浣�
+                // 姘歌繙涓嶄細鎾斁鍔ㄧ敾锛屽鑷存彁绀烘潯鍗″湪灞忓箷涓婏紙绗竴娆$櫥褰曞鐜扮殑鏍瑰洜锛夈��
+                if (ScrollTip.m_Hints.Count == 0)
+                {
+                    ScrollTip.Release(tipDetail, false);
+                    return;
+                }
                 tipDetail.SetTipConfig(m_TipShowTime, m_TipHideTime, m_TipDistance);
                 ScrollTip.m_ActiveTips.Add(tipDetail);
                 var rt = tipDetail.transform;

--
Gitblit v1.8.0