1
This commit is contained in:
@@ -8,6 +8,9 @@ using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using UnityEngine;
|
||||
using UnityEngine.AddressableAssets;
|
||||
using UnityEngine.ResourceManagement.AsyncOperations;
|
||||
using UnityEngine.ResourceManagement.ResourceProviders;
|
||||
using UnityEngine.SceneManagement;
|
||||
|
||||
namespace Assets.MyGame.Scripts.Net
|
||||
@@ -17,6 +20,15 @@ namespace Assets.MyGame.Scripts.Net
|
||||
/// <summary>已加载(或正在加载)的游戏场景名集合,防止人机 RoomJoinNotice 触发重复 LoadSceneAsync</summary>
|
||||
private static readonly HashSet<string> _loadedGameScenes = new HashSet<string>();
|
||||
|
||||
/// <summary>
|
||||
/// 游戏场景的 Addressables 加载句柄。
|
||||
/// 游戏场景(XJMH/FLZY/HHWK/YYSC)里挂的是热更脚本(BGManager/BgFit 等),
|
||||
/// HybridCLR 要求热更脚本所在场景必须通过 AB/AA 加载,否则运行时会变成 missing script。
|
||||
/// 卸载时也必须用这个句柄释放,不能只调 SceneManager.UnloadSceneAsync(否则 ab 包会泄漏)。
|
||||
/// </summary>
|
||||
private static readonly Dictionary<string, AsyncOperationHandle<SceneInstance>> _gameSceneHandles
|
||||
= new Dictionary<string, AsyncOperationHandle<SceneInstance>>();
|
||||
|
||||
/// <summary>清除指定场景的加载标记(退出游戏时调用,下次进入可重新加载)</summary>
|
||||
public static void ClearLoadedGameScene(string sceneName)
|
||||
{
|
||||
@@ -125,8 +137,7 @@ namespace Assets.MyGame.Scripts.Net
|
||||
var s = SceneManager.GetSceneByName(sn);
|
||||
if (s.IsValid() && s.isLoaded)
|
||||
{
|
||||
SceneManager.UnloadSceneAsync(sn);
|
||||
_loadedGameScenes.Remove(sn);
|
||||
UnloadGameScene(sn);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -187,8 +198,19 @@ namespace Assets.MyGame.Scripts.Net
|
||||
var targetScene = SceneManager.GetSceneByName(sceneName);
|
||||
if (!targetScene.IsValid() || !targetScene.isLoaded)
|
||||
{
|
||||
var op = SceneManager.LoadSceneAsync(sceneName, LoadSceneMode.Additive);
|
||||
while (op != null && !op.isDone) yield return null;
|
||||
// ⭐ 必须通过 Addressables 加载:场景里挂的是热更脚本(Game.Hotfix 里的 BGManager/BgFit 等),
|
||||
// 如果走 Build Settings(随主包)加载,热更脚本会解析失败变成 missing script —— 背景就会不动。
|
||||
var handle = Addressables.LoadSceneAsync(sceneName, LoadSceneMode.Additive);
|
||||
_gameSceneHandles[sceneName] = handle;
|
||||
while (!handle.IsDone) yield return null;
|
||||
|
||||
if (handle.Status != AsyncOperationStatus.Succeeded)
|
||||
{
|
||||
Debug.LogError($"[GameScene] Addressables 加载场景失败: {sceneName} → {handle.OperationException}。" +
|
||||
$"请确认已在 Addressables 里把该场景标记为可寻址,且 address = \"{sceneName}\"。");
|
||||
_loadedGameScenes.Remove(sceneName);
|
||||
_gameSceneHandles.Remove(sceneName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -197,6 +219,26 @@ namespace Assets.MyGame.Scripts.Net
|
||||
fishPanel.BeginLoadResources();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 卸载一个已加载的游戏场景。
|
||||
/// 如果该场景是通过 Addressables 加载的,必须用句柄释放(否则 ab 包会一直驻留);
|
||||
/// 没有句柄时退回 SceneManager 卸载,兼容历史上用 SceneManager 加载的场景。
|
||||
/// </summary>
|
||||
public static void UnloadGameScene(string sceneName)
|
||||
{
|
||||
if (_gameSceneHandles.TryGetValue(sceneName, out var handle))
|
||||
{
|
||||
if (handle.IsValid())
|
||||
Addressables.UnloadSceneAsync(handle, true);
|
||||
_gameSceneHandles.Remove(sceneName);
|
||||
}
|
||||
else
|
||||
{
|
||||
SceneManager.UnloadSceneAsync(sceneName);
|
||||
}
|
||||
_loadedGameScenes.Remove(sceneName);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 把 RoomJoinNotice 玩家数据写入 currRoomData.players(存在则更新,不存在则添加)。
|
||||
/// JoinGame 里 SetUserInfo 按 userId 从 currRoomData.players 查显示信息
|
||||
|
||||
Reference in New Issue
Block a user