From 6d53dcee9145e7c3c50f95f2a65cbf7b09d855ae Mon Sep 17 00:00:00 2001 From: Le Duc Anh Date: Tue, 5 May 2026 17:00:17 +0700 Subject: [PATCH] mini map load the coresponding map after player enter world. --- .../AssetGroups/a61.asset | 5 ++ .../Scripts/Addressable/AddressableManager.cs | 52 +++++++++++++++++++ .../Scripts/MainFiles/EC_Game.Time.cs | 4 +- .../Scripts/UI/Login/LoginScreenUI.cs | 7 +++ .../Scripts/UI/MiniMap/CDlgMiniMap.cs | 45 ++++++++++++++-- .../{a61.spriteatlasv2 => 161.spriteatlasv2} | 0 ...iteatlasv2.meta => 161.spriteatlasv2.meta} | 2 +- 7 files changed, 108 insertions(+), 7 deletions(-) rename Assets/PerfectWorld/UI/surfaces/minimaps/a61/{a61.spriteatlasv2 => 161.spriteatlasv2} (100%) rename Assets/PerfectWorld/UI/surfaces/minimaps/a61/{a61.spriteatlasv2.meta => 161.spriteatlasv2.meta} (94%) diff --git a/Assets/AddressableAssetsData/AssetGroups/a61.asset b/Assets/AddressableAssetsData/AssetGroups/a61.asset index 7edce66d65..7670e6882d 100644 --- a/Assets/AddressableAssetsData/AssetGroups/a61.asset +++ b/Assets/AddressableAssetsData/AssetGroups/a61.asset @@ -2655,6 +2655,11 @@ MonoBehaviour: m_ReadOnly: 0 m_SerializedLabels: [] FlaggedDuringContentUpdateRestriction: 0 + - m_GUID: 34322d27488583140acae7497762ccbc + m_Address: minimaps/161 + m_ReadOnly: 0 + m_SerializedLabels: [] + FlaggedDuringContentUpdateRestriction: 0 - m_GUID: 343d97392dfbe4113b96ae477e3867eb m_Address: litmodels/a61/7/litmodel_1007.bmd m_ReadOnly: 0 diff --git a/Assets/PerfectWorld/Scripts/Addressable/AddressableManager.cs b/Assets/PerfectWorld/Scripts/Addressable/AddressableManager.cs index 20589903b2..3142c5dd05 100644 --- a/Assets/PerfectWorld/Scripts/Addressable/AddressableManager.cs +++ b/Assets/PerfectWorld/Scripts/Addressable/AddressableManager.cs @@ -7,6 +7,7 @@ using UnityEngine; using UnityEngine.AddressableAssets; using UnityEngine.AddressableAssets.ResourceLocators; using UnityEngine.ResourceManagement.AsyncOperations; +using UnityEngine.U2D; namespace BrewMonster.Scripts { @@ -18,6 +19,7 @@ namespace BrewMonster.Scripts private Dictionary> _loadedPrefabAssets = new(); private Dictionary> _loadedTextAssets = new(); private Dictionary> _loadedAudioAssets = new(); + private Dictionary> _loadedSpriteAtlasAssets = new(); private Dictionary _loadedAssetReferenceCount = new(); @@ -174,6 +176,56 @@ namespace BrewMonster.Scripts } + AsyncOperationHandle _loadedSpriteAtlasHandle; + /// Load a sprite atlas asynchronously. + public async Task LoadSpriteAtlasAsync(string assetPath) + { + // increase the reference count of the asset. + if (!_loadedAssetReferenceCount.ContainsKey(assetPath)) + { + _loadedAssetReferenceCount[assetPath] = 0; + } + _loadedAssetReferenceCount[assetPath]++; + + // remove the asset from the release timestamp dictionary. So it won't be released. + RemoveFromReleaseAssetDictionary(assetPath); + + if (_loadedSpriteAtlasAssets.TryGetValue(assetPath, out _loadedSpriteAtlasHandle)) + { + if (_loadedTextAssetHandle.IsValid() && _loadedTextAssetHandle.Result != null) + { + BMLogger.Log($"AddressableManager: Loaded text asset from cache: {assetPath}"); + return _loadedSpriteAtlasHandle.Result; + } + else + { + BMLogger.Log($"AddressableManager: Text asset handle is invalid or result is null, need to load new one: {assetPath}"); + } + } + + try + { + var handle = Addressables.LoadAssetAsync(assetPath); + await handle.Task; + if (handle.OperationException != null) + { + BMLogger.Log($"AddressableManager: Failed to load Sprite Atlas '{assetPath}': {handle.OperationException.Message} {handle.OperationException.StackTrace}"); + #if UNITY_EDITOR + _invalidAssetPaths.Add(assetPath); + #endif + return null; + } + _loadedSpriteAtlasAssets[assetPath] = handle; + return handle.Result; + } + catch (Exception e) + { + BMLogger.LogError($"AddressableManager: Failed to load SpriteAtlas '{assetPath}': {e}"); + return null; + } + } + + AsyncOperationHandle _loadedPrefabHandle; /// /// Load an asset asynchronously. The address should look like this: "models/npcs/npc/魅灵首领/魅灵首领/魅灵首领.prefab" diff --git a/Assets/PerfectWorld/Scripts/MainFiles/EC_Game.Time.cs b/Assets/PerfectWorld/Scripts/MainFiles/EC_Game.Time.cs index f3ac9436a8..801ecc0fd6 100644 --- a/Assets/PerfectWorld/Scripts/MainFiles/EC_Game.Time.cs +++ b/Assets/PerfectWorld/Scripts/MainFiles/EC_Game.Time.cs @@ -1,8 +1,8 @@ using UnityEngine; using System; -using BrewMonster.UI; -using CSNetwork; + +//TODO: [DUCK] EC_Game shouldn't be in BrewMonster.Network namespace, it should be in BrewMonster.Scripts namespace. namespace BrewMonster.Network { public partial class EC_Game diff --git a/Assets/PerfectWorld/Scripts/UI/Login/LoginScreenUI.cs b/Assets/PerfectWorld/Scripts/UI/Login/LoginScreenUI.cs index afa7df7bd8..5cbde28ad9 100644 --- a/Assets/PerfectWorld/Scripts/UI/Login/LoginScreenUI.cs +++ b/Assets/PerfectWorld/Scripts/UI/Login/LoginScreenUI.cs @@ -358,6 +358,13 @@ namespace BrewMonster.UI private async void OnEnterWorldComplete() { + // initialize the mini map + CECGameUIMan pGameUI = EC_Game.GetGameRun().GetUIManager().GetInGameUIMan(); + if (pGameUI != null) + { + pGameUI.m_pDlgMiniMap.InitializeMiniMap(); + } + await Task.Delay(2000); // Request all known packages: 0=Inventory,1=Equipment,2=Task UnityGameSession.RequestAllInventoriesAsync(() => { /*BMLogger.Log("Sent Inventory Detail Requests (all packs)");*/ }, 0, 1, 2); diff --git a/Assets/PerfectWorld/Scripts/UI/MiniMap/CDlgMiniMap.cs b/Assets/PerfectWorld/Scripts/UI/MiniMap/CDlgMiniMap.cs index b557b233fa..90eccde575 100644 --- a/Assets/PerfectWorld/Scripts/UI/MiniMap/CDlgMiniMap.cs +++ b/Assets/PerfectWorld/Scripts/UI/MiniMap/CDlgMiniMap.cs @@ -1,5 +1,6 @@ using System.Collections.Generic; using BrewMonster; +using BrewMonster.Network; using BrewMonster.Scripts; using BrewMonster.Scripts.Extensions; using BrewMonster.UI; @@ -55,13 +56,15 @@ namespace PerfectWorld.UI.MiniMap private bool isShowMiniMap = true; CECHostPlayer m_pHostPlayer; + private float coordinateFactor = 0.5f; // the factor to convert the world coordinates to the mini map coordinates. + Vector3Int _lastIntHostPos = Vector3Int.zero; private int m_nMode; // TODO: currently, there is only get logic, not set logic private void Awake() { - LoadAllMiniMapTextures(); + // LoadAllMiniMapTextures(); _worldMapButton.onClick.AddListener(OnMiniMapClicked); } @@ -80,7 +83,6 @@ namespace PerfectWorld.UI.MiniMap m_pHostPlayer = GetHostPlayer(); if (m_pHostPlayer == null) return; - // TODO: This should be the position of the host player, not hardcoded. Transform hostTransform = m_pHostPlayer.transform; Vector3 vecPosHost = hostTransform.position; Vector3Int currentIntHostPos = new Vector3Int(Mathf.RoundToInt(vecPosHost.x) / 10 + 400, Mathf.RoundToInt(vecPosHost.y) / 10, Mathf.RoundToInt(vecPosHost.z) / 10 + 550); @@ -89,7 +91,7 @@ namespace PerfectWorld.UI.MiniMap txtHostPos.text = $"{currentIntHostPos.x}, {currentIntHostPos.z}, ↑{currentIntHostPos.y}"; _lastIntHostPos = currentIntHostPos; } - Vector2 hostPlayerPos = new Vector2(vecPosHost.x / 2, vecPosHost.z / 2); + Vector2 hostPlayerPos = new Vector2(vecPosHost.x * coordinateFactor, vecPosHost.z * coordinateFactor); _transformMiniMapParent.anchoredPosition = -hostPlayerPos; _hostPlayerIcon.localRotation = Quaternion.Euler(0, 0, -hostTransform.localRotation.eulerAngles.y); } @@ -117,6 +119,40 @@ namespace PerfectWorld.UI.MiniMap // dlg?.OnInitDialog(); } + + /// + /// Call this function when user enter the game world (after select role or when use GOTO to jump to a new instance). + /// This function will get the world instance data and setup the mini map. + /// + public async void InitializeMiniMap() + { + // get current world instance + var idInstance = CECGameRun.Instance?.GetWorld()?.GetInstanceID() ?? 161; + var worldInstance = EC_Game.GetGameRun()?.GetInstance(idInstance); + + if (worldInstance == null) + { + BMLogger.LogError("InitializeMiniMap: worldInstance is null"); + return; + } + // set the number of rows and columns of the mini map + nRow = (byte)worldInstance.GetRowNum(); + nCol = (byte)worldInstance.GetColNum(); + + + // use Addressable to load all the textures of the mini map + _spriteAtlas = await AddressableManager.Instance.LoadSpriteAtlasAsync($"minimaps/{idInstance}"); + + if (_spriteAtlas == null) + { + BMLogger.LogError("InitializeMiniMap: sprite atlas is null"); + return; + } + + LoadAllMiniMapTextures(); + } + + // keep this so we can load all textures of other map also. [ContextMenu("LoadAllMiniMapTextures")] public void LoadAllMiniMapTextures() @@ -142,7 +178,7 @@ namespace PerfectWorld.UI.MiniMap } } - +#if UNITY_EDITOR // this is for debuging/testing while this feature was in development [ContextMenu("MoveHostPlayerIconToPos")] public void MoveHostPlayerIconToPos() @@ -151,5 +187,6 @@ namespace PerfectWorld.UI.MiniMap _transformMiniMapParent.anchoredPosition = -hostPlayerPos; } +#endif } } \ No newline at end of file diff --git a/Assets/PerfectWorld/UI/surfaces/minimaps/a61/a61.spriteatlasv2 b/Assets/PerfectWorld/UI/surfaces/minimaps/a61/161.spriteatlasv2 similarity index 100% rename from Assets/PerfectWorld/UI/surfaces/minimaps/a61/a61.spriteatlasv2 rename to Assets/PerfectWorld/UI/surfaces/minimaps/a61/161.spriteatlasv2 diff --git a/Assets/PerfectWorld/UI/surfaces/minimaps/a61/a61.spriteatlasv2.meta b/Assets/PerfectWorld/UI/surfaces/minimaps/a61/161.spriteatlasv2.meta similarity index 94% rename from Assets/PerfectWorld/UI/surfaces/minimaps/a61/a61.spriteatlasv2.meta rename to Assets/PerfectWorld/UI/surfaces/minimaps/a61/161.spriteatlasv2.meta index 159e47e4e8..c8f8e51ca4 100644 --- a/Assets/PerfectWorld/UI/surfaces/minimaps/a61/a61.spriteatlasv2.meta +++ b/Assets/PerfectWorld/UI/surfaces/minimaps/a61/161.spriteatlasv2.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: b764c7c6d08a20e41a8ebfb3435954db +guid: 34322d27488583140acae7497762ccbc SpriteAtlasImporter: externalObjects: {} textureSettings: