There's a problem with my projectiles not returning me XP!

Earlier, I would find that since the character continues punching even after the target is dead, it would reward experience multiple times. The way I dealt with that was:

public void TakeDamage(in GameObject instigator, in float damage)
{
    // Start when we aren't dead
    if (!dead)
    {
        // This will call DieOrResurrect(), setting "dead" to true if necessary
        Hp -= damage;
        // We might be dead now!
        AwardXp(instigator);
    }
}

private void AwardXp(GameObject instigator)
{
    if (dead)
    {
        instigator.GetComponent<Experience>()?.AwardXp(stats.XpReward);
    }
}

Where the Hp property is defined as

private float Hp
{
    get => hitPoints;
    set
    {
        hitPoints = Mathf.Max(value, 0);
        DieOrResurrect();
    }
}

… and DieOrResurrect() works like

private void DieOrResurrect()
{
    if (hitPoints <= 0 && !dead)
    {
        dead = true;
        collider.enabled = false;
        animator.SetTrigger("die");
        actionScheduler.CancelCurrentAction();
    }
    else if (hitPoints > 0 && dead)
    {
        dead = false;
        collider.enabled = true;
        animator.SetTrigger("resurrect");
    }
}

By discerning stuff from the Debugger, somehow hitting with a melee attack (if the projectilePrefab is null) calls TakeDamage() twice, while for projectiles, it doesn’t. So an enemy killed by a projectile doesn’t call AwardXp since I don’t hit its dead body (yikes).

My whole repo is at https://gitlab.com/ShivamMukherjee/TL7_RPG2. Are there any corners I’m missing?

Turns out it was the silliest of mistakes, classic me.

I didn’t update the gameObject reference on the projectile. Sigh.
However, I did resolve the bug of XP being awarded only for already dead people by performing a check for the killing blow:

public void TakeDamage(in GameObject instigator, in float damage)
{
    if (!dead)
    {
        // Check if it's the killing blow [[ MONT'KA ]]
        if ((hitPoints - damage) <= 0)
        {
            instigator?.GetComponent<Experience>()?.AwardXp(stats.XpReward);
        }
        // Actually apply the damage
        Hp -= damage;
    }
}
  1. I went back on my previous observation and placed the DieOrResurrect() call inside Hp's set method.
  2. I ripped out the AwardXp() call since it remained unused otherwise.
1 Like

This topic was automatically closed 24 hours after the last reply. New replies are no longer allowed.

Privacy & Terms