using System.Collections.Generic;
public static void Main()
Console.WriteLine("Hello World");
public class Component : Object {}
public class Behaviour : Component {}
public class MonoBehaviour : Behaviour {}
public class ScriptableObject : Object {}
public class SO_Enum : ScriptableObject
public string Name { get; set; }
public abstract class StatType : SO_Enum {}
public sealed class CharacterStat : StatType {}
public sealed class GunStat : StatType {}
public sealed class ItemStat : StatType {}
private List<Modifier> _modifiers = new List<Modifier>();
public Action<float> ValueChanged = default;
ValueChanged?.Invoke(_value);
public interface IController {}
public abstract class StatController : MonoBehaviour
private List<StatType> _attributes = new List<StatType>();
private Dictionary<StatType, Stat> _stats = new Dictionary<StatType, Stat>();
public IReadOnlyList<StatType> Attributes => _attributes;
public IReadOnlyDictionary<StatType, Stat> Stats => _stats;
public abstract class StatController<T> : StatController, IController where T : StatType
private List<T> _attributes = new List<T>();
private Dictionary<T, Stat> _stats = new Dictionary<T, Stat>();
public IReadOnlyList<T> Attributes => _attributes;
public IReadOnlyDictionary<T, Stat> Stats => _stats;
public void OnInitialize()
var count = _attributes.Count;
if (count == 0) { return; }
for (var i = 0; i < count; ++i)
statType = _attributes[i];
_stats.Add(statType, new Stat());
public sealed class CharacterStats : StatController<CharacterStat> {}
public sealed class GunStats : StatController<GunStat> {}
public sealed class ItemStats : StatController<ItemStat> {}
public sealed class CharacterController : MonoBehaviour
private CharacterStats _stats = default;
public CharacterStats Stats => _stats;
public class StatTracker<T> : MonoBehaviour where T : StatType
private T _type = default;
private Stat _stat = default;
private StatController _controller = default;
public Action<float> ValueChanged = default;
public void OnInitialized()
_stat = _controller.Stats[_type];
_stat.ValueChanged += ValueChanged;
public class HealthService : ScriptableObject {}
public sealed class HealService : HealthService
public void Invoke(float value, Stat stat)
public sealed class RegenService : HealthService
public void Invoke(float value, Stat stat)
public sealed class Heal : StatTracker<CharacterStat>
private HealthService _service = default;