Hello.
I am kind of desperate since I do not know how to debug my issue. the delegate does not work, except in my ExperienceDisplay script:
namespace RPG.Stats
{
public class PlayerExperienceDisplay : MonoBehaviour
{
PlayerExperience playerExperience;
BaseStats baseStats;
void Awake()
{
playerExperience= GameObject.FindWithTag("Player").GetComponent<PlayerExperience>();
baseStats = GameObject.FindWithTag("Player").GetComponent<BaseStats>();
}
void Start()
{
GetComponent<TextMeshProUGUI>().text = String.Format("{0}, XP:{1}", baseStats.CalculateLevel(), playerExperience.GetExperienceForDisplay());
playerExperience.onExperienceGained += UpdateExperienceDisplay;
}
void UpdateExperienceDisplay()
{
GetComponent<TextMeshProUGUI>().text= String.Format("{0}, XP:{1}", baseStats.CalculateLevel(),playerExperience.GetExperienceForDisplay());
}
}
}
It is the only place where I successfully implemented it.
In BaseStats, Nothing happens when I actually level up (UpdateLevel() does not execute at all). I looked up and down the commit, I compared my scripts to no avail.
Here is BaseStats
namespace RPG.Stats
{
public class BaseStats : MonoBehaviour
{
[Range(1,5)]
[SerializeField] int startingLevel= 1;
[SerializeField] CharacterClass characterClass;
[SerializeField] Progression progression= null;
[SerializeField] GameObject levelUpParticleEffect= null;
int currentLevel= 0;
public event Action onLevelPromotion;
void Sart()
{
currentLevel= CalculateLevel();
PlayerExperience playerExperience = GetComponent<PlayerExperience>();
if (playerExperience != null)
{
playerExperience.onExperienceGained += UpdateLevel;
}
}
private void UpdateLevel()
{
int newLevel= CalculateLevel();
if(newLevel > currentLevel)
{
currentLevel= newLevel;
TriggerPromotion();
onLevelPromotion();
}
}
private void TriggerPromotion()
{
if(levelUpParticleEffect!= null)
{
Instantiate(levelUpParticleEffect,transform);
}
}
public int GetLevel()
{
if(currentLevel<1)
{
currentLevel= CalculateLevel();
}
return currentLevel;
}
public float GetStatValueFromBaseStats(Stats stats)
{
return progression.GetStatValueFromProgression(stats, characterClass, GetLevel());
}
public int CalculateLevel()
{
PlayerExperience playerExperience = GetComponent<PlayerExperience>();
if(playerExperience== null) return startingLevel;
float currentXP = playerExperience.GetExperienceForDisplay();
// the penultimateLevel is how many levels in total we can have. maxLevel would be penultimateLevel+1
int penultimateLevel = progression.GetLevelsFromStat(Stats.ExperienceRequiredToLevelUp, characterClass);
for (int level = 1; level < penultimateLevel; level++)
{
float XPToLevelUp = progression.GetStatValueFromProgression(Stats.ExperienceRequiredToLevelUp, characterClass, level);
if (XPToLevelUp > currentXP)
{
return level;
}
}
return penultimateLevel + 1;
}
}
}
My experience script:
namespace RPG.Stats
{
public class PlayerExperience : MonoBehaviour, ISaveable
{
[SerializeField] float experience= 0;
public delegate void ExperienceGainedDelegate();
public event ExperienceGainedDelegate onExperienceGained;
// public event Action onExperienceGained;
public void GainExperience(float experiencePoints)
{
experience += experiencePoints;
if(onExperienceGained!= null)
{
onExperienceGained();
}
}
public float GetExperienceForDisplay()
{
return experience;
}
public object CaptureState()
{
return experience;
}
public void RestoreState(object state)
{
experience= (float)state;
}
}
}
and my Health script, which does nothing either when I level up
namespace RPG.Attributes
{
public class Health : MonoBehaviour ,ISaveable
{
BaseStats baseStats;
float maxHealth= -1f;
bool isDead= false;
public bool IsDead{get{return isDead;}}
void Start()
{
GetMaxHealth();
GetComponent<BaseStats>().onLevelPromotion += RewardWithHeal;
if(baseStats != null)
{
baseStats.onLevelPromotion += RewardWithHeal;
}
}
float GetMaxHealth()
{
if (maxHealth < 0)
{
maxHealth = GetComponent<BaseStats>().GetStatValueFromBaseStats(Stats.Stats.Health);
}
return maxHealth;
}
void RewardWithHeal()
{
// float regeneratedHealth= maxHealth += ((GetComponent<BaseStats>().GetStatValueFromBaseStats(Stats.Stats.Health))/4);
// maxHealth= Mathf.Min(regeneratedHealth,GetComponent<BaseStats>().GetStatValueFromBaseStats(Stats.Stats.Health) );
maxHealth = GetComponent<BaseStats>().GetStatValueFromBaseStats(Stats.Stats.Health);
}
public float GetHealthForDisplay()
{
return (maxHealth/GetComponent<BaseStats>().GetStatValueFromBaseStats(Stats.Stats.Health)) * 100;
}
public void TakeDamage(GameObject instigator,float damage)
{
maxHealth= Mathf.Max(maxHealth-damage, 0);
// print(currentHealth);
if(maxHealth<= 0)
{
TriggerDeath();
if(instigator != null)
{
RewardExperience(instigator);
}
}
}
private void TriggerDeath()
{
if(isDead) return;
GetComponent<Animator>().SetTrigger("dying");
GetComponent<CapsuleCollider>().enabled= false;
GetComponent<ActionScheduler>().CancelCurrentAction();
isDead = true;
}
void RewardExperience(GameObject killer)
{
if (killer.gameObject.tag != "Player") return;
float experienceToReward = GetComponent<BaseStats>().GetStatValueFromBaseStats(Stats.Stats.ExperienceReward);
PlayerExperience playerExperience= killer.GetComponent<PlayerExperience>();
if(playerExperience == null) return;
playerExperience.GainExperience(experienceToReward);
}
public object CaptureState()
{
return maxHealth;
}
public void RestoreState(object state)
{
maxHealth = (float) state;
if (maxHealth <= 0)
{
TriggerDeath();
}
}
}
}
So frustrated with myself. I need help please