Random.Range(int, int) returning only min value

After having had no issue with Random.Range for the last few months, it suddenly has decided to stop working for me.

int random = UnityEngine.Random.Range(1, 4);

Is returning 1, and ONLY 1.

Here’s the full code for context:

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

public class ForgeSprite : TimelineSprite
{
	protected static ForgeSprite mForgeSprite;

	static string mNextAnimation = "";

	Timeline mCommonTimeline = null;
	Timeline mFinishTimeline = null;
	bool mIsFinished = false;

	protected override void Start()
	{
		base.Start();

		Common.hideObject(transform);

		mForgeSprite = this;

		mCommonTimeline = getTimeline("Forge_Common");
	}

	public override void Update()
	{
		if (mNextAnimation != "")
		{
			if (mCommonTimeline != null && mCommonTimeline.isFinished())
			{
				int random = UnityEngine.Random.Range(1, 4);

				mNextAnimation += random;

				mFinishTimeline = getTimeline(mNextAnimation);
				mForgeSprite.playAnimation(mNextAnimation);

				mNextAnimation = "";
			}
		}

		if (mFinishTimeline != null)
		{
			if (mFinishTimeline.isFinished())
			{
				mFinishTimeline = null;

				mIsFinished = true;


			}
		}

		base.Update();
	}

	protected override void OnDestroy()
	{
		mForgeSprite = null;

		base.OnDestroy();
	}

	public static ForgeSprite getForgeSprite()
	{
		if (mForgeSprite == null)
		{
			mForgeSprite = Common.getNewObject("Effects/CutIns/ForgeAnimation").GetComponent<ForgeSprite>();
		}

		return mForgeSprite;
	}

	public static void playSuccess()
	{
		getForgeSprite();

		if (mForgeSprite != null)
		{
			Common.showObject(mForgeSprite.transform);

			mForgeSprite.mIsFinished = false;
			mForgeSprite.mFinishTimeline = null;

			mForgeSprite.playAnimation("Forge_Common");
			mNextAnimation = "Forge_Success_" ;
		}
	}

	public static void playFail()
	{
		getForgeSprite();

		if (mForgeSprite != null)
		{
			Common.showObject(mForgeSprite.transform);

			mForgeSprite.mIsFinished = false;
			mForgeSprite.mFinishTimeline = null;

			mForgeSprite.playAnimation("Forge_Common");
			mNextAnimation = "Forge_Miss_";
		}
	}

	public static void load()
	{
		getForgeSprite();
	}

	public static bool isPlaying()
	{
		if (mForgeSprite != null)
		{
			return mNextAnimation != "" || mForgeSprite.mFinishTimeline != null || mForgeSprite.mIsFinished;
		}

		return false;
	}

	public static bool isFinished()
	{
		if (mForgeSprite != null)
		{
			return mForgeSprite.mIsFinished;
		}

		return false;
	}

	public static void clicked()
	{
		if (mForgeSprite.mIsFinished)
		{
			mForgeSprite.mIsFinished = false;

			Common.hideObject(mForgeSprite.transform);
		}
	}
}

Any ideas on what I’m missing here?

Unless you’re constantly setting Random.seed to the same value every frame somewhere, that will return 1, 2, or 3.

I had the same/similar problem now, I had mistakenly used Random.Next(low, max) believing that max was inclusive, while it really is exclusive: Unity - Scripting API: Random.Range
So Random.Next.Range(3, 5) will return 3 or 4 only, never 5.

Yes, as a 2017 update to this post, using Random.Range on an int will never return the max result. Using the for loop above:

for(int i = 0; i<100; i++){
		int x = Random.Range (1, 2);
		Debug.Log (x);
}

… returns a value of 1 each time.

The current answer is a bit useless and doesn’t explain anything, give examples, links, and the keyword “Seeds” isn’t explained nor is this keyword explained in the linked docs. Here is the REAL answer, posted in a comment by @Bunny83 :

Note that the method has two overloads: one that accepts float values where the upper limit is inclusive and one that accept int values where the upper limit is exclusive. So Random.Range with int parameters will never return the upper limit itself.

 int a = Random.Range(0,1); // [0]
 int b = Random.Range(0,5); // [0,1,2,3,4]
 int c = Random.Range(5,7); // [5,6]
 int d = Random.Range(10,11); // [10]
 float f = Random.Range(1f, 2f); // [1f - 2f]
 float g = Random.Range(1.1001f, 1.123f); // [1.1001f - 1.123f]

Additionally:

  • Here is a legacy doc to explain seeds: Unity - Scripting API: Random.seed
  • However, since Random Range has seeds in the background, that’s too much theory for what OP was trying to achieve, since he was wondering why he never returned the max #:

Random.Range with FLOATS, eg, (1f, 2f) will return anywhere between 1 and 2.

However, ints are tricky: (1, 2) will return only 1. Never 2. Ints will never return the max.

TL;DR: Random.Range() with ints will NEVER return the max specified range (eg, 0 to 3 will only return 0 to 2).

Do this

float rand = Random.Range(0.0f,1);

It will works perfectly. Seemlike Unity will generate integer if min max values are integers.