Home > Software engineering >  Trying to Grab int Variable From Separate Script
Trying to Grab int Variable From Separate Script

Time:11-23

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);
}

CodePudding user response:

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;
}

CodePudding user response:

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.

  • Related