Why are Multiple Random Numbers Being Generated

I am trying to use a very simple random number generator but something weird is happening. After the first few numbers are generated, two or three or more numbers are generated at once.
I am just using

tubeCoice = Random.Range (1, 6);

tubeChoice is declared as a public int.

Does anyone have any ideas why this might be happening?

This is like me saying “I’m having a problem. The other day, I couldn’t drive to the store. I’m just using a handle. Does anyone have any ideas?”

You probably need to provide a lot more information.

The full details of my program are that I am trying to make a rather simple remake of the original mario game. I am generating a random number in order to have a coin appear at a specific location at a given time. The code seems to work for the first two coins, but then after that two coins appear at a time, then three, then four, and so on. When I print out the random number again it starts with one at a time, then multiple start appearing. I have attached the full code as I have it so far.

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

public class coinScript : MonoBehaviour {

    public GameObject myCoin;
    public int tubeCoice;
    public int randTime;
    public float myTime;

    void Start () {
        myTime = Time.time + 10;
    }

    void Update ()
    {
        if (myTime < Time.time) {
            tubeCoice = Random.Range (1, 6);
            print (tubeCoice);
            
            //top left tube
            if (tubeCoice == 1) {
                Instantiate (myCoin, new Vector2 (-11, 4), Quaternion.identity);
            }

            //bottom left tube
            if (tubeCoice == 2) {
                Instantiate (myCoin, new Vector2 (-9, -3), Quaternion.identity);
            }

            //top center tube
            if (tubeCoice == 3) {
                Instantiate (myCoin, new Vector2 (0, 4), Quaternion.identity);
            }

            //top right
            if (tubeCoice == 4) {
                Instantiate (myCoin, new Vector2 (11, 1), Quaternion.identity);
            }

            //bottom right
            if (tubeCoice == 5) {
                Instantiate (myCoin, new Vector2 (10, -3), Quaternion.identity);
            }

            randTime = Random.Range (15, 60);
            myTime = Time.time + 5;
        }
    }

    void coinFlood()
    {
        Instantiate (myCoin, new Vector2 (-11, 4), Quaternion.identity);
        Instantiate (myCoin, new Vector2 (-9, -3), Quaternion.identity);
        Instantiate (myCoin, new Vector2 (0, 4), Quaternion.identity);
        Instantiate (myCoin, new Vector2 (11, 1), Quaternion.identity);
        Instantiate (myCoin, new Vector2 (10, -3), Quaternion.identity);
    }
}

It’s hard for me to see past the redundancy. Please just put those vectors in an array and use tubeChoice to index into the array. Then coinFlood can just foreach over the array or, better yet, call the method you wrote to encapsulate the idea of putting a coin in a tube.

If it was 1, 2, 4, 8, my first question would be “Does the prefab that myCoin points to have an instance of the coinScript MonoBehaviour on it?”

Since you say it’s 1, 2, 3, 4, 5, my first question is going to be “Are you sure it’s not 1, 2, 4, 8, …?” with a follow up of “Does the prefab that myCoin points to have an instance of the coinScript MonoBehaviour on it?”

You are right in that an array would be more efficient, I am just not there yet, so although I know the code is less efficient, I can follow it for now and clean it up later.
Just to be sure, I have attached a screen capture of my coin in the inspector window.

So, the prefab also has the script on it?

So your coin prefab has an instance of the coin script on it and uses itself as the prefab. When it instantiates the prefab, it generates another coin, which has another copy of the coin script. Now you have two. When their timers burn down, they will each generate another coin, leaving you with four. Those four will make eight. Those eight will make sixteen, and so on until you get an OutOfMemoryException. If you don’t believe me, you can make it so that the interval between instantiates is always five seconds, instead of ten seconds followed by five seconds.

If you want to see the effect of this, watch your hierarchy window. You’ll see them grow out of control.

What you need is to make this coin script (which should really be the coin spawn script) live on something other than the prefab it instantiates.

(You’re not the first person who’s done this…don’t worry) :slight_smile:

Oh, I am so stupid!!! I have not attached it to an empty game object and it works fine now.
Just to clarify though, since I have people helping me, is attaching to an empty game object a good way of doing it, or have I just gotten lucky?

Yeah. I think there’s a story about a guy who defeated an emperor with this script…

public class GrainOfRice : MonoBehaviour
{
  public GrainOfRice Template;

  void Start()
  {
    Template = this;
  }

  void Update()
  {
    Instantiate(Template);
  }
}

…empty game object. An object called “coin maker”… whatever. Just not the prefab that it instantiates.

The more people you think you might want to collaborate with, the more important it is that the game object which hosts this script be easily discovered in the editor.

1 Like

heh, you wrote you have not attached it… :slight_smile:

Anyways, for sure… any object that isn’t itself… some general manager/empty object will suffice. :slight_smile:

This may be really dumb but planning ahead, since I am going to have multiple things appearing and moving on the screen, can attach those scripts to the same game object, or should I have a game object for each script?

I think it’s kinda handy to attach them to the same script, sometimes. :slight_smile: It’s really up to you; both ways will work.

1 Like