- Home /
When enemy health is 0, the player gets 73 XP, about 500,000 times.
I have a code right now where you can damage the enemy with the Z key, and if the EnemyHealth = 0, then the player gets 72 XP, and the Enemy dies, and respawns 15 seconds later. The problem is, I have to set EnemyHealth = EnemyMaxHealth right after the XP is given, so even if the enemy is "dead" you can still kill it and get XP, because the health is = MaxHealth, though the collider and renderer are disabled. But, if I make the EnemyHealth = 0 right off the bat, then the XP just keeps going up. And up. And up. And up even more until the Enemy respawns. I will post the Enemy stats script, and the player level script.
Enemy Stats(The version where u can kill the dead enemy(Doesn't flood the XP) (If Health = 0 then it does flood XP))
using UnityEngine;
using System.Collections;
public class EnemyStats : MonoBehaviour {
public int EnemyHealth = 100;
public int EnemyMaxHealth = 100;
public int DropXP = 74; //Enemy won't drop this exact amount...
public int DropGold = 126;
public GameObject GiveStuff;
// Use this for initialization
void Start () {
}
// Update is called once per frame
void Update () {
PlayerLevelDeclaration PT = (PlayerLevelDeclaration)GiveStuff.GetComponent("PlayerLevelDeclaration");
if(EnemyHealth <= 0){
EnemyHealth = 0;
StartCoroutine(OnDeath());
}
}
IEnumerator OnDeath(){
bool IsDead = false;
PlayerLevelDeclaration PT = (PlayerLevelDeclaration)GiveStuff.GetComponent("PlayerLevelDeclaration");
if(EnemyHealth <= 0){
EnemyHealth = 0;
IsDead = true;
if(PT.DroppedXP >= DropXP){
PT.DroppedXP = 0;
}
if(IsDead == true){
PT.DroppedXP = (int)(DropXP / 2) + PT.DroppedXP;
IsDead = false;
EnemyHealth = EnemyMaxHealth; //Comment this out, (<-) and it increases XP by 72, about 500,000 times.
yield return new WaitForSeconds(.0000000000000000000000001f);
if(DropXP >= DropXP){
PT.DroppedXP = 0;
}
yield return new WaitForSeconds(2f);
collider.enabled = false;
renderer.enabled = false;
IsDead = false;
yield return new WaitForSeconds(10f);
EnemyHealth = EnemyMaxHealth;
PT.DroppedXP = 0;
collider.enabled = true;
renderer.enabled = true;
}
}
yield return IsDead;
}
}
The Playerlevel script
using UnityEngine;
using System.Collections;
public class PlayerLevelDeclaration : MonoBehaviour {
public int PlayerLevel = 1;
public int XP = 0;
public int DroppedXP = 0;
public int NeededXPUntilLevelUp = 100;
public int LeftoverXP = 0;
public int newXP = 0;
public int AddAmount = 50;
public AttributeDeclaration AD;
// Use this for initialization
void Start () {
Debug.Log (LevelUp());
}
// Update is called once per frame
void Update () {
LevelUp ();
AddXP ();
}
public int LevelUp(){
AD = gameObject.GetComponent<AttributeDeclaration>();
XP = XP + DroppedXP;
newXP = XP;
if(XP >= NeededXPUntilLevelUp)
{
//XP = 250, NeededXPUntilLevelUp = 249, then hopefully this sets xp to one, and increases the player level by one
newXP = XP - NeededXPUntilLevelUp;
LeftoverXP = newXP;
PlayerLevel = PlayerLevel + 1;
XP = newXP;
NeededXPUntilLevelUp = NeededXPUntilLevelUp + (int)(PlayerLevel * 3.2f);
//Increase Attributes
AD.Health = AD.Health + (int)(PlayerLevel * 1.9f);
AD.Magic = AD.Magic + (int)(PlayerLevel * 2.1f);
AD.Strength = AD.Strength + (int)(PlayerLevel * 1.6f);
AD.Stamina = AD.Stamina + (int)(PlayerLevel * 1.8f);
AD.Defense = AD.Defense + (int)(PlayerLevel * 1.2f);
//Increase Max Attributes
AD.MaxHealth = AD.MaxHealth + (int)(PlayerLevel * 1.9f);
AD.MaxMagic = AD.MaxMagic + (int)(PlayerLevel * 2.1f);
AD.MaxStrength = AD.MaxStrength + (int)(PlayerLevel * 1.6f);
AD.MaxStamina = AD.MaxStamina + (int)(PlayerLevel * 1.8f);
AD.MaxDefense = AD.MaxDefense + (int)(PlayerLevel * 1.2f);
//Refills current Attributes upon LevelUp
AD.Health = AD.MaxHealth;
AD.Magic = AD.MaxMagic;
AD.Strength = AD.MaxStrength;
AD.Stamina = AD.MaxStamina;
AD.Defense = AD.MaxDefense;
}
XP = newXP;
return PlayerLevel;
}
//Just a test for above code, adds 50 to XP when J is hit.
public int AddXP()
{
#region TestingForFuture
if(Input.GetKeyDown(KeyCode.Q))
{
XP = XP + AddAmount;
}
return XP;
#endregion
}
}
Answer by Eck · Nov 23, 2014 at 06:13 AM
Update is called once per frame. When your enemy is killed, it's health is lessthan or equal to zero, so every frame it tries to award the xp.
public int DropGold = 126;
public int isAlive = true;
...
public void Update
{
// Make sure the enemy was alive before awarding the xp.
if(isAlive && EnemyHealth <= 0)
{
// Mark the enemy as not alive so next update it's fine.
isAlive = false;
EnemyHealth = 0;
StartCoroutine(OnDeath());
}
}
...
// Then set it back to alive when you're "respawning" him
collider.enabled = true;
renderer.enabled = true;
isAlive = true;
THAN$$anonymous$$ YOU! I was sitting here for 30 $$anonymous$$ working with the other answer, and it almost worked, but when I used this, it works perfect. The enemy's health was able to go < 0, but I just added a simple if statement into Update. Thank you so much again!!!
Answer by sevensixtytwo · Nov 23, 2014 at 07:10 AM
I believe it is actually calling the Enemy OnDeath function multiple times. You should move your isDead boolean to the main script rather than keep it a local variable. Then you can check if isDead is false before calling OnDeath.
Like so:
if(EnemyHealth <= 0 && !isDead){
EnemyHealth = 0;
StartCoroutine(OnDeath());
isDead = true;
}
This'll make sure OnDeath is called once and once only. (btw, I usually code in JS so I'm not that familiar with C#)l
Thanks for the help, that helped a little bit, but the other answer solved the problem completely. Thanks again!
Your answer
Follow this Question
Related Questions
Multiple Cars not working 1 Answer
Instantiate prefab once help C# 1 Answer
How do I fix this broken walking animation start in C#? 1 Answer
Distribute terrain in zones 3 Answers
Script won't exit application.Why? 1 Answer