Random.Range Except current value

Hi there, I have this script which regularly changes the material on a object. It uses Random.Range to pick from an array of materials. The only problem is that it often picks the material that is already being used and therefore doesn’t change. I want the to ensure that the Random.range picks one of the materials from the array that is not already in use.

public class LightSwitcher : MonoBehaviour {

	public int timerToChange;

	public Material[] colorArray;

	SpriteRenderer currentColor;


	// Use this for initialization
	void Start () {
		currentColor = GetComponent<SpriteRenderer> ();

	
		InvokeRepeating ("Change",1,timerToChange);
	}
	
	void Change() {
		currentColor.material = colorArray [Random.Range (0, colorArray.Length)];
		Debug.Log ("Changed");
	}

Any help would be appreciated!

The easiest solution (but not the best) is to check the current material with the one you just selected. If it’s the same you should get another random and check again. However, for a small number of materials you have a high probability to get the same material, so the time you spend in while is greater.

The second solution is to create a list of unused materials. In Start initialize this list with all your materials from the array. Then make the random, remove the selected material from the list. When you’ll need another material, the list contains all the materials but the one you’re currently use (so you’re sure that the new material is different). After you select the new material, remove it from the list and add the old one.

using UnityEngine;
using System.Collections.Generic;

public class LightSwitcher : MonoBehaviour {

	public int timerToChange;

	public Material[] colorArray;
	public List<Material> mats = new List<Material> ();

	SpriteRenderer currentColor;
	Material currentMaterial;
	Material oldMaterial;


	// Use this for initialization
	void Start () {
		currentColor = GetComponent<SpriteRenderer> ();
		for (int i = 0; i < colorArray.Length; i++)
			mats.Add (colorArray *);*
  •  InvokeRepeating ("Change",1,timerToChange);*
    
  • }*

  • void Change() {*

  •  if (currentMaterial != null)*
    
  •  	oldMaterial = currentMaterial;*
    
  •  currentMaterial = mats [Random.Range (0, mats.Count)];*
    
  •  mats.Remove (currentMaterial);*
    
  •  if (oldMaterial != null)*
    
  •  	mats.Add (oldMaterial);*
    
  •  Debug.Log ("Changed");*
    
  • }*
    }