【Unity 3D学习】控制Animator动画从随机帧开始
程序员文章站
2022-03-26 18:06:22
...
一、前提:游戏主场景有很多建筑,然后建筑上会有动画,如果存在多个同类型的建筑,就会出现多个相同动画频率一致的情况,这样子产品说体验性较差,所以考虑怎么控制动画从不同帧开始播放。
二、处理方案。
1、原理:通过设置动画状态机中的Cycle Offset,可以控制动画起始播放点,该值的区间是0到1,类型为float类型。
2、具体操作:我们首先给Animator添加一个“offset”参数,然后指定Animator状态机中所有状态使用Cycle offset属性,并且指定使用上面添加的“offset”参数。然后我们可以在动画挂上一个随机脚本,该脚本在OnEnable的时候会随机在0到1之间生成一个随机值,同时把该随机值设置为animtor的“offfset”值,即可达到效果。
三、具体代码
1、统一处理建筑prefab动画参数
public static void HandleBuildingBlockAnimRandom()
{
UnityEngine.Object[] selection = Selection.objects;
foreach (var obj in selection)
{
Animator[] anims = ((GameObject)obj).GetComponentsInChildren<Animator>();
for (int i = 0; i < anims.Length; i++)
{
UnityEditor.Animations.AnimatorController controller = (UnityEditor.Animations.AnimatorController)anims[i].runtimeAnimatorController;
bool is_find = false;
foreach (AnimatorControllerParameter param in controller.parameters)
{
if (param.name == "offset")
{
is_find = true;
break;
}
}
if (!is_find)
{
controller.AddParameter("offset", UnityEngine.AnimatorControllerParameterType.Float);
}
foreach (UnityEditor.Animations.ChildAnimatorState state in controller.layers[0].stateMachine.states)
{
state.state.cycleOffsetParameterActive = true;
state.state.cycleOffsetParameter = "offset";
}
}
AnimationRandom comp = ((GameObject)obj).GetComponent<AnimationRandom>();
if (comp == null)
{
((GameObject)obj).AddComponent<AnimationRandom>();
}
}
AssetDatabase.Refresh();
AssetDatabase.SaveAssets();
}
2、随机脚本
public class AnimationRandom : MonoBehaviour {
// Use this for initialization
void OnEnable () {
var animators = GetComponentsInChildren<Animator>(true);
foreach (var anim in animators)
anim.SetFloat("offset", Random.Range(0.0f, 1.0f));
}
}