I set up a healthy hat-esque item that should give 20 Health. The Player is set to use modifiers. The player can equip this item but it doesn’t actually add any HP to their maximum from what I can tell; neither the HP bar nor current or max HP counter I have set up change at all. I could use advice on where I may have gone wrong.
I will provide my base stats script here and can provide other scripts as needed:
using System.Reflection.Emit;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;
using RPG.Saving.Utils;
namespace RPG.Attributes
{
public class BaseStats : MonoBehaviour//Chracter's base stats before item bonuses and penalties
{
[Range(1, 99)][SerializeField] int startingLevel = 1;//Max level is set at 99. Shouldn't be an issue in most games.
[SerializeField] CharacterClass characterClass;
[SerializeField] Progression progression = null;
[SerializeField] GameObject levelUpParticleEffect = null;
[SerializeField] Transform levelTarget = null;
[SerializeField] bool shouldUseModifiers = false;//By default, entities ignore modifiers, since only the player really needs them and it makes tuning easier
public event Action onLevelUp;
LazyValue<int> currentLevel; //Intentionally invalid by default
Experience experience;
private void Awake()
{
experience = GetComponent<Experience>();
currentLevel = new LazyValue<int>(CalculateLevel);
}
private void Start()
{
currentLevel.ForceInit();
}
private void OnEnable()
{
if (experience != null)
{
experience.onExperienceGained += UpdateLevel;
}
}
private void OnDisable()
{
if (experience != null)
{
experience.onExperienceGained -= UpdateLevel;
}
}
private void UpdateLevel()
{
int newLevel = CalculateLevel();
if(newLevel > currentLevel.value)//will need tweaking if deleveling is ever introduced
{
currentLevel.value = newLevel;
LevelUpEffect();
onLevelUp();
}
}
private void LevelUpEffect()
{
Instantiate(levelUpParticleEffect, levelTarget.transform);
}
public float GetStat(Stats stat)
{
return (GetBaseStat(stat) + GetAdditiveModifier(stat)) * (1 + GetPercentageModifier(stat)/100);
}
public float GetBaseStat(Stats stat)
{
return progression.GetStat(stat, characterClass, GetLevel());
}
public int GetLevel()//helps avoid calculating level a bunch of times each frame
{
return currentLevel.value;
}
public int CalculateLevel()
{
Experience experience = GetComponent<Experience>();
if (experience == null) return startingLevel;
float currentXP = experience.GetExperience();
int penultimateLevel = progression.GetLevels(Stats.ExperienceToLevelUp, characterClass);
for (int level = 1; level <= penultimateLevel; level++)
{
float XPToLevelUp = progression.GetStat(Stats.ExperienceToLevelUp, characterClass, level);
if (XPToLevelUp > currentXP)
{
return level;
}
}
return penultimateLevel + 1;
}
private float GetAdditiveModifier(Stats stat)
{
if (!shouldUseModifiers) return 0;
float total = 0;
foreach (IModifierProvider provider in GetComponents<IModifierProvider>())
{
foreach (float modifier in provider.GetAdditiveModifiers(stat))
{
total += modifier;
}
}
return total;
}
private float GetPercentageModifier(Stats stat)
{
if (!shouldUseModifiers) return 0;
float total = 0;
foreach (IModifierProvider provider in GetComponents<IModifierProvider>())
{
foreach (float modifier in provider.GetPercentageModifiers(stat))
{
total += modifier;
}
}
return total;
}
}
}
I will also include my StatsEquipableItem script:
using System.Collections;
using System.Collections.Generic;
using RPG.Attributes;
using UnityEngine;
namespace RPG.Saving.Inventories
{
[CreateAssetMenu(menuName = ("RPG/Inventory/Equipable Item"))]
public class StatsEquipableItem : EquipableItem, IModifierProvider
{
[SerializeField] Modifier[] additiveModifers;
[SerializeField] Modifier[] percentageModifiers;
[System.Serializable] struct Modifier
{
public Stats stat;
public float value;
}
public IEnumerable<float> GetAdditiveModifiers(Stats stat)
{
foreach (var modifier in additiveModifers)
{
if(modifier.stat == stat)
{
yield return modifier.value;
}
}
}
public IEnumerable<float> GetPercentageModifiers(Stats stat)
{
foreach (var modifier in percentageModifiers)
{
if(modifier.stat == stat)
{
yield return modifier.value;
}
}
}
}
}
Thanks for any help!