- Home /
I am trying to take away some health from a slider using a coroutine, but it takes away too much
Hi, I'm trying to on button press (CardBoyAttack) trigger a bool to be true (isActivated) which starts a coroutine to take away some health from each slider. However when the coroutine is started, it subtracts 1000 health from each healthbar in one second. I have no idea why this is happening. Here is my code:
using System.Collections;
using System.Collections.Generic; using UnityEngine; using UnityEngine.EventSystems; using UnityEngine.UI;
public class MoveCardBoy : MonoBehaviour { public bool IsActivated = false; public Vector2 newPosition; public Vector2 originalPosition; public Button AttackButton; public SpellFireSpirit fireSpiritScript; public float playerattackValue; public float enemyAttackValue; public bool isAttacking = false;
void FixedUpdate()
{
if (IsActivated)
{
transform.position = newPosition;
StartCoroutine(ReturnToPosition());
}
}
IEnumerator ReturnToPosition()
{
yield return new WaitForSeconds(1f);
fireSpiritScript.enemyHealth = fireSpiritScript.enemyHealth - playerattackValue;
Debug.Log(fireSpiritScript.enemyHealth.ToString());
fireSpiritScript.playerHealth = fireSpiritScript.enemyHealth - enemyAttackValue;
Debug.Log(fireSpiritScript.playerHealth.ToString());
isAttacking = false;
transform.position = originalPosition;
IsActivated = false;
AttackButton.interactable = true;
}
public void CardBoyAttack()
{
IsActivated = true;
AttackButton.interactable = false;
}
}
Answer by Llama_w_2Ls · Apr 13, 2021 at 12:31 PM
The problem is that you're starting your coroutine in the FixedUpdate method. Coroutines are different to functions in the regard that all code after it runs regardless of whether the coroutine has finished or not.
This means that even though the coroutine hasn't finished yet, you can still run it again and again simultaneously, which seems to be what you're doing here, every fixed update, which drains more health than it needs to.
To fix this, you can use a bool to keep track of whether the coroutine has finished or not. Here's the new code:
bool CoroutineIsFinished = true;
void FixedUpdate()
{
if (IsActivated && CoroutineIsFinished)
{
transform.position = newPosition;
StartCoroutine(ReturnToPosition());
}
}
IEnumerator ReturnToPosition()
{
CoroutineIsFinished = false;
yield return new WaitForSeconds(1f);
fireSpiritScript.enemyHealth = fireSpiritScript.enemyHealth - playerattackValue;
Debug.Log(fireSpiritScript.enemyHealth.ToString());
fireSpiritScript.playerHealth = fireSpiritScript.enemyHealth - enemyAttackValue;
Debug.Log(fireSpiritScript.playerHealth.ToString());
isAttacking = false;
transform.position = originalPosition;
IsActivated = false;
AttackButton.interactable = true;
CoroutineIsFinished = true;
}
public void CardBoyAttack()
{
IsActivated = true;
AttackButton.interactable = false;
}
Thanks bro, I fixed it using another method, but thank you so much for your help
Your answer
Follow this Question
Related Questions
Coroutine stops working after first run 1 Answer
Call Functions On Player From Canvas Elements In a Multiplayer Game 1 Answer
How to make a GUI button 1 Answer
Healthpickup isn't working 1 Answer
Enabling/Disabling a slider from script 0 Answers