-1

I've tried a lot of different things. Assigning the array elements just in the editor. Assigning the elements on boot using the Await(). Changing what script calls the functions. What GameObject has the attached script. How the Vector2 is called. How the array is initialized. I can't figure out what I'm missing.

GameRules Script

using System.Collections.Generic;
using UnityEngine;

public class GameRules : MonoBehaviour
{
    public GameObject[] rightSwitchSpawns = new GameObject[7];
    public GameObject[] leftSwitchSpawns = new GameObject[7];

    public GameObject rightSwitchPrefab;
    public GameObject leftSwitchPrefab;
    
    void Awake(){
        rightSwitchSpawns =  GameObject.FindGameObjectsWithTag("RightSpawns");
        leftSwitchSpawns = GameObject.FindGameObjectsWithTag("LeftSpawns");
    }
    // Start is called before the first frame update
    void Start()
    {
        RandomLeft();
        RandomRight();
    }

    public void RandomLeft()
    {   Debug.Log("This Left array length is " + leftSwitchSpawns.Length);
        int leftRandom1 = Random.Range(0, leftSwitchSpawns.Length -1);
        Debug.Log("left 1 index is " + leftRandom1);
        Vector2 leftOne = new Vector2(leftSwitchSpawns[leftRandom1].transform.position.x,leftSwitchSpawns[leftRandom1].transform.position.y);
        leftSwitchPrefab = Instantiate(leftSwitchPrefab, new Vector2(leftOne.x,leftOne.y), Quaternion.identity);

        int leftRandom2 = Random.Range(0, leftSwitchSpawns.Length -1);
        while(leftRandom2 == leftRandom1)
        {
            leftRandom2 = Random.Range(0, leftSwitchSpawns.Length -1);
        }
        Vector2 leftTwo = new Vector2(leftSwitchSpawns[leftRandom2].transform.position.x,leftSwitchSpawns[leftRandom2].transform.position.y);
        leftSwitchPrefab = Instantiate(leftSwitchPrefab, new Vector2(leftTwo.x,leftTwo.y), Quaternion.identity);
        Debug.Log("Left 2 index is: " + leftRandom2);

        int leftRandom3 = Random.Range(0, leftSwitchSpawns.Length -1);
        while(leftRandom3 == leftRandom1 || leftRandom3 == leftRandom2)
        {
            leftRandom3 = Random.Range(0, leftSwitchSpawns.Length -1);
        }
        Vector2 leftThree = new Vector2(leftSwitchSpawns[leftRandom3].transform.position.x,leftSwitchSpawns[leftRandom3].transform.position.y);
        leftSwitchPrefab = Instantiate(leftSwitchPrefab, new Vector2(leftThree.x,leftThree.y), Quaternion.identity);
        Debug.Log("Left 3 index is: " + leftRandom3);
    }

    public void RandomRight()
    {
        int rightRandom1 = Random.Range(0, rightSwitchSpawns.Length -1);
        Debug.Log("This Right array length is " + rightSwitchSpawns.Length);
        Vector2 rightOne = rightSwitchSpawns[rightRandom1].transform.position;
        rightSwitchPrefab = Instantiate(rightSwitchPrefab, new Vector2(rightOne.x,rightOne.y), Quaternion.identity);
        Debug.Log("Right 1 index is: " + rightRandom1);

        int rightRandom2 = Random.Range(0, rightSwitchSpawns.Length -1);
        while (rightRandom2 == rightRandom1)
        {
            rightRandom2 = Random.Range(0, rightSwitchSpawns.Length -1);
        }
        Vector2 rightTwo = rightSwitchSpawns[rightRandom2].transform.position;
        rightSwitchPrefab = Instantiate(rightSwitchPrefab, new Vector2(rightTwo.x,rightTwo.y), Quaternion.identity);
        Debug.Log("Right 2 index is: " + rightRandom2);

        int rightRandom3 = Random.Range(0, rightSwitchSpawns.Length -1);
        while (rightRandom3 == rightRandom1 || rightRandom3 == rightRandom2)
        {
            rightRandom3 = Random.Range(0, rightSwitchSpawns.Length -1);
        }
        Vector2 rightThree = rightSwitchSpawns[rightRandom3].transform.position;
        rightSwitchPrefab = Instantiate(rightSwitchPrefab, new Vector2(rightThree.x,rightThree.y), Quaternion.identity);
        Debug.Log("Right 3 index is: " + rightRandom3);
    }

