在 Unity 中如果角色的动画状态机一致的话,可以采用 动画模板控制器+动画重载控制器 的方式来实现,这样就无需每个角色都创建自己的动画控制器,当增加动画状态时,重载控制器只需覆盖掉相应的动画即可。
但是,动画模板控制器AnimatorController 里面的每个状态都需要关联动画片段,否则重载控制器AnimatorOverrideController 无法进行覆盖。那么为了可以进行覆盖,就需要创建空的动画片段来进行关联。以下是两种方式创建:
从3ds Max
导出个1帧的FBX动画文件,导入到Unity,编写代码来自动根据动画控制器的状态生成相应的动画片段,如下所示:
这种方式可以方便的直接对动画片段进行增删改,但是对于自动生成的,可以不考虑增删改。
另一点是模板控制器和动画片段是分开的,如下所示:
在打包的时候,就需要注意将它们打包在一起,而不要打成两个 AssetBundle 包,增加读取依赖的复杂度。
当然,可以使用AssetDatabase.AddObjectToAsset
将它们合并成一个资源。
在 UGUI 中的按钮点击过渡状态可以使用动画控制器,它会生成一个内嵌动画片段的动画控制器,如下所示:
那么可以借鉴使用这种方式来生成所要关联的空动画片段。
代码如下:
登录后复制
public static void SetTemplateUpdate()
{
string controllerPath = kTemplateController;
AnimatorController ac = AssetDatabase.LoadAssetAtPath<AnimatorController>(controllerPath);
var allAssets = AssetDatabase.LoadAllAssetsAtPath(controllerPath);
foreach (var asset in allAssets)
{
// 删除已有的
if (asset is AnimationClip)
{
Object.DestroyImmediate(asset, true);
}
}
// 需要设置循环的动画片段
string[] loopAnims = new[] { "idle", "run", "patrol", "ready" };
// 获取所有的状态,自定义的方法
List<ChildAnimatorState> childAnimatorStates = AnimatorControllerUtil.AnimatorController_States(ac);
foreach (var childAnimatorState in childAnimatorStates)
{
string clipName = childAnimatorState.state.name;
// 创建动画片段
AnimationClip animationClip = AnimatorController.AllocateAnimatorClip(clipName);
// 设置循环
var settings = AnimationUtility.GetAnimationClipSettings(animationClip);
settings.loopTime = loopAnims.Contains(clipName);
AnimationUtility.SetAnimationClipSettings(animationClip, settings);
// 合并资源
AssetDatabase.AddObjectToAsset(animationClip, ac);
// 设置关联
childAnimatorState.state.motion = animationClip;
}
AssetDatabase.ImportAsset(controllerPath);
AssetDatabase.SaveAssets();
}
最后效果如下:
这种方式不能对生成的动画片段进行方便的改名和删除,只能通过代码来操作。
免责声明:本文系网络转载或改编,未找到原创作者,版权归原作者所有。如涉及版权,请联系删