Files
riversong-code-showcase/Source/Riversong/Game/UI/Panels/PopulationPanel/PopulationPanelUIView.cs
2026-05-21 16:04:49 +02:00

113 lines
3.8 KiB
C#

using System.Collections.Generic;
using Cysharp.Threading.Tasks;
using Unity.Mathematics;
using UnityEngine;
using UnityEngine.UIElements;
namespace DanieleMarotta.RiversongCodeShowcase
{
[UIView("population-panel")]
public class PopulationPanelUIView : UIView<PopulationPanelModel>
{
private Label _populationLabel;
private VisualElement _happinessIcon;
private Label _happinessLabel;
private List<VisualElement> _laborTier;
private float _happinessIconScale = 1;
public override UniTask InitializeAsync(UIService uiService, VisualElement rootElement)
{
base.InitializeAsync(uiService, rootElement);
_populationLabel = rootElement.Q<Label>(className: "population-panel__population-label");
_happinessIcon = rootElement.Q<VisualElement>(className: "population-panel__happiness-icon");
_happinessLabel = rootElement.Q<Label>(className: "population-panel__happiness-label");
_laborTier = rootElement.Query<VisualElement>(className: "population-panel__labor-dot").ToList();
return UniTask.CompletedTask;
}
protected override void OnNewModel(PopulationPanelModel model)
{
base.OnNewModel(model);
UpdatePopulationLabel();
UpdateHappinessLabel();
UpdateLaborRating();
}
protected override void OnModelPropertyChanged(object sender, BindablePropertyChangedEventArgs e)
{
base.OnModelPropertyChanged(sender, e);
switch (e.propertyName)
{
case nameof(PopulationPanelModel.Population):
UpdatePopulationLabel();
break;
case nameof(PopulationPanelModel.Happiness):
UpdateHappinessLabel();
break;
case nameof(PopulationPanelModel.LaborTier):
UpdateLaborRating();
break;
}
}
private void UpdatePopulationLabel()
{
_populationLabel.text = Model.Population.ToString();
}
private void UpdateHappinessLabel()
{
_happinessLabel.text = Model.Happiness.ToString();
}
private void UpdateLaborRating()
{
var ratingClass = Model.LaborTier switch
{
LaborTier.Medium => "medium",
LaborTier.High => "high",
_ => "low"
};
foreach (var element in _laborTier)
{
element.RemoveFromClassList("low");
element.RemoveFromClassList("medium");
element.RemoveFromClassList("high");
element.AddToClassList(ratingClass);
}
var rating = math.clamp((int)Model.LaborTier, 0, _laborTier.Count);
for (var i = 0; i < _laborTier.Count; i++) _laborTier[i].EnableInClassList("empty", i >= rating);
}
public void UpdateHappinessIconAnimation()
{
var normalizedHappiness = Model.Happiness * 0.01f;
const float minSpeed = 1.8f;
const float maxSpeed = 2.4f;
var speed = math.lerp(minSpeed, maxSpeed, normalizedHappiness);
const float minAmplitude = 0.03f;
const float maxAmplitude = 0.06f;
var amplitude = math.lerp(minAmplitude, maxAmplitude, normalizedHappiness);
if (normalizedHappiness > 0.98f) amplitude *= 1.15f;
var targetScale = 1 + amplitude * 0.5f * (1 + math.sin(Time.unscaledTime * speed));
_happinessIconScale = math.lerp(_happinessIconScale, targetScale, math.saturate(Time.unscaledDeltaTime * 4));
_happinessIcon.style.scale = new StyleScale(new Scale(Vector2.one * _happinessIconScale));
}
}
}