working on inventory
This commit is contained in:
83
Assets/jelycho/Code/Player/HUD/ObjectsLabelsVC.cs
Normal file
83
Assets/jelycho/Code/Player/HUD/ObjectsLabelsVC.cs
Normal 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
3
Assets/jelycho/Code/Player/HUD/ObjectsLabelsVC.cs.meta
Normal file
3
Assets/jelycho/Code/Player/HUD/ObjectsLabelsVC.cs.meta
Normal file
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 42a4ccf83ed64ac58aef118275bd2414
|
||||
timeCreated: 1752068186
|
||||
45
Assets/jelycho/Code/Player/HUD/PlayerHUD.cs
Normal file
45
Assets/jelycho/Code/Player/HUD/PlayerHUD.cs
Normal 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
3
Assets/jelycho/Code/Player/HUD/PlayerHUD.cs.meta
Normal file
3
Assets/jelycho/Code/Player/HUD/PlayerHUD.cs.meta
Normal file
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e0712c9d21534362b219edf44601f57d
|
||||
timeCreated: 1752067887
|
||||
111
Assets/jelycho/Code/Player/HUD/PlayerInventoryUI.cs
Normal file
111
Assets/jelycho/Code/Player/HUD/PlayerInventoryUI.cs
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
3
Assets/jelycho/Code/Player/HUD/PlayerInventoryUI.cs.meta
Normal file
3
Assets/jelycho/Code/Player/HUD/PlayerInventoryUI.cs.meta
Normal file
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ffb52c4d0a3c4e17917100cbb52494ea
|
||||
timeCreated: 1752183541
|
||||
Reference in New Issue
Block a user