From 2dd1841d03a730d3d369092c2a3ad656cee4bf64 Mon Sep 17 00:00:00 2001
From: lcy <1459594991@qq.com>
Date: 星期四, 07 五月 2026 15:11:38 +0800
Subject: [PATCH] 512 跨服演武场

---
 Main/System/Hero/UIHeroController.cs |  258 +++++++++++++++++++++++----------------------------
 1 files changed, 116 insertions(+), 142 deletions(-)

diff --git a/Main/System/Hero/UIHeroController.cs b/Main/System/Hero/UIHeroController.cs
index 8cd36f1..5db01b9 100644
--- a/Main/System/Hero/UIHeroController.cs
+++ b/Main/System/Hero/UIHeroController.cs
@@ -1,5 +1,6 @@
 
 using System;
+using System.Threading;
 using Spine;
 using Spine.Unity;
 using UnityEngine;
@@ -16,8 +17,14 @@
 	private GameObject instanceGO;
 	private bool isInitializing = false;
 	private bool isInitialized = false;
-	private static int activeInitializationCount = 0; // 褰撳墠姝e湪鍒濆鍖栫殑鍗$墖鏁伴噺
-	private static readonly object initializationLock = new object();
+	private CancellationTokenSource loadCancellationToken; // 鐢ㄤ簬鍙栨秷涔嬪墠鐨勫姞杞戒换鍔�
+
+	// 浣跨敤 UniTask 鎻愪緵鐨勫苟鍙戞帶鍒� - 鏀寔 WebGL
+	// 闄愬埗鍚屾椂鍔犺浇鐨勮祫婧愭暟閲忥紙榛樿涓�4锛屽彲鏍规嵁璁惧鎬ц兘璋冩暣锛�
+	private const int MAX_CONCURRENT_LOADS = 4;
+	private static int currentLoadingCount = 0;
+	private static readonly object loadLock = new object();
+	private static int initializationOrder = 0; // 鐢ㄤ簬鍒嗗抚寤惰繜鐨勫簭鍙�
 
 	public Action onComplete;
 	public void Create(int _skinID, float scale = 0.8f, Action _onComplete = null, string motionName = "idle", bool isLh = false)
@@ -99,17 +106,25 @@
 		}
 
 		onComplete = _onComplete;
-		
-		// 绔嬬粯闇�瑕佺珛鍗虫樉绀猴紝鍏朵粬鎯呭喌寤惰繜鍒濆鍖�
-		if (isLh)
+
+
+		// 鍙栨秷涔嬪墠鐨勫紓姝ヤ换鍔★紝閬垮厤澶氭璋冪敤瀵艰嚧閿欎贡
+		CancelLoadTask();
+		// 鍒涘缓鏂扮殑鍙栨秷浠ょ墝
+		loadCancellationToken = new CancellationTokenSource();
+		// 浣跨敤 UniTask 杩涜寮傛鍒濆鍖栵紝灏唅nstanceGO鍒涘缓鍜岃祫婧愬姞杞介兘绉诲埌寮傛澶勭悊
+		DelayedInitializeAsync(skinConfig, motionName, isLh, loadCancellationToken.Token).Forget();
+	}
+
+	/// <summary>
+	/// 鍙栨秷涔嬪墠鐨勫姞杞戒换鍔�
+	/// </summary>
+	private void CancelLoadTask()
+	{
+		if (loadCancellationToken != null && !loadCancellationToken.IsCancellationRequested)
 		{
-			// 绔嬬粯绔嬪嵆鍒濆鍖�
-			ForceInitialize(motionName);
-		}
-		else
-		{
-			// 浣跨敤 UniTask 杩涜寮傛鍒濆鍖栵紝灏唅nstanceGO鍒涘缓鍜岃祫婧愬姞杞介兘绉诲埌寮傛澶勭悊
-			DelayedInitializeAsync(skinConfig, motionName).Forget();
+			loadCancellationToken.Cancel();
+			loadCancellationToken.Dispose();
 		}
 	}
 
