- Home /
Applying Damage
I am working on my AI Scipt for a while and I thought it's about time to make an attack feature. I am having a problem with the attack timing and amount of damage done. I have an ideea of what this could be caused by but I don't know how to solve it.
I am using Coroutine to call the function and yield to delay the damage. In the script below i have set to do -maxDamage at 1 seconds distance. The "health.curHealth -= maxDamage" is executed more than 20 times in one check and I don't know how to solve that?
void Update(){
.
.
.
.
if(health.curHealth > 1)
attack = true;
else if(health.curHealth < 1)
attack = false;
if ( attack == true ){
StartCoroutine( Attack());
}
.
.
.
.
.
IEnumerator Attack () {
animation.CrossFade(idleAnimation.name);
while( health.curHealth > 1 ){
yield return new WaitForSeconds(1.0f);
Debug.Log(health.curHealth);
Debug.Log(maxDamage);
animation.CrossFade(attackAnimation.name);
health.curHealth -= maxDamage;
}
}
Debug.Log are showing the following : 100 - 50 50 - 50 0 - 50 0 - 50 0 - 50 (Repeating for 10 times or more)
Try putting a Debug.Log call right before health.curHealth = etc. and print out your curHealth and maxDamage variables to make sure they are what you expect them to be.
I have added as you said 2 debugs 1 for health and 1 for damage : 100 - 50 50 - 50 0 - 50 0 - 50 0 - 50
What function do you start the Attack() CoRoutine in? It might be that you are starting multiple instances of Attack() CoRoutine
Oh yes I frogot to post the funcion. It is Update function
Answer by raoz · Oct 27, 2012 at 03:10 PM
The problem is that Coroutine Attack() is started multiple times in Update(). Try this:
private var gapTest = true;
private var attacking = false;
if(health.curHealth > 1)
attack = true;
else if(health.curHealth < 1)
attack = false;
if ( attack == true && !attacking){
StartCoroutine( Attack());
attacking = true;
}
Answer by Montraydavis · Oct 27, 2012 at 03:57 AM
Try the following:
IEnumerator Attack () {
animation.CrossFade(attackAnimation.name); yield WaitForSeconds(2.0f); // Change here health.curHealth -= maxDamage; attack = false ; // Change here
}
I don't know if you just didn't post it, but, I don't see you ever stopping the 'attack', and your yield is a bit off.
It doesn't work because attack variable is changed in Update depending of enemy's position compared to the player so it will become true right next frame and I will get the same result. Here is where it becomes false :
if( Chase == true && Distance > stopChasing ) { //2. $$anonymous$$ove towards target moveSpeed = change; controller.Simple$$anonymous$$ove(moveSpeed*transform.forward); attack = false; }
Then why not just change WaitForSeconds ( 2.0f ) to WaitForSeconds ( TotalTimeHere ). Does that not work either ?
This works perfectly I have no problem with this, but the health.curHealth -= maxDamage is executed more than 10 times at once. How do I fix that ?
Answer by Griffo · Oct 27, 2012 at 09:46 AM
Try this, alter the (0.05) to suit your requirements.
private var gapTest = true;
if(health.curHealth > 1)
attack = true;
else if(health.curHealth < 1)
attack = false;
if ( attack == true ){
StartCoroutine( Attack());
}
.
.
.
.
.
IEnumerator Attack () {
animation.CrossFade(idleAnimation.name);
while( health.curHealth > 1 ){
yield return new WaitForSeconds(1.0f);
Debug.Log(health.curHealth);
Debug.Log(maxDamage);
animation.CrossFade(attackAnimation.name);
if(gapTest){
health.curHealth -= maxDamage;
GapSet();
}
}
}
function GapSet(){
gapTest = false;
yield WaitForSeconds (0.05);
gapTest = true;
}
Nope, the problem is still here. Expression "health.curHealth -= maxDamage" is executed like 40 times at once.
Try putting the health before the yield, and see if that changes anything, though unlikely. $$anonymous$$ind posting the whole script ?
No, that won't change anything(in good) and sorry I wish I could post it but I've been working a lot on it and there will be others who will come and copy-paste it. Please understand
Answer by skoandi · Oct 27, 2012 at 02:58 PM
I use something like this:
function ApplyDamage(ammount : int){
curHealth -= ammount;
}
Answer by Montraydavis · Oct 27, 2012 at 05:01 PM
I totally understand. Maybe try adding an 'ease' function/routine of some sort? This is usually what I do until I am able to fully utilize .
var ApplyDamageCounter : float ;
var ApplyDamageCounterIndex : float ;
var ApplyDamageCounterMax : float = 1;
function ApplyDamage ( ammo : int )
{
if ( ApplyDamageCounter < ApplyDamageCounterMax )
{ curHealth -= ammount;
}else{
ApplyDamageCounter += 1 * Time.deltaTime ;
}
}
This will allow only one damage query per second. You can manipulate this to your need, obviously.
Your answer
Follow this Question
Related Questions
Enemy attack constantly with a coroutine 1 Answer
rigidbody enemy goes only forward, no damage delay. 2 Answers
Enemy will only take (melee) damage when the distance is below 1 (ie. A zero with decimals after it) 2 Answers
Need help developing Damage Over Time mechanic 0 Answers
Melee Damage script by collision 2 Answers