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); } }