Accessing Component from Objects in Array

I am trying to create a Medic type unit in a RTS prototype, and am now stuck when my Medic tries to heal other units.

Every 10 seconds, the Medic creates an array of every other friendly unit, then tries to add 100 to their health script, finally the array is destroyed. I am able to create/delete the array no problem, but am currently unable to access the health component of each GameObject.

The error occurs at line 39, as enemyHeal… is invalid. I’m not sure what should be in its place.

public float timer;
private float timerMax;
public GameObject[] enemyHeal;

void Start()
    {
        timer = 0.0f;
        timerMax = 10f;
    }

void Update()
    {
        timer += Time.deltaTime;
       
        if(timer > timerMax)
        {
            timer = 0.0f;
            FindHealUnits();
        }
    }

    void FindHealUnits()
    {
        GameObject[] enemyHealGameObjectReference  = GameObject.FindGameObjectsWithTag("Enemy");
        enemyHeal = new GameObject[enemyHealGameObjectReference.Length];
        for (int i = 0; i < enemyHealGameObjectReference.Length; i++)
        {
            enemyHeal[i] = enemyHealGameObjectReference[i];
        }
        if(enemyHeal != null)
        {
            StartCoroutine(HealUnits());
        }
        Debug.Log("Found nearby units");
    }

    IEnumerator HealUnits()
    {
        var heal = enemyHeal[i].GetComponent<EnemyHealth>();
        heal.health = heal.health + 100;
        //Heal the units
        //Do a snazzy effect/particle and SFX
        yield return new WaitForSeconds(0.5f);
        enemyHeal = null;
        Debug.Log("Healed units and reset array");
    }

If any more information is required to make things clearer, I am happy to provide it. Any help would be appreciated.

i

this exists in the for loop. not in the coroutine…

you just need a for loop in the coroutine to iterate over the entire array doing the heals

1 Like

I would say that the bulk of your problems stem from line 41. You are using the variable “i” but it is not defined. That being said, your not looping through your enemies at this point.

Check out some changes to your script that I did.

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

public class HealerBot : PowerUp {

    private float timer = 0;
    private float timerMax = 10;
    public float radius = 10;

    void Start()
    {
    }

    void Update()
    {
        timer += Time.deltaTime;

        if (timer > timerMax)
        {
            timer = 0.0f;
            FindHealUnits();
        }
    }

    void FindHealUnits()
    {
        // get a list of the friendlies that we want to heal.
        GameObject[] enemyHealGameObjectReference = GameObject.FindGameObjectsWithTag("Enemy");
        // create a new list of friendlies that need healing.

        // use a simple boolean to see if we healed.
        bool didHealing = false;
        
        // go through the friendlies and see which need to be healed.
        foreach (GameObject friend in enemyHealGameObjectReference) {
            EnemyHealth health = friend.GetComponent<EnemyHealth>();

            // for nearby units
            float rad = (transform.position - friend.transform.position).sqrMagnitude;

            // check to see if this person needs health and is within our radius.
            if (health.health < health.maxHealth && rad < radius * radius) {
                heal.health = heal.health + 100;
                didHealing = true;
            }
            
        }

        // if we cant heal anyone, just wait until we find someone to heal.
        if (!didHealing)
            return;

        // since we now have something to heal, now lets do our co routine.
        //Do a snazzy effect/particle and SFX

        // this does the same thing as the coroutine.
        timer = -0.5f;
        Debug.Log("Healed nearby units");
    }
}
1 Like

@LeftyRighty and @ Showing me where I went wrong and a solution has been really useful, thank you. :slight_smile:
Also thank you for adding a radius, this was the next job on my to-do list.