- Home /
Start Mecanim animation at random time.
I am in the process of changing over my game to use Mecanim and have one issue remaining. Previously with the legacy animation system I started animations at a random point for groups and crowds so that animations were not synced up.
This was easy to accomplish using the following code:
animation["idle"].time = Random.Range(0.0f, animation["idle"].length;
Is there any way to duplicate this behavior in Mecanim?
Answer by komodor · Jan 24, 2014 at 12:15 AM
dunno, but now you can do just:
Animator.Play(state, layer, normalizedTime);
or
Animator.CrossFade(state, crossFadeTime, layer, normalizedTime);
if you put whatever float from 0 to 1 into normalized time, you can set it to any time position you want
This is excellent, exactly what I have been looking for but not finding. If you set the animator speed to 0, this can also be used to link the playback of animations directly to a value in your script (e.g. an animation of your character's head turning from far left to far right can be used to make him look in the right direction just by setting the normalized time based on how left or right the script thinks he should be looking).
Thanks for sharing this, komodor. It seems obvious in retrospect, but I know a lot of people have been overlooking this essential little gem. $$anonymous$$aybe the api is a little counter-intuitive (I don't want to play a new animation, I just want to control the currently playing animation).
Been meaning to update this. This functionality was added when ForceStateNormalizedTime was deprecated.
This works to start an animation, but what if the animation is the default, such as idle, i.e. an anim the characters will return to after finishing moving etc?
5 characters running together will then go back to standing still at pretty much the same time (or, exactly the same time, if doing a turn-based game) and I would like to avoid doing a hard cut back to idle via code, upon finising moving, as oppose to set the state-flag as per usual.
What is the approach then? Any way to set a different start-location of a looped animation per character?
Answer by Bryan-Legend · Jan 05, 2018 at 06:29 PM
void Start()
{
var animator = GetComponentInChildren<Animator>();
animator.Update(Random.value);
}
Answer by thor_tillas · May 07, 2013 at 01:46 PM
In just run into this and I come up with the following solution:
protected virtual void Start()
{
this.Animator.ForceStateNormalizedTime(UnityEngine.Random.Range(0.0f, 1.0f));
}
But be aware that once you will transition to another state and then go back to the Idle one, if two or more pawns make the transition at the same time, their animations would be sync again. I have not found a way to avoid that for the moment.
Cheers ! Flo
Thank you for pointing that out (it worked for me). Note that this method is deprecated in Unity v4.3. If someone knows how to de-sync avatars another way, I'd love to see the code.
Answer by grande_graf · Apr 18, 2015 at 05:23 PM
Or as an extension:
protected bool _randomSet = false;
void Update ()
{
if (_randomSet == false)
{
// random animation start point
_animator.SetTimeForCurrentClip(Random.value);
_randomSet = true;
}
}
public static Animator SetTimeForCurrentClip(this Animator self, float percent, int layer = 0)
{
AnimatorClipInfo[] cInfo = self.GetCurrentAnimatorClipInfo(layer);
if (cInfo.Length > 0)
{
AnimationClip clip = cInfo[0].clip;
self.Play(clip.name, layer, clip.length * percent);
}
return self;
}
Thank you! This worked for me. With this method, you don't need the state name which is wonderful and generic.
Answer by Ash-Blue · Sep 01, 2014 at 06:22 AM
Here is a code snippet I use that randomizes the start time with a public bool at awake. That way you can easily tweak whether it should be randomized or not.
anim = GetComponent<Animator>();
if (!randomizeStartFrame) {
anim.Play(animatiorStartName);
} else {
float startPoint = Random.Range(0f, 1f);
anim.Play(animatiorStartName, -1, startPoint);
}
I've actually created an open source helper library that includes this script and others for typical use cases like this.
Your answer
Follow this Question
Related Questions
What is the proper way to wait for an Animator Controller to update? 1 Answer
Trigger Activated Multiple Times From One Click 2 Answers
How to maintain FIFO in Animator controller when you set multiple parameter in one frame ? 0 Answers
AddMixingTransform with Mecanim 1 Answer
mecanim, adjusting character stance with mouse input using c# script 0 Answers