#Using autoload singletons for a PlayerStats

3 messages · Page 1 of 1 (latest)

summer vigil
#

Hello all, I'm following the Heartbeast ARPG tutorial and I'm having trouble setting up signals for a Autoload Singleton. The way I did it following the tutorial is that we first had a "Stats" node with a script Stats.cs attached to it, and then we created an inherited scene "PlayerStats" inheriting from the Stats node. This scene is attached to the same Stats.cs script, and then I added the PlayerStats to the project's globals as seen in the image.

Now I'm trying to set up a signal for the PlayerStats for when the health changes, notifying my UI (HealthUI). Here's what my code looks like for Stats.cs

using Godot;
using System;

public partial class Stats : Node
{
    public static Stats Instance { get; private set; }

    [Export]
    public int MaxHealth = 1;

    private int _currentHealth;

    [Signal]
    public delegate void NoHealthEventHandler();
    [Signal]
    public delegate void HealthChangedEventHandler(int value);
    public int Health
    {
        get => _currentHealth;
        set
        {
            _currentHealth = value;
            EmitSignal(SignalName.HealthChanged, _currentHealth);
            if (_currentHealth <= 0)
            {
                EmitSignal(SignalName.NoHealth);
            }
        }
    }

    public override void _Ready()
    {
        Instance = this;
        _currentHealth = MaxHealth;
    }
}
#

and here's the HealthUI.cs, where I'm trying to connect the signal to:

using Godot;
using System;

public partial class HealthUI : Control
{
    [Export]
    public Label HealthLabel;

    private int _hearts = 4;
    [Export]
    public int Hearts
    {
        get => _hearts;
        set
        {
            _hearts = Mathf.Clamp(value, 0, MaxHearts);
        }
    }

    private int _maxHearts = 4;
    [Export]
    public int MaxHearts
    {
        get => _maxHearts;
        set
        {
            _maxHearts = Mathf.Max(value, 1);
        }
    }

    private Stats _stats;

    public override void _Ready()
    {
        _stats = Stats.Instance;
        MaxHearts = _stats.MaxHealth;
        Hearts = _stats.Health;
        _stats.HealthChanged += SetHearts;
    }

    public void SetHearts(int hearts)
    {
        Hearts = hearts;
    }
}
#

I was following the tutorial so it led to this weird scenario where we created a new scene inheriting from Stats node even though they share the same script, so I feel like I might have messed something up setting up the Autoload singleton, especially since it's C#

If anyone has any idea or experience with C# singletons any help or comments is appreciated