Colony Tab Interface
Properties panel supports read/write properties Colony tab is now populated with colony data when a colony is selected
This commit is contained in:
parent
87ebb18c0b
commit
a99b4e82f3
30 changed files with 7598 additions and 3280 deletions
|
|
@ -363,21 +363,60 @@ public class DatabaseListView : EditorWindow
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
using (var h = new HorizontalScope(ListItemStyle))
|
||||
{
|
||||
if (GUI.Button(h.rect, GUIContent.none, GUIStyle.none))
|
||||
{
|
||||
CreateItem(_itemTypes[i], newItem =>
|
||||
{
|
||||
if(newItem is SimpleCommodityData simpleCommodityData)
|
||||
{
|
||||
simpleCommodityData.Category =
|
||||
(SimpleCommodityCategory) Enum.Parse(typeof(SimpleCommodityCategory),
|
||||
itemGroup.Key);
|
||||
simpleCommodityData.Name = $"New {itemGroup.Key}";
|
||||
}
|
||||
else if(newItem is CompoundCommodityData compoundCommodityData)
|
||||
{
|
||||
compoundCommodityData.Category =
|
||||
(CompoundCommodityCategory) Enum.Parse(
|
||||
typeof(CompoundCommodityCategory), itemGroup.Key);
|
||||
compoundCommodityData.Name = $"New {itemGroup.Key}";
|
||||
}
|
||||
else if(newItem is GearData gearData)
|
||||
{
|
||||
gearData.Hardpoint =
|
||||
(HardpointType) Enum.Parse(typeof(HardpointType), itemGroup.Key);
|
||||
gearData.Name = $"New {itemGroup.Key}";
|
||||
}
|
||||
else if(newItem is HullData hullData)
|
||||
{
|
||||
hullData.HullType = (HullType) Enum.Parse(typeof(HullType), itemGroup.Key);
|
||||
hullData.Name = $"New {itemGroup.Key}";
|
||||
}
|
||||
});
|
||||
}
|
||||
GUILayout.Space(30);
|
||||
GUILayout.Label("New " + itemGroup.Key);
|
||||
var rect = GetControlRect(false, GUILayout.Width(EditorGUIUtility.singleLineHeight));
|
||||
GUI.DrawTexture(rect, Icons.Instance.plus, ScaleMode.StretchToFill, true, 1, LabelColor, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
foreach (var item in items.Where(e=>e.GetType()==_itemTypes[i]).OrderBy(item=>item.Name))
|
||||
|
||||
if (!itemGroups.Any())
|
||||
{
|
||||
}
|
||||
|
||||
using (var h = new HorizontalScope(ListItemStyle))
|
||||
{
|
||||
if(GUI.Button(h.rect, GUIContent.none, GUIStyle.none))
|
||||
CreateItem(_itemTypes[i]);
|
||||
GUILayout.Space(20);
|
||||
GUILayout.Label("New " + _itemTypes[i].Name);
|
||||
var rect = GetControlRect(false, GUILayout.Width(EditorGUIUtility.singleLineHeight));
|
||||
GUI.DrawTexture(rect, Icons.Instance.plus, ScaleMode.StretchToFill, true, 1, LabelColor, 0, 0);
|
||||
using (var h = new HorizontalScope(ListItemStyle))
|
||||
{
|
||||
if(GUI.Button(h.rect, GUIContent.none, GUIStyle.none))
|
||||
CreateItem(_itemTypes[i]);
|
||||
GUILayout.Space(20);
|
||||
GUILayout.Label("New " + _itemTypes[i].Name);
|
||||
var rect = GetControlRect(false, GUILayout.Width(EditorGUIUtility.singleLineHeight));
|
||||
GUI.DrawTexture(rect, Icons.Instance.plus, ScaleMode.StretchToFill, true, 1, LabelColor, 0, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -449,11 +488,12 @@ public class DatabaseListView : EditorWindow
|
|||
_inspector.Repaint();
|
||||
}
|
||||
|
||||
private DatabaseEntry CreateItem(Type type)
|
||||
private DatabaseEntry CreateItem(Type type, Action<DatabaseEntry> onCreate = null)
|
||||
{
|
||||
var newEntry = (DatabaseEntry) Activator.CreateInstance(type);
|
||||
if(newEntry is INamedEntry entry)
|
||||
entry.EntryName = $"New {FormatTypeName(type.Name)}";
|
||||
onCreate?.Invoke(newEntry);
|
||||
_databaseCache.Add(newEntry);
|
||||
Select(newEntry);
|
||||
return newEntry;
|
||||
|
|
|
|||
|
|
@ -32,12 +32,16 @@ public interface INamedEntry
|
|||
Union(11, typeof(Player)),
|
||||
Union(12, typeof(Corporation)),
|
||||
Union(13, typeof(MegaCorporation)),
|
||||
Union(14, typeof(StationData)),
|
||||
Union(14, typeof(OrbitalEntity)),
|
||||
Union(15, typeof(OrbitData)),
|
||||
Union(16, typeof(PlanetData)),
|
||||
Union(17, typeof(PersonalityAttribute)),
|
||||
Union(18, typeof(AgentTask)),
|
||||
Union(19, typeof(LoadoutData)),
|
||||
Union(20, typeof(Ship)),
|
||||
Union(21, typeof(Mining)),
|
||||
Union(22, typeof(StationTowing)),
|
||||
Union(23, typeof(Survey)),
|
||||
JsonObject(MemberSerialization.OptIn), JsonConverter(typeof(JsonKnownTypesConverter<DatabaseEntry>))]
|
||||
//[Union(21, typeof(ContractData))]
|
||||
//[Union(22, typeof(Station))]
|
||||
|
|
|
|||
|
|
@ -15,19 +15,50 @@ using static Unity.Mathematics.math;
|
|||
JsonObject(MemberSerialization.OptIn), JsonConverter(typeof(JsonKnownTypesConverter<Entity>))]
|
||||
public abstract class Entity : DatabaseEntry, IMessagePackSerializationCallbackReceiver, INamedEntry
|
||||
{
|
||||
[JsonProperty("temperature"), Key(1)] public float Temperature;
|
||||
[JsonProperty("energy"), Key(2)] public float Energy;
|
||||
[JsonProperty("position"), Key(3)] public float2 Position;
|
||||
[JsonProperty("direction"), Key(4)] public float2 Direction = float2(0,1);
|
||||
[JsonProperty("velocity"), Key(5)] public float2 Velocity;
|
||||
[JsonProperty("cargo"), Key(6)] public readonly List<Guid> Cargo; // Type: ItemInstance
|
||||
[JsonProperty("equipment"), Key(7)] public readonly List<Guid> EquippedItems; // Type: Gear
|
||||
[JsonProperty("parent"), Key(8)] public Guid Parent; // Type: Entity
|
||||
[JsonProperty("children"), Key(9)] public List<Guid> Children = new List<Guid>(); // Type: Entity
|
||||
[JsonProperty("hull"), Key(10)] public Guid Hull; // Type: Gear
|
||||
[JsonProperty("persistedBehaviorData"), Key(11)] public Dictionary<Guid, PersistentBehaviorData[]> PersistedBehaviors;
|
||||
[JsonProperty("corporation"), Key(12)] public Guid Corporation;
|
||||
[JsonProperty("name"), Key(13)] public string Name;
|
||||
[JsonProperty("temperature"), Key(1)]
|
||||
public float Temperature;
|
||||
|
||||
[JsonProperty("energy"), Key(2)]
|
||||
public float Energy;
|
||||
|
||||
[JsonProperty("position"), Key(3)]
|
||||
public float2 Position;
|
||||
|
||||
[JsonProperty("direction"), Key(4)]
|
||||
public float2 Direction = float2(0,1);
|
||||
|
||||
[JsonProperty("velocity"), Key(5)]
|
||||
public float2 Velocity;
|
||||
|
||||
[JsonProperty("cargo"), Key(6)]
|
||||
public readonly List<Guid> Cargo; // Type: ItemInstance
|
||||
|
||||
[JsonProperty("equipment"), Key(7)]
|
||||
public readonly List<Guid> EquippedItems; // Type: Gear
|
||||
|
||||
[JsonProperty("parent"), Key(8)]
|
||||
public Guid Parent; // Type: Entity
|
||||
|
||||
[JsonProperty("children"), Key(9)]
|
||||
public List<Guid> Children = new List<Guid>(); // Type: Entity
|
||||
|
||||
[JsonProperty("hull"), Key(10)]
|
||||
public Guid Hull; // Type: Gear
|
||||
|
||||
[JsonProperty("persistedBehaviorData"), Key(11)]
|
||||
public Dictionary<Guid, PersistentBehaviorData[]> PersistedBehaviors;
|
||||
|
||||
[JsonProperty("corporation"), Key(12)]
|
||||
public Guid Corporation;
|
||||
|
||||
[JsonProperty("name"), Key(13)]
|
||||
public string Name;
|
||||
|
||||
[JsonProperty("population"), Key(14)]
|
||||
public int Population;
|
||||
|
||||
[JsonProperty("personality"), Key(15)]
|
||||
public Dictionary<Guid, float> Personality = new Dictionary<Guid, float>();
|
||||
|
||||
// [IgnoreMember] protected List<IBehavior> Behaviors;
|
||||
[IgnoreMember] public Guid Zone;
|
||||
|
|
|
|||
|
|
@ -745,8 +745,12 @@ public class GameContext
|
|||
cargo.Select(c => c.ID).Concat(simpleCargo.Select(c => c.ID)), orbit.ID, zone, corporation)
|
||||
{
|
||||
Name = $"{loadoutData.Name} {Random.NextInt(1,255):X}",
|
||||
Temperature = 293
|
||||
Temperature = 293,
|
||||
Population = 1
|
||||
};
|
||||
var parentCorp = Cache.Get<MegaCorporation>(corpData.Parent);
|
||||
foreach (var attribute in parentCorp.Personality)
|
||||
entity.Personality[attribute.Key] = attribute.Value;
|
||||
Cache.Add(entity);
|
||||
|
||||
ZoneEntities[zone][entity.ID] = entity;
|
||||
|
|
|
|||
|
|
@ -40,37 +40,37 @@ public class ZoneData : DatabaseEntry, INamedEntry
|
|||
}
|
||||
}
|
||||
|
||||
[RethinkTable("Galaxy"), MessagePackObject, JsonObject(MemberSerialization.OptIn)]
|
||||
public class StationData : DatabaseEntry, INamedEntry
|
||||
{
|
||||
[JsonProperty("name"), Key(1)]
|
||||
public string Name;
|
||||
|
||||
// Can be Planet or Orbit
|
||||
[JsonProperty("parent"), Key(2)]
|
||||
public Guid Parent;
|
||||
|
||||
[JsonProperty("owner"), Key(3)]
|
||||
public Guid Owner;
|
||||
|
||||
[JsonProperty("inventory"), Key(4)]
|
||||
public List<ItemInstance> Inventory = new List<ItemInstance>();
|
||||
|
||||
[JsonProperty("buying"), Key(5)]
|
||||
public Dictionary<Guid, float> BuyPrices = new Dictionary<Guid, float>();
|
||||
|
||||
[JsonProperty("selling"), Key(6)]
|
||||
public Dictionary<Guid, float> SellPrices = new Dictionary<Guid, float>();
|
||||
|
||||
[JsonProperty("zone"), Key(7)]
|
||||
public Guid Zone;
|
||||
|
||||
[IgnoreMember] public string EntryName
|
||||
{
|
||||
get => Name;
|
||||
set => Name = value;
|
||||
}
|
||||
}
|
||||
// [RethinkTable("Galaxy"), MessagePackObject, JsonObject(MemberSerialization.OptIn)]
|
||||
// public class StationData : DatabaseEntry, INamedEntry
|
||||
// {
|
||||
// [JsonProperty("name"), Key(1)]
|
||||
// public string Name;
|
||||
//
|
||||
// // Can be Planet or Orbit
|
||||
// [JsonProperty("parent"), Key(2)]
|
||||
// public Guid Parent;
|
||||
//
|
||||
// [JsonProperty("owner"), Key(3)]
|
||||
// public Guid Owner;
|
||||
//
|
||||
// [JsonProperty("inventory"), Key(4)]
|
||||
// public List<ItemInstance> Inventory = new List<ItemInstance>();
|
||||
//
|
||||
// [JsonProperty("buying"), Key(5)]
|
||||
// public Dictionary<Guid, float> BuyPrices = new Dictionary<Guid, float>();
|
||||
//
|
||||
// [JsonProperty("selling"), Key(6)]
|
||||
// public Dictionary<Guid, float> SellPrices = new Dictionary<Guid, float>();
|
||||
//
|
||||
// [JsonProperty("zone"), Key(7)]
|
||||
// public Guid Zone;
|
||||
//
|
||||
// [IgnoreMember] public string EntryName
|
||||
// {
|
||||
// get => Name;
|
||||
// set => Name = value;
|
||||
// }
|
||||
// }
|
||||
|
||||
[RethinkTable("Galaxy"), MessagePackObject, JsonObject(MemberSerialization.OptIn)]
|
||||
public class PlanetData : DatabaseEntry, INamedEntry
|
||||
|
|
|
|||
|
|
@ -27,10 +27,12 @@ public class StrategyGameManager : MonoBehaviour
|
|||
public MeshRenderer ZoneBackground;
|
||||
public MeshRenderer ZoneBoundary;
|
||||
public ClickRaycaster ClickRaycaster;
|
||||
public ReadOnlyPropertiesPanel PropertiesPanel;
|
||||
public GameObject PropertiesPanelView;
|
||||
public PropertiesPanel PropertiesPanel;
|
||||
public ContextMenu ContextMenu;
|
||||
public RectTransform GameMenuRoot;
|
||||
public RectTransform CorpMenuRoot;
|
||||
public ColonyTab ColonyTab;
|
||||
public CorporationMenuItem CorpOptionPrefab;
|
||||
public TabButton CorpMenuContinueButton;
|
||||
public TMP_InputField CorpNameInputField;
|
||||
|
|
@ -41,6 +43,7 @@ public class StrategyGameManager : MonoBehaviour
|
|||
public TabButton GalaxyTabButton;
|
||||
public TabButton ZoneTabButton;
|
||||
public TabButton TechTabButton;
|
||||
public TabButton ColonyTabButton;
|
||||
|
||||
[Section("Prefabs & Prototypes")]
|
||||
public Prototype GalaxyZonePrototype;
|
||||
|
|
@ -104,6 +107,7 @@ public class StrategyGameManager : MonoBehaviour
|
|||
private Guid _selectedOrbit = Guid.Empty;
|
||||
private Guid _selectedTowingTarget = Guid.Empty;
|
||||
private float _orbitRadius;
|
||||
private Guid _selectedEntity;
|
||||
|
||||
void Start()
|
||||
{
|
||||
|
|
@ -115,6 +119,7 @@ public class StrategyGameManager : MonoBehaviour
|
|||
{
|
||||
_cache.Load(new DirectoryInfo(Application.dataPath).Parent.FullName);
|
||||
_context = new GameContext(_cache, Debug.Log);
|
||||
ColonyTab.Context = _context;
|
||||
TechTree.Context = _context;
|
||||
_context.MapLayers = _cache.GetAll<GalaxyMapLayerData>().ToDictionary(ml => ml.Name);
|
||||
_context.GalaxyZones = _cache.GetAll<ZoneData>()
|
||||
|
|
@ -206,6 +211,7 @@ public class StrategyGameManager : MonoBehaviour
|
|||
for(int i=0; i<loadout.Value; i++)
|
||||
entities.Add(_context.CreateEntity(_selectedZone, newCorp.ID, loadout.Key));
|
||||
var colony = entities.First(e => e is OrbitalEntity);
|
||||
_selectedEntity = colony.ID;
|
||||
foreach (var ship in entities.Where(e => e is Ship))
|
||||
{
|
||||
foreach (var controller in ship.GetBehaviors<ControllerBase>())
|
||||
|
|
@ -257,7 +263,7 @@ public class StrategyGameManager : MonoBehaviour
|
|||
_currentTab = button;
|
||||
if (_currentTab == GalaxyTabButton)
|
||||
{
|
||||
PropertiesPanel.gameObject.SetActive(true);
|
||||
PropertiesPanelView.gameObject.SetActive(true);
|
||||
PopulateGalaxyProperties();
|
||||
if (!_galaxyPopulated) PopulateGalaxy();
|
||||
Camera.transform.position = _galaxyCameraPos;
|
||||
|
|
@ -266,7 +272,7 @@ public class StrategyGameManager : MonoBehaviour
|
|||
|
||||
else if (_currentTab == ZoneTabButton)
|
||||
{
|
||||
PropertiesPanel.gameObject.SetActive(true);
|
||||
PropertiesPanelView.gameObject.SetActive(true);
|
||||
var zone = _cache.Get<ZoneData>(_selectedZone);
|
||||
if (_populatedZone != _selectedZone && zone != null)
|
||||
PopulateZone();
|
||||
|
|
@ -278,7 +284,7 @@ public class StrategyGameManager : MonoBehaviour
|
|||
|
||||
else if (_currentTab == TechTabButton)
|
||||
{
|
||||
PropertiesPanel.gameObject.SetActive(true);
|
||||
PropertiesPanelView.gameObject.SetActive(true);
|
||||
PopulateTechProperties();
|
||||
if (!_techLayoutGenerated)
|
||||
{
|
||||
|
|
@ -288,7 +294,12 @@ public class StrategyGameManager : MonoBehaviour
|
|||
}
|
||||
}
|
||||
|
||||
else PropertiesPanel.gameObject.SetActive(false);
|
||||
else PropertiesPanelView.gameObject.SetActive(false);
|
||||
|
||||
if (_currentTab == ColonyTabButton)
|
||||
{
|
||||
ColonyTab.Open(_selectedEntity);
|
||||
}
|
||||
};
|
||||
|
||||
_boundaryMaterial = ZoneBoundary.material;
|
||||
|
|
@ -464,7 +475,13 @@ public class StrategyGameManager : MonoBehaviour
|
|||
zoneOrbital.Icon.GetComponent<ClickableCollider>().OnClick += (collider, data) =>
|
||||
{
|
||||
if (data.button == PointerEventData.InputButton.Left)
|
||||
Select(orbital.ID);
|
||||
{
|
||||
_selectedEntity = orbital.ID;
|
||||
if (data.clickCount == 1)
|
||||
Select(orbital.ID);
|
||||
else if (data.clickCount == 2)
|
||||
ColonyTabButton.OnPointerClick(data);
|
||||
}
|
||||
else if (data.button == PointerEventData.InputButton.Right)
|
||||
ShowContextMenu(orbital.ID);
|
||||
};
|
||||
|
|
@ -714,9 +731,6 @@ public class StrategyGameManager : MonoBehaviour
|
|||
var equippedItems = entity.EquippedItems.Select(g => _context.Cache.Get<Gear>(g));
|
||||
foreach(var gear in equippedItems)
|
||||
PopulateGearProperties(gearList.AddList(gear.ItemData.Name), gear, entity);
|
||||
// gearList.AddProperty(gear.ItemData.Name);
|
||||
// var firstGear = equippedItems.First();
|
||||
// PopulateGearProperties(gearList.AddList(firstGear.ItemData.Name), firstGear, entity);
|
||||
if(!entity.Cargo.Any())
|
||||
PropertiesPanel.AddProperty("No Cargo");
|
||||
else
|
||||
|
|
@ -741,6 +755,8 @@ public class StrategyGameManager : MonoBehaviour
|
|||
PropertiesPanel.AddSection("Sector");
|
||||
PropertiesPanel.AddProperty("Planets", () => $"{zone.Planets.Length}");
|
||||
}
|
||||
|
||||
PropertiesPanel.RefreshValues();
|
||||
}
|
||||
|
||||
void PopulateGearProperties(PropertiesList panel, Gear gear, Entity entity)
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ public class TechTreeMsagl : MonoBehaviour
|
|||
public Prototype Arrow;
|
||||
|
||||
[Section("UI Links")]
|
||||
public ReadOnlyPropertiesPanel PropertiesPanel;
|
||||
public PropertiesPanel PropertiesPanel;
|
||||
|
||||
[Section("Graph Generation")]
|
||||
public bool TestMode;
|
||||
|
|
|
|||
95
Assets/Scripts/UI/ColonyTab.cs
Normal file
95
Assets/Scripts/UI/ColonyTab.cs
Normal file
|
|
@ -0,0 +1,95 @@
|
|||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using UnityEngine;
|
||||
|
||||
public class ColonyTab : MonoBehaviour
|
||||
{
|
||||
public PropertiesPanel General;
|
||||
public PropertiesPanel Inventory;
|
||||
public PropertiesPanel Details;
|
||||
|
||||
[HideInInspector]
|
||||
public GameContext Context;
|
||||
|
||||
private Guid _selectedColony;
|
||||
|
||||
public void Open(Guid colony)
|
||||
{
|
||||
_selectedColony = colony;
|
||||
|
||||
General.Clear();
|
||||
Inventory.Clear();
|
||||
Details.Clear();
|
||||
|
||||
var entity = Context.Cache.Get<Entity>(_selectedColony);
|
||||
|
||||
General.AddProperty("Capacity", () => $"{entity.OccupiedCapacity}/{entity.Capacity:0}");
|
||||
General.AddProperty("Mass", () => $"{entity.Mass.SignificantDigits(Context.GlobalData.SignificantDigits)}");
|
||||
General.AddProperty("Temperature", () => $"{entity.Temperature:0}°K");
|
||||
General.AddProperty("Energy", () => $"{entity.Energy:0}/{entity.GetBehaviors<Reactor>().First().Capacitance:0}");
|
||||
General.AddProperty("Population", () => $"{entity.Population}");
|
||||
General.AddSection("Personality");
|
||||
foreach (var attribute in entity.Personality)
|
||||
General.AddPersonalityProperty(Context.Cache.Get<PersonalityAttribute>(attribute.Key),
|
||||
() => attribute.Value);
|
||||
General.RefreshValues();
|
||||
|
||||
Inventory.ChildRadioSelection = true;
|
||||
Inventory.AddSection("Gear");
|
||||
var equippedItems = entity.EquippedItems.Select(g => Context.Cache.Get<Gear>(g));
|
||||
foreach(var gear in equippedItems)
|
||||
Inventory.AddProperty(gear.ItemData.Name, null, () => PopulateDetails(gear, entity));
|
||||
if(!entity.Cargo.Any())
|
||||
Inventory.AddSection("No Cargo");
|
||||
else
|
||||
{
|
||||
Inventory.AddSection("Cargo");
|
||||
foreach (var itemID in entity.Cargo)
|
||||
{
|
||||
var itemInstance = Context.Cache.Get<ItemInstance>(itemID);
|
||||
var data = Context.Cache.Get<ItemData>(itemInstance.Data);
|
||||
if(itemInstance is SimpleCommodity simpleCommodity)
|
||||
Inventory.AddProperty(data.Name, () => simpleCommodity.Quantity.ToString());
|
||||
else
|
||||
Inventory.AddProperty(data.Name);
|
||||
}
|
||||
}
|
||||
Inventory.RefreshValues();
|
||||
}
|
||||
|
||||
void PopulateDetails(ItemInstance item, Entity entity)
|
||||
{
|
||||
Details.Clear();
|
||||
if (item is Gear gear)
|
||||
{
|
||||
var data = gear.ItemData;
|
||||
Details.AddProperty("Durability",
|
||||
() =>
|
||||
$"{gear.Durability.SignificantDigits(Context.GlobalData.SignificantDigits)}/{Context.Evaluate(data.Durability, gear).SignificantDigits(Context.GlobalData.SignificantDigits)}");
|
||||
foreach (var behavior in data.Behaviors)
|
||||
{
|
||||
var type = behavior.GetType();
|
||||
if (type.GetCustomAttribute(typeof(RuntimeInspectable)) != null)
|
||||
{
|
||||
foreach (var field in type.GetFields().Where(f => f.GetCustomAttribute<RuntimeInspectable>() != null))
|
||||
{
|
||||
var fieldType = field.FieldType;
|
||||
if (fieldType == typeof(float))
|
||||
Details.AddProperty(field.Name, () => $"{((float) field.GetValue(behavior)).SignificantDigits(Context.GlobalData.SignificantDigits)}");
|
||||
else if (fieldType == typeof(int))
|
||||
Details.AddProperty(field.Name, () => $"{(int) field.GetValue(behavior)}");
|
||||
else if (fieldType == typeof(PerformanceStat))
|
||||
{
|
||||
var stat = (PerformanceStat) field.GetValue(behavior);
|
||||
Details.AddProperty(field.Name, () => $"{Context.Evaluate(stat, gear, entity).SignificantDigits(Context.GlobalData.SignificantDigits)}");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Details.RefreshValues();
|
||||
}
|
||||
}
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 8c2bf4a7080061d42a87046c37bf0c60
|
||||
guid: 69422316520cbd649ad89629be288c06
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
|
|
@ -5,7 +5,7 @@ using TMPro;
|
|||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
public class PropertiesList : ReadOnlyPropertiesPanel
|
||||
public class PropertiesList : PropertiesPanel
|
||||
{
|
||||
public Image FoldoutIcon;
|
||||
public float FoldoutRotationDamping;
|
||||
|
|
|
|||
|
|
@ -3,214 +3,255 @@ using System.Collections;
|
|||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Reflection.Emit;
|
||||
using System.Text.RegularExpressions;
|
||||
using JM.LinqFaster;
|
||||
using TMPro;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
public class PropertiesPanel : MonoBehaviour
|
||||
{
|
||||
public Prototype LabelField;
|
||||
public Prototype FreeFloatField;
|
||||
public Prototype RangedFloatField;
|
||||
public Prototype EnumField;
|
||||
public Prototype BoolField;
|
||||
public Prototype ColorField;
|
||||
public Prototype Divider;
|
||||
public TextMeshProUGUI Title;
|
||||
public RectTransform SectionPrefab;
|
||||
public PropertiesList ListPrefab;
|
||||
public PropertyLabel PropertyPrefab;
|
||||
public AttributeProperty AttributePrefab;
|
||||
public InputField InputField;
|
||||
public RangedFloatField RangedFloatField;
|
||||
public EnumField EnumField;
|
||||
public BoolField BoolField;
|
||||
public bool ChildRadioSelection;
|
||||
|
||||
public int ResolutionExponentMinumum = 6;
|
||||
public int ResolutionExponentCount = 5;
|
||||
protected List<GameObject> Properties = new List<GameObject>();
|
||||
protected List<FlatFlatButton> Buttons = new List<FlatFlatButton>();
|
||||
protected FlatFlatButton SelectedChild;
|
||||
protected event Action RefreshPropertyValues;
|
||||
|
||||
private void Update()
|
||||
{
|
||||
RefreshValues();
|
||||
}
|
||||
|
||||
public void Clear()
|
||||
{
|
||||
foreach(var property in Properties)
|
||||
Destroy(property);
|
||||
Properties.Clear();
|
||||
Buttons.Clear();
|
||||
SelectedChild = null;
|
||||
RefreshPropertyValues = null;
|
||||
}
|
||||
|
||||
public void Deselect()
|
||||
{
|
||||
if (SelectedChild != null)
|
||||
SelectedChild.CurrentState = FlatButtonState.Unselected;
|
||||
SelectedChild = null;
|
||||
}
|
||||
|
||||
public RectTransform AddSection(string name)
|
||||
{
|
||||
var section = Instantiate(SectionPrefab, transform);
|
||||
section.GetComponentInChildren<TextMeshProUGUI>().text = name;
|
||||
Properties.Add(section.gameObject);
|
||||
return section;
|
||||
}
|
||||
|
||||
public PropertyLabel AddProperty(string name, Func<string> read = null, Action onClick = null)
|
||||
{
|
||||
var property = Instantiate(PropertyPrefab, transform);
|
||||
property.Name.text = name;
|
||||
if (ChildRadioSelection)
|
||||
{
|
||||
Buttons.Add(property.Button);
|
||||
property.Button.OnClick += () =>
|
||||
{
|
||||
if (SelectedChild != null)
|
||||
SelectedChild.CurrentState = FlatButtonState.Unselected;
|
||||
SelectedChild = property.Button;
|
||||
SelectedChild.CurrentState = FlatButtonState.Selected;
|
||||
onClick?.Invoke();
|
||||
};
|
||||
}
|
||||
else if(onClick!=null) property.Button.OnClick += onClick;
|
||||
RefreshPropertyValues += () => property.Value.text = read?.Invoke() ?? "";
|
||||
Properties.Add(property.gameObject);
|
||||
return property;
|
||||
}
|
||||
|
||||
public PropertiesList AddList(string name) //, IEnumerable<(string, Func<string>)> elements)
|
||||
{
|
||||
var list = Instantiate(ListPrefab, transform);
|
||||
list.Title.text = name;
|
||||
// foreach (var element in elements)
|
||||
// {
|
||||
// var item = Instantiate(PropertyPrefab, list);
|
||||
// item.Name.text = element.Item1;
|
||||
// item.Value.text = element.Item2();
|
||||
// item.ValueFunction = element.Item2;
|
||||
// Properties.Add(item.gameObject);
|
||||
// }
|
||||
RefreshPropertyValues += () => list.RefreshValues();
|
||||
Properties.Add(list.gameObject);
|
||||
return list;
|
||||
}
|
||||
|
||||
public AttributeProperty AddPersonalityProperty(PersonalityAttribute attribute, Func<float> read)
|
||||
{
|
||||
var attributeInstance = Instantiate(AttributePrefab, transform);
|
||||
attributeInstance.Title.text = attribute.Name;
|
||||
attributeInstance.HighLabel.text = attribute.HighName;
|
||||
attributeInstance.LowLabel.text = attribute.LowName;
|
||||
RefreshPropertyValues += () => attributeInstance.Slider.value = read();
|
||||
Properties.Add(attributeInstance.gameObject);
|
||||
return attributeInstance;
|
||||
}
|
||||
|
||||
private readonly List<Prototype> _propertyFields = new List<Prototype>();
|
||||
private event EventHandler RefreshPropertyValues;
|
||||
|
||||
public void Clear()
|
||||
public void AddProperty(string name, Func<string> read, Action<string> write)
|
||||
{
|
||||
foreach (var property in _propertyFields.ReverseF())
|
||||
{
|
||||
property.ReturnToPool();
|
||||
}
|
||||
|
||||
RefreshPropertyValues = null;
|
||||
var field = Instantiate(InputField, transform);
|
||||
field.Label.text = name;
|
||||
field.Field.contentType = TMP_InputField.ContentType.Standard;
|
||||
field.Field.onValueChanged.AddListener(val => write(val));
|
||||
RefreshPropertyValues += () => field.Field.text = read();
|
||||
Properties.Add(field.gameObject);
|
||||
}
|
||||
|
||||
public void Inspect(object obj, bool inspectablesOnly = false, bool readWrite = false, bool topLevel = false)
|
||||
public void AddProperty(string name, Func<float> read, Action<float> write)
|
||||
{
|
||||
if(topLevel)
|
||||
Clear();
|
||||
|
||||
var fields = obj.GetType().GetFields();
|
||||
foreach (var field in fields)
|
||||
Inspect(obj, field, inspectablesOnly, readWrite);
|
||||
|
||||
if(topLevel)
|
||||
foreach (var field in _propertyFields)
|
||||
field.transform.SetSiblingIndex(_propertyFields.IndexOf(field));
|
||||
|
||||
RefreshValues();
|
||||
}
|
||||
|
||||
public void Inspect(object obj, FieldInfo field, bool inspectablesOnly = false, bool readWrite = false)
|
||||
{
|
||||
var inspectable = field.GetCustomAttribute<InspectableFieldAttribute>();
|
||||
if (inspectable == null && inspectablesOnly) return;
|
||||
var type = field.FieldType;
|
||||
|
||||
if (type == typeof(float))
|
||||
{
|
||||
if (readWrite)
|
||||
{
|
||||
var ranged = inspectable as RangedFloatInspectableAttribute;
|
||||
if (ranged != null)
|
||||
Inspect(field.Name.SplitCamelCase(), () => (float) field.GetValue(obj), f => field.SetValue(obj, f),
|
||||
ranged.Min, ranged.Max);
|
||||
else
|
||||
Inspect(field.Name.SplitCamelCase(), () => (float) field.GetValue(obj), f => field.SetValue(obj, f));
|
||||
} else Inspect(field.Name.SplitCamelCase(), () => ((float) field.GetValue(obj)).ToString("0.##"));
|
||||
}
|
||||
else if (type == typeof(int))
|
||||
{
|
||||
if (readWrite)
|
||||
{
|
||||
var ranged = inspectable as RangedIntInspectableAttribute;
|
||||
if (ranged != null)
|
||||
Inspect(field.Name.SplitCamelCase(), () => (int) field.GetValue(obj), f => field.SetValue(obj, f),
|
||||
ranged.Min, ranged.Max);
|
||||
else
|
||||
Inspect(field.Name.SplitCamelCase(), () => (int) field.GetValue(obj), f => field.SetValue(obj, f));
|
||||
} else Inspect(field.Name.SplitCamelCase(), () => ((int) field.GetValue(obj)).ToString());
|
||||
}
|
||||
else if (type.IsEnum)
|
||||
{
|
||||
if (readWrite)
|
||||
Inspect(field.Name.SplitCamelCase(), () => (int) field.GetValue(obj), i => field.SetValue(obj, i),
|
||||
Enum.GetNames(field.FieldType));
|
||||
else
|
||||
Inspect(field.Name.SplitCamelCase(), () => Enum.GetName(type, field.GetValue(obj)).SplitCamelCase());
|
||||
}
|
||||
else if (type == typeof(string))
|
||||
{
|
||||
if (readWrite)
|
||||
Inspect(field.Name.SplitCamelCase(), () => (string) field.GetValue(obj), i => field.SetValue(obj, i));
|
||||
else
|
||||
Inspect(field.Name.SplitCamelCase(), () => (string) field.GetValue(obj));
|
||||
}
|
||||
//else if (field.FieldType == typeof(Color)) Inspect(field.Name, () => (Color) field.GetValue(obj), c => field.SetValue(obj, c));
|
||||
else if (field.FieldType == typeof(bool)) Inspect(field.Name, () => (bool) field.GetValue(obj), b => field.SetValue(obj, b));
|
||||
else if (type.GetCustomAttribute<InspectableFieldAttribute>() != null)
|
||||
{
|
||||
if(!_propertyFields.Any() || !_propertyFields.Last().gameObject.name.ToUpper().Contains("DIVIDER"))
|
||||
_propertyFields.Add(Divider.Instantiate<Prototype>());
|
||||
Inspect(field.GetValue(obj), inspectablesOnly, readWrite);
|
||||
}
|
||||
else
|
||||
Debug.Log($"Field \"{field.Name}\" has unknown type {field.FieldType.Name}. No inspector was generated.");
|
||||
}
|
||||
|
||||
public void Inspect(string name, Func<string> read)
|
||||
{
|
||||
var labelFieldInstance = LabelField.Instantiate<Prototype>();
|
||||
_propertyFields.Add(labelFieldInstance);
|
||||
labelFieldInstance.transform.Find("Label").GetComponent<TextMeshProUGUI>().text = name;
|
||||
var field = labelFieldInstance.transform.Find("Field").GetComponent<TextMeshProUGUI>();
|
||||
field.text = read();
|
||||
RefreshPropertyValues += (sender, args) => field.text = read();
|
||||
}
|
||||
|
||||
public void Inspect(string name, Func<float> read, Action<float> write)
|
||||
{
|
||||
var freeFloatFieldInstance = FreeFloatField.Instantiate<Prototype>();
|
||||
_propertyFields.Add(freeFloatFieldInstance);
|
||||
freeFloatFieldInstance.transform.Find("Label").GetComponent<TextMeshProUGUI>().text = name;
|
||||
var inputField = freeFloatFieldInstance.GetComponentInChildren<TMP_InputField>();
|
||||
inputField.contentType = TMP_InputField.ContentType.DecimalNumber;
|
||||
inputField.onValueChanged.AddListener(val => write(float.Parse(val)));
|
||||
RefreshPropertyValues += (sender, args) => inputField.text = read().ToString(CultureInfo.InvariantCulture);
|
||||
}
|
||||
|
||||
public void Inspect(string name, Func<string> read, Action<string> write)
|
||||
{
|
||||
var freeFloatFieldInstance = FreeFloatField.Instantiate<Prototype>();
|
||||
_propertyFields.Add(freeFloatFieldInstance);
|
||||
freeFloatFieldInstance.transform.Find("Label").GetComponent<TextMeshProUGUI>().text = name;
|
||||
var inputField = freeFloatFieldInstance.GetComponentInChildren<TMP_InputField>();
|
||||
inputField.contentType = TMP_InputField.ContentType.Standard;
|
||||
inputField.onValueChanged.AddListener(val => write(val));
|
||||
RefreshPropertyValues += (sender, args) => inputField.text = read();
|
||||
var field = Instantiate(InputField, transform);
|
||||
field.Label.text = name;
|
||||
field.Field.contentType = TMP_InputField.ContentType.DecimalNumber;
|
||||
field.Field.onValueChanged.AddListener(val => write(float.Parse(val)));
|
||||
RefreshPropertyValues += () => field.Field.text = read().ToString(CultureInfo.InvariantCulture);
|
||||
Properties.Add(field.gameObject);
|
||||
}
|
||||
|
||||
public void Inspect(string name, Func<float> read, Action<float> write, float min, float max)
|
||||
public void AddProperty(string name, Func<int> read, Action<int> write)
|
||||
{
|
||||
var rangedFloatFieldInstance = RangedFloatField.Instantiate<Prototype>();
|
||||
_propertyFields.Add(rangedFloatFieldInstance);
|
||||
rangedFloatFieldInstance.transform.Find("Label").GetComponent<TextMeshProUGUI>().text = name;
|
||||
var slider = rangedFloatFieldInstance.GetComponentInChildren<Slider>();
|
||||
slider.minValue = min;
|
||||
slider.maxValue = max;
|
||||
slider.onValueChanged.AddListener(val => write(val));
|
||||
RefreshPropertyValues += (sender, args) => slider.value = read();
|
||||
var field = Instantiate(InputField, transform);
|
||||
field.Label.text = name;
|
||||
field.Field.contentType = TMP_InputField.ContentType.IntegerNumber;
|
||||
field.Field.onValueChanged.AddListener(val => write(int.Parse(val)));
|
||||
RefreshPropertyValues += () => field.Field.text = read().ToString(CultureInfo.InvariantCulture);
|
||||
Properties.Add(field.gameObject);
|
||||
}
|
||||
|
||||
public void AddProperty(string name, Func<float> read, Action<float> write, float min, float max)
|
||||
{
|
||||
var field = Instantiate(RangedFloatField, transform);
|
||||
field.Label.text = name;
|
||||
field.Slider.wholeNumbers = false;
|
||||
field.Slider.minValue = min;
|
||||
field.Slider.maxValue = max;
|
||||
field.Slider.onValueChanged.AddListener(val => write(val));
|
||||
RefreshPropertyValues += () => field.Slider.value = read();
|
||||
Properties.Add(field.gameObject);
|
||||
}
|
||||
|
||||
public void AddProperty(string name, Func<int> read, Action<int> write, int min, int max)
|
||||
{
|
||||
var field = Instantiate(RangedFloatField, transform);
|
||||
field.Label.text = name;
|
||||
field.Slider.wholeNumbers = true;
|
||||
field.Slider.minValue = min;
|
||||
field.Slider.maxValue = max;
|
||||
field.Slider.onValueChanged.AddListener(val => write(Mathf.RoundToInt(val)));
|
||||
RefreshPropertyValues += () => field.Slider.value = read();
|
||||
Properties.Add(field.gameObject);
|
||||
}
|
||||
|
||||
public void AddProperty(string name, Func<bool> read, Action<bool> write)
|
||||
{
|
||||
var field = Instantiate(BoolField, transform);
|
||||
field.Label.text = name;
|
||||
field.Toggle.onValueChanged.AddListener(val => write(val));
|
||||
RefreshPropertyValues += () => field.Toggle.isOn = read();
|
||||
Properties.Add(field.gameObject);
|
||||
}
|
||||
|
||||
public void AddProperty(string name, Func<int> read, Action<int> write, string[] enumOptions)
|
||||
{
|
||||
var field = Instantiate(EnumField, transform);
|
||||
field.Label.text = name;
|
||||
field.Dropdown.options = enumOptions.Select(s => new TMP_Dropdown.OptionData(s)).ToList();
|
||||
field.Dropdown.onValueChanged.AddListener(val => write(val));
|
||||
RefreshPropertyValues += () => field.Dropdown.value = read();
|
||||
Properties.Add(field.gameObject);
|
||||
}
|
||||
|
||||
public void Inspect(string name, Func<int> read, Action<int> write)
|
||||
{
|
||||
var freeFloatFieldInstance = FreeFloatField.Instantiate<Prototype>();
|
||||
_propertyFields.Add(freeFloatFieldInstance);
|
||||
freeFloatFieldInstance.transform.Find("Label").GetComponent<TextMeshProUGUI>().text = name;
|
||||
var inputField = freeFloatFieldInstance.GetComponentInChildren<TMP_InputField>();
|
||||
inputField.contentType = TMP_InputField.ContentType.IntegerNumber;
|
||||
inputField.onValueChanged.AddListener(val => write(int.Parse(val)));
|
||||
RefreshPropertyValues += (sender, args) => inputField.text = read().ToString(CultureInfo.InvariantCulture);
|
||||
}
|
||||
|
||||
public void Inspect(string name, Func<int> read, Action<int> write, int min, int max)
|
||||
{
|
||||
var rangedFloatFieldInstance = RangedFloatField.Instantiate<Prototype>();
|
||||
_propertyFields.Add(rangedFloatFieldInstance);
|
||||
rangedFloatFieldInstance.transform.Find("Label").GetComponent<TextMeshProUGUI>().text = name;
|
||||
var slider = rangedFloatFieldInstance.GetComponentInChildren<Slider>();
|
||||
slider.wholeNumbers = true;
|
||||
slider.minValue = min;
|
||||
slider.maxValue = max;
|
||||
slider.onValueChanged.AddListener(val => write(Mathf.RoundToInt(val)));
|
||||
RefreshPropertyValues += (sender, args) => slider.value = read();
|
||||
}
|
||||
|
||||
// public void Inspect(string name, Func<Color> read, Action<Color> write)
|
||||
// public void Inspect(object obj, bool inspectablesOnly = false, bool readWrite = false, bool topLevel = true)
|
||||
// {
|
||||
// var colorFieldInstance = ColorField.Instantiate<Prototype>();
|
||||
// _propertyFields.Add(colorFieldInstance);
|
||||
// colorFieldInstance.transform.Find("Label").GetComponent<TextMeshProUGUI>().text = name;
|
||||
// var colorButton = colorFieldInstance.GetComponentInChildren<ColorButton>();
|
||||
// colorButton.OnColorChanged.AddListener(col => write(col));
|
||||
// RefreshPropertyValues += (sender, args) => colorButton.GetComponent<Image>().color = read();
|
||||
// if(topLevel)
|
||||
// Clear();
|
||||
//
|
||||
// var fields = obj.GetType().GetFields();
|
||||
// foreach (var field in fields)
|
||||
// Inspect(obj, field, inspectablesOnly, readWrite);
|
||||
//
|
||||
// if(topLevel)
|
||||
// foreach (var field in _propertyFields)
|
||||
// field.transform.SetSiblingIndex(_propertyFields.IndexOf(field));
|
||||
//
|
||||
// RefreshValues();
|
||||
// }
|
||||
//
|
||||
// public void Inspect(object obj, FieldInfo field, bool inspectablesOnly = false, bool readWrite = false)
|
||||
// {
|
||||
// var inspectable = field.GetCustomAttribute<InspectableFieldAttribute>();
|
||||
// if (inspectable == null && inspectablesOnly) return;
|
||||
// var type = field.FieldType;
|
||||
//
|
||||
// if (type == typeof(float))
|
||||
// {
|
||||
// if (readWrite)
|
||||
// {
|
||||
// var ranged = inspectable as RangedFloatInspectableAttribute;
|
||||
// if (ranged != null)
|
||||
// Inspect(field.Name.SplitCamelCase(), () => (float) field.GetValue(obj), f => field.SetValue(obj, f),
|
||||
// ranged.Min, ranged.Max);
|
||||
// else
|
||||
// Inspect(field.Name.SplitCamelCase(), () => (float) field.GetValue(obj), f => field.SetValue(obj, f));
|
||||
// } else Inspect(field.Name.SplitCamelCase(), () => ((float) field.GetValue(obj)).ToString("0.##"));
|
||||
// }
|
||||
// else if (type == typeof(int))
|
||||
// {
|
||||
// if (readWrite)
|
||||
// {
|
||||
// var ranged = inspectable as RangedIntInspectableAttribute;
|
||||
// if (ranged != null)
|
||||
// Inspect(field.Name.SplitCamelCase(), () => (int) field.GetValue(obj), f => field.SetValue(obj, f),
|
||||
// ranged.Min, ranged.Max);
|
||||
// else
|
||||
// Inspect(field.Name.SplitCamelCase(), () => (int) field.GetValue(obj), f => field.SetValue(obj, f));
|
||||
// } else Inspect(field.Name.SplitCamelCase(), () => ((int) field.GetValue(obj)).ToString());
|
||||
// }
|
||||
// else if (type.IsEnum)
|
||||
// {
|
||||
// if (readWrite)
|
||||
// Inspect(field.Name.SplitCamelCase(), () => (int) field.GetValue(obj), i => field.SetValue(obj, i),
|
||||
// Enum.GetNames(field.FieldType));
|
||||
// else
|
||||
// Inspect(field.Name.SplitCamelCase(), () => Enum.GetName(type, field.GetValue(obj)).SplitCamelCase());
|
||||
// }
|
||||
// else if (type == typeof(string))
|
||||
// {
|
||||
// if (readWrite)
|
||||
// Inspect(field.Name.SplitCamelCase(), () => (string) field.GetValue(obj), i => field.SetValue(obj, i));
|
||||
// else
|
||||
// Inspect(field.Name.SplitCamelCase(), () => (string) field.GetValue(obj));
|
||||
// }
|
||||
// //else if (field.FieldType == typeof(Color)) Inspect(field.Name, () => (Color) field.GetValue(obj), c => field.SetValue(obj, c));
|
||||
// else if (field.FieldType == typeof(bool)) Inspect(field.Name, () => (bool) field.GetValue(obj), b => field.SetValue(obj, b));
|
||||
// else if (type.GetCustomAttribute<InspectableFieldAttribute>() != null)
|
||||
// {
|
||||
// if(!_propertyFields.Any() || !_propertyFields.Last().gameObject.name.ToUpper().Contains("DIVIDER"))
|
||||
// _propertyFields.Add(Divider.Instantiate<Prototype>());
|
||||
// Inspect(field.GetValue(obj), inspectablesOnly, readWrite, false);
|
||||
// }
|
||||
// else
|
||||
// Debug.Log($"Field \"{field.Name}\" has unknown type {field.FieldType.Name}. No inspector was generated.");
|
||||
// }
|
||||
|
||||
public void Inspect(string name, Func<bool> read, Action<bool> write)
|
||||
{
|
||||
var boolFieldInstance = BoolField.Instantiate<Prototype>();
|
||||
_propertyFields.Add(boolFieldInstance);
|
||||
boolFieldInstance.transform.Find("Label").GetComponent<TextMeshProUGUI>().text = name;
|
||||
var toggle = boolFieldInstance.GetComponentInChildren<Toggle>();
|
||||
toggle.onValueChanged.AddListener(val => write(val));
|
||||
RefreshPropertyValues += (sender, args) => toggle.isOn = read();
|
||||
}
|
||||
|
||||
public void Inspect(string name, Func<int> read, Action<int> write, string[] enumOptions)
|
||||
{
|
||||
var enumFieldInstance = EnumField.Instantiate<Prototype>();
|
||||
_propertyFields.Add(enumFieldInstance);
|
||||
enumFieldInstance.transform.Find("Label").GetComponent<TextMeshProUGUI>().text = name;
|
||||
var dropDown = enumFieldInstance.GetComponentInChildren<TMP_Dropdown>();
|
||||
dropDown.options = enumOptions.Select(s => new TMP_Dropdown.OptionData(s)).ToList();
|
||||
dropDown.onValueChanged.AddListener(val => write(val));
|
||||
RefreshPropertyValues += (sender, args) => dropDown.value = read();
|
||||
}
|
||||
|
||||
public void RefreshValues()
|
||||
{
|
||||
RefreshPropertyValues?.Invoke(this, EventArgs.Empty);
|
||||
RefreshPropertyValues?.Invoke();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 522d91e5cc66d574486096884d806861
|
||||
guid: 8c2bf4a7080061d42a87046c37bf0c60
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
|
|
|
|||
|
|
@ -8,12 +8,5 @@ public class PropertyLabel : MonoBehaviour
|
|||
{
|
||||
public TextMeshProUGUI Name;
|
||||
public TextMeshProUGUI Value;
|
||||
public Func<string> ValueFunction;
|
||||
public FlatFlatButton Button;
|
||||
|
||||
private void Update()
|
||||
{
|
||||
if(ValueFunction != null)
|
||||
Value.text = ValueFunction();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,170 +0,0 @@
|
|||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using TMPro;
|
||||
using UnityEngine;
|
||||
|
||||
public class ReadOnlyPropertiesPanel : MonoBehaviour
|
||||
{
|
||||
public TextMeshProUGUI Title;
|
||||
public RectTransform SectionPrefab;
|
||||
public PropertiesList ListPrefab;
|
||||
public PropertyLabel PropertyPrefab;
|
||||
public AttributeProperty AttributePrefab;
|
||||
public InputField InputField;
|
||||
public RangedFloatField RangedFloatField;
|
||||
public EnumField EnumField;
|
||||
public BoolField BoolField;
|
||||
public bool ChildRadioSelection;
|
||||
|
||||
protected List<GameObject> Properties = new List<GameObject>();
|
||||
protected List<FlatFlatButton> Buttons = new List<FlatFlatButton>();
|
||||
protected FlatFlatButton SelectedChild;
|
||||
protected event Action RefreshPropertyValues;
|
||||
|
||||
public void Clear()
|
||||
{
|
||||
foreach(var property in Properties)
|
||||
Destroy(property);
|
||||
Properties.Clear();
|
||||
Buttons.Clear();
|
||||
SelectedChild = null;
|
||||
}
|
||||
|
||||
public PropertyLabel AddProperty(string name, Func<string> value = null, Action onClick = null)
|
||||
{
|
||||
var property = Instantiate(PropertyPrefab, transform);
|
||||
property.Name.text = name;
|
||||
property.Value.text = value?.Invoke() ?? "";
|
||||
property.ValueFunction = value;
|
||||
if (ChildRadioSelection)
|
||||
{
|
||||
Buttons.Add(property.Button);
|
||||
property.Button.OnClick += () =>
|
||||
{
|
||||
if (SelectedChild != null)
|
||||
SelectedChild.CurrentState = FlatButtonState.Unselected;
|
||||
SelectedChild = property.Button;
|
||||
SelectedChild.CurrentState = FlatButtonState.Selected;
|
||||
onClick?.Invoke();
|
||||
};
|
||||
}
|
||||
else if(onClick!=null) property.Button.OnClick += onClick;
|
||||
Properties.Add(property.gameObject);
|
||||
return property;
|
||||
}
|
||||
|
||||
public RectTransform AddSection(string name)
|
||||
{
|
||||
var section = Instantiate(SectionPrefab, transform);
|
||||
section.GetComponentInChildren<TextMeshProUGUI>().text = name;
|
||||
Properties.Add(section.gameObject);
|
||||
return section;
|
||||
}
|
||||
|
||||
public PropertiesList AddList(string name) //, IEnumerable<(string, Func<string>)> elements)
|
||||
{
|
||||
var list = Instantiate(ListPrefab, transform);
|
||||
list.Title.text = name;
|
||||
// foreach (var element in elements)
|
||||
// {
|
||||
// var item = Instantiate(PropertyPrefab, list);
|
||||
// item.Name.text = element.Item1;
|
||||
// item.Value.text = element.Item2();
|
||||
// item.ValueFunction = element.Item2;
|
||||
// Properties.Add(item.gameObject);
|
||||
// }
|
||||
Properties.Add(list.gameObject);
|
||||
return list;
|
||||
}
|
||||
|
||||
public AttributeProperty AddAttribute(PersonalityAttribute attribute, float value)
|
||||
{
|
||||
var attributeInstance = Instantiate(AttributePrefab, transform);
|
||||
attributeInstance.Slider.value = value;
|
||||
attributeInstance.Title.text = attribute.Name;
|
||||
attributeInstance.HighLabel.text = attribute.HighName;
|
||||
attributeInstance.LowLabel.text = attribute.LowName;
|
||||
return attributeInstance;
|
||||
}
|
||||
|
||||
public void AddProperty(string name, Func<string> read, Action<string> write)
|
||||
{
|
||||
var field = Instantiate(InputField, transform);
|
||||
field.Label.text = name;
|
||||
field.Field.contentType = TMP_InputField.ContentType.Standard;
|
||||
field.Field.onValueChanged.AddListener(val => write(val));
|
||||
RefreshPropertyValues += () => field.Field.text = read();
|
||||
Properties.Add(field.gameObject);
|
||||
}
|
||||
|
||||
public void AddProperty(string name, Func<float> read, Action<float> write)
|
||||
{
|
||||
var field = Instantiate(InputField, transform);
|
||||
field.Label.text = name;
|
||||
field.Field.contentType = TMP_InputField.ContentType.DecimalNumber;
|
||||
field.Field.onValueChanged.AddListener(val => write(float.Parse(val)));
|
||||
RefreshPropertyValues += () => field.Field.text = read().ToString(CultureInfo.InvariantCulture);
|
||||
Properties.Add(field.gameObject);
|
||||
}
|
||||
|
||||
public void AddProperty(string name, Func<int> read, Action<int> write)
|
||||
{
|
||||
var field = Instantiate(InputField, transform);
|
||||
field.Label.text = name;
|
||||
field.Field.contentType = TMP_InputField.ContentType.IntegerNumber;
|
||||
field.Field.onValueChanged.AddListener(val => write(int.Parse(val)));
|
||||
RefreshPropertyValues += () => field.Field.text = read().ToString(CultureInfo.InvariantCulture);
|
||||
Properties.Add(field.gameObject);
|
||||
}
|
||||
|
||||
public void AddProperty(string name, Func<float> read, Action<float> write, float min, float max)
|
||||
{
|
||||
var field = Instantiate(RangedFloatField, transform);
|
||||
field.Label.text = name;
|
||||
field.Slider.wholeNumbers = false;
|
||||
field.Slider.minValue = min;
|
||||
field.Slider.maxValue = max;
|
||||
field.Slider.onValueChanged.AddListener(val => write(val));
|
||||
RefreshPropertyValues += () => field.Slider.value = read();
|
||||
Properties.Add(field.gameObject);
|
||||
}
|
||||
|
||||
public void AddProperty(string name, Func<int> read, Action<int> write, int min, int max)
|
||||
{
|
||||
var field = Instantiate(RangedFloatField, transform);
|
||||
field.Label.text = name;
|
||||
field.Slider.wholeNumbers = true;
|
||||
field.Slider.minValue = min;
|
||||
field.Slider.maxValue = max;
|
||||
field.Slider.onValueChanged.AddListener(val => write(Mathf.RoundToInt(val)));
|
||||
RefreshPropertyValues += () => field.Slider.value = read();
|
||||
Properties.Add(field.gameObject);
|
||||
}
|
||||
|
||||
public void AddProperty(string name, Func<bool> read, Action<bool> write)
|
||||
{
|
||||
var field = Instantiate(BoolField, transform);
|
||||
field.Label.text = name;
|
||||
field.Toggle.onValueChanged.AddListener(val => write(val));
|
||||
RefreshPropertyValues += () => field.Toggle.isOn = read();
|
||||
Properties.Add(field.gameObject);
|
||||
}
|
||||
|
||||
public void AddProperty(string name, Func<int> read, Action<int> write, string[] enumOptions)
|
||||
{
|
||||
var field = Instantiate(EnumField, transform);
|
||||
field.Label.text = name;
|
||||
field.Dropdown.options = enumOptions.Select(s => new TMP_Dropdown.OptionData(s)).ToList();
|
||||
field.Dropdown.onValueChanged.AddListener(val => write(val));
|
||||
RefreshPropertyValues += () => field.Dropdown.value = read();
|
||||
Properties.Add(field.gameObject);
|
||||
}
|
||||
|
||||
public void RefreshValues()
|
||||
{
|
||||
RefreshPropertyValues?.Invoke();
|
||||
}
|
||||
}
|
||||
Loading…
Reference in a new issue