working on inventory

This commit is contained in:
2025-07-11 14:40:23 +02:00
parent 0d69e37385
commit dc998d907c
81 changed files with 3468 additions and 231 deletions

View File

@@ -0,0 +1,83 @@
using System;
using System.Collections.Generic;
using RebootKit.Engine.Main;
using Unity.Collections;
using UnityEngine;
using UnityEngine.Pool;
using UnityEngine.UIElements;
namespace RebootReality.jelycho.Player.HUD {
public class ObjectsLabelsVC : MonoBehaviour {
[SerializeField] UIDocument m_Document;
[SerializeField] VisualTreeAsset m_LabelTemplate;
IObjectPool<LabelEntry> m_LabelPool;
readonly List<LabelEntry> m_ActiveLabels = new List<LabelEntry>();
void Awake() {
m_LabelPool = new ObjectPool<LabelEntry>(() => {
LabelEntry entry = new LabelEntry();
entry.Parent = this;
entry.Root = new VisualElement();
entry.Root.style.position = Position.Absolute;
entry.Root.style.visibility = Visibility.Hidden;
entry.Root.style.minWidth = 300;
entry.Root.style.height = 64;
m_LabelTemplate.CloneTree(entry.Root);
entry.Label = entry.Root.Q<Label>("player-hud__object-label");
m_Document.rootVisualElement.Add(entry.Root);
return entry;
},
entry => {
entry.Root.style.visibility = Visibility.Visible;
m_ActiveLabels.Add(entry);
},
entry => {
entry.Root.style.visibility = Visibility.Hidden;
m_ActiveLabels.RemoveSwapBack(entry);
},
entry => {
m_ActiveLabels.RemoveSwapBack(entry);
m_Document.rootVisualElement.Remove(entry.Root);
});
}
void Update() {
foreach (LabelEntry entry in m_ActiveLabels) {
Vector3 worldPosition = entry.TargetTransform.position;
Vector2 screenPosition = RR.MainCamera.WorldToScreenPoint(worldPosition);
entry.Root.style.left = screenPosition.x - entry.Root.contentRect.width * 0.5f;
entry.Root.style.top = Screen.height - screenPosition.y - entry.Root.contentRect.height * 0.5f;
}
}
public IDisposable CreateLabel(Transform targetTransform, string labelText) {
if (targetTransform == null) {
throw new ArgumentNullException(nameof(targetTransform));
}
LabelEntry entry = m_LabelPool.Get();
entry.TargetTransform = targetTransform;
entry.Label.text = labelText;
entry.Root.style.visibility = Visibility.Visible;
return entry;
}
class LabelEntry : IDisposable {
public ObjectsLabelsVC Parent;
public VisualElement Root;
public Label Label;
public Transform TargetTransform;
public void Dispose() {
Parent.m_LabelPool.Release(this);
}
}
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 42a4ccf83ed64ac58aef118275bd2414
timeCreated: 1752068186

View File

@@ -0,0 +1,45 @@
using System;
using R3;
using UnityEngine;
using UnityEngine.UIElements;
using Logger = RebootKit.Engine.Foundation.Logger;
namespace RebootReality.jelycho.Player.HUD {
public class PlayerHUD : MonoBehaviour {
static readonly Logger s_Logger = new Logger(nameof(PlayerHUD));
[SerializeField] UIDocument m_MainDocument;
[field: SerializeField] public ObjectsLabelsVC ObjectsLabels { get; private set; }
[field: SerializeField] public PlayerInventoryUI InventoryUI { get; private set; }
PlayerActor m_PlayerActor;
DisposableBag m_ActorBag;
void OnEnable() {
}
void OnDisable() {
InventoryUI.CleanUp();
m_ActorBag.Dispose();
}
public void SetPlayerActor(PlayerActor actor) {
m_ActorBag.Dispose();
if (actor == null) {
m_PlayerActor = null;
InventoryUI.CleanUp();
return;
}
m_ActorBag = new DisposableBag();
m_PlayerActor = actor;
InventoryUI.Configure(m_MainDocument.rootVisualElement.Q("player-hud__inventory-slots"), actor.Inventory);
actor.SelectedInventorySlot.Subscribe(x => {
InventoryUI.SetSelectedSlot(x);
}).AddTo(ref m_ActorBag);
}
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: e0712c9d21534362b219edf44601f57d
timeCreated: 1752067887

View File

@@ -0,0 +1,111 @@
using System;
using System.Collections.Generic;
using RebootReality.jelycho.Items;
using UnityEngine;
using UnityEngine.Assertions;
using UnityEngine.UIElements;
using Logger = RebootKit.Engine.Foundation.Logger;
namespace RebootReality.jelycho.Player.HUD {
public class PlayerInventoryUI : MonoBehaviour {
static readonly Logger s_Logger = new Logger(nameof(PlayerInventoryUI));
[SerializeField] VisualTreeAsset m_InventorySlotTemplate;
Inventory m_Inventory;
VisualElement m_Root;
struct InventorySlot {
public VisualElement Root;
public VisualElement Slot;
public VisualElement Icon;
public Label QuantityLabel;
}
readonly List<InventorySlot> m_InventorySlots = new List<InventorySlot>();
public void Configure(VisualElement root, Inventory inventory) {
CleanUp();
m_Root = root;
m_Inventory = inventory;
m_Inventory.OnSlotUpdated += OnSlotUpdated;
m_Root.Clear();
for (int i = 0; i < m_Inventory.SlotsCount; i++) {
VisualElement slotRoot = m_InventorySlotTemplate.CloneTree();
m_Root.Add(slotRoot);
slotRoot .style.width = new StyleLength(new Length(72, LengthUnit.Pixel));
slotRoot.style.height = new StyleLength(new Length(72, LengthUnit.Pixel));
InventorySlot slot = new InventorySlot {
Root = slotRoot,
Slot = slotRoot.Q<VisualElement>("player-hud__inventory-slot"),
Icon = slotRoot.Q<VisualElement>("player-hud__inventory-slot-icon"),
QuantityLabel = slotRoot.Q<Label>("player-hud__inventory-slot-quantity"),
};
Assert.IsNotNull(slot.Root, "Slot root cannot be null");
Assert.IsNotNull(slot.Slot, "Slot element cannot be null");
Assert.IsNotNull(slot.Icon, "Slot icon cannot be null");
Assert.IsNotNull(slot.QuantityLabel, "Slot quantity label cannot be null");
m_InventorySlots.Add(slot);
OnSlotUpdated(i);
}
}
public void CleanUp() {
if (m_Root != null) {
m_Root.Clear();
m_Root = null;
}
if (m_Inventory != null) {
m_Inventory.OnSlotUpdated -= OnSlotUpdated;
m_Inventory = null;
}
m_InventorySlots.Clear();
}
public void SetSelectedSlot(int slotIndex) {
if (slotIndex < 0 || slotIndex >= m_InventorySlots.Count) {
s_Logger.Error($"Invalid slot index: {slotIndex}. Inventory has {m_InventorySlots.Count} slots.");
return;
}
for (int i = 0; i < m_InventorySlots.Count; i++) {
m_InventorySlots[i].Slot.EnableInClassList("inventory-slot-selected", i == slotIndex);
}
}
void OnSlotUpdated(int slotIndex) {
if (slotIndex < 0 || slotIndex >= m_InventorySlots.Count) {
s_Logger.Error($"Invalid slot index: {slotIndex}. Inventory has {m_InventorySlots.Count} slots.");
return;
}
int quantity = m_Inventory.GetQuantity(slotIndex);
if (quantity <= 0) {
m_InventorySlots[slotIndex].QuantityLabel.style.display = DisplayStyle.None;
m_InventorySlots[slotIndex].Icon.style.backgroundImage = null;
m_InventorySlots[slotIndex].Icon.style.display = DisplayStyle.None;
} else {
m_InventorySlots[slotIndex].QuantityLabel.style.display = DisplayStyle.Flex;
m_InventorySlots[slotIndex].QuantityLabel.text = quantity.ToString();
ItemActor itemActor = m_Inventory.GetFirstItem(slotIndex);
if (itemActor != null) {
m_InventorySlots[slotIndex].Icon.style.backgroundImage = new StyleBackground(itemActor.Config.icon);
m_InventorySlots[slotIndex].Icon.style.display = DisplayStyle.Flex;
} else {
m_InventorySlots[slotIndex].Icon.style.backgroundImage = null;
m_InventorySlots[slotIndex].Icon.style.display = DisplayStyle.None;
}
}
}
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: ffb52c4d0a3c4e17917100cbb52494ea
timeCreated: 1752183541