Unity3D开发之遍历检查AnimatorController里面所有部件

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


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值