Randomizing the same animation transition on multiple instances of a prefab?

Hi everyone,

I have a prefab that currently has an animator and four different animation clips on it, as you can see below:

  1. Animation 1 - Gem glows red in colour (Default Animation)
  2. Animation 2 - Gem transitions to blue colour, if the ChangeGemToBlue boolean is set to true.
  3. Animation 3 - Gem glows blue in colour (automatically happens after the gem changes to blue).
  4. Animation 4 - Gem transitions back to red colour, if the ChangeGemToRed boolean is set to true.

My ultimate goal is for this entire animation sequence to happen for all instances of this prefab, but at random times (i,e. the two animation transitions based on booleans will occur at random times, not the actual length of each animation clip).

However, I am facing a couple of issues:

  1. When I create multiple instances of this prefab, they are only able to do the default animation (Animation 1). I have a script that calls for an animator, but this only allows for a single instance of the prefab to transition to the next animation clip. How do I get all the instances to change, without having to create multiple animators?

The script currently uses the Update function (not sure if that was the right move). I’ve copied the part of the script that relates to this specific animation. Currently I’ve just set up the first transition from animation 1 to 2.

public Animator gems;

void Update()
{
GemChange();
}

public void GemChange()
{
gems.SetBool((“ChangeGemToBlue”), true);
}

And this is what it looks like in the inspector:
6209720--682241--upload_2020-8-16_19-4-7.png

  1. How do I randomize when the transition starts, for different objects?

Very new to this, so apologies in advance if I misunderstand anything! Please let me know if you’d like more information.

You can do it cheap and cheerful with a coroutine, something like this:

IEnumerator RandomlyChangeColors()
{
   const float MinTime = 4.0f;   // you adjust these obviously
   const float MaxTime = 8.0f;

   while(true)
   {
      yield return new WaitForSeconds( Random.Range( MinTime, MaxTime);
      gems.SetBool(("ChangeGemToRed"), false);
      gems.SetBool(("ChangeGemToBlue"), true);

      yield return new WaitForSeconds( Random.Range( MinTime, MaxTime);
      gems.SetBool(("ChangeGemToBlue"), false);
      gems.SetBool(("ChangeGemToRed"), true);
   }
}

In your Start function you would do:

StartCoroutine( RandomlyChangeColors());

Each script instance will pick its own random time (based on MinTime/MaxTime variables) and I think that’s what you want.

Have you looked into using a Trigger type animator parameter? That way you don’t have to change the old one to false:

Once the trigger is acted on by the animation, it gets automatically cleared.

Also, for future code postings, please use code tags:

1 Like

That worked perfectly thank you so much! Will look into the trigger type parameters. And noted on the code tags, will use them in the future!

As for the prefab, how do I get this script to work on multiple objects? Currently it just works on the single gameObject I drag into the animator field in the inspector, and I can’t seem to drag the prefab (which has the animator on it) into this field.

Didn’t realize you have that on another object… you can do that but traditionally animation-related scripts are placed on the actual instance, to centralize knowledge about animation to that one object. This means it would go on the prefab itself and then get instantiated however many times you want them.

Then if you have a bunch of these, you would refer to either each GameObject in an array, using GetComponent to find the scripts you want on it, or you can just keep an array of those scripts, up to you.

Got it - did that, and it works perfectly! Thank you so much :slight_smile:

1 Like