Update equipment preview show, hide

This commit is contained in:
HungDK
2025-12-01 14:49:41 +07:00
parent 287d59288d
commit 7ba4c0fed5
3 changed files with 157 additions and 16 deletions
@@ -43,6 +43,8 @@ namespace BrewMonster.Scripts.UI.Inventory
private GameObject _previewInstance;
private bool _refreshQueued;
private int _lastOriginModelChildCount;
private Transform _lastOriginModelRoot;
private void Awake()
{
@@ -55,22 +57,36 @@ namespace BrewMonster.Scripts.UI.Inventory
EnsureCameraBindings();
}
/*private void OnEnable()
private void OnEnable()
{
EventBus.Subscribe<PlayerEquipmentChangedEvent>(OnEquipmentChanged);
QueueRefresh();
}*/
}
/*private void OnDisable()
private void OnDisable()
{
EventBus.Unsubscribe<PlayerEquipmentChangedEvent>(OnEquipmentChanged);
DestroyPreviewInstance();
}*/
}
private void LateUpdate()
{
TryBindHostPlayer();
// Check if origin model structure has changed (equipment models are child objects)
// This detects equipment changes in realtime since all equipment is attached as children
var currentOriginRoot = ResolveSourceModelRoot();
if (currentOriginRoot != null)
{
int currentChildCount = CountAllChildren(currentOriginRoot);
// Refresh if origin model changed or child count changed (equipment added/removed)
if (_lastOriginModelRoot != currentOriginRoot || _lastOriginModelChildCount != currentChildCount)
{
_lastOriginModelRoot = currentOriginRoot;
_lastOriginModelChildCount = currentChildCount;
QueueRefresh();
}
}
if (_refreshQueued)
{
_refreshQueued = false;
@@ -103,13 +119,6 @@ namespace BrewMonster.Scripts.UI.Inventory
_refreshQueued = true;
}
/*private void OnEquipmentChanged(PlayerEquipmentChangedEvent evt)
{
if (hostPlayer != null && evt.Player == hostPlayer)
{
QueueRefresh();
}
}*/
private void TryBindHostPlayer()
{
@@ -317,6 +326,23 @@ namespace BrewMonster.Scripts.UI.Inventory
animator.speed = 0f;
}
}
/// <summary>
/// Counts all children recursively in the transform hierarchy.
/// Used to detect when equipment (child objects) are added or removed from the origin model.
/// </summary>
private int CountAllChildren(Transform root)
{
if (root == null)
return 0;
int count = root.childCount;
for (int i = 0; i < root.childCount; i++)
{
count += CountAllChildren(root.GetChild(i));
}
return count;
}
}
}
+3 -1
View File
@@ -861,6 +861,7 @@ namespace BrewMonster
{
ui.RefreshAll();
}
UpdateEquipSkins();
}
break;
case CommandID.PICKUP_ITEM:
@@ -979,6 +980,7 @@ namespace BrewMonster
var equipInv = GetInventory(InventoryConst.IVTRTYPE_EQUIPPACK);
var invItem = packInv?.GetItem(index_inv, true);
var equipItem = equipInv?.GetItem(index_equip, true);
UpdateEquipSkins();
if (invItem != null)
{
invItem.Package = InventoryConst.IVTRTYPE_EQUIPPACK;
@@ -999,7 +1001,7 @@ namespace BrewMonster
{
ui.RefreshAll();
}
UpdateEquipSkins();
break;
}
}
+115 -2
View File
@@ -115,6 +115,16 @@ public partial class CECPlayer
// We use this to setup the bones for the equipment skinned mesh renderers
private SkeletonBuilder _skeletonBuilder;
private PlayerDefaultEquipments _playerDefaultEquipments;
// Track instantiated armor objects for each slot
private GameObject _currentUpperArmor;
private GameObject _currentLowerArmor;
private GameObject _currentWristArmor;
private GameObject _currentFootArmor;
// Track instantiated weapon objects
private GameObject _currentRightHandWeapon;
private GameObject _currentLeftHandWeapon;
private PlayerDefaultEquipments PlayerDefaultEquipments
{
get
@@ -211,6 +221,21 @@ public partial class CECPlayer
string fileModelRight = AFile.NormalizePath(weaponData.FileModelRight, true).ToLower();
string fileModelLeft = AFile.NormalizePath(weaponData.FileModelLeft, true).ToLower();
// BMLogger.Log($"ShowEquipments():: Weapon Essence: {fileModelRight} -- {fileModelLeft}");
// Destroy existing right hand weapon before creating new one
if (_currentRightHandWeapon != null)
{
Destroy(_currentRightHandWeapon);
_currentRightHandWeapon = null;
}
// Destroy existing left hand weapon before creating new one
if (_currentLeftHandWeapon != null)
{
Destroy(_currentLeftHandWeapon);
_currentLeftHandWeapon = null;
}
GameObject weaponPrefab = null;
if (!string.IsNullOrEmpty(fileModelRight))
{
@@ -223,6 +248,7 @@ public partial class CECPlayer
weaponObject.transform.localRotation = weaponPrefab.transform.localRotation;
weaponObject.transform.localScale = Vector3.one;
weaponObject.SetActive(true);
_currentRightHandWeapon = weaponObject;
}
}
@@ -237,6 +263,7 @@ public partial class CECPlayer
weaponObject.transform.localRotation = weaponPrefab.transform.localRotation;
weaponObject.transform.localScale = Vector3.one;
weaponObject.SetActive(true);
_currentLeftHandWeapon = weaponObject;
}
}
break;
@@ -253,6 +280,39 @@ public partial class CECPlayer
var armorPrefab = await AddressableManager.Instance.LoadPrefabAsync(armorSkinPath);
if (armorPrefab != null)
{
// Destroy existing armor for this slot before creating new one
switch (nLocation)
{
case (uint)SkinIndex.SKIN_UPPER_BODY_INDEX:
if (_currentUpperArmor != null)
{
Destroy(_currentUpperArmor);
_currentUpperArmor = null;
}
break;
case (uint)SkinIndex.SKIN_LOWER_INDEX:
if (_currentLowerArmor != null)
{
Destroy(_currentLowerArmor);
_currentLowerArmor = null;
}
break;
case (uint)SkinIndex.SKIN_WRIST_INDEX:
if (_currentWristArmor != null)
{
Destroy(_currentWristArmor);
_currentWristArmor = null;
}
break;
case (uint)SkinIndex.SKIN_FOOT_INDEX:
if (_currentFootArmor != null)
{
Destroy(_currentFootArmor);
_currentFootArmor = null;
}
break;
}
var armorObject = Instantiate(armorPrefab);
armorObject.transform.SetParent(GetSkeletonBuilder()?.transform);
armorObject.transform.localPosition = Vector3.zero;
@@ -270,19 +330,23 @@ public partial class CECPlayer
}
}
// disable/enable the default equipment
// Store the armor object for this slot
switch (nLocation)
{
case (uint)SkinIndex.SKIN_UPPER_BODY_INDEX:
_currentUpperArmor = armorObject;
useDefaultUpper = false;
break;
case (uint)SkinIndex.SKIN_LOWER_INDEX:
_currentLowerArmor = armorObject;
useDefaultLower = false;
break;
case (uint)SkinIndex.SKIN_WRIST_INDEX:
_currentWristArmor = armorObject;
useDefaultWrist = false;
break;
case (uint)SkinIndex.SKIN_FOOT_INDEX:
_currentFootArmor = armorObject;
useDefaultFoot = false;
break;
}
@@ -319,6 +383,19 @@ public partial class CECPlayer
{
switch (i)
{
case InventoryConst.EQUIPIVTR_WEAPON:
// Destroy weapons when weapon slot is empty
if (_currentRightHandWeapon != null)
{
Destroy(_currentRightHandWeapon);
_currentRightHandWeapon = null;
}
if (_currentLeftHandWeapon != null)
{
Destroy(_currentLeftHandWeapon);
_currentLeftHandWeapon = null;
}
break;
case InventoryConst.EQUIPIVTR_BODY:
useDefaultUpper = true;
break;
@@ -336,9 +413,45 @@ public partial class CECPlayer
}
// enable/disable the default equipment
// If using default, destroy non-default equipment if it exists
if (useDefaultUpper)
{
if (_currentUpperArmor != null)
{
Destroy(_currentUpperArmor);
_currentUpperArmor = null;
}
}
PlayerDefaultEquipments.DefaultUpper.SetActive(useDefaultUpper);
if (useDefaultLower)
{
if (_currentLowerArmor != null)
{
Destroy(_currentLowerArmor);
_currentLowerArmor = null;
}
}
PlayerDefaultEquipments.DefaultLower.SetActive(useDefaultLower);
if (useDefaultWrist)
{
if (_currentWristArmor != null)
{
Destroy(_currentWristArmor);
_currentWristArmor = null;
}
}
PlayerDefaultEquipments.DefaultWirst.SetActive(useDefaultWrist);
if (useDefaultFoot)
{
if (_currentFootArmor != null)
{
Destroy(_currentFootArmor);
_currentFootArmor = null;
}
}
PlayerDefaultEquipments.DefaultFoot.SetActive(useDefaultFoot);
}
@@ -376,4 +489,4 @@ public partial class CECPlayer
{
return string.Format(_equipment_skin[nProfession * NUM_GENDER + nGender], szSkinName, szSkinName);
}
}
}