My Code : TP:FF21DDCC
现在做的项目用的动画系统是Generic,然后每次用AnimatorController的时候,都要重新拖拖拉拉很麻烦
如果加入一个新的角色,但它又有部分动作是复用之前的,这个时候导入FBX的时候就可以直接检查里面所有部件,并且把自己新的动作赋值进去:
先获取得到一个FBX里面所有的物件,并剔除动画文件出来:
List<AnimationClip> clipList = new List<AnimationClip>();
clipList.Clear();
Object[] objects = AssetDatabase.LoadAllAssetRepresentationsAtPath(assetPath);
foreach (Object obj in objects)
{
AnimationClip clip = obj as AnimationClip;
if (clip != null)
{
clipList.Add(clip);
}
}
再进行检测或者替换:
void CheckAndRefreshAnimatorController(AnimationClip[] newClips, AnimatorStateMachine stateMachine)
{
for(int i = 0; i < stateMachine.states.Length; i++)
{
ChildAnimatorState childState = stateMachine.states[i];
if(childState.state.motion == null)
{
Debug.Log("Null : " + childState.state.name);
continue;
}
if(childState.state.motion.GetType() == typeof(AnimationClip))
{
Debug.Log("Animation : " + childState.state.motion.name);
}else if(childState.state.motion.GetType() == typeof(BlendTree))
{
Debug.Log("BlendTree : " + childState.state.motion.name);
CheckAndRefreshBlendTree((BlendTree)childState.state.motion);
}
}
for(int i = 0; i < stateMachine.stateMachines.Length; i++)
{
Debug.Log("StateMachine : " + stateMachine.stateMachines[i].stateMachine.name);
CheckAndRefreshAnimatorController(newClips, stateMachine.stateMachines[i].stateMachine);
}
}
void CheckAndRefreshBlendTree(BlendTree tree)
{
for(int i = 0; i < tree.children.Length; i++)
{
ChildMotion childMotion = tree.children[i];
if(childMotion.motion.GetType() == typeof(AnimationClip))
{
Debug.Log("Animation : " + childMotion.motion.name);
}else if(childMotion.motion.GetType() == typeof(BlendTree))
{
Debug.Log("BlendTree : " + childMotion.motion.name);
CheckAndRefreshBlendTree((BlendTree)childMotion.motion);
}
}
}
void CheckAnimationClip(AnimationClip clip, AnimationClip[] clips)
{
}
用途很广,可以用作导入模型的时候就生成新的AnimatorController,完全不用手动(我现在项目就是如此)。
补充:
//不能用递归,因为用不了ref.
void CheckAndRefreshAnimatorController(AnimationClip[] newClips, AnimatorStateMachine stateMachine)
{
for(int i = 0; i < stateMachine.states.Length; i++)
{
ChildAnimatorState childState = stateMachine.states[i];
if(childState.state.motion == null)
{
if(childState.state.name.CompareTo("New State") == 0)
continue;
Debug.LogError("Null : " + childState.state.name);
continue;
}
if(childState.state.motion.GetType() == typeof(AnimationClip))
{
for(int j = 0; j < newClips.Length; j++)
{
if(newClips[j].name.CompareTo(childState.state.motion.name) == 0)
{
childState.state.motion = (Motion)newClips[j];
countChange ++;
break;
}
}
}else if(childState.state.motion.GetType() == typeof(BlendTree))
{
//BlendTree这个类有BUG,不能直接修改Motion, 要先记录原本的信息,再全部删除原本的,再修改,再加上去.
List<Motion> allMotion = new List<Motion>();
List<float> allThreshold = new List<float>();
BlendTree tree = (BlendTree)childState.state.motion;
for(int k = 0; k < tree.children.Length; k++)
{
allMotion.Add(tree.children[k].motion);
allThreshold.Add(tree.children[k].threshold);
}
for(int k = 0; k < allMotion.Count; k++)
{
if(allMotion[k].GetType() == typeof(AnimationClip))
{
for(int j = 0; j < newClips.Length; j++)
{
if(newClips[j].name.CompareTo(allMotion[k].name) == 0)
{
allMotion[k] = (Motion)newClips[j];
countChange ++;
break;
}
}
}else if(allMotion[k].GetType() == typeof(BlendTree))
{
Debug.LogError("You need to change it!");
}
}
for(int k = tree.children.Length - 1; k >= 0; k--)
{
tree.RemoveChild(k);
}
for(int k = 0; k < allMotion.Count; k++)
{
tree.AddChild(allMotion[k], allThreshold[k]);
}
}
}
for(int i = 0; i < stateMachine.stateMachines.Length; i++)
{
CheckAndRefreshAnimatorController(newClips, stateMachine.stateMachines[i].stateMachine);
}
}