Hi I personally don’t like everything related to experience being in stats I think it will lead to the progress SO(Scriptable Object) becoming a bloated mess, especially if it had multiple classes that can level up and I don’t view it as a stat.
So I’ve created an alternative.
First create a new SO:
[CreateAssetMenu(fileName = "ExperienceToLevel", menuName = "Attributes/Experience To Level", order = 0)]
public class ExperienceToLevel : ScriptableObject
{
public int[] XPRequiredArray;
}
In Base stats create a public Getter for the level with a private setter, then a method for changing the level:
public int CurrentLevel => _level;
public void SetCurrentLevel(int level)
{
_level = level;
}
Then in Experience.cs add access to the new SO:
[SerializeField] ExperienceToLevel _experienceToLevel = null;
Make sure in the player prefab to attach the SO and to fill in the XP required within the SO.
Then back in Experience.cs:
BaseStats _baseStats;
private void Awake()
{
_baseStats = GetComponent<BaseStats>();
}
public void GainExperience(float experience)
{
_experiencePoints += experience;
CheckAndUpdateLevel();
}
void CheckAndUpdateLevel()
{
int currentLevel = _baseStats.CurrentLevel;
for (int level = currentLevel; level < _experienceToLevel.XPRequiredArray.Length; level++)
{
int nextLevelInArray = level - 1;
if (_experiencePoints >= _experienceToLevel.XPRequiredArray[nextLevelInArray])
{
int nextLevel = level + 1;
_baseStats.SetCurrentLevel(nextLevel);
}
}
}
This code makes it so you can manage everything related to experience except for the XPReward in the experience script and SO, I would ideally separate the XPReward as well.
The level is automatically updated upon receiving experience.