init
This commit is contained in:
@@ -0,0 +1,9 @@
|
||||
using VOID.UserInterface.Game.Util;
|
||||
|
||||
namespace VOID.UserInterface.Game.Interfaces
|
||||
{
|
||||
public interface IHasWindow
|
||||
{
|
||||
public WindowUI windowUI { get; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 54723d0142c14d8a9dd1b6ccebbba3dd
|
||||
timeCreated: 1720718867
|
||||
@@ -0,0 +1,10 @@
|
||||
<ui:UXML xmlns:ui="UnityEngine.UIElements" xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
engine="UnityEngine.UIElements" editor="UnityEditor.UIElements"
|
||||
noNamespaceSchemaLocation="../../../../../UIElementsSchema/UIElements.xsd" editor-extension-mode="False">
|
||||
<Style src="project://database/Assets/92%20-%20UserInterface/Generic/Game/Utility/SlotInner.uss?fileID=7433441132597879392&guid=28796e98eb4058846bf25d5786d0b036&type=3#SlotInner" />
|
||||
<ui:Button name="root-slot" enable-rich-text="false" picking-mode="Ignore">
|
||||
<ui:VisualElement name="background" picking-mode="Ignore" />
|
||||
<ui:VisualElement name="icon" picking-mode="Ignore" />
|
||||
<ui:VisualElement name="border" picking-mode="Ignore" />
|
||||
</ui:Button>
|
||||
</ui:UXML>
|
||||
@@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5a74e2b56bbc27c4ab7a5d0c1de93f00
|
||||
ScriptedImporter:
|
||||
internalIDToNameTable: []
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
script: {fileID: 13804, guid: 0000000000000000e000000000000000, type: 0}
|
||||
@@ -0,0 +1,37 @@
|
||||
#root-slot {
|
||||
width: 100%;
|
||||
margin-left: 0;
|
||||
margin-right: 0;
|
||||
margin-top: 0;
|
||||
margin-bottom: 0;
|
||||
background-color: rgba(0, 0, 0, 0);
|
||||
height: 100%;
|
||||
padding-left: 0;
|
||||
padding-right: 0;
|
||||
padding-top: 0;
|
||||
padding-bottom: 0;
|
||||
border-left-width: 0;
|
||||
border-right-width: 0;
|
||||
border-top-width: 0;
|
||||
border-bottom-width: 0;
|
||||
}
|
||||
|
||||
#root-slot > #background {
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-image: url('project://database/Assets/_ADDONS/MedievalKingdomUI/Artworks/White_gold_Skin/UI_elements_W/icon_frame_bg.png?fileID=2800000&guid=27f3ca780c69fcf49b884913b9ac5e3b&type=3#icon_frame_bg');
|
||||
}
|
||||
|
||||
#root-slot > #icon {
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
#root-slot > #border {
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-image: url('project://database/Assets/_ADDONS/MedievalKingdomUI/Artworks/White_gold_Skin/UI_elements_W/icon_frame.png?fileID=2800000&guid=f272753cabc45b9419037998d01412e7&type=3#icon_frame');
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 28796e98eb4058846bf25d5786d0b036
|
||||
ScriptedImporter:
|
||||
internalIDToNameTable: []
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
script: {fileID: 12385, guid: 0000000000000000e000000000000000, type: 0}
|
||||
disableValidation: 0
|
||||
@@ -0,0 +1,17 @@
|
||||
.slot {
|
||||
}
|
||||
|
||||
.slot-small {
|
||||
height: 40px;
|
||||
width: 40px;
|
||||
}
|
||||
|
||||
.slot-medium {
|
||||
height: 55px;
|
||||
width: 55px;
|
||||
}
|
||||
|
||||
.slot-big {
|
||||
height: 70px;
|
||||
width: 70px;
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 760aa0b2431a11e46a81be0018d225b1
|
||||
ScriptedImporter:
|
||||
internalIDToNameTable: []
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
script: {fileID: 12385, guid: 0000000000000000e000000000000000, type: 0}
|
||||
disableValidation: 0
|
||||
@@ -0,0 +1,128 @@
|
||||
using UnityEngine;
|
||||
using UnityEngine.UIElements;
|
||||
using VOID.Generic.Dict;
|
||||
using VOID.Generic.Objects.Item;
|
||||
using VOID.ScriptableObjects.Abilities;
|
||||
|
||||
namespace VOID.UserInterface.Game.Util
|
||||
{
|
||||
/// <summary>
|
||||
/// Manages all visuals inside slot: <see cref="ItemObject"/> or <see cref="BasicAbility"/>,
|
||||
/// including: image, border and background
|
||||
/// </summary>
|
||||
public class SlotUI
|
||||
{
|
||||
// Where slot belongs with its index
|
||||
public SlotType slotType { get; private set; }
|
||||
public int slotIndex { get; private set; }
|
||||
|
||||
// Content of slot
|
||||
public bool isEmpty { get; private set; } = true;
|
||||
public ItemObject item { get; private set; }
|
||||
public BasicAbility ability { get; private set; }
|
||||
|
||||
// Elements
|
||||
private VisualElement _templateElement;
|
||||
private VisualElement _backgroundElement;
|
||||
private VisualElement _borderElement;
|
||||
private VisualElement _iconElement;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes <see cref="SlotUI"/> on existing slot visual element.
|
||||
/// </summary>
|
||||
/// <param name="templateElement">Existing template to use for this slot</param>
|
||||
/// <param name="slotType">Defines to which UI it belongs.</param>
|
||||
/// <param name="slotIndex">Defines specific slot index in UI.</param>
|
||||
public void Init(VisualElement templateElement, SlotType slotType, int slotIndex)
|
||||
{
|
||||
_templateElement = templateElement;
|
||||
this.slotType = slotType;
|
||||
this.slotIndex = slotIndex;
|
||||
|
||||
// Find all Slot's elements
|
||||
_backgroundElement = _templateElement.Q("background");
|
||||
_borderElement = _templateElement.Q("border");
|
||||
_iconElement = _templateElement.Q("icon");
|
||||
|
||||
// Binding component to element
|
||||
_templateElement.dataSource = this;
|
||||
_templateElement.pickingMode = PickingMode.Position;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes completly new <see cref="SlotUI"/> inside given parent.
|
||||
/// </summary>
|
||||
/// <param name="parentElement">Create new slot as child in given parent.</param>
|
||||
/// <param name="slotType">Defines to which UI it belongs.</param>
|
||||
/// <param name="slotIndex">Defines specific slot index in UI.</param>
|
||||
/// <param name="name">Name for new Visual Element</param>
|
||||
public void InitNew(VisualElement parentElement, SlotType slotType, int slotIndex, string name = null)
|
||||
{
|
||||
// Create Slot (from template) in GUI
|
||||
var templateElement = GameUI.current.slotTemplate.CloneTree().contentContainer;
|
||||
templateElement.name = name ?? "slot";
|
||||
templateElement.AddToClassList("slot");
|
||||
templateElement.AddToClassList("slot-medium");
|
||||
parentElement.Add(templateElement);
|
||||
|
||||
Init(templateElement, slotType, slotIndex);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Change slot index. Useful when slot don't move anywhere, but whole counting change.
|
||||
/// </summary>
|
||||
public void ChangeIndex(int newIndex)
|
||||
{
|
||||
slotIndex = newIndex;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Put <see cref="ItemObject"/> into this slot and update all visuals.
|
||||
/// </summary>
|
||||
public void Set(ItemObject item)
|
||||
{
|
||||
Clear();
|
||||
if (!item) return;
|
||||
this.item = item;
|
||||
UpdateIconElement(item.basicData.image, item.itemData.quality.background, item.itemData.quality.border);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Put <see cref="BasicAbility"/> into this slot and update all visuals.
|
||||
/// </summary>
|
||||
public void Set(BasicAbility ability)
|
||||
{
|
||||
Clear();
|
||||
if (!ability) return;
|
||||
this.ability = ability;
|
||||
UpdateIconElement(ability.displayIcon, ability.quality.background, ability.quality.border);
|
||||
}
|
||||
|
||||
private void UpdateIconElement(Texture2D icon, Texture2D background, Texture2D border)
|
||||
{
|
||||
isEmpty = false;
|
||||
_backgroundElement.style.backgroundImage = new StyleBackground(background);
|
||||
_iconElement.style.backgroundImage = new StyleBackground(icon);
|
||||
_borderElement.style.backgroundImage = new StyleBackground(border);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Remove <see cref="ItemObject"/> or <see cref="BasicAbility"/> from this slot and make it empty.
|
||||
/// </summary>
|
||||
public void Clear()
|
||||
{
|
||||
_iconElement.style.backgroundImage = new StyleBackground(StyleKeyword.Null);
|
||||
ability = null;
|
||||
item = null;
|
||||
isEmpty = true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Destroy whole <see cref="SlotUI"/> with its <see cref="VisualElement"/>.
|
||||
/// </summary>
|
||||
public void Destroy()
|
||||
{
|
||||
_templateElement.parent.Remove(_templateElement);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f1c96fb02c124931b4416e0465f9a5bb
|
||||
timeCreated: 1673204998
|
||||
@@ -0,0 +1,10 @@
|
||||
<ui:UXML xmlns:ui="UnityEngine.UIElements" xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
engine="UnityEngine.UIElements" editor="UnityEditor.UIElements"
|
||||
noNamespaceSchemaLocation="../../../../../UIElementsSchema/UIElements.xsd" editor-extension-mode="False">
|
||||
<Style src="project://database/Assets/92%20-%20UserInterface/Generic/Game/Utility/StatusInner.uss?fileID=7433441132597879392&guid=f7652f06b5fcc1e4c92df4749fc71467&type=3#StatusInner" />
|
||||
<ui:VisualElement name="root-status" picking-mode="Ignore" style="flex-grow: 1;">
|
||||
<ui:VisualElement name="background" picking-mode="Ignore" style="flex-grow: 1;" />
|
||||
<ui:VisualElement name="icon" picking-mode="Ignore" style="background-image: url('project://database/Assets/5%20-%20Textures/Generic/Icons/status_placeholder_icon.png?fileID=2800000&guid=f386e7ee1fbaf804396fd2b5d6176a56&type=3#status_placeholder_icon');" />
|
||||
<ui:Label text="{TIME}" name="time-remaining" picking-mode="Ignore" />
|
||||
</ui:VisualElement>
|
||||
</ui:UXML>
|
||||
@@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9c95cff4b708f194db8bb1259ba03d85
|
||||
ScriptedImporter:
|
||||
internalIDToNameTable: []
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
script: {fileID: 13804, guid: 0000000000000000e000000000000000, type: 0}
|
||||
@@ -0,0 +1,29 @@
|
||||
#root-status {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
#root-status > #background {
|
||||
background-color: rgba(0, 0, 0, 0.48);
|
||||
}
|
||||
|
||||
#root-status > #icon {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
#root-status > #time-remaining {
|
||||
position: absolute;
|
||||
margin-left: 0;
|
||||
margin-right: 0;
|
||||
margin-top: 0;
|
||||
margin-bottom: 0;
|
||||
padding-left: 0;
|
||||
padding-right: 0;
|
||||
padding-top: 0;
|
||||
padding-bottom: 0;
|
||||
width: 100%;
|
||||
-unity-text-align: upper-center;
|
||||
-unity-font-style: bold;
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f7652f06b5fcc1e4c92df4749fc71467
|
||||
ScriptedImporter:
|
||||
internalIDToNameTable: []
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
script: {fileID: 12385, guid: 0000000000000000e000000000000000, type: 0}
|
||||
disableValidation: 0
|
||||
@@ -0,0 +1,29 @@
|
||||
.status {
|
||||
}
|
||||
|
||||
.status-small {
|
||||
height: 30px;
|
||||
width: 30px;
|
||||
}
|
||||
|
||||
.status-small #time-remaining {
|
||||
font-size: 10px;
|
||||
}
|
||||
|
||||
.status-medium {
|
||||
height: 45px;
|
||||
width: 45px;
|
||||
}
|
||||
|
||||
.status-medium #time-remaining {
|
||||
font-size: 15px;
|
||||
}
|
||||
|
||||
.status-big {
|
||||
height: 60px;
|
||||
width: 60px;
|
||||
}
|
||||
|
||||
.status-big #time-remaining {
|
||||
font-size: 20px;
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6eb1ae18d8fd2c541be09b7ecad6e722
|
||||
ScriptedImporter:
|
||||
internalIDToNameTable: []
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
script: {fileID: 12385, guid: 0000000000000000e000000000000000, type: 0}
|
||||
disableValidation: 0
|
||||
@@ -0,0 +1,61 @@
|
||||
using System;
|
||||
using UnityEngine.UIElements;
|
||||
using VOID.ScriptableObjects;
|
||||
|
||||
namespace VOID.UserInterface.Game.Util
|
||||
{
|
||||
[Serializable]
|
||||
public class StatusUI
|
||||
{
|
||||
// Content of slot
|
||||
public BasicStatus status { get; private set; }
|
||||
|
||||
// Elements
|
||||
private VisualElement _templateElement;
|
||||
private VisualElement _iconElement;
|
||||
private Label _timerLabel;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes completly new <see cref="StatusUI"/> inside given parent.
|
||||
/// </summary>
|
||||
/// <param name="parentWrapperElement">Create new status as child in given parent.</param>
|
||||
/// <param name="status"><see cref="BasicStatus"/> to use for this StatusUI</param>
|
||||
/// <param name="name">Optional name for UI element</param>
|
||||
public void InitNew(VisualElement parentWrapperElement, BasicStatus status, string name = null)
|
||||
{
|
||||
this.status = status;
|
||||
|
||||
// Create Status (from template) in GUI
|
||||
_templateElement = GameUI.current.statusTemplate.CloneTree().contentContainer;
|
||||
_templateElement.name = name ?? "status";
|
||||
_templateElement.AddToClassList("status");
|
||||
_templateElement.AddToClassList("status-medium");
|
||||
parentWrapperElement.Add(_templateElement);
|
||||
|
||||
// Find all Status's elements
|
||||
_iconElement = _templateElement.Q("icon");
|
||||
_iconElement.style.backgroundImage = new StyleBackground(status.displayIcon);
|
||||
_timerLabel = _templateElement.Q<Label>("time-remaining");
|
||||
|
||||
// Monitor what happening to displayed status
|
||||
status.OnTimeDecrease += OnTimeDecrease;
|
||||
|
||||
// Also force
|
||||
OnTimeDecrease();
|
||||
|
||||
_templateElement.dataSource = this;
|
||||
_templateElement.pickingMode = PickingMode.Position;
|
||||
}
|
||||
|
||||
public void Destroy()
|
||||
{
|
||||
status.OnTimeDecrease -= OnTimeDecrease;
|
||||
_templateElement.parent.Remove(_templateElement);
|
||||
}
|
||||
|
||||
private void OnTimeDecrease()
|
||||
{
|
||||
_timerLabel.text = status.durationLeft.ToString("0");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c7631d6650df4a3fbf44905ca6c5c0d7
|
||||
timeCreated: 1696165886
|
||||
@@ -0,0 +1,12 @@
|
||||
<ui:UXML xmlns:ui="UnityEngine.UIElements" xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
engine="UnityEngine.UIElements" editor="UnityEditor.UIElements"
|
||||
noNamespaceSchemaLocation="../../../../../UIElementsSchema/UIElements.xsd" editor-extension-mode="False">
|
||||
<Style src="project://database/Assets/92%20-%20UserInterface/Generic/Game/Utility/UnitPortraitInner.uss?fileID=7433441132597879392&guid=6aa5b13cdb7a3d84994729c506f6ba51&type=3#UnitPortraitInner" />
|
||||
<ui:VisualElement name="root-unit-portrait" picking-mode="Ignore">
|
||||
<ui:Button name="portrait" picking-mode="Ignore">
|
||||
<ui:ProgressBar value="69" title=" " name="health-bar" picking-mode="Ignore" />
|
||||
</ui:Button>
|
||||
<ui:Label text="69/100" name="health-label" />
|
||||
<ui:VisualElement name="border" picking-mode="Ignore" />
|
||||
</ui:VisualElement>
|
||||
</ui:UXML>
|
||||
@@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2b588e131b790bd408086718bd2f82cd
|
||||
ScriptedImporter:
|
||||
internalIDToNameTable: []
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
script: {fileID: 13804, guid: 0000000000000000e000000000000000, type: 0}
|
||||
@@ -0,0 +1,124 @@
|
||||
#root-unit-portrait {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
margin-left: 0;
|
||||
margin-right: 0;
|
||||
margin-top: 0;
|
||||
margin-bottom: 0;
|
||||
padding-left: 0;
|
||||
padding-right: 0;
|
||||
padding-top: 0;
|
||||
padding-bottom: 0;
|
||||
}
|
||||
|
||||
#portrait {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-image: url('project://database/Assets/5%20-%20Textures/Generic/Portraits/Units/PortraitPlaceholder.png?fileID=2800000&guid=257f48a9190bac44e9fc555146d7690d&type=3#PortraitPlaceholder');
|
||||
margin-left: 0;
|
||||
margin-right: 0;
|
||||
margin-top: 0;
|
||||
margin-bottom: 0;
|
||||
padding-left: 0;
|
||||
padding-right: 0;
|
||||
padding-top: 0;
|
||||
padding-bottom: 0;
|
||||
border-top-left-radius: 7%;
|
||||
border-top-right-radius: 7%;
|
||||
border-bottom-right-radius: 7%;
|
||||
border-bottom-left-radius: 7%;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
#health-bar {
|
||||
width: 100%;
|
||||
background-color: rgba(88, 88, 88, 0.59);
|
||||
position: absolute;
|
||||
height: 5%;
|
||||
margin-top: 0;
|
||||
margin-right: 0;
|
||||
margin-bottom: 0;
|
||||
margin-left: 0;
|
||||
padding-top: 0;
|
||||
padding-right: 5%;
|
||||
padding-left: 5%;
|
||||
bottom: 3%;
|
||||
}
|
||||
|
||||
#health-bar .unity-progress-bar__container {
|
||||
max-height: 100%;
|
||||
max-width: 100%;
|
||||
min-height: auto;
|
||||
min-width: auto;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
#health-bar .unity-progress-bar__background {
|
||||
background-color: rgba(0, 0, 0, 0.39);
|
||||
margin-left: 0;
|
||||
margin-right: 0;
|
||||
margin-top: 0;
|
||||
margin-bottom: 0;
|
||||
padding-left: 0;
|
||||
padding-right: 0;
|
||||
padding-top: 0;
|
||||
padding-bottom: 0;
|
||||
max-width: 100%;
|
||||
max-height: 100%;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
border-left-width: 0;
|
||||
border-right-width: 0;
|
||||
border-top-width: 0;
|
||||
border-bottom-width: 0;
|
||||
}
|
||||
|
||||
#health-bar .unity-progress-bar__progress {
|
||||
background-color: rgb(255, 0, 0);
|
||||
margin-left: 0;
|
||||
margin-right: 0;
|
||||
margin-top: 0;
|
||||
margin-bottom: 0;
|
||||
max-width: 100%;
|
||||
max-height: 100%;
|
||||
width: auto;
|
||||
height: 100%;
|
||||
padding-left: 0;
|
||||
padding-right: 0;
|
||||
padding-top: 0;
|
||||
padding-bottom: 0;
|
||||
}
|
||||
|
||||
#health-bar .unity-progress-bar__title-container {
|
||||
display: none;
|
||||
}
|
||||
|
||||
#health-label {
|
||||
position: absolute;
|
||||
bottom: 5%;
|
||||
align-self: center;
|
||||
margin-top: 0;
|
||||
margin-right: 0;
|
||||
margin-bottom: 0;
|
||||
margin-left: 0;
|
||||
padding-top: 0;
|
||||
padding-right: 0;
|
||||
padding-bottom: 0;
|
||||
padding-left: 0;
|
||||
-unity-font-style: bold;
|
||||
color: rgb(255, 255, 255);
|
||||
text-shadow: 1px 1px 1px rgb(0, 0, 0);
|
||||
}
|
||||
|
||||
#border {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
position: absolute;
|
||||
background-image: url('project://database/Assets/_ADDONS/MedievalKingdomUI/Artworks/Classic_Skin/UI_elements_C/icon_frame_lg.png?fileID=2800000&guid=f8efd3dc9609b4e45add8aebb16b34f2&type=3#icon_frame_lg');
|
||||
}
|
||||
|
||||
.active #border {
|
||||
background-image: url('project://database/Assets/_ADDONS/MedievalKingdomUI/Artworks/White_gold_Skin/UI_elements_W/icon_frame_lg.png?fileID=2800000&guid=0964db7d06777d1429e0648e8be94ba7&type=3#icon_frame_lg');
|
||||
-unity-background-image-tint-color: rgb(255, 255, 0);
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6aa5b13cdb7a3d84994729c506f6ba51
|
||||
ScriptedImporter:
|
||||
internalIDToNameTable: []
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
script: {fileID: 12385, guid: 0000000000000000e000000000000000, type: 0}
|
||||
disableValidation: 0
|
||||
@@ -0,0 +1,41 @@
|
||||
.unit-portrait-small {
|
||||
height: 120px;
|
||||
width: 80px;
|
||||
}
|
||||
|
||||
.unit-portrait-small #health-bar {
|
||||
height: 5px;
|
||||
}
|
||||
|
||||
.unit-portrait-small #health-label {
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.unit-portrait-medium {
|
||||
height: 165px;
|
||||
width: 110px;
|
||||
}
|
||||
|
||||
.unit-portrait-medium #health-bar {
|
||||
height: 7px;
|
||||
}
|
||||
|
||||
.unit-portrait-medium #health-label {
|
||||
font-size: 15px;
|
||||
}
|
||||
|
||||
.unit-portrait-big {
|
||||
height: 210px;
|
||||
width: 140px;
|
||||
}
|
||||
|
||||
.unit-portrait-big #health-bar {
|
||||
height: 9px;
|
||||
}
|
||||
|
||||
.unit-portrait-big #health-label {
|
||||
font-size: 18px;
|
||||
}
|
||||
|
||||
.unit-portrait {
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a9fd7af89854ed243b3383ce693bc254
|
||||
ScriptedImporter:
|
||||
internalIDToNameTable: []
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
script: {fileID: 12385, guid: 0000000000000000e000000000000000, type: 0}
|
||||
disableValidation: 0
|
||||
@@ -0,0 +1,119 @@
|
||||
using System;
|
||||
using Sirenix.OdinInspector;
|
||||
using UnityEngine.UIElements;
|
||||
using VOID.Generic.Dict;
|
||||
using VOID.Generic.Objects.Abstract.Events;
|
||||
using VOID.Generic.Objects.Unit;
|
||||
|
||||
namespace VOID.UserInterface.Game.Party
|
||||
{
|
||||
/// <summary>
|
||||
/// Manages all visuals inside <see cref="UnitObject"/> portrait, including: image, border and healthbar
|
||||
/// </summary>
|
||||
public class UnitPortraitUI
|
||||
{
|
||||
[ShowInInspector, ReadOnly] public UnitObject unit { get; private set; }
|
||||
|
||||
public event Action<UnitObject> OnClick;
|
||||
|
||||
// Visual Elements
|
||||
public VisualElement templateElement { get; private set; }
|
||||
private Button _portrait;
|
||||
private ProgressBar _healthBar;
|
||||
private Label _healthLabel;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes <see cref="UnitPortraitUI"/> on existing potrait visual element.
|
||||
/// </summary>
|
||||
/// <param name="unitPortraitTemplate">Existing template to use for this portrait</param>
|
||||
public void Init(VisualElement unitPortraitTemplate)
|
||||
{
|
||||
// Find all important elements
|
||||
templateElement = unitPortraitTemplate;
|
||||
_portrait = templateElement.Q<Button>("portrait");
|
||||
_healthBar = templateElement.Q<ProgressBar>("health-bar");
|
||||
_healthLabel = templateElement.Q<Label>("health-label");
|
||||
|
||||
templateElement.RegisterCallback(new EventCallback<MouseDownEvent>(_ => OnClick?.Invoke(unit)), TrickleDown.TrickleDown);
|
||||
|
||||
// Binding component to element
|
||||
templateElement.dataSource = this;
|
||||
templateElement.pickingMode = PickingMode.Position;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes completly new <see cref="UnitPortraitUI"/> inside given parent.
|
||||
/// </summary>
|
||||
/// <param name="parentElement">Create new potratit as child in given parent.</param>
|
||||
public void InitNew(VisualElement parentElement)
|
||||
{
|
||||
// Find all important elements
|
||||
var newTemplateElement = GameUI.current.unitPortraitTemplate.CloneTree().contentContainer;
|
||||
newTemplateElement.AddToClassList("unit-portrait");
|
||||
newTemplateElement.AddToClassList("unit-portrait-small");
|
||||
parentElement.Add(newTemplateElement);
|
||||
Init(newTemplateElement);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Display given <see cref="UnitObject"/> in this portrait.
|
||||
/// </summary>
|
||||
public void SetUnit(UnitObject unitToSet)
|
||||
{
|
||||
// Remove everything about previous Unit
|
||||
UnsetUnit();
|
||||
|
||||
// New Unit assigned - start listeners and wait
|
||||
unit = unitToSet;
|
||||
unit.basicEvents.onCurrentResourceChange.AddListener(OnBasicResourceChange);
|
||||
|
||||
// Set Unit's portrait
|
||||
_portrait.style.backgroundImage = new StyleBackground(unit.basicData.image);
|
||||
|
||||
UnitPortraitHealthChange();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Clear currently displaying <see cref="UnitObject"/> in this portrait.
|
||||
/// </summary>
|
||||
public void UnsetUnit()
|
||||
{
|
||||
// There is no unit currently
|
||||
if (!unit) return;
|
||||
|
||||
// Remove all listeners, then remove assigned Unit
|
||||
unit.basicEvents.onCurrentResourceChange.RemoveListener(OnBasicResourceChange);
|
||||
unit = null;
|
||||
|
||||
// Make UI invisible and unset portrait
|
||||
_portrait.style.backgroundImage = null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Completly destroy this potratit.
|
||||
/// </summary>
|
||||
public void Destroy()
|
||||
{
|
||||
unit.basicEvents.onCurrentResourceChange.RemoveListener(OnBasicResourceChange);
|
||||
templateElement.parent.Remove(templateElement);
|
||||
}
|
||||
|
||||
private void OnBasicResourceChange(BasicResourceChangeEvent basicResourceChangeEvent)
|
||||
{
|
||||
// Update HealthBar length
|
||||
if (basicResourceChangeEvent.type is BasicResourceType.Health)
|
||||
{
|
||||
UnitPortraitHealthChange();
|
||||
}
|
||||
}
|
||||
|
||||
private void UnitPortraitHealthChange()
|
||||
{
|
||||
// Update HealthBar length
|
||||
_healthBar.value = unit.basicData.currentResources.Get(BasicResourceType.Health) / unit.basicData.maxResources.Get(BasicResourceType.Health) * 100;
|
||||
|
||||
// Update HealthBar label
|
||||
_healthLabel.text = $"{unit.basicData.currentResources.Get(BasicResourceType.Health)}/{unit.basicData.maxResources.Get(BasicResourceType.Health)}";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1f4b363d4ac84b1dacd35f6a1ed17802
|
||||
timeCreated: 1697404285
|
||||
@@ -0,0 +1,15 @@
|
||||
<ui:UXML xmlns:ui="UnityEngine.UIElements" xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
engine="UnityEngine.UIElements" editor="UnityEditor.UIElements"
|
||||
noNamespaceSchemaLocation="../../../../../UIElementsSchema/UIElements.xsd" editor-extension-mode="False">
|
||||
<Style src="project://database/Assets/92%20-%20UserInterface/Generic/Game/Utility/WindowInner.uss?fileID=7433441132597879392&guid=29ea7ef4a8f41f04a97d41ef15550aca&type=3#WindowInner" />
|
||||
<ui:VisualElement name="root-window" picking-mode="Ignore" style="flex-grow: 1;">
|
||||
<ui:VisualElement name="image" picking-mode="Ignore" />
|
||||
<ui:VisualElement name="header-center" picking-mode="Ignore">
|
||||
<ui:VisualElement name="header">
|
||||
<ui:Label text="EXAMPLE_TITLE" display-tooltip-when-elided="true" name="title" picking-mode="Ignore" />
|
||||
</ui:VisualElement>
|
||||
</ui:VisualElement>
|
||||
<ui:VisualElement name="border" picking-mode="Ignore" />
|
||||
<ui:Button text="x" name="close" />
|
||||
</ui:VisualElement>
|
||||
</ui:UXML>
|
||||
@@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 04235ec1d1b764e448e2524000a1b87a
|
||||
ScriptedImporter:
|
||||
internalIDToNameTable: []
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
script: {fileID: 13804, guid: 0000000000000000e000000000000000, type: 0}
|
||||
@@ -0,0 +1,66 @@
|
||||
#root-window > #image {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
position: absolute;
|
||||
background-color: rgb(33, 33, 33);
|
||||
min-width: auto;
|
||||
min-height: auto;
|
||||
}
|
||||
|
||||
#root-window > #header-center {
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
#root-window > #header-center > #header {
|
||||
position: absolute;
|
||||
padding-top: 15px;
|
||||
padding-left: 5px;
|
||||
padding-right: 5px;
|
||||
padding-bottom: 5px;
|
||||
background-color: rgba(0, 0, 0, 0.39);
|
||||
}
|
||||
|
||||
#root-window > #header-center > #header > #title {
|
||||
-unity-text-align: upper-center;
|
||||
width: 100%;
|
||||
margin-left: 0;
|
||||
margin-right: 0;
|
||||
margin-top: 0;
|
||||
margin-bottom: 0;
|
||||
padding-left: 0;
|
||||
padding-right: 0;
|
||||
padding-top: 0;
|
||||
padding-bottom: 0;
|
||||
color: rgb(187, 187, 187);
|
||||
}
|
||||
|
||||
#root-window > #border {
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-image: url('project://database/Assets/_ADDONS/MedievalKingdomUI/Artworks/White_gold_Skin/UI_elements_W/Main_bar_frame.png?fileID=2800000&guid=f3e73c26aa3a97547bc7b96427ec4084&type=3#Main_bar_frame');
|
||||
min-width: 150px;
|
||||
min-height: 150px;
|
||||
-unity-background-scale-mode: stretch-to-fill;
|
||||
-unity-slice-left: 32;
|
||||
-unity-slice-top: 32;
|
||||
-unity-slice-right: 32;
|
||||
-unity-slice-bottom: 32;
|
||||
-unity-slice-scale: 0.5px;
|
||||
}
|
||||
|
||||
#root-window > #close {
|
||||
position: absolute;
|
||||
width: 25px;
|
||||
height: 25px;
|
||||
margin-left: 0;
|
||||
margin-right: 0;
|
||||
margin-top: 0;
|
||||
margin-bottom: 0;
|
||||
padding-left: 5px;
|
||||
padding-right: 5px;
|
||||
padding-top: 5px;
|
||||
padding-bottom: 5px;
|
||||
right: 5px;
|
||||
top: 5px;
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 29ea7ef4a8f41f04a97d41ef15550aca
|
||||
ScriptedImporter:
|
||||
internalIDToNameTable: []
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
script: {fileID: 12385, guid: 0000000000000000e000000000000000, type: 0}
|
||||
disableValidation: 0
|
||||
@@ -0,0 +1,5 @@
|
||||
#window {
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 80611877e61dcf346bf43cfc4ebd3394
|
||||
ScriptedImporter:
|
||||
internalIDToNameTable: []
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
script: {fileID: 12385, guid: 0000000000000000e000000000000000, type: 0}
|
||||
disableValidation: 0
|
||||
@@ -0,0 +1,169 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using UnityEngine;
|
||||
using UnityEngine.InputSystem;
|
||||
using UnityEngine.UIElements;
|
||||
using PlayerInputManager = VOID.Generic.Player.Input.PlayerInputManager;
|
||||
using ShortcutsInputManager = VOID.Generic.Player.Input.ShortcutsInputManager;
|
||||
|
||||
namespace VOID.UserInterface.Game.Util
|
||||
{
|
||||
[Serializable]
|
||||
public class WindowUI : MonoBehaviour
|
||||
{
|
||||
public static List<WindowUI> openWindows = new();
|
||||
|
||||
// UI Visual Elements
|
||||
private VisualElement _parentElement;
|
||||
private VisualElement _rootElement;
|
||||
private Button _windowCloseButton;
|
||||
private VisualElement _headerElement;
|
||||
private Label _titleLabel;
|
||||
|
||||
// Events
|
||||
public event Action OnClose;
|
||||
public event Action OnOpen;
|
||||
|
||||
// References
|
||||
private PlayerInputManager _playerInputManager;
|
||||
private GameUI _gameUI;
|
||||
|
||||
// Toggle
|
||||
private bool _isOpen;
|
||||
private bool _isOverHeader;
|
||||
private bool _isDragging;
|
||||
|
||||
// Offset - relative position from window position to cursor
|
||||
private Vector2 _draggingOffset;
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
var uiDocument = gameObject.GetComponent<UIDocument>();
|
||||
var templateElement = uiDocument.rootVisualElement;
|
||||
|
||||
// Find all visual elements
|
||||
_rootElement = templateElement.Q("root-window");
|
||||
_parentElement = _rootElement.parent.parent;
|
||||
_headerElement = _rootElement.Q("header");
|
||||
_titleLabel = _headerElement.Q<Label>("title");
|
||||
_windowCloseButton = _rootElement.Q<Button>("close");
|
||||
|
||||
// Close backpack when "x" pressed
|
||||
_windowCloseButton.clicked += Close;
|
||||
|
||||
// Make window active if pressed
|
||||
_parentElement.RegisterCallback(new EventCallback<MouseDownEvent>(_ => SetActiveWindow()), TrickleDown.TrickleDown);
|
||||
}
|
||||
|
||||
private void Start()
|
||||
{
|
||||
_gameUI = GameUI.current;
|
||||
_playerInputManager = PlayerInputManager.current;
|
||||
_playerInputManager.OnDraggingPrepare += PrepareDragging;
|
||||
_playerInputManager.OnDraggingStart += StartDragging;
|
||||
_playerInputManager.OnDraggingEnd += EndDragging;
|
||||
}
|
||||
|
||||
public void SetTitle(string title)
|
||||
{
|
||||
_titleLabel.text = title;
|
||||
}
|
||||
|
||||
public void Toggle()
|
||||
{
|
||||
if (_isOpen)
|
||||
{
|
||||
Close();
|
||||
}
|
||||
else
|
||||
{
|
||||
Open();
|
||||
}
|
||||
}
|
||||
|
||||
public void Close()
|
||||
{
|
||||
// Hide element
|
||||
_parentElement.style.display = DisplayStyle.None;
|
||||
|
||||
// Reset element position styles
|
||||
_parentElement.style.right = StyleKeyword.Null;
|
||||
_parentElement.style.top = StyleKeyword.Null;
|
||||
_parentElement.style.bottom = StyleKeyword.Null;
|
||||
_parentElement.style.left = StyleKeyword.Null;
|
||||
|
||||
_isOpen = false;
|
||||
OnClose?.Invoke();
|
||||
openWindows.Remove(this);
|
||||
}
|
||||
|
||||
public void Open()
|
||||
{
|
||||
// Show Element
|
||||
_parentElement.style.display = DisplayStyle.Flex;
|
||||
|
||||
_isOpen = true;
|
||||
OnOpen?.Invoke();
|
||||
openWindows.Add(this);
|
||||
SetActiveWindow();
|
||||
}
|
||||
|
||||
private void Update()
|
||||
{
|
||||
if (!_isDragging) return;
|
||||
|
||||
var mousePos = _gameUI.cursorPositionOnUI;
|
||||
_parentElement.style.top = new StyleLength(mousePos.y - Mathf.Abs(_draggingOffset.y));
|
||||
_parentElement.style.left = new StyleLength(mousePos.x - Mathf.Abs(_draggingOffset.x));
|
||||
}
|
||||
|
||||
private void PrepareDragging()
|
||||
{
|
||||
// Check if dragging started at window's title header...
|
||||
_isOverHeader = GameUI.current.elementsUnderCursor.Contains(_headerElement);
|
||||
|
||||
// ...Only dragging by TITLE element allows to drag whole window
|
||||
if (!_isOverHeader) return;
|
||||
|
||||
// Calculate offset from mouse position to window position
|
||||
var windowPos = new Vector2(_parentElement.worldBound.x,_parentElement.worldBound.y);
|
||||
var mousePos = _gameUI.cursorPositionOnUI;
|
||||
_draggingOffset = windowPos - mousePos;
|
||||
}
|
||||
|
||||
private void StartDragging()
|
||||
{
|
||||
if (!_isOverHeader) return;
|
||||
|
||||
_isDragging = true;
|
||||
_parentElement.style.right = new StyleLength(StyleKeyword.Auto);
|
||||
_parentElement.style.bottom = new StyleLength(StyleKeyword.Auto);
|
||||
}
|
||||
|
||||
public void EndDragging()
|
||||
{
|
||||
_isDragging = false;
|
||||
_isOverHeader = false;
|
||||
}
|
||||
|
||||
public void SetActiveWindow()
|
||||
{
|
||||
openWindows.Remove(this);
|
||||
openWindows = openWindows.Prepend(this).ToList();
|
||||
UpdateDocumentUIOrder();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Calculating sorting order for all windows (in which order they will be rendered)
|
||||
/// </summary>
|
||||
public static void UpdateDocumentUIOrder()
|
||||
{
|
||||
openWindows.ForEach(window =>
|
||||
{
|
||||
var sortingOrder = openWindows.Count - openWindows.IndexOf(window);
|
||||
window.GetComponent<UIDocument>().sortingOrder = sortingOrder;
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7739f7d2ddb54e68ba72bbd6d7d955df
|
||||
timeCreated: 1693497508
|
||||
Reference in New Issue
Block a user