melee combat with multiple hitboxes

Hello guys,
I was trying to create a method for attacking based on a Brackeys video I saw, but I wanted to use more than just one single circle to check the collision so I tried to use an array of of transforms and another array for the range on each circle, but I keep getting two error messages that i can’t get rid off (
IndexOutOfRangeException: Index was outside the bounds of the array.
NullReferenceException: Object reference not set to an instance of an object
espadaencantada.OnDrawGizmosSelected ()
)

here’s the code
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class espadaencantada : itens
{
float[ ] attackRange;
public Transform[ ] transforms;
public LayerMask Enemies;
public int health;
private int i = 0;
private void Awake ()
{
attackRange = new float[5];
attackRange[0] = 0.5f;
attackRange[1] = 0.7f;
attackRange[2] = 1f;
attackRange[3] = 0.7f;
attackRange[4] = 0.5f;

transforms = new Transform[5];

}

public override void ataque(int attack)
{
foreach(Transform transform in transforms)
{

Collider2D[ ] hitenemies = Physics2D.OverlapCircleAll(transform.position, attackRange*, Enemies);*
i++;
foreach(Collider2D inimigos in hitenemies)
{
health -= attack;
}
}
}
private void Update()
{
if (Input.GetMouseButtonDown(0))
{
ataque(attack);
}
}
private void OnDrawGizmosSelected()
{
Gizmos.color = Color.red;
foreach (Transform transform in transforms)
{
Gizmos.DrawWireSphere(transform.position, attackRange*);*
}
}
}
I’m still a begginer at coding and I don’t know a way to acces each element on the attackRange array using a foreach
And the attack method is in the other itens script, but there is nothing on it there

Hi and welcome,
please use code tags to post code examples.
It’s the <> button, but there is also a sticky post explaining how to use them on this subforum.

Further, it would help if you mentioned what line throws the exceptions.
The exceptions you are getting are rather self explanatory, if you know what they mean.
NullReferenceException means that you try to access something in an object reference that was not set, thus is null. Or in other words, you are trying to do something with an object that was never created or assigned yet.
IndexOutOfBoundsException means that you have an array of x elements and try to access it at index >= x, thus accessing it outside the bounds of the array, which is not possible (or rather, the memory at that location would be undefined).

You can iterate over elements in any array / list using a normal for loop (foreach is just a kind of lazy shortcut for that):

for(int i = 0; i < array.Length; i++){
    // do something at array[i]
}

It reads as “define i as 0, repeat the (for-)body while i < array.Length, afterwards increase i”. That’s the standard format for for-loops, but you could also define your completely own ways to use it. The first part always gets called once, the second contains the condition for running the loop, the last is called after each iteration.

Last but not least, and a bit off-topic:
I would highly recommend to follow common coding conventions. When coding in C#, most people name their methods, classes and properties in UpperCamelCase, their variables in camelCase and so on.
Also, it is recommended to code using english variable, method, class, … names, especially if the code is to ever be read by other people (like when you post it on a forum). For small examples like these it doesnt matter that much, but if you write more code and people effectively understand as little about it as if you just called your variables “a”, “b”, “c123” or something along those lines, then others wont be able to help much.

Hope this helps for now :slight_smile:

Hello!
Thank you a lot for your help, I’ve made the convention changes and changed the foreach loop for a for loop, but I still get the same errors. I think it must be something related to the fact that I added the elements on the Transforms array on the inspector

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

public class sword : itens
{
    float[] attackRange;
    public Transform[] transforms;
    public LayerMask enemies;
    public int health;
  
    private void Awake ()
    {
        attackRange = new float[5];
        attackRange[0] = 0.5f;
        attackRange[1] = 0.7f;
        attackRange[2] = 1f;   
        attackRange[3] = 0.7f;
        attackRange[4] = 0.5f;

        transforms = new Transform[5];

    }
   
    public override void Attack(int attack)
    {
      for(int i = 0; i < transforms.Length; i++)
        {

            Collider2D[] hitenemies = Physics2D.OverlapCircleAll(transforms[i].position, attackRange[i], enemies);
            foreach(Collider2D Enemies in hitenemies)
            {
                health -= attack;
            }
        }
    }
    private void Update()
    {
        if (Input.GetMouseButtonDown(0))
        {
            Attack(attack);
        }
    }
    private void OnDrawGizmosSelected()
    {
        Gizmos.color = Color.red;
        for (int i = 0; i < transforms.Length; i++)
        {
            Gizmos.DrawWireSphere(transforms[i].position, attackRange[i]);
        }
    }
}

I don’t have any idea on why it is still happening, maybe I’m just a bit dumb

Conventions arent going to fix any errors, and i mostly explained to you how to use for-loops since you mentioned you are not sure how to iterate arrays other than using foreach loops.

To tackle your exceptions it would still help if you mentioned which line of your code example actually threw which one.

Edit: You mentioned that you add the elements for ‘transforms’ in the inspector. In that case, try deleting line 21 as it may just replace your inspector values with a new empty array after launching. You can check this by pressing play and seeing if the transforms you put there in the inspector are still in place, or if the array is now empty.
This would explain the NullReferences tho.
Currently not quire sure what’s throwing the OutOfBoundsException.

Edit2: Does line 41 even compile? Where are you getting the ‘attack’ from you are passing to your Attack() function? It doesnt seem like you have a variable with that name in the available scope.

hello, I’ve made changes on the code and now I don’t have the problem with the OtOfBoundsException, but the other issue is still there. I’m getting the attack variable from the ‘itens’ parent class

public class sword : itens
{
    public float[] attackRange;
    public Transform[] transforms;
    public LayerMask enemies;
    public int health;
 
    public override void Attack(int attack)
    {
      for(int i = 0; i < transforms.Length; i++)
        {

            Collider2D[] hitenemies = Physics2D.OverlapCircleAll(transforms[i].position, attackRange[i], enemies);
            foreach(Collider2D Enemies in hitenemies)
            {
                health -= attack;
            }
        }
    }
    private void Update()
    {
        attackRange = new float[5];
        transforms = new Transform[5];
        if (Input.GetMouseButtonDown(0))
        {
            Attack(attack);

        }
    }
}

attackRange array was showing the same error as the transforms, the only way I could fix it was by making it public and setting the elements in the inspector, wich is something I don’t like doing
This is the problem I’m having rn:
NullReferenceException: Object reference not set to an instance of an object
sword.Attack (System.Int32 attack) (at Assets/objects/New Folder/sword.cs:17)
sword.Update () (at Assets/objects/New Folder/sword.cs:30)

I just realized the problem and now I know for sure that I’m dumb. As I was declaring the new ‘transforms’ array and the new ‘attackRange’ array on the update method, it was overwritting the values I set on the inspector every frame.
And the reason why I was getting the errors when I was using the awake function, was the fact that it was private