From 2602ab0ea34bdbc6dfdaa563c461407e67a63764 Mon Sep 17 00:00:00 2001 From: Tran Hai Nam Date: Fri, 8 May 2026 17:39:14 +0700 Subject: [PATCH 1/3] ADd buff icon for npc and else player --- .../Scripts/Addressable/AddressableManager.cs | 56 ++++++++ .../Scripts/Managers/CECNPCMan.cs | 18 ++- .../Scripts/Managers/FLoatingTextManager.cs | 64 ++++----- Assets/PerfectWorld/Scripts/NPC/CECNPC.cs | 29 +++- .../Scripts/Players/EC_ElsePlayer.cs | 5 + .../Scripts/UI/GamePlay/AUIFloatTextIcon.cs | 3 + Assets/PerfectWorld/Scripts/UI/HUDNPC.cs | 133 +++++++++++++++++- 7 files changed, 265 insertions(+), 43 deletions(-) diff --git a/Assets/PerfectWorld/Scripts/Addressable/AddressableManager.cs b/Assets/PerfectWorld/Scripts/Addressable/AddressableManager.cs index 3142c5dd05..394eb1ccb8 100644 --- a/Assets/PerfectWorld/Scripts/Addressable/AddressableManager.cs +++ b/Assets/PerfectWorld/Scripts/Addressable/AddressableManager.cs @@ -19,6 +19,7 @@ namespace BrewMonster.Scripts private Dictionary> _loadedPrefabAssets = new(); private Dictionary> _loadedTextAssets = new(); private Dictionary> _loadedAudioAssets = new(); + private Dictionary> _loadedSpriteAssets = new(); private Dictionary> _loadedSpriteAtlasAssets = new(); private Dictionary _loadedAssetReferenceCount = new(); @@ -318,6 +319,43 @@ namespace BrewMonster.Scripts } } + AsyncOperationHandle _loadedSpriteHandle; + + /// + /// Load a Sprite asynchronously (e.g. UI art). Key must match the Addressables address. + /// + public async Task LoadSpriteAsync(string assetPath) + { + RemoveFromReleaseAssetDictionary(assetPath); + + if (_loadedSpriteAssets.TryGetValue(assetPath, out _loadedSpriteHandle)) + { + if (_loadedSpriteHandle.IsValid() && _loadedSpriteHandle.Result != null) + { + BMLogger.Log($"AddressableManager: Loaded sprite from cache: {assetPath}"); + return _loadedSpriteHandle.Result; + } + } + + try + { + var handle = Addressables.LoadAssetAsync(assetPath.Trim()); + await handle.Task; + if (handle.OperationException != null) + { + BMLogger.Log($"AddressableManager: Failed to load Sprite '{assetPath}': {handle.OperationException.Message}"); + return null; + } + _loadedSpriteAssets[assetPath] = handle; + return handle.Result; + } + catch (Exception e) + { + BMLogger.LogError($"AddressableManager: Failed to load Sprite '{assetPath}': {e.Message}"); + return null; + } + } + /// /// True if this address is already in the audio cache (play immediately vs async load). /// @@ -377,6 +415,15 @@ namespace BrewMonster.Scripts _loadedAudioAssets.Remove(assetPath); BMLogger.Log($"AddressableManager: Force released audio asset: {assetPath}"); } + else if (_loadedSpriteAssets.TryGetValue(assetPath, out var loadedSpriteHandle)) + { + if (loadedSpriteHandle.IsValid()) + { + Addressables.Release(loadedSpriteHandle); + } + _loadedSpriteAssets.Remove(assetPath); + BMLogger.Log($"AddressableManager: Force released sprite asset: {assetPath}"); + } } /// @@ -412,9 +459,18 @@ namespace BrewMonster.Scripts } } _loadedAudioAssets.Clear(); + foreach (var kvp in _loadedSpriteAssets) + { + if (kvp.Value.IsValid()) + { + Addressables.Release(kvp.Value); + } + } + _loadedSpriteAssets.Clear(); BMLogger.Log("AddressableManager: Released all assets"); } + /// /// Check if an asset is currently loaded in the cache. /// diff --git a/Assets/PerfectWorld/Scripts/Managers/CECNPCMan.cs b/Assets/PerfectWorld/Scripts/Managers/CECNPCMan.cs index 7bbb25730f..db367ff587 100644 --- a/Assets/PerfectWorld/Scripts/Managers/CECNPCMan.cs +++ b/Assets/PerfectWorld/Scripts/Managers/CECNPCMan.cs @@ -446,8 +446,22 @@ public class CECNPCMan : IMsgHandler break; case long value when value == EC_MsgDef.MSG_NM_NPCEXTSTATE: - nid = GPDataTypeHelper.FromBytes((byte[])Msg.dwParam1).id; - break; + { + int cmdType = Convert.ToInt32(Msg.dwParam2); + byte[] buf = (byte[])Msg.dwParam1; + if (cmdType == CommandID.UPDATE_EXT_STATE) + nid = GPDataTypeHelper.FromBytes(buf).id; + else if (cmdType == CommandID.ICON_STATE_NOTIFY) + { + var iconCmd = new cmd_icon_state_notify(); + if (!iconCmd.Initialize(buf)) + return false; + nid = iconCmd.id; + } + else + return false; + break; + } case long value when value == EC_MsgDef.MSG_NM_NPCCASTSKILL: diff --git a/Assets/PerfectWorld/Scripts/Managers/FLoatingTextManager.cs b/Assets/PerfectWorld/Scripts/Managers/FLoatingTextManager.cs index 8e0895d391..2991c4093c 100644 --- a/Assets/PerfectWorld/Scripts/Managers/FLoatingTextManager.cs +++ b/Assets/PerfectWorld/Scripts/Managers/FLoatingTextManager.cs @@ -1,11 +1,13 @@ using System; using System.Collections.Generic; +using System.Threading.Tasks; using UnityEngine; using UnityEngine.AddressableAssets; using UnityEngine.ResourceManagement.AsyncOperations; using TMPro; using DG.Tweening; // cần DOTween using BrewMonster.Scripts.UI.GamePlay; +using BrewMonster.Scripts; public enum ImageResType { IMG_POPUPNUM = 0, @@ -155,36 +157,36 @@ public class FLoatingTextManager : MonoBehaviour { pool.Enqueue(text); } - public bool LoadAllImages() + public async Task LoadAllImages() { - LoadImage(ImageResType.IMG_HITMISSED, "InGame/未命中.tga"); - LoadImage(ImageResType.IMG_LEVELUP, "InGame/升级了.tga"); - LoadImage(ImageResType.IMG_GOTEXP, "InGame/经验.tga"); - LoadImage(ImageResType.IMG_GOTMONEY, "InGame/金钱.tga"); - LoadImage(ImageResType.IMG_DEADLYSTRIKE, "InGame/爆击.tga"); - LoadImage(ImageResType.IMG_GOTSP, "InGame/元神.tga"); - LoadImage(ImageResType.IMG_INVALIDHIT, "InGame/无效.tga"); + await LoadImage(ImageResType.IMG_HITMISSED, "InGame/未命中.tga"); + await LoadImage(ImageResType.IMG_LEVELUP, "InGame/升级了.tga"); + await LoadImage(ImageResType.IMG_GOTEXP, "InGame/经验.tga"); + await LoadImage(ImageResType.IMG_GOTMONEY, "InGame/金钱.tga"); + await LoadImage(ImageResType.IMG_DEADLYSTRIKE, "InGame/爆击.tga"); + await LoadImage(ImageResType.IMG_GOTSP, "InGame/元神.tga"); + await LoadImage(ImageResType.IMG_INVALIDHIT, "InGame/无效.tga"); //LoadImage(ImageResType.IMG_TEAMLEADER, "Window/LeaderMark.tga"); - LoadImage(ImageResType.IMG_HPWARN, "InGame/hp_warn.tga"); - LoadImage(ImageResType.IMG_MPWARN, "InGame/mp_warn.tga"); - LoadImage(ImageResType.IMG_RETORT, "InGame/反震.tga"); - LoadImage(ImageResType.IMG_IMMUNE, "InGame/免疫.tga"); + await LoadImage(ImageResType.IMG_HPWARN, "InGame/hp_warn.tga"); + await LoadImage(ImageResType.IMG_MPWARN, "InGame/mp_warn.tga"); + await LoadImage(ImageResType.IMG_RETORT, "InGame/反震.tga"); + await LoadImage(ImageResType.IMG_IMMUNE, "InGame/免疫.tga"); //LoadImage(ImageResType.IMG_TEAMMATE, "Window/Teammate.tga"); - LoadImage(ImageResType.IMG_PKSTATE, "InGame/PK状态标记.tga"); - LoadImage(ImageResType.IMG_GMFLAG, "InGame/GM标志.dds"); - LoadImage(ImageResType.IMG_ATTACKLOSE, "InGame/失败.tga"); - LoadImage(ImageResType.IMG_SUCCESS, "InGame/成功.tga"); - LoadImage(ImageResType.IMG_REBOUND, "InGame/复仇惩戒.tga"); - LoadImage(ImageResType.IMG_BEAT_BACK, "InGame/复仇镜像.tga"); - LoadImage(ImageResType.IMG_ADD, "InGame/吸血.tga"); - LoadImage(ImageResType.IMG_DODGE_DEBUFF, "InGame/状态闪避.tga"); + await LoadImage(ImageResType.IMG_PKSTATE, "InGame/PK状态标记.tga"); + await LoadImage(ImageResType.IMG_GMFLAG, "InGame/GM标志.dds"); + await LoadImage(ImageResType.IMG_ATTACKLOSE, "InGame/失败.tga"); + await LoadImage(ImageResType.IMG_SUCCESS, "InGame/成功.tga"); + await LoadImage(ImageResType.IMG_REBOUND, "InGame/复仇惩戒.tga"); + await LoadImage(ImageResType.IMG_BEAT_BACK, "InGame/复仇镜像.tga"); + await LoadImage(ImageResType.IMG_ADD, "InGame/吸血.tga"); + await LoadImage(ImageResType.IMG_DODGE_DEBUFF, "InGame/状态闪避.tga"); //LoadImage(ImageResType.IMG_KING, "King/皇冠图标.tga"); return false; } - private void LoadImage(ImageResType type, string path) + private async Task LoadImage(ImageResType type, string path) { if (string.IsNullOrEmpty(path)) - return; + return false; // Same normalization as skill/gfx paths (PC backslashes → Addressables-style slashes). // 与技能 gfx 路径一致:反斜杠转为斜杠,便于与 Addressables 地址对齐。 @@ -194,23 +196,17 @@ public class FLoatingTextManager : MonoBehaviour foreach (string address in candidates) { // TODO: use AddressableManager to load the sprite. - var handle = Addressables.LoadAssetAsync(address); - handle.WaitForCompletion(); - - if (handle.Status == AsyncOperationStatus.Succeeded && handle.Result != null) + var sprite = await AddressableManager.Instance.LoadSpriteAsync(address); + if (sprite != null) { - imageDic[type] = handle.Result; - _spriteLoadHandles.Add(handle); - return; + imageDic[type] = sprite; + return true; } - if (handle.IsValid()) - Addressables.Release(handle); - } Debug.Log($"[FLoatingTextManager] Sprite load failed for {type}. Addressables keys must match the catalog exactly; " + - $"tried: {string.Join("; ", candidates)}. " + - $"Similar file names are not auto-resolved (unlike fuzzy file search)."); + $"tried: {string.Join("; ", candidates)}. "); + return false; } /// diff --git a/Assets/PerfectWorld/Scripts/NPC/CECNPC.cs b/Assets/PerfectWorld/Scripts/NPC/CECNPC.cs index 39aca84030..f267f0ed32 100644 --- a/Assets/PerfectWorld/Scripts/NPC/CECNPC.cs +++ b/Assets/PerfectWorld/Scripts/NPC/CECNPC.cs @@ -7,6 +7,7 @@ using ModelRenderer.Scripts.Common; using System; using System.Threading.Tasks; using BrewMonster.Scripts.Chat; +using System.Collections.Generic; using UnityEngine; public class CECNPC : CECObject { @@ -44,6 +45,8 @@ public class CECNPC : CECObject protected CECPolicyAction m_pPolicyAction; public int m_iMMIndex; public int m_idAttackTarget; + /// Buff/debuff icon states from server (ICON_STATE_NOTIFY). Same role as CECPlayer.m_aIconStates. + public List m_aIconStates = new List(); protected UINPC m_npcUI; private CECModel m_pNPCCECModel; // CECModel instance for hook system / 用于挂点系统的CECModel实例 CECCounter m_IdleCnt = new CECCounter(); @@ -199,7 +202,7 @@ public class CECNPC : CECObject { case long value when value == EC_MsgDef.MSG_NM_NPCATKRESULT: OnMsgNPCAtkResult(Msg); break; case long value when value == EC_MsgDef.MSG_NM_NPCSTARTPLAYACTION: OnMsgNPCStartPlayAction(Msg); break; - //case long value when value == EC_MsgDef.MSG_NM_NPCEXTSTATE: OnMsgNPCExtState(Msg); break; + case long value when value == EC_MsgDef.MSG_NM_NPCEXTSTATE: OnMsgNPCExtState(Msg); break; //case long value when value == EC_MsgDef.MSG_NM_NPCCASTSKILL: OnMsgNPCCastSkill(Msg); break; //case long value when value == EC_MsgDef.MSG_NM_ENCHANTRESULT: OnMsgNPCEnchantResult(Msg); break; //case long value when value == EC_MsgDef.MSG_NM_NPCROOT: OnMsgNPCRoot(Msg); break; @@ -211,6 +214,29 @@ public class CECNPC : CECObject } } + private void OnMsgNPCExtState(ECMSG Msg) + { + if (Convert.ToInt32(Msg.dwParam2) == CommandID.ICON_STATE_NOTIFY) + { + var cmd = new cmd_icon_state_notify(); + if (!cmd.Initialize((byte[])Msg.dwParam1)) + return; + if (cmd.id != GetNPCID()) + return; + m_aIconStates = cmd.states ?? new List(); + if (m_aIconStates.Count > 1) + { + m_aIconStates.Sort((a, b) => + { + if (a.id < b.id) return -1; + if (a.id > b.id) return 1; + return 0; + }); + } + } + // UPDATE_EXT_STATE for NPC is handled separately from icon strip; extend if NPC state GFX is ported. + } + private void OnMsgNPCLevel(ECMSG Msg) { cmd_level_up pCmd = GPDataTypeHelper.FromBytes((byte[])Msg.dwParam1); @@ -656,6 +682,7 @@ public class CECNPC : CECObject ::memset(m_aExtStates, 0, sizeof(m_aExtStates)); m_aIconStates.clear();*/ + m_aIconStates?.Clear(); m_pNPCModelPolicy = null; PoolManager.Instance.Despawn(m_modelVisual); diff --git a/Assets/PerfectWorld/Scripts/Players/EC_ElsePlayer.cs b/Assets/PerfectWorld/Scripts/Players/EC_ElsePlayer.cs index c4eafb0a73..c9c0ad150c 100644 --- a/Assets/PerfectWorld/Scripts/Players/EC_ElsePlayer.cs +++ b/Assets/PerfectWorld/Scripts/Players/EC_ElsePlayer.cs @@ -479,10 +479,15 @@ namespace BrewMonster public bool ProcessMessage(ECMSG Msg) { + if(Msg.dwMsg == EC_MsgDef.MSG_PM_PLAYEREXTSTATE) + { + Debug.Log("MSG_PM_ElsePLAYEREXTSTATE"); + } switch (Msg.dwMsg) { case EC_MsgDef.MSG_PM_PLAYERFLY: OnMsgPlayerFly(Msg); break; case EC_MsgDef.MSG_PM_PLAYERBASEINFO: OnMsgPlayerBaseInfo(Msg); break; + case EC_MsgDef.MSG_PM_PLAYEREXTSTATE: OnMsgPlayerExtState(Msg); break; case EC_MsgDef.MSG_PM_PLAYEREQUIPDATA: OnMsgPlayerEquipData(Msg); break; case EC_MsgDef.MSG_PM_PLAYERATKRESULT: OnMsgPlayerAtkResult(Msg); break; case EC_MsgDef.MSG_PM_CASTSKILL: OnMsgPlayerCastSkill(Msg); break; diff --git a/Assets/PerfectWorld/Scripts/UI/GamePlay/AUIFloatTextIcon.cs b/Assets/PerfectWorld/Scripts/UI/GamePlay/AUIFloatTextIcon.cs index 947416d8b1..12b69a42fd 100644 --- a/Assets/PerfectWorld/Scripts/UI/GamePlay/AUIFloatTextIcon.cs +++ b/Assets/PerfectWorld/Scripts/UI/GamePlay/AUIFloatTextIcon.cs @@ -19,6 +19,9 @@ namespace BrewMonster.Scripts.UI.GamePlay { ingameIcon.sprite = sprite; ingameIcon.gameObject.SetActive(true); + color = new Color(color.r/255f, color.g/255f, color.b/255f, 1f); + ingameIcon.color = color; + } else { diff --git a/Assets/PerfectWorld/Scripts/UI/HUDNPC.cs b/Assets/PerfectWorld/Scripts/UI/HUDNPC.cs index 4e0d68dc8e..dadc7eb2a8 100644 --- a/Assets/PerfectWorld/Scripts/UI/HUDNPC.cs +++ b/Assets/PerfectWorld/Scripts/UI/HUDNPC.cs @@ -1,12 +1,17 @@ +using System.Collections.Generic; +using BrewMonster.Managers; +using BrewMonster.Network; +using BrewMonster.Scripts; +using BrewMonster.Scripts.Skills; +using BrewMonster.UI; +using CSNetwork.GPDataType; using TMPro; using UnityEngine; using UnityEngine.UI; -using BrewMonster.Network; -using CSNetwork.GPDataType; namespace BrewMonster { - public class HUDNPC : MonoBehaviour + public class HUDNPC : MonoBehaviour, ITickable { [SerializeField] private Button _NPCIconBtn; [SerializeField] private TextMeshProUGUI _healthText; @@ -15,6 +20,26 @@ namespace BrewMonster [SerializeField] private Image healthImage; [SerializeField] private RawImage _avatarImage; + private List _buffIcons; + [SerializeField] private AUIBuffIcon _buffIconPrefab; + + private void Awake() + { + _buffIcons = new List(); + TickInvoker.Instance.RegisterTickable(this); + } + + private void OnDestroy() + { + TickInvoker.Instance.UnregisterTickable(this); + } + + public bool Tick(uint dwDeltaTime) + { + UpdateBuffIcons(); + return true; + } + private void OnEnable() { if (_NPCIconBtn != null) @@ -40,13 +65,109 @@ namespace BrewMonster int id = host.GetSelectedTarget(); if (id == 0 || id == host.GetCharacterID() || !GPDataTypeHelper.ISPLAYERID(id)) return; - CECUIManager.Instance?.ShowPlayerOptionsDialog(id, _NPCIconBtn.transform.position); - + CECUIManager.Instance?.ShowPlayerOptionsDialog(id, _NPCIconBtn.transform.position); + } + + /// + /// Target buff/debuff row for the selected non-host entity (other player or NPC). + /// + private void UpdateBuffIcons() + { + if (!gameObject.activeInHierarchy) + { + SetAllBuffIconsActive(false); + return; + } + + var host = EC_Game.GetGameRun()?.GetHostPlayer(); + if (host == null) + { + SetAllBuffIconsActive(false); + return; + } + + int targetId = host.GetSelectedTarget(); + if (targetId == 0 || targetId == host.GetCharacterID()) + { + SetAllBuffIconsActive(false); + return; + } + + List iconStates = null; + if (GPDataTypeHelper.ISPLAYERID(targetId)) + { + var player = EC_ManMessageMono.Instance?.GetECManPlayer?.GetPlayer(targetId); + iconStates = player?.m_aIconStates; + } + else if (GPDataTypeHelper.ISNPCID(targetId)) + { + var npc = EC_ManMessageMono.Instance?.CECNPCMan?.GetNPCFromAll(targetId); + iconStates = npc?.m_aIconStates; + } + + if (iconStates == null || iconStates.Count == 0) + { + SetAllBuffIconsActive(false); + return; + } + + if (_buffIconPrefab == null) + { + SetAllBuffIconsActive(false); + return; + } + + var gameUIMan = CECUIManager.Instance?.GetInGameUIMan(); + if (gameUIMan == null) + { + SetAllBuffIconsActive(false); + return; + } + + if (_buffIcons.Count < iconStates.Count) + { + for (int i = _buffIcons.Count; i < iconStates.Count; i++) + { + var buffIcon = Instantiate(_buffIconPrefab, _buffIconPrefab.transform.parent); + _buffIcons.Add(buffIcon); + } + } + + for (int i = 0; i < _buffIcons.Count; i++) + { + if (i < iconStates.Count) + { + var teamState = GNET.QueryTeamState(iconStates[i].id); + if (teamState == null) + { + _buffIcons[i].gameObject.SetActive(false); + continue; + } + _buffIcons[i].gameObject.SetActive(true); + var szFile = teamState.GetIcon(); + szFile = szFile.ToLower(); + gameUIMan.SetCover(_buffIcons[i], szFile, EC_GAMEUI_ICONS.ICONS_STATE); + } + else + { + _buffIcons[i].gameObject.SetActive(false); + } + } + } + + private void SetAllBuffIconsActive(bool active) + { + if (_buffIcons == null) return; + for (int i = 0; i < _buffIcons.Count; i++) + { + if (_buffIcons[i] != null) + _buffIcons[i].gameObject.SetActive(active); + } } public void SetText(string healthText, string nameText, string statText) { - _healthText.text = healthText; + _healthText.text = healthText; _nameText.text = nameText; _statText.text = statText; } From de6917f0cdb2a39baaef7de5b46920583dfc5f1c Mon Sep 17 00:00:00 2001 From: Tran Hai Nam Date: Fri, 8 May 2026 17:44:08 +0700 Subject: [PATCH 2/3] add hud npc prefab --- Assets/PerfectWorld/Prefab/UI/HUDNPC.prefab | 221 +++++++++++++++++++- Assets/PerfectWorld/Prefab/UIManager.prefab | 117 +---------- 2 files changed, 216 insertions(+), 122 deletions(-) diff --git a/Assets/PerfectWorld/Prefab/UI/HUDNPC.prefab b/Assets/PerfectWorld/Prefab/UI/HUDNPC.prefab index dec0e348f5..79f8062054 100644 --- a/Assets/PerfectWorld/Prefab/UI/HUDNPC.prefab +++ b/Assets/PerfectWorld/Prefab/UI/HUDNPC.prefab @@ -1,5 +1,94 @@ %YAML 1.1 %TAG !u! tag:unity3d.com,2011: +--- !u!1 &1172007003875469888 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 6367968922383945468} + - component: {fileID: 8777696811020310446} + - component: {fileID: 7675664214308521901} + - component: {fileID: 72103662956892879} + m_Layer: 5 + m_Name: Background + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &6367968922383945468 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1172007003875469888} + m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 2177533424404370772} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!222 &8777696811020310446 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1172007003875469888} + m_CullTransparentMesh: 1 +--- !u!114 &7675664214308521901 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1172007003875469888} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 0 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 0} + m_Type: 0 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!114 &72103662956892879 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1172007003875469888} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 31a19414c41e5ae4aae2af33fee712f6, type: 3} + m_Name: + m_EditorClassIdentifier: + m_ShowMaskGraphic: 1 --- !u!1 &1273460584854605297 GameObject: m_ObjectHideFlags: 0 @@ -37,7 +126,7 @@ RectTransform: m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0.5, y: 0.5} m_AnchorMax: {x: 0.5, y: 0.5} - m_AnchoredPosition: {x: -160, y: -42} + m_AnchoredPosition: {x: -150, y: 2.4} m_SizeDelta: {x: 123, y: 123} m_Pivot: {x: 0.5, y: 0.5} --- !u!222 &1981970930610958667 @@ -238,13 +327,14 @@ RectTransform: m_Children: - {fileID: 7183588826468540253} - {fileID: 8841982213385894347} + - {fileID: 5298541048597512026} m_Father: {fileID: 0} m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0.5, y: 1} m_AnchorMax: {x: 0.5, y: 1} - m_AnchoredPosition: {x: 0, y: -50} - m_SizeDelta: {x: 100, y: 100} - m_Pivot: {x: 0.5, y: 0.5} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 400, y: 129.4} + m_Pivot: {x: 0.5, y: 1} --- !u!114 &9105272519104429228 MonoBehaviour: m_ObjectHideFlags: 0 @@ -263,6 +353,7 @@ MonoBehaviour: _statText: {fileID: 7225922753763360209} healthImage: {fileID: 391766345810538963} _avatarImage: {fileID: 2274486941820472865} + _buffIconPrefab: {fileID: 6278983905934311425} --- !u!1 &5230218528339883288 GameObject: m_ObjectHideFlags: 0 @@ -298,11 +389,11 @@ RectTransform: - {fileID: 1333050478342715942} m_Father: {fileID: 7601428160728630082} m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} - m_AnchorMin: {x: 0.5, y: 0.5} - m_AnchorMax: {x: 0.5, y: 0.5} - m_AnchoredPosition: {x: 22, y: -42.000004} + m_AnchorMin: {x: 0.5, y: 1} + m_AnchorMax: {x: 0.5, y: 1} + m_AnchoredPosition: {x: 22, y: -30} m_SizeDelta: {x: 336, y: 95} - m_Pivot: {x: 0.5, y: 0.5} + m_Pivot: {x: 0.5, y: 1} --- !u!222 &6172505155667263140 CanvasRenderer: m_ObjectHideFlags: 0 @@ -341,6 +432,57 @@ MonoBehaviour: m_FillOrigin: 0 m_UseSpriteMesh: 0 m_PixelsPerUnitMultiplier: 1 +--- !u!1 &6604678107028403134 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 2177533424404370772} + - component: {fileID: 6278983905934311425} + m_Layer: 5 + m_Name: BuffIconTemplate + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 0 +--- !u!224 &2177533424404370772 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 6604678107028403134} + m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 6367968922383945468} + m_Father: {fileID: 5298541048597512026} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 1} + m_AnchorMax: {x: 0, y: 1} + m_AnchoredPosition: {x: 12, y: -12} + m_SizeDelta: {x: 24, y: 24} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &6278983905934311425 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 6604678107028403134} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 200754299bc29436e9c9d608b6927e2d, type: 3} + m_Name: + m_EditorClassIdentifier: + slotIndex: -1 + disPlayImage: {fileID: 7675664214308521901} --- !u!1 &7164650417342813199 GameObject: m_ObjectHideFlags: 0 @@ -417,6 +559,67 @@ MonoBehaviour: m_FillOrigin: 0 m_UseSpriteMesh: 0 m_PixelsPerUnitMultiplier: 1 +--- !u!1 &7442649156186235319 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 5298541048597512026} + - component: {fileID: 7950876844531695353} + m_Layer: 5 + m_Name: BuffDisplayer + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &5298541048597512026 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 7442649156186235319} + m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1.1249999, y: 1.1249999, z: 1.1249999} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 2177533424404370772} + m_Father: {fileID: 7601428160728630082} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 1, y: 0} + m_AnchoredPosition: {x: 100, y: 32.6} + m_SizeDelta: {x: -130, y: 30} + m_Pivot: {x: 0, y: 1} +--- !u!114 &7950876844531695353 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 7442649156186235319} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 8a8695521f0d02e499659fee002a26c2, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Padding: + m_Left: 0 + m_Right: 0 + m_Top: 0 + m_Bottom: 0 + m_ChildAlignment: 0 + m_StartCorner: 0 + m_StartAxis: 0 + m_CellSize: {x: 24, y: 24} + m_Spacing: {x: 2, y: 2} + m_Constraint: 0 + m_ConstraintCount: 2 --- !u!1 &7483462528009603224 GameObject: m_ObjectHideFlags: 0 @@ -587,7 +790,7 @@ RectTransform: m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0.5, y: 0.5} m_AnchorMax: {x: 0.5, y: 0.5} - m_AnchoredPosition: {x: -0.5261, y: -1.6} + m_AnchoredPosition: {x: -0.5261, y: -1.5999985} m_SizeDelta: {x: 241.0417, y: 20.1006} m_Pivot: {x: 0.5, y: 0.5} --- !u!222 &6237368962895350952 diff --git a/Assets/PerfectWorld/Prefab/UIManager.prefab b/Assets/PerfectWorld/Prefab/UIManager.prefab index c75c8eb48b..862af4b04b 100644 --- a/Assets/PerfectWorld/Prefab/UIManager.prefab +++ b/Assets/PerfectWorld/Prefab/UIManager.prefab @@ -19142,17 +19142,13 @@ PrefabInstance: propertyPath: m_Name value: HUDNPC objectReference: {fileID: 0} - - target: {fileID: 5010991128992349155, guid: 7130d91d43d72c145a379b373c8c27b0, type: 3} - propertyPath: m_IsActive - value: 0 - objectReference: {fileID: 0} - target: {fileID: 7601428160728630082, guid: 7130d91d43d72c145a379b373c8c27b0, type: 3} propertyPath: m_Pivot.x value: 0.5 objectReference: {fileID: 0} - target: {fileID: 7601428160728630082, guid: 7130d91d43d72c145a379b373c8c27b0, type: 3} propertyPath: m_Pivot.y - value: 0.5 + value: 1 objectReference: {fileID: 0} - target: {fileID: 7601428160728630082, guid: 7130d91d43d72c145a379b373c8c27b0, type: 3} propertyPath: m_AnchorMax.x @@ -19172,23 +19168,11 @@ PrefabInstance: objectReference: {fileID: 0} - target: {fileID: 7601428160728630082, guid: 7130d91d43d72c145a379b373c8c27b0, type: 3} propertyPath: m_SizeDelta.x - value: 100 + value: 420 objectReference: {fileID: 0} - target: {fileID: 7601428160728630082, guid: 7130d91d43d72c145a379b373c8c27b0, type: 3} propertyPath: m_SizeDelta.y - value: 100 - objectReference: {fileID: 0} - - target: {fileID: 7601428160728630082, guid: 7130d91d43d72c145a379b373c8c27b0, type: 3} - propertyPath: m_LocalScale.x - value: 1 - objectReference: {fileID: 0} - - target: {fileID: 7601428160728630082, guid: 7130d91d43d72c145a379b373c8c27b0, type: 3} - propertyPath: m_LocalScale.y - value: 1 - objectReference: {fileID: 0} - - target: {fileID: 7601428160728630082, guid: 7130d91d43d72c145a379b373c8c27b0, type: 3} - propertyPath: m_LocalScale.z - value: 1 + value: 150 objectReference: {fileID: 0} - target: {fileID: 7601428160728630082, guid: 7130d91d43d72c145a379b373c8c27b0, type: 3} propertyPath: m_LocalPosition.x @@ -19224,7 +19208,7 @@ PrefabInstance: objectReference: {fileID: 0} - target: {fileID: 7601428160728630082, guid: 7130d91d43d72c145a379b373c8c27b0, type: 3} propertyPath: m_AnchoredPosition.y - value: -44.444336 + value: 0 objectReference: {fileID: 0} - target: {fileID: 7601428160728630082, guid: 7130d91d43d72c145a379b373c8c27b0, type: 3} propertyPath: m_LocalEulerAnglesHint.x @@ -19238,22 +19222,6 @@ PrefabInstance: propertyPath: m_LocalEulerAnglesHint.z value: 0 objectReference: {fileID: 0} - - target: {fileID: 7601428160728630082, guid: 7130d91d43d72c145a379b373c8c27b0, type: 3} - propertyPath: m_ConstrainProportionsScale - value: 1 - objectReference: {fileID: 0} - - target: {fileID: 9105272519104429228, guid: 7130d91d43d72c145a379b373c8c27b0, type: 3} - propertyPath: _nameText - value: - objectReference: {fileID: 8894872406734287223} - - target: {fileID: 9105272519104429228, guid: 7130d91d43d72c145a379b373c8c27b0, type: 3} - propertyPath: _statText - value: - objectReference: {fileID: 7661620612787195405} - - target: {fileID: 9105272519104429228, guid: 7130d91d43d72c145a379b373c8c27b0, type: 3} - propertyPath: _healthText - value: - objectReference: {fileID: 9151738778944310921} m_RemovedComponents: [] m_RemovedGameObjects: [] m_AddedGameObjects: [] @@ -19264,17 +19232,6 @@ RectTransform: m_CorrespondingSourceObject: {fileID: 7601428160728630082, guid: 7130d91d43d72c145a379b373c8c27b0, type: 3} m_PrefabInstance: {fileID: 1014481099860472796} m_PrefabAsset: {fileID: 0} ---- !u!114 &7661620612787195405 stripped -MonoBehaviour: - m_CorrespondingSourceObject: {fileID: 7225922753763360209, guid: 7130d91d43d72c145a379b373c8c27b0, type: 3} - m_PrefabInstance: {fileID: 1014481099860472796} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 0} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: f4688fdb7df04437aeb418b961361dc5, type: 3} - m_Name: - m_EditorClassIdentifier: --- !u!114 &8090791712930107248 stripped MonoBehaviour: m_CorrespondingSourceObject: {fileID: 9105272519104429228, guid: 7130d91d43d72c145a379b373c8c27b0, type: 3} @@ -19286,28 +19243,6 @@ MonoBehaviour: m_Script: {fileID: 11500000, guid: d072871c8791e284dbad61ce13ba6887, type: 3} m_Name: m_EditorClassIdentifier: ---- !u!114 &8894872406734287223 stripped -MonoBehaviour: - m_CorrespondingSourceObject: {fileID: 8459104239633154731, guid: 7130d91d43d72c145a379b373c8c27b0, type: 3} - m_PrefabInstance: {fileID: 1014481099860472796} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 0} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: f4688fdb7df04437aeb418b961361dc5, type: 3} - m_Name: - m_EditorClassIdentifier: ---- !u!114 &9151738778944310921 stripped -MonoBehaviour: - m_CorrespondingSourceObject: {fileID: 8148604647689649493, guid: 7130d91d43d72c145a379b373c8c27b0, type: 3} - m_PrefabInstance: {fileID: 1014481099860472796} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 0} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: f4688fdb7df04437aeb418b961361dc5, type: 3} - m_Name: - m_EditorClassIdentifier: --- !u!1001 &1257740176129564677 PrefabInstance: m_ObjectHideFlags: 0 @@ -22368,22 +22303,6 @@ PrefabInstance: propertyPath: m_AnchoredPosition.y value: 0 objectReference: {fileID: 0} - - target: {fileID: 2985336126980033672, guid: 76408ccdbeb4c654291462fcff24a8c5, type: 3} - propertyPath: m_IsActive - value: 1 - objectReference: {fileID: 0} - - target: {fileID: 3313561919066668394, guid: 76408ccdbeb4c654291462fcff24a8c5, type: 3} - propertyPath: m_SizeDelta.x - value: 0 - objectReference: {fileID: 0} - - target: {fileID: 3661057301147371696, guid: 76408ccdbeb4c654291462fcff24a8c5, type: 3} - propertyPath: m_IsActive - value: 0 - objectReference: {fileID: 0} - - target: {fileID: 3663290235883915697, guid: 76408ccdbeb4c654291462fcff24a8c5, type: 3} - propertyPath: m_IsActive - value: 1 - objectReference: {fileID: 0} - target: {fileID: 3951120581356990872, guid: 76408ccdbeb4c654291462fcff24a8c5, type: 3} propertyPath: m_AnchorMax.y value: 0 @@ -22400,38 +22319,10 @@ PrefabInstance: propertyPath: m_AnchoredPosition.y value: 0 objectReference: {fileID: 0} - - target: {fileID: 4263483627851733539, guid: 76408ccdbeb4c654291462fcff24a8c5, type: 3} - propertyPath: m_AnchorMax.y - value: 1 - objectReference: {fileID: 0} - - target: {fileID: 4263483627851733539, guid: 76408ccdbeb4c654291462fcff24a8c5, type: 3} - propertyPath: m_AnchorMin.y - value: 1 - objectReference: {fileID: 0} - - target: {fileID: 4263483627851733539, guid: 76408ccdbeb4c654291462fcff24a8c5, type: 3} - propertyPath: m_SizeDelta.x - value: 24 - objectReference: {fileID: 0} - - target: {fileID: 4263483627851733539, guid: 76408ccdbeb4c654291462fcff24a8c5, type: 3} - propertyPath: m_SizeDelta.y - value: 24 - objectReference: {fileID: 0} - - target: {fileID: 4263483627851733539, guid: 76408ccdbeb4c654291462fcff24a8c5, type: 3} - propertyPath: m_AnchoredPosition.x - value: 12 - objectReference: {fileID: 0} - - target: {fileID: 4263483627851733539, guid: 76408ccdbeb4c654291462fcff24a8c5, type: 3} - propertyPath: m_AnchoredPosition.y - value: -12 - objectReference: {fileID: 0} - target: {fileID: 4823752405346273106, guid: 76408ccdbeb4c654291462fcff24a8c5, type: 3} propertyPath: m_Name value: HUDPlayer objectReference: {fileID: 0} - - target: {fileID: 4823752405346273106, guid: 76408ccdbeb4c654291462fcff24a8c5, type: 3} - propertyPath: m_IsActive - value: 1 - objectReference: {fileID: 0} - target: {fileID: 6806681442789174374, guid: 76408ccdbeb4c654291462fcff24a8c5, type: 3} propertyPath: m_Pivot.x value: 0 From 5abbd11d4add2b5133140afa8f1a261e3ddb9b26 Mon Sep 17 00:00:00 2001 From: Tran Hai Nam Date: Fri, 8 May 2026 17:52:29 +0700 Subject: [PATCH 3/3] fix npc buff not expire --- Assets/PerfectWorld/Scripts/NPC/CECNPC.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Assets/PerfectWorld/Scripts/NPC/CECNPC.cs b/Assets/PerfectWorld/Scripts/NPC/CECNPC.cs index b76d1720b7..107e7bbfe0 100644 --- a/Assets/PerfectWorld/Scripts/NPC/CECNPC.cs +++ b/Assets/PerfectWorld/Scripts/NPC/CECNPC.cs @@ -243,7 +243,7 @@ public class CECNPC : CECObject }); } } - else if (Convert.ToInt32(Msg.dwParam2) == CommandID.UPDATE_EXT_STATE) + if (Convert.ToInt32(Msg.dwParam2) == CommandID.UPDATE_EXT_STATE) { cmd_update_ext_state pCmd = GPDataTypeHelper.FromBytes((byte[])Msg.dwParam1); if (pCmd.id == m_NPCInfo.nid)