    public void DestroyRightSwitches(){
        Debug.Log("Right Switches Destroyed");
        Destroy(rightSwitchPrefab);
    }

    public void DestroyLeftSwitches(){
        Debug.Log("Left Switches Destroyed");
        Destroy(leftSwitchPrefab);
    }
}

PlayerMovement Script

using System.Collections.Generic;
using UnityEngine;

public class PlayerMovement : GameRules
{
    private float speed = 5f;
    private float jump = 5f;
    private Rigidbody2D rb;
    private bool isPlaying = false;
    private Transform trans;

    // Start is called before the first frame update
    void Awake()
    {
        trans = gameObject.GetComponent<Transform>();
        rb = gameObject.GetComponent<Rigidbody2D>();
        rb.simulated = false;
        
    }

    // Update is called once per frame
    void Update()
    {
        if(Input.GetMouseButtonDown(0)){
            if(isPlaying == false){
                isPlaying = true;
                rb.simulated = true;
                rb.velocity = new Vector2(speed,0f); 
            }
            else{
                rb.velocity = new Vector2(speed,jump);
            }
        }
    }
    void OnCollisionEnter2D(Collision2D collision)
    {
        if (collision.gameObject.tag == "Wall")
        {
           OnDeath();
        }

        if(collision.gameObject.tag == "RightSwitch"){
            speed = -speed;
            rb.velocity = new Vector2(speed,0f); 
            DestroyRightSwitches();
            RandomRight();
        }
         if(collision.gameObject.tag == "LeftSwitch"){
            speed = -speed;
            rb.velocity = new Vector2(speed,0f); 
            DestroyLeftSwitches();
            RandomLeft();
        }
    }

    void OnDeath(){
        isPlaying = false;
        rb.simulated = false;
        trans.position = new Vector2(0,0);
        DestroyLeftSwitches();
        DestroyRightSwitches();
        RandomLeft();
        RandomRight();
    }
}

The specific error is

IndexOutOfRangeException: Index was outside the bounds of the array. GameRules.RandomLeft () (at Assets/Scripts/GameRules.cs:28) GameRules.Start () (at Assets/Scripts/GameRules.cs:20)

But if you look at the debug statements. At initial runtime the array is full with a length of 7, Gives you the indexes of each point. and then it runs again for some reason with a length and index of 0. Then the error shows up.

The errors I Get in picture form

  • Your array length is zero in the case where it encountered an IndexOutOfRangeException. Generating a random number in the range (0, -1) will produce 0. The index 0 is out of range for an array with zero elements. You'll have to handle what to do when your array length is zero with a special case, as no index is valid. No value of `leftRandom1` will permit `leftSwitchSpawns[leftRandom1]` to execute without exception if `leftSwitchSpawns` has length zero. – Wyck Jul 07 '22 at 16:21
  • Does this answer your question? [What is an IndexOutOfRangeException / ArgumentOutOfRangeException and how do I fix it?](https://stackoverflow.com/questions/20940979/what-is-an-indexoutofrangeexception-argumentoutofrangeexception-and-how-do-i-f) – Wyck Jul 07 '22 at 16:24
  • No sorry I know what the error is and means. The issue was the I’m making my playermovement script inherit from the game rules script so I could use it’s functions. But that created a 2nd array that never gets filled so I have the one array doing what it’s supposed to and then another array that is empty at all times throwing the error. – Damion Russell Jul 07 '22 at 17:16

2 Answers2

0

Your arrays are declared as public. In Unity3d's MonoBehaviour it means that these fields are serialized. If you have this script attached to the game object on the scene or to some prefab that is instantiated after, serialized values will be taken from this game object (you can see it in the inspector). It means that if there will be empty arrays in the serialized object, the length of your arrays will be 0 at runtime.

Morion
  • 10,495
  • 1
  • 24
  • 33
0

The issue is that I have the Playermovement script deriving from my GameRules script so in the hierarchy the player movement script also has empty arrays attached to the game object.

  • Your answer could be improved with additional supporting information. Please [edit] to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Jul 08 '22 at 08:57