@@ -126,6 +141,9 @@
 
 	protected void OnDestroy()
 	{
+		// 鍙栨秷姝e湪杩涜鐨勫姞杞戒换鍔�
+		CancelLoadTask();
+
 		if (spineAnimationState != null)
 		{
 			spineAnimationState.Complete -= OnAnimationComplete;
@@ -294,41 +312,58 @@
 	}
 
 	/// <summary>
-	/// 寤惰繜鍒濆鍖栵紝閬垮厤鎵归噺鍒涘缓鏃跺崱椤� - 浣跨敤 UniTask
+	/// 寤惰繜鍒濆鍖栵紝缁撳悎骞跺彂鎺у埗鍜屽垎甯у欢杩�
+	/// 1. 璧勬簮鍔犺浇浣跨敤鐪熸鐨勫紓姝ワ紙LoadAssetAsync锛�
+	/// 2. skeletonGraphic.Initialize() 鍓嶈繘琛屽垎甯у欢杩燂紝閬垮厤涓荤嚎绋嬪崱椤�
 	/// </summary>
-	private async UniTaskVoid DelayedInitializeAsync(HeroSkinConfig skinConfig, string motionName)
+	private async UniTaskVoid DelayedInitializeAsync(HeroSkinConfig skinConfig, string motionName, bool isLh, CancellationToken cancellationToken)
 	{
 		isInitializing = true;
 
 		try
 		{
-			// 澧炲姞褰撳墠鍒濆鍖栬鏁板櫒
-			int currentIndex;
-			lock (initializationLock)
+			// 妫�鏌ユ槸鍚﹀凡琚彇娑�
+			cancellationToken.ThrowIfCancellationRequested();
+
+			// 鑾峰彇鍔犺浇淇″彿閲� - 闄愬埗骞跺彂鏁帮紝閬垮厤璧勬簮绔炰簤
+			await AcquireLoadSlotAsync(cancellationToken);
+
+			// 寮傛鍒涘缓instanceGO鍜屽姞杞借祫婧愶紙鐪熸鐨勫紓姝ワ紝涓嶉樆濉烇級
+			await CreateInstanceAndLoadAssetsAsync(skinConfig, isLh, cancellationToken);
+
+			// 鑾峰彇褰撳墠搴忓彿鐢ㄤ簬鍒嗗抚寤惰繜
+			int myOrder;
+			lock (loadLock)
 			{
-				currentIndex = activeInitializationCount++;
+				myOrder = initializationOrder++;
 			}
 
-		// 鏍规嵁褰撳墠鍒濆鍖栧簭鍙疯绠楀欢杩熸椂闂�
-		// 绗竴涓崱鐗囧欢杩�1甯э紝绗簩涓欢杩�2甯э紝浠ユ绫绘帹锛屾渶澶氬欢杩�60甯�
-		int delayFrames = Mathf.Min(currentIndex + 1, 60);
+			// 鍐嶆妫�鏌ユ槸鍚﹀凡琚彇娑�
+			cancellationToken.ThrowIfCancellationRequested();
 
-		for (int i = 0; i < delayFrames; i++)
-		{
-			await UniTask.NextFrame();
-		}
+			// 鍦� skeletonGraphic.Initialize() 鍓嶈繘琛屽垎甯у欢杩�
+			// 鏍规嵁 MAX_CONCURRENT_LOADS 璋冩暣寤惰繜锛岄伩鍏嶆墍鏈夊璞″悓鏃舵墽琛� Initialize
+			int delayFrames = (myOrder % MAX_CONCURRENT_LOADS);
+			if (delayFrames > 0)
+			{
+				for (int i = 0; i < delayFrames; i++)
+				{
+					cancellationToken.ThrowIfCancellationRequested();
+					await UniTask.NextFrame(cancellationToken);
+				}
+			}
 
-		// 寮傛鍒涘缓instanceGO鍜屽姞杞借祫婧�
-		await CreateInstanceAndLoadAssetsAsync(skinConfig, isLh: false);
+			// 鍐嶆妫�鏌ユ槸鍚﹀凡琚彇娑堬紙鍙兘鍦ㄥ欢杩熸湡闂磋鍙栨秷锛�
+			cancellationToken.ThrowIfCancellationRequested();
 
-		if (skeletonGraphic == null || skeletonGraphic.skeletonDataAsset == null)
-		{
-			Debug.LogError("璧勬簮鍔犺浇澶辫触锛屾棤娉曞垵濮嬪寲妯″瀷");
-			return;
-		}
+			if (skeletonGraphic == null || skeletonGraphic.skeletonDataAsset == null)
+			{
+				Debug.LogError("璧勬簮鍔犺浇澶辫触锛屾棤娉曞垵濮嬪寲妯″瀷");
+				return;
+			}
 
-		skeletonGraphic.initialSkinName = skinConfig.InitialSkinName;
-		skeletonGraphic.Initialize(true);
+			skeletonGraphic.initialSkinName = skinConfig.InitialSkinName;
+			skeletonGraphic.Initialize(true);
 
 			// 鍒濆鍖栧畬鎴愬悗璁剧疆鐨偆
 			if (!string.IsNullOrEmpty(skinConfig.InitialSkinName))
@@ -339,13 +374,12 @@
 				skeletonGraphic.Update(0);
 			}
 
-
 			spineAnimationState = skeletonGraphic.AnimationState;
 			spineAnimationState.Data.DefaultMix = 0f;
-			
+
 			// 鍒濆鍖栧畬鎴愬悗鎵嶆樉绀烘ā鍨�
 			skeletonGraphic.enabled = pendingEnabled;
-			
+
 			if (pendingGray)
 			{
 				skeletonGraphic.material = MaterialUtility.GetDefaultSpriteGrayMaterial();
@@ -354,18 +388,17 @@
 			{
 				skeletonGraphic.material = null;
 			}
-			
+
 			// 妫�鏌ユ槸鍚︽湁寰呰缃殑閫熷害锛屽鏋滄湁鍒欒缃�
 			if (pendingSpeed.HasValue)
 			{
 				spineAnimationState.TimeScale = pendingSpeed.Value;
-				pendingSpeed = null; // 娓呴櫎寰呰缃�熷害
+				pendingSpeed = null;
 			}
-			
+
 			// 妫�鏌ユ槸鍚︽湁寰呮挱鏀剧殑鍔ㄧ敾锛屽鏋滄湁鍒欎紭鍏堟挱鏀惧閮ㄨ皟鐢ㄧ殑鍔ㄧ敾
 			if (!string.IsNullOrEmpty(pendingAnimationName))
 			{
-				// 涓存椂璁剧疆isInitializing涓篺alse锛屼互渚縋layAnimation鑳芥甯告挱鏀�
 				isInitializing = false;
 				PlayAnimation(pendingAnimationName, pendingAnimationLoop, pendingAnimationReplay);
 				// 娓呴櫎鎵�鏈夊緟鎾斁鍔ㄧ敾鍙傛暟
@@ -378,12 +411,11 @@
 				// 濡傛灉娌℃湁澶栭儴璋冪敤鐨勫姩鐢伙紝鎾斁榛樿鍔ㄧ敾
 				if (motionName == "")
 					motionName = GetFistSpineAnim();
-				
-				// 涓存椂璁剧疆isInitializing涓篺alse锛屼互渚縋layAnimation鑳芥甯告挱鏀�
+
 				isInitializing = false;
 				PlayAnimation(motionName, true);
 			}
-			
+
 			spineAnimationState.Complete -= OnAnimationComplete;
 			spineAnimationState.Complete += OnAnimationComplete;
 
@@ -392,120 +424,61 @@
 		}
 		catch (System.OperationCanceledException)
 		{
-			// 浠诲姟琚彇娑堬紝姝e父澶勭悊
+			// 浠诲姟琚彇娑堬紝姝e父杩斿洖
+			isInitializing = false;
+		}
+		catch (System.Exception e)
+		{
+			Debug.LogError($"鑻遍泟鍒濆鍖栧紓甯�: {e.Message}");
 			isInitializing = false;
 		}
 		finally
 		{
-			// 鍑忓皯褰撳墠鍒濆鍖栬鏁板櫒
-			lock (initializationLock)
-			{
-				activeInitializationCount--;
-			}
+			// 閲婃斁鍔犺浇妲戒綅
+			ReleaseLoadSlot();
 		}
 	}
 
 	/// <summary>
-	/// 寮哄埗绔嬪嵆鍒濆鍖栵紙鐢ㄤ簬鐗规畩鎯呭喌锛�
+	/// 鑾峰彇鍔犺浇妲戒綅锛堟敮鎸� WebGL 鐨勫苟鍙戞帶鍒讹級
 	/// </summary>
-	public void ForceInitialize(string motionName = "idle")
+	private async UniTask AcquireLoadSlotAsync(CancellationToken cancellationToken)
 	{
-		if (isInitializing)
+		while (true)
 		{
-			// 璁剧疆鏍囧織浣嶅彇娑堜箣鍓嶇殑寮傛浠诲姟
-			isInitializing = false;
-		}
+			// 妫�鏌ユ槸鍚﹀凡琚彇娑�
+			cancellationToken.ThrowIfCancellationRequested();
 
-		var skinConfig = HeroSkinConfig.Get(skinID);
-		if (skinConfig != null)
-		{
-			// 鍚屾鍒涘缓instanceGO鍜屽姞杞借祫婧愶紙绔嬬粯闇�瑕佺珛鍗虫樉绀猴級
-			CreateInstanceAndLoadAssetsSync(skinConfig, isLh: true);
-			
-			if (skeletonGraphic != null && skeletonGraphic.skeletonDataAsset != null)
+			lock (loadLock)
 			{
-				skeletonGraphic.initialSkinName = skinConfig.InitialSkinName;
-				skeletonGraphic.Initialize(true);
-				
-				if (!string.IsNullOrEmpty(skinConfig.InitialSkinName))
+				if (currentLoadingCount < MAX_CONCURRENT_LOADS)
 				{
-					var skeleton = skeletonGraphic.Skeleton;
-					skeleton.SetSkin(skinConfig.InitialSkinName);
-					skeleton.SetSlotsToSetupPose();
-					skeletonGraphic.Update(0);
+					currentLoadingCount++;
+					return;
 				}
-
-				skeletonGraphic.enabled = true;
-				SetMaterialNone();
-
-				spineAnimationState = skeletonGraphic.AnimationState;
-				if (spineAnimationState != null)
-				{
-					spineAnimationState.Data.DefaultMix = 0f;
-					if (string.IsNullOrEmpty(motionName))
-						motionName = GetFistSpineAnim();
-					PlayAnimation(motionName, true);
-					spineAnimationState.Complete -= OnAnimationComplete;
-					spineAnimationState.Complete += OnAnimationComplete;
-				}
-
-				isInitialized = true;
-				isInitializing = false;
 			}
+			// 濡傛灉宸茶揪鍒版渶澶у苟鍙戞暟锛岀瓑寰呬笅涓�甯у啀璇�
+			await UniTask.NextFrame(cancellationToken);
 		}
 	}
 
 	/// <summary>
-	/// 鍚屾鍒涘缓instanceGO鍜屽姞杞借祫婧愶紙鐢ㄤ簬绔嬬粯锛�
+	/// 閲婃斁鍔犺浇妲戒綅
 	/// </summary>
-	private void CreateInstanceAndLoadAssetsSync(HeroSkinConfig skinConfig, bool isLh)
+	private void ReleaseLoadSlot()
 	{
-		// 纭繚transform澶勪簬婵�娲荤姸鎬�
-		if (!transform.gameObject.activeSelf)
+		lock (loadLock)
 		{
-			transform.SetActive(true);
-		}
-
-		// 鍒涘缓pool鍜宨nstanceGO
-		pool = GameObjectPoolManager.Instance.GetPool(UILoader.LoadPrefab("UIHero"));
-		
-		if (instanceGO == null)
-		{
-			instanceGO = pool.Request();
-			instanceGO.transform.SetParent(transform);
-			//transform 鐨凱ivot Y鏄�0锛岃instanceGO 灞呬腑
-			instanceGO.transform.localPosition = new Vector3(0, instanceGO.GetComponent<RectTransform>().sizeDelta.y * 0.5f);
-			instanceGO.transform.localScale = Vector3.one;
-			instanceGO.transform.localRotation = Quaternion.identity;
-		}
-
-		skeletonGraphic = instanceGO.GetComponentInChildren<SkeletonGraphic>(true);
-		
-		// 鍚屾鍔犺浇璧勬簮
-		if (isLh)
-		{
-			skeletonGraphic.skeletonDataAsset = ResManager.Instance.LoadAsset<SkeletonDataAsset>("Hero/SpineRes/", skinConfig.Tachie);
-		}
-		else
-		{
-			skeletonGraphic.skeletonDataAsset = ResManager.Instance.LoadAsset<SkeletonDataAsset>("Hero/SpineRes/", skinConfig.SpineRes);
-		}
-
-		if (skeletonGraphic.skeletonDataAsset == null)
-		{
-			transform.SetActive(false);
-			if (pool != null)
-				pool.Release(instanceGO);
-			skeletonGraphic = null;
-			Destroy(instanceGO);
-			Debug.LogError("鏈厤缃畇pine");
+			currentLoadingCount--;
 		}
 	}
+
 
 	/// <summary>
 	/// 寮傛鍒涘缓instanceGO鍜屽姞杞借祫婧愶紙鐢ㄤ簬闈炵珛缁橈級
+	/// 浣跨敤鐪熸鐨勫紓姝ュ姞杞斤紝涓嶉樆濉炰富绾跨▼
 	/// </summary>
-	private async UniTask CreateInstanceAndLoadAssetsAsync(HeroSkinConfig skinConfig, bool isLh)
+	private async UniTask CreateInstanceAndLoadAssetsAsync(HeroSkinConfig skinConfig, bool isLh, CancellationToken cancellationToken)
 	{
 		// 纭繚transform澶勪簬婵�娲荤姸鎬�
 		if (!transform.gameObject.activeSelf)
@@ -513,9 +486,12 @@
 			transform.SetActive(true);
 		}
 
+		// 妫�鏌ユ槸鍚﹀凡琚彇娑�
+		cancellationToken.ThrowIfCancellationRequested();
+
 		// 鍒涘缓pool鍜宨nstanceGO
 		pool = GameObjectPoolManager.Instance.GetPool(UILoader.LoadPrefab("UIHero"));
-		
+
 		if (instanceGO == null)
 		{
 			instanceGO = pool.Request();
@@ -527,21 +503,19 @@
 		}
 
 		skeletonGraphic = instanceGO.GetComponentInChildren<SkeletonGraphic>(true);
-		
-		// 鍦ㄤ富绾跨▼涓姞杞借祫婧愶紝閬垮厤Unity API绾跨▼瀹夊叏闂
-		// 浣跨敤UniTask.Yield()鏉ョ‘淇濆湪涓荤嚎绋嬩腑鎵ц
-		await UniTask.Yield();
-		
-		if (isLh)
+
+		// 鐪熸鐨勫紓姝ュ姞杞借祫婧� - 涓嶉樆濉炰富绾跨▼
+		string assetName = isLh ? skinConfig.Tachie : skinConfig.SpineRes;
+		SkeletonDataAsset loadedAsset = await ResManager.Instance.LoadAssetAsync<SkeletonDataAsset>("Hero/SpineRes/", assetName);
+
+		// 鍐嶆妫�鏌ユ槸鍚﹀凡琚彇娑�
+		cancellationToken.ThrowIfCancellationRequested();
+
+		if (loadedAsset != null)
 		{
-			skeletonGraphic.skeletonDataAsset = ResManager.Instance.LoadAsset<SkeletonDataAsset>("Hero/SpineRes/", skinConfig.Tachie);
+			skeletonGraphic.skeletonDataAsset = loadedAsset;
 		}
 		else
-		{
-			skeletonGraphic.skeletonDataAsset = ResManager.Instance.LoadAsset<SkeletonDataAsset>("Hero/SpineRes/", skinConfig.SpineRes);
-		}
-
-		if (skeletonGraphic.skeletonDataAsset == null)
 		{
 			transform.SetActive(false);
 			if (pool != null)

--
Gitblit v1.8.0