Making an Array of Animations Play at Random With No Repeats

I have created a practice project to figure out how to get a random animation to play every time a button is clicked until all the animations have played with no animation playing twice. Ten animations are assigned to anims[] in the inspector. So far I have come up with this script:

var anims : AnimationClip[];
var randomAnims : AnimationClip[];
var order = new ArrayList(); 
var currentClip : AnimationClip;
var chosenOne: int;
var orderString = new ArrayList(); 

function OnGUI()
{ 
    if (GUI.Button (Rect (105, 457, 100, 22), "Next")) 
    {
        PlayAtRandom();
    }
}

function PlayAtRandom()
{
    for (var i = anims.length - 1; i > 0; i--) 
    {
        chosenOne = Random.Range(0,anims.length);
        var next = i.ToString();
        var ind = orderString.IndexOf(next);

        if (ind < 0)
        {
            orderString.Add(next);
            order.Add(i);
            randomAnims[chosenOne] = anims[order*];*
 *currentClip = randomAnims[chosenOne];*
 *animation.Play(currentClip.name);*
 *}*
 *}*
*}*
*```*
_<p>When I press play, and press the "Next" button, it generates an error saying "ArgumentOutOfRangeException: Index is less than 0 or more than or equal to the list count."  Pointing to line 26 "randomAnims[chosenOne] = anims[order*];".</p>*_
_*<p>What am I doing wrong here?*_
_*Thank you.</p>*_

If you're willing to rewrite your code, consider this example which uses shuffling and queues. It is still possible that two animations come after each other if the first order was a, c, b and the other order is b, a, c. However you can easily modify this code to know the last used animation and swap it for the one in the other end of the array. That way you're guaranteed to never have same animation appear twice in a row.

import System.Collections.Generic;
var anims : AnimationClip[];
private var queue : Queue.<AnimationClip>;

// Added for comment discussion.
private var lastAnim : AnimationClip;

function OnGUI()
{ 
    if (GUI.Button (Rect (105, 457, 100, 22), "Next")) 
        PlayNext();
}

function PlayNext()
{
    if (queue == null || queue.Count == 0)
        CreateQueue();

    // Changed for comment discussion.
    lastAnim = queue.Dequeue();
    animation.Play(lastAnim.name);
}

function CreateQueue()
{
    Shuffle(anims);
    Shuffle(anims);
    Shuffle(anims);

    // Added for comment discussion.
    // Swap the first and last if the first is the same as 
    // was used last animation.
    if (anims[0] == lastAnim)
    {
        var last = anims.Length - 1;
        var tmp = value[0];
        value[0] = value[last];
        value[last] = tmp;
    }

    queue = new Queue.<AnimationClip>(anims);
}

function Shuffle(value : AnimationClip[])
{
    for (var i = 0; i < value.Length; ++i)
    {
        var r = Random.Range(0, value.Length);
        var tmp = value*;*
 _value *= value[r];*_
 _*value[r] = tmp;*_
 _*}*_
_*}*_
_*```*_
randomAnims[chosenOne] = anims[order*];*
*```*
*<p>You must have arrays of inconsistent length. </p>*
*<p>You're using an index based of the length of <strong>anims</strong> but it's unclear if <strong>order</strong> is at least as long as anims, and if <em>any value in <strong>order</em></strong> is less than <strong>anims.length</strong>. Finally, your <strong>randomAnims</strong> also must be at least the size of <strong>anims</strong>. Are they?</p>*
_<p>Since you seem to be adding items to order procedurally, <strong>order.Add(i);</strong>, then try to index into it <strong>order*</strong>, and <strong>i</strong> starts as the highest index, this looks like the place you're getting errors. Consider this with literal values:</p>*_
_*```*_
_*order.Add(30);*_
_*randomAnims[chosenOne] = anims[   order[30]   ];*_
_*```*_
_*<p>order only contains one item in the first iteration still you're trying to access the last...</p>*_

Change the line of code that reads...

chosenOne = Random.Range(0,anims.length);

to

chosenOne = Random.Range(0,anims.length - 1);

You are trying to get a random animation, but since Random.Range takes a 0 based value, you need to put in the -1, so it will make sure you always getting a range within the bounds of the array.