I wrote the resource code with the [GlobalClass] attribute, then built the project (clicked the hammer) and still the resource is not displayed. What can I do?
using Godot;
namespace Game.Resources
{
[GlobalClass]
public partial class HealthData : Resource // Data for saving and loading
{
[Export] public float RevivalHealth { get; set; }
[Export] public float SavedHealth { get; set; }
[Export] public bool Immortality { get; set; }
}
}
namespace Game.Components
{
using Game.Resources;
public partial class HealthInfo : RefCounted // Data when health changes
{
public float CurrentHealth;
public float PreviousHealth;
public float HealthDelta => CurrentHealth - PreviousHealth;
public bool IsDamage => HealthDelta < 0;
public bool IsHeal => HealthDelta > 0;
}
public partial class HealthComponent : Node3D
{
// SIGNALS
[Signal] public delegate void HealthChangedEventHandler(HealthInfo info);
[Signal] public delegate void DiedEventHandler();
// EXPORTED DATA
[Export] private HealthData _data_resource; // Data is saved and loaded from the same file
// CONSTANTS
private const float MINIMUM_POSSIBLE_HEALTH = 1.0f;
private const float MAXIMUM_POSSIBLE_HEALTH = 10000.0f; // There may be a change
private const float CRITICAL_HEALTH_RATIO = 0.2f;
// FIELDS AND PROPERTIES
private float _revival_health; // The current name is better than "_max_health"
public float RevivalHealth
{
get
{
return _revival_health;
}
private set
{
_revival_health = Mathf.Clamp(value, MINIMUM_POSSIBLE_HEALTH, MAXIMUM_POSSIBLE_HEALTH);
}
}
private float _current_health;
public float CurrentHealth
{
get
{
return _current_health;
}
private set
{
if (Mathf.IsEqualApprox(_current_health, value)) return;
HealthInfo info = new HealthInfo();
info.CurrentHealth = Mathf.Clamp(value, 0.0f, _revival_health);
info.PreviousHealth = CurrentHealth;
EmitSignal(SignalName.HealthChanged, info);
if (info.CurrentHealth == 0 && IsMortal)
{
EmitSignal(SignalName.Died);
}
if (IsMortal)
{
_current_health = info.CurrentHealth;
}
}
}
private bool _immortality;
// STATE CHECK PROPERTIES
public bool IsAlive => CurrentHealth > 0.0f;
public bool IsDead => !IsAlive;
public bool IsImmortal => _immortality;
public bool IsMortal => !IsImmortal;
public bool IsHealthFull => Mathf.IsEqualApprox(CurrentHealth, RevivalHealth);
public bool IsCriticalHealth => CurrentHealth <= RevivalHealth * CRITICAL_HEALTH_RATIO;
public bool IsDamaged => CurrentHealth < RevivalHealth;
public bool CanBeHealed => IsDamaged && IsAlive;
public string CurrentHealthText => $"{CurrentHealth:F0}";
public string RevivalHealthText => $"{RevivalHealth:F0}";
// OVERRIDED FUNCTIONS
public override void _Ready()
{
Load(); // There may be a change
}
// FUNCTIONS
public void Heal(float heal)
{
if (heal < 0.0f)
{
GD.PushWarning("The value of the Heal() function must be positive. The passed value was converted to a positive value.");
CurrentHealth += Mathf.Abs(heal);
return;
}
CurrentHealth += heal;
}
public void Damage(float damage)
{
if (damage < 0.0f)
{
GD.PushWarning("The value of the Heal() function must be positive. The passed value was converted to a positive value.");
CurrentHealth += Mathf.Abs(damage);
return;
}
CurrentHealth -= damage;
}
public void Save()
{
HealthData data = new HealthData();
data.RevivalHealth = RevivalHealth;
data.SavedHealth = CurrentHealth;
data.Immortality = _immortality;
Error e = ResourceSaver.Save(data, _data_resource.ResourcePath, ResourceSaver.SaverFlags.None);
if (e != Error.Ok)
{
GD.PrintErr("Error when saving a file (", _data_resource.ResourcePath, ").");
}
}
public void Load()
{
HealthData data = ResourceLoader.Load<HealthData>(_data_resource.ResourcePath, "HealthData", ResourceLoader.CacheMode.Ignore);
if (data == null)
{
GD.PrintErr("Error when opening a file (", _data_resource.ResourcePath, ").");
return;
}
RevivalHealth = data.RevivalHealth;
CurrentHealth = data.SavedHealth;
_immortality = data.Immortality;
}
}
}
Your properties need to have a getter and a setter, so this would be correct:
using Godot;
namespace Game.Resources
{
[GlobalClass]
public partial class HealthData : Resource // Data for saving and loading
{
[Export] public float RevivalHealth { get; set; }
[Export] public float SavedHealth { get; set; }
[Export] public bool Immortality { get; set; }
}
}