0

I understand what I need to do to get my script to work I just don't know exactly what code to write. What Im trying to do is get my currentHealth int (not a public int just an int) from my Enemy script to my Enemy Combat script so I can make my second attack do 0 dmg while my currentHealth is above 50. If I Really want to get down to the true issue, its that my second attack, although the animation doesnt play when hp is 50 or higher as that attack is only supposed to happen at 50 hp or lower, the collider check still functions and damages the player even tho its not set to activate until 50 hp or lower. Even more detail, i have my bosses split into to stages, first stage is until you dmg the boss to 50hp then he goes into the second stage and does his second attack. That function works fine, however, the second attack that activates in the second stage by having a bool set to true when hp is below 50, will still damage in the attack range even though the animation isnt playing but for some reason my damage still damages even at the very start of the match even when no animation is playing.

Here is the Enemy script holding the health logic.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Enemy : MonoBehaviour
{
public Component enemyCombat;

public Component aiScript;

public Animator animator;

public int maxHealth = 100;

int currentHealth;

// Start is called before the first frame update
void Start()
{
    currentHealth = maxHealth;
}

public void TakeDamage(int damage)
{
    currentHealth -= damage;
    animator.SetTrigger("Hurt");

    if (currentHealth <= 50)
    {
        animator.SetBool("IsAngry", true);
    }

    if(currentHealth <= 0)
    {
        Die();
    }
}

void Die()
{
    Debug.Log("Enemy Died");

    animator.SetBool("IsDead", true);

    Destroy(aiScript);

    Destroy(enemyCombat);

    GetComponent<Collider2D>().enabled = false;

   this.enabled = false;      
}

And here is my EnemyCombat script (named after my boss which is an upgraded version of Orion)

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class OrionUpgradedCombat : MonoBehaviour
{
public Animator animator;

public GameObject gameObject;

public Transform AttackPoint;

public Transform secondAttackPoint;

public float attackRange = 0.5f;

public float secondAttackRange = 0.5f;

public LayerMask enemyLayers;

public int attackDamage = 8;

public int secondAttackDamage = 15;

public float attackRate = 2f;
float nextAttackTime = 0f;

void Start()
{
    enemy enemyScript = gameObject.GetComponent<Enemy>();
}

// Update is called once per frame
void Update()
{
    if (Time.time >= nextAttackTime)
    {
        StartCoroutine(Attack());
        StartCoroutine(AttackTwo());
        nextAttackTime = Time.time + 8f / attackRate;
    }

    if (currentHealth >= 50)
    {
        secondAttackDamage -= 15;
    }
    else
    {
        secondAttackDamage = 15;
    }
}

public IEnumerator Attack()
{
    yield return new WaitForSeconds(2);
    animator.SetTrigger("Attack");
    Collider2D[] hitEnemies = Physics2D.OverlapCircleAll(AttackPoint.position, attackRange, enemyLayers);
    foreach (Collider2D enemy in hitEnemies)
    {
        enemy.GetComponent<PlayerHealth>().TakeDamage(attackDamage);
    }
}

public IEnumerator AttackTwo()
{
    yield return new WaitForSeconds(4);
    animator.SetTrigger("AttackTwo");
    Collider2D[] hitEnemies = Physics2D.OverlapCircleAll(secondAttackPoint.position, secondAttackRange, enemyLayers);
    foreach (Collider2D enemy in hitEnemies)
    {
        enemy.GetComponent<PlayerHealth>().TakeDamage(secondAttackDamage);
    }
}

void OnDrawGizmosSelected()
{
    if (AttackPoint == null)
        return;

    Gizmos.DrawWireSphere(AttackPoint.position, attackRange);
}
  • 1
    Welcome to SO! Generally you want to avoid opening with _"...if what youre saying isn't helpful or you're trying to pick on me for being a beginner don't waste your time typing Im new..."_. We are all, _new to something, somewhere, sometime._ So don't worry. :) Good luck! –  Nov 22 '21 at 03:29
  • Thank you, I'm not necessarily new I just lost my other account but i only asked three questions there so still kinda new lol. you're right I've just had bad previous experiences withpeople insinuating things and telling me to reference elsewhere instead of them actually helping me. Im relatively competent and I almost always reference all other places before resorting to asking the question myself. They just don't understand every project is different /: Thank you again though for your wise wisdom haha – FighterOne12344 Nov 22 '21 at 03:35
  • So it looks like your `currentHealth` should be `public` and then in the second script `OrionUpgradeCombat` you want to use `if(GetComponent().currentHealth >= 50` .... ? Doesn't really sound to me like your previous comment is very true ... [In Unity, how can I pass values from one script to another?](https://stackoverflow.com/questions/13891892/in-unity-how-can-i-pass-values-from-one-script-to-another) – derHugo Nov 22 '21 at 07:09

2 Answers2

1

The reason why it's still applying damage is because you're starting the AttackTwo coroutine right after you start the AttackOne coroutine. You're also doing this before you change your secondAttackDamage to 0. I would recommend calling the AttackTwo coroutine once your enemy is less than 50 health.

Extain
  • 72
  • 7
0

It would be great if you could use animation events in this situation, but if it's not possible for any reason, I guess it might be a problem with calling coroutines in the Update() method, so I suggest using a flag to start coroutine only when the previous call has finished. It would be something like this:

bool isCoroutineStarted = false;

void Update()
{
    if (!isCoroutineStarted)
    {
        StartCoroutine("YourAttackCoroutine");
    }
}

IEnumerator YourAttackCoroutine()
{
    isCoroutineStarted = true;

    //Your Code 

    yield return new WaitForSeconds(0);

    isCoroutineStarted = false;
}