## Contents

- Introduction
`random`

- Creating An Array
`while`

Loop- Applying It To Things Other Than Numbers
- Conclusion

## Introduction

Sometimes you just need a random number. But not *that* random. I find that, when having numbers flash randomly on the screen for a video effect, that it works best when there are no repeats in the sequence. This can happen from time to time, especially if your range isn't that large, when using the `random()`

function. While it is perfectly understandable for what the function does, it still makes our animation look a little staggered.

So I set myself the challenge of writing an expression that excludes the previous number from the random generation, and thought about how this could be applied to projects in the future.

Here's what I did.

##
`random()`

Let's start at the beginning. If you need a random number in After Effects, using the `random(minVal, maxVal)`

function is a great place to start. By inputting a minimum and maximum value into the function, After Effects will generate a random number from within those bounds every frame.

```
random(1, 11)
```

That's a lot of decimal places! Since I just want integers, I use `Math.floor`

to round the numbers down. Because the range of the `random`

function is 1 to 11, this method will produce a random number between 1 and 10, since the top of the range is not included.

```
Math.floor(random(1, 11))
```

Much better. However I want to control how often the number changes, not on every frame. To do that, we need to use the `seedRandom(seed, timeless?)`

function. This function requires 2 arguments, the seed, and whether or not timeless mode is set to true or false. By default, timeless is set to false, meaning that the `random`

function will generate a new number each frame. However, if we set this to true, the `random`

function will only generate a number once.

```
seedRandom(0, timeless = true);
Math.floor(random(1, 11))
```

Now that the number only generates once, I can manipulate the seed number using a simple `for`

loop to control how often the number generates. If you're unfamiliar with `for`

loops I've written up an article about them in depth here.

Here is my basic loop:

```
let counter = 0;
let num = 0;
for (i = 0; time >= i; i++) {
seedRandom(counter, timeless = true);
num = Math.floor(random(1, 11));
counter++
}
num
```

First, I set up the variables `counter`

to track the changes in time, and `num`

, to store my random number. The loop is set to add 1 to `i`

whenever `time >= i`

, meaning the loop updates every second the timeline is active. Everytime the loop refreshes, `seedRandom`

is updated by the change in `counter`

's value, producing a new random number when `num`

is called at the end of the expression.

By adjusting `i`

in the `for`

loop, we can control how often the number changes per second. For instance, if we were to change the argument to `time >= i/2`

, the number will change twice every second instead of once.

Now that we have an expression which allows us to generate a new random number at an interval of our choosing, it needs to be amended to ensure we never have any duplicate entries one after another.

## Creating An Array

In order for After Effects to be able to compare numbers, the numbers need to be saved somewhere for After Effects to review. So I decided to save my random numbers to an array as they are generated over time.

```
let counter = 0;
let num = 0;
let allNum = [];
for (i = 0; time >= i/2; i++) {
seedRandom(counter, timeless = true);
num = Math.floor(random(1, 11));
allNum.push(num);
counter++
}
allNum
```

I create the variable `allNum`

outside of my `for`

loop, and then `push()`

the number currently inside of our `num`

variable to the array. This saves each number as it is generated across the timeline.

By calling `allNum`

at the end, we are able to see all the numbers in our array by the end of our timeline:

As you can see, this is less than ideal with a set of double 7s and triple 1s in our sequence. If we called `num`

and played our timeline, the doubles could make it look as if our timeline had frozen or stopped animating. Therefore, we need to ensure that our expression takes into account the previous entry of this array, and excludes it from being added again in such quick succession.

##
`while`

Loop

I found the answer to this was to add a `while`

loop within the existing `for`

loop.

A `while`

loop allows you to specify a command while certain criteria is true. In this case, we want it to be active while the current value of `num`

matches the previous value, listed in our `allNum`

array.

```
while (num == allNum[counter - 1]) num = Math.floor(random(1, 11));
```

While the current value of `num`

matches the previous entry inside of `allNum`

, the `while`

loop will generate a new random number using a new iteration of `Math.floor(random(1, 11))`

. This loop remains active as long as the numbers stay the same. Therefore, until a different number is generated, the `while`

loop will prevent the same number from being added to the `allNum`

array.

The while loop is inserted into our `for`

loop like so:

```
let counter = 0;
let num = 0;
let allNum = [];
for (i = 0; time >= i/2; i++) {
seedRandom(counter, timeless = true);
num = Math.floor(random(1, 11));
while (num == allNum[counter - 1]) num = Math.floor(random(1, 11));
allNum.push(num);
counter++
}
allNum
```

It is added after `num`

has attempted to generate a new number with the update to `seedRandom`

, but before it is pushed to the array so it can be re-generated if necessary.

With this amend, our array now looks like this:

As you can see, we no longer have double 7s or triple 1s in our sequence.

Therefore, if we call `num`

at the end of our expression instead of `allNum`

, we will have a random number between 1 and 10, excluding the previous entry generated, twice every second. Hooray!

## Applying It To Things Other Than Numbers

While random numbers are all well and good, there are other uses for this expression too. For instance, what if we wanted to randomise words on the screen instead, without duplicate repeats?

All we need to do is add another array.

```
var ranText = ["Banana", "Apple", "Pear", "Peach", "Pulm", "Orange", "Mango", "Lychee", "Pinapple", "Dragonfruit"];
```

Here is an array housing the text we want randomised. There are 10 entries, matching the range of the number generator we made previously.

By calling an entry of our new array using our `num`

variable, we can call the entry whose index matches that number:

```
//Text
var ranText = ["Banana", "Apple", "Pear", "Peach", "Pulm", "Orange", "Mango", "Lychee", "Pinapple", "Dragonfruit"];
//variables
let counter = 0;
let num = 0;
let allNum = [];
//For loop
for (i = 0; time >= i/2; i++) {
seedRandom(counter, timeless = true);
num = Math.floor(random(1, 11));
while (num == allNum[counter - 1]) num = Math.floor(random(1, 11));
allNum.push(num);
counter++
}
//return
ranText[num - 1]
```

Useful! Just remember to make sure that your `num`

variable at the end includes `-1`

, to account for the array index starting at 0.

Instead of using an array, it is possible to connect your expression to data inside of a .csv file. I go into how this is possible in my kinetic text breakdown here, should you want to make a template that is constantly updatable.

However you can use it in other ways too. Images can be randomly displayed as well, by connecting this expression to a slider controlling the frames of a precomp.

## Conclusion

In conclusion, it is possible to add a little bit more control over random numbers in order to make them look a little more aesthetically pleasing to the eye.

What did you think of this method? Is there an easier way? Did this help you with your project in any way? Please leave a comment and let me know.

## Top comments (0)