Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Issues with random element in an array

Discussion in 'Scripting' started by misterG420, May 24, 2020.

  1. misterG420

    misterG420

    Joined:
    Jan 23, 2020
    Posts:
    31
    Hello community,

    I would love your view on the following issues I am having: I have a scene with "tiles" that I assign a random color in the start of the game. When I click on a tile, the color disappears (or rather the tile with the color gets set to inactive). Now I wanted to include a flask/jar of white circles that when you click on the colored tile, the circle in the jar gets the same color as the clicked tile.

    In essence, I will have an array of gameobjects which I call colorHolder. Whenever I click on a tile, colorHolder's aray element's color will be set equal to the color of the tile. However, there are some issues:

    At the start, the game correctly counts the array length, I check it in the start method with debug.log and it spit out 72. However, when I debug.log in the if statement, it states that the "index was outside the bounds of the array" and the array.length is apparenty 0. But the array's length hasn't changed. Why won't it assign the tile's color to the array's element colorHolder?

    Any help would be greatly appreciated - I am just stuck and need help please <3

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. public class ColorAssignment : MonoBehaviour
    6. {
    7.     private Vector3 mousePos;
    8.     private Camera mainCamera;
    9.     private Vector3 mousePosWorld;
    10.     private Vector2 mousePosWorld2D;
    11.     RaycastHit2D hit;
    12.  
    13.     private Player player;
    14.     private Color hitColor;
    15.  
    16.     public GameObject[] colorHolder;
    17.  
    18.     void Start()
    19.     {
    20.  
    21.                 player = GameObject.FindGameObjectWithTag("Player").GetComponent<Player>();
    22.         if (player == null)
    23.         {
    24.             Debug.LogError("Player Script is NULL!");
    25.         }
    26.  
    27.         GetComponent<SpriteRenderer>().material.color = new Color(Random.value, Random.value, Random.value, 0.5f);
    28.  
    29.         mainCamera = GameObject.FindGameObjectWithTag("MainCamera").GetComponent<Camera>();
    30.         if(mainCamera == null)
    31.         {
    32.             Debug.LogError("Camera is NULL!");
    33.         }
    34.  
    35.         transform.gameObject.tag = "Tiles";
    36.  
    37.         GameObject[] colorHolder = GameObject.FindGameObjectsWithTag("ColorHolder");
    38.         Debug.Log("colorHolder.length: " + colorHolder.Length); //correctly states that colorHolder.length is 72 - which is true!
    39.     }
    40.  
    41.  
    42.     void Update()
    43.     {
    44.         HandlePlayerClicking();
    45.     }
    46.  
    47.  
    48.     private void HandlePlayerClicking()
    49.     {
    50.         if (Input.GetMouseButtonDown(0))
    51.         {
    52.             mousePos = Input.mousePosition;
    53.             mousePosWorld = mainCamera.ScreenToWorldPoint(mousePos);
    54.             mousePosWorld2D = new Vector2(mousePosWorld.x, mousePosWorld.y);
    55.  
    56.             hit = Physics2D.Raycast(mousePosWorld2D, Vector2.zero);
    57.             GameObject hitObject;
    58.  
    59.             if (hit.collider != null)
    60.             {
    61.              
    62.                 if (hit.collider.gameObject.tag == "Tiles")
    63.                 {
    64.                     hitObject = hit.collider.gameObject;
    65.                     hitColor = gameObject.GetComponent<SpriteRenderer>().material.color; //this is the color the tile has been assigned to;
    66.                     player.IncreaseClickedTilesCounter();
    67.                     hitObject.SetActive(false);
    68.  
    69.                     int rand = Random.Range(0, colorHolder.Length);
    70.                     Debug.Log("colorHolder.Length: " + colorHolder.Length); //causes error that colorHolder.length is 0 - which is not true!
    71.                     colorHolder[rand].GetComponent<SpriteRenderer>().material.color = gameObject.GetComponent<SpriteRenderer>().material.color;
    72.                  
    73.                 }
    74.             }
    75.         }
    76.     }
    77.  
    78.     /*
    79.     GameObject[] GetAllColorHolders()
    80.     {
    81.         GameObject[] allColorHolders = GameObject.FindGameObjectsWithTag("ColorHolder");
    82.         {
    83.             foreach (var p in allColorHolders)
    84.             {
    85.                 p.GetComponent<SpriteRenderer>().material.color = gameObject.GetComponent<SpriteRenderer>().material.color;
    86.             }
    87.             return allColorHolders;
    88.         }
    89.     }
    90.     */
    91.  
    92. }
    93.  
    94.  
     
  2. tonemcbride

    tonemcbride

    Joined:
    Sep 7, 2010
    Posts:
    1,077
    It looks like you're assigning 'colorHolder' to a local variable (which then gets destroyed when the function ends).

    Code (CSharp):
    1. GameObject[] colorHolder = GameObject.FindGameObjectsWithTag("ColorHolder");
    2. Debug.Log("colorHolder.length: " + colorHolder.Length); //correctly states that colorHolder.length is 72 - which is true!
    This should probably be:

    Code (CSharp):
    1. colorHolder = GameObject.FindGameObjectsWithTag("ColorHolder");
    2. Debug.Log("colorHolder.length: " + colorHolder.Length); //correctly states that colorHolder.length is 72 - which is true!
    if you want to assign it to your class member variable 'colorHolder'.
     
  3. misterG420

    misterG420

    Joined:
    Jan 23, 2020
    Posts:
    31
    Wow - you are a genius.

    But it still does not quite work: It now assignes the same color to the different colorHolder elements. It does not accurately "clone" the color of the tile to the colorHolder :(

    Which is really weird, because I actually even define a color variable in the if-statement: "hitColor". So the color of the tile should theoretically be stored in the hitColor, so that I can set the hitColor equal to the color of the colorHolder element.

    Man, arrays are giving me headaches :(
     
    Last edited: May 24, 2020
  4. tonemcbride

    tonemcbride

    Joined:
    Sep 7, 2010
    Posts:
    1,077
    It looks like you're taking the color from your object with the 'ColorAssignment' component on it.

    For example, you do this:

    Code (CSharp):
    1. 64) hitObject = hit.collider.gameObject;
    2. 65) hitColor = gameObject.GetComponent<SpriteRenderer>().material.color; //this is the color the tile has been assigned to;
    It looks like you should maybe be taking the colour from 'hitObject' instead of 'gameObject' (which is the object you're running the script on)

    Code (CSharp):
    1. 64) hitObject = hit.collider.gameObject;
    2. 65) hitColor = hitObject.GetComponent<SpriteRenderer>().material.color; //this is the color the tile has been assigned to;
    It would make sense for this line to do the same:

    Code (CSharp):
    1. 71) colorHolder[rand].GetComponent<SpriteRenderer>().material.color = hitColor;
     
  5. misterG420

    misterG420

    Joined:
    Jan 23, 2020
    Posts:
    31
    Amazing, you are right - it works perfectly now! Think I'll never get used to arrays and such :D Thanks a bunch sir! You helped me implement a feature that won't make the game any more fun, but it looks nicer :)
     
    tonemcbride likes this.
  6. tonemcbride

    tonemcbride

    Joined:
    Sep 7, 2010
    Posts:
    1,077
    Great, glad you got it working ok!