private void AddClipsToState(AnimatorStateMachine stateMachine, List<AnimationClip> animationClips, string prefix = "") { foreach (var clip in animationClips) { var state = stateMachine.AddState(clip.name); state.motion = clip; var transition = stateMachine.AddEntryTransition(state); transition.AddCondition(AnimatorConditionMode.If, 1f, prefix + clip.name); var exitTransition = state.AddExitTransition(); exitTransition.hasExitTime = true; exitTransition.duration = 0.1f; } }
private void CreateStateMachine() { if (avatarPreview == null || avatarPreview.Animator == null) return; if (controller == null) { controller = new AnimatorController(); controller.hideFlags = HideFlags.DontSave; controller.AddLayer("preview"); stateMachine = controller.layers[0].stateMachine; CreateParameters(); state = stateMachine.AddState("preview"); state.motion = previewedMotion; state.iKOnFeet = this.avatarPreview.IKOnFeet; state.hideFlags = HideFlags.DontSave; stateMachine.hideFlags = HideFlags.DontSave; AnimatorController.SetAnimatorController(avatarPreview.Animator, controller); controller.AppendOnAnimatorControllerDirtyCallback(this.ControllerDitry); controllerIsDitry = false; } if (AnimatorControllerExtension.GetEffectiveAnimatorController(avatarPreview.Animator) != this.controller) { AnimatorController.SetAnimatorController(avatarPreview.Animator, this.controller); } }
void CreateController() { if (m_Controller == null && m_AvatarPreview != null && m_AvatarPreview.Animator != null && m_RefTransition != null) { // controller m_LayerIndex = 0; m_Controller = new AnimatorController(); m_Controller.pushUndo = false; m_Controller.hideFlags = HideFlags.HideAndDontSave; m_Controller.AddLayer("preview"); bool isDefaultMask = true; if (m_LayerMask != null) { for (AvatarMaskBodyPart i = 0; i < AvatarMaskBodyPart.LastBodyPart && isDefaultMask; i++) { if (!m_LayerMask.GetHumanoidBodyPartActive(i)) { isDefaultMask = false; } } if (!isDefaultMask) { m_Controller.AddLayer("Additionnal"); m_LayerIndex++; AnimatorControllerLayer[] layers = m_Controller.layers; layers[m_LayerIndex].avatarMask = m_LayerMask; m_Controller.layers = layers; } } m_StateMachine = m_Controller.layers[m_LayerIndex].stateMachine; m_StateMachine.pushUndo = false; m_StateMachine.hideFlags = HideFlags.HideAndDontSave; m_SrcMotion = m_RefSrcState.motion; m_DstMotion = m_RefDstState.motion; /// Add parameters m_ParameterMinMax.Clear(); if (m_SrcMotion && m_SrcMotion is BlendTree) { BlendTree leftBlendTree = m_SrcMotion as BlendTree; for (int i = 0; i < leftBlendTree.recursiveBlendParameterCount; i++) { string blendValueName = leftBlendTree.GetRecursiveBlendParameter(i); if (m_Controller.IndexOfParameter(blendValueName) == -1) { m_Controller.AddParameter(blendValueName, AnimatorControllerParameterType.Float); m_ParameterMinMax.Add(new Vector2(leftBlendTree.GetRecursiveBlendParameterMin(i), leftBlendTree.GetRecursiveBlendParameterMax(i))); } } } if (m_DstMotion && m_DstMotion is BlendTree) { BlendTree rightBlendTree = m_DstMotion as BlendTree; for (int i = 0; i < rightBlendTree.recursiveBlendParameterCount; i++) { string blendValueName = rightBlendTree.GetRecursiveBlendParameter(i); int parameterIndex = m_Controller.IndexOfParameter(blendValueName); if (parameterIndex == -1) { m_Controller.AddParameter(blendValueName, AnimatorControllerParameterType.Float); m_ParameterMinMax.Add(new Vector2(rightBlendTree.GetRecursiveBlendParameterMin(i), rightBlendTree.GetRecursiveBlendParameterMax(i))); } else { m_ParameterMinMax[parameterIndex] = new Vector2(Mathf.Min(rightBlendTree.GetRecursiveBlendParameterMin(i), m_ParameterMinMax[parameterIndex][0]), Mathf.Max(rightBlendTree.GetRecursiveBlendParameterMax(i), m_ParameterMinMax[parameterIndex][1])); } } } // states m_SrcState = m_StateMachine.AddState(m_RefSrcState.name); m_SrcState.pushUndo = false; m_SrcState.hideFlags = HideFlags.HideAndDontSave; m_DstState = m_StateMachine.AddState(m_RefDstState.name); m_DstState.pushUndo = false; m_DstState.hideFlags = HideFlags.HideAndDontSave; CopyStateForPreview(m_RefSrcState, ref m_SrcState); CopyStateForPreview(m_RefDstState, ref m_DstState); // transition m_Transition = m_SrcState.AddTransition(m_DstState, true); m_Transition.pushUndo = false; m_Transition.hideFlags = HideFlags.DontSave; CopyTransitionForPreview(m_RefTransition, ref m_Transition); DisableIKOnFeetIfNeeded(); AnimatorController.SetAnimatorController(m_AvatarPreview.Animator, m_Controller); m_Controller.OnAnimatorControllerDirty += ControllerDirty; } }
public static AnimatorStateMachine CloneDeep(this AnimatorStateMachine source) { var dest = new AnimatorStateMachine { defaultState = InstanceCaches <AnimatorState> .FindOrCreate(source.defaultState, w => w.CloneDeep()), anyStatePosition = source.anyStatePosition, entryPosition = source.entryPosition, exitPosition = source.exitPosition, parentStateMachinePosition = source.parentStateMachinePosition, hideFlags = source.hideFlags, name = source.name }; foreach (var sourceState in source.states) { dest.AddState(InstanceCaches <AnimatorState> .FindOrCreate(sourceState.state, w => w.CloneDeep()), sourceState.position); } foreach (var sourceTransition in source.anyStateTransitions) { AnimatorStateTransition transition = null; if (sourceTransition.destinationStateMachine != null) { transition = dest.AddAnyStateTransition(InstanceCaches <AnimatorStateMachine> .FindOrCreate(sourceTransition.destinationStateMachine, CloneDeep)); } if (sourceTransition.destinationState != null) { transition = dest.AddAnyStateTransition(InstanceCaches <AnimatorState> .FindOrCreate(sourceTransition.destinationState, w => w.CloneDeep())); } if (transition == null) { throw new ArgumentNullException(nameof(transition)); } sourceTransition.CloneTo(transition); // should always false if (InstanceCaches <AnimatorStateTransition> .Find(sourceTransition.GetInstanceID()) == null) { InstanceCaches <AnimatorStateTransition> .Register(sourceTransition.GetInstanceID(), transition); } } foreach (var sourceTransition in source.entryTransitions) { AnimatorTransition transition = null; if (sourceTransition.destinationStateMachine != null) { transition = dest.AddEntryTransition(InstanceCaches <AnimatorStateMachine> .FindOrCreate(sourceTransition.destinationStateMachine, CloneDeep)); } if (sourceTransition.destinationState != null) { transition = dest.AddEntryTransition(InstanceCaches <AnimatorState> .FindOrCreate(sourceTransition.destinationState, w => w.CloneDeep())); } if (transition == null) { throw new ArgumentNullException(nameof(transition)); } transition.CloneTo(sourceTransition); // should always false if (InstanceCaches <AnimatorTransition> .Find(sourceTransition.GetInstanceID()) == null) { InstanceCaches <AnimatorTransition> .Register(sourceTransition.GetInstanceID(), transition); } } foreach (var sourceBehaviour in source.behaviours) { var behaviour = dest.AddStateMachineBehaviour(sourceBehaviour.GetType()); sourceBehaviour.CloneDeepTo(behaviour); // store InstanceCaches <StateMachineBehaviour> .Register(behaviour.GetInstanceID(), behaviour); } foreach (var sourceStateMachine in source.stateMachines) { dest.AddStateMachine(InstanceCaches <AnimatorStateMachine> .FindOrCreate(sourceStateMachine.stateMachine, CloneDeep), sourceStateMachine.position); } return(dest); }
private static void createAC(string objPath, string objName, Dictionary <string, animCond> conds, List <animClip> lstInfo) { //查找混合树 List <animClip> blendInfo = new List <animClip>(); for (int i = 0; i < lstInfo.Count; i++) { if (lstInfo[i].blendIndex > 0) { blendInfo.Add(lstInfo[i]); } } int index = objPath.LastIndexOf("/"); string savePath = getAnimPathByName(objName, "ac"); string clipPath = getAnimPathByName(objName, "clip"); AnimatorController ac = AnimatorController.CreateAnimatorControllerAtPath(Path.Combine(savePath, objName + ".controller")); AnimatorControllerLayer layer = ac.layers[0]; //添加clip AnimatorStateMachine stateMachine = layer.stateMachine; string[] files = Directory.GetFiles(clipPath, "*anim"); Dictionary <string, Motion> dictClips = new Dictionary <string, Motion>(); for (int i = 0; i < files.Length; i++) { Motion cp = AssetDatabase.LoadAssetAtPath <Motion>(files[i]); if (cp != null) { dictClips.Add(cp.name, cp); } } AnimatorState animState = null; //先创建blendTree if (blendInfo.Count > 0) { if (!isExitParam(ac, "tree")) { ac.AddParameter("tree", AnimatorControllerParameterType.Float); } BlendTree btree = null; animState = ac.CreateBlendTreeInController(defaultAnim, out btree); btree.blendParameter = "tree"; for (int i = 0; i < blendInfo.Count; i++) { string cname = blendInfo[i].clipName; if (dictClips.ContainsKey(cname)) { btree.AddChild(dictClips[cname]); } } stateMachine.AddState(animState, new Vector2(600, -200)); stateMachine.defaultState = animState; } int startY = 0; int startX = 300; for (int i = 0; i < lstInfo.Count; i++) { if (lstInfo[i].blendIndex > 0) { continue; } string name = lstInfo[i].clipName; animState = stateMachine.AddState(name, new Vector2(startX, startY * 80)); animState.motion = dictClips[name]; startY++; } //连线 ChildAnimatorState[] states = stateMachine.states; for (int i = 0; i < states.Length; i++) { ChildAnimatorState currState = states[i]; string name = currState.state.name; if (conds.ContainsKey(name)) { animCond cond = conds[name]; string fromStateName = cond.fromState; if (fromStateName == "Any State") { AnimatorStateTransition trans = stateMachine.AddAnyStateTransition(currState.state); if (!isExitParam(ac, cond.fromCond)) { ac.AddParameter(cond.fromCond, AnimatorControllerParameterType.Trigger); } trans.AddCondition(AnimatorConditionMode.If, 0, cond.fromCond); } string toStateName = cond.toState; ChildAnimatorState toState = getState(states, toStateName); if (toState.state != null && name != defaultAnim) { AnimatorStateTransition trans = currState.state.AddTransition(toState.state); if (cond.toCond == "None") { trans.hasExitTime = false; } else if (cond.toCond == "Exit") { trans.hasExitTime = true; } else { if (!isExitParam(ac, cond.toCond)) { ac.AddParameter(cond.toCond, AnimatorControllerParameterType.Trigger); } trans.AddCondition(AnimatorConditionMode.If, 0, cond.toCond); } } } } ac.name = objName; //AssetDatabase.CreateAsset(ac, Path.Combine(savePath, objName + ".controller")); AssetDatabase.SaveAssets(); AssetDatabase.Refresh(); }
/// <summary> /// 创建动画文件 /// </summary> /// <param name="type">动画的类型,用于标记是Sprite或Image</param> /// <param name="sprites">Sprite帧列表</param> /// <param name="assetNamePath">Assets文件夹下无后缀的资源路径</param> private void CreateAnimationFile(AnimationType type, Sprite[] sprites, string assetNamePath) { int len = sprites.Length; AnimationClip animationClip = new AnimationClip(); //帧频 animationClip.frameRate = frameRate; //设置循环 SerializedObject serializedClip = new SerializedObject(animationClip); SerializedProperty clipSettings = serializedClip.FindProperty("m_AnimationClipSettings"); SerializedProperty loopTimeSet = clipSettings.FindPropertyRelative("m_LoopTime"); loopTimeSet.boolValue = true; serializedClip.ApplyModifiedProperties(); //动画曲线 EditorCurveBinding curveBinding = new EditorCurveBinding(); if (type == AnimationType.Sprite) { curveBinding.type = typeof(SpriteRenderer); } else { curveBinding.type = typeof(Image); } curveBinding.path = ""; curveBinding.propertyName = "m_Sprite"; //添加帧 ObjectReferenceKeyframe[] keyframes = new ObjectReferenceKeyframe[len]; const float frameTime = 1f / frameRate; for (int i = 0; i < len; i++) { Sprite sprite = sprites[i]; ObjectReferenceKeyframe keyframe = new ObjectReferenceKeyframe(); keyframe.time = frameTime * i; keyframe.value = sprite; keyframes[i] = keyframe; } AnimationUtility.SetObjectReferenceCurve(animationClip, curveBinding, keyframes); //创建.anim文件 string animFilePath; if (type == AnimationType.Sprite) { animFilePath = assetNamePath + "_sprite.anim"; } else { animFilePath = assetNamePath + "_image.anim"; } AssetDatabase.CreateAsset(animationClip, animFilePath); //创建.controller文件 string controllerFilePath; if (type == AnimationType.Sprite) { controllerFilePath = assetNamePath + "_sprite.controller"; } else { controllerFilePath = assetNamePath + "_image.controller"; } AnimatorController animatorController = AnimatorController.CreateAnimatorControllerAtPath(controllerFilePath); AnimatorControllerLayer layer = animatorController.layers[0]; AnimatorStateMachine stateMachine = layer.stateMachine; AnimatorState state = stateMachine.AddState(animationClip.name); state.motion = animationClip; stateMachine.AddEntryTransition(state); AssetDatabase.SaveAssets(); }
private static void ReverseClip(AnimationClip clip, Animator[] animators)//List<AnimatorController> animConts { AnimationClip originalClip = clip; string directoryPath = Path.GetDirectoryName(AssetDatabase.GetAssetPath(clip)); //Selection.activeObject string fileName = Path.GetFileName(AssetDatabase.GetAssetPath(clip)); string fileExtension = Path.GetExtension(AssetDatabase.GetAssetPath(clip)); fileName = fileName.Split('.')[0]; string copiedFilePath = directoryPath + Path.DirectorySeparatorChar + fileName + "_Reversed" + fileExtension; AssetDatabase.CopyAsset(AssetDatabase.GetAssetPath(clip), copiedFilePath); clip = (AnimationClip)AssetDatabase.LoadAssetAtPath(copiedFilePath, typeof(AnimationClip)); if (clip == null) { return; } float clipLength = clip.length; var curves = AnimationUtility.GetCurveBindings(clip); foreach (EditorCurveBinding binding in curves) { var animCurve = AnimationUtility.GetEditorCurve(clip, binding); var keys = animCurve.keys; int keyCount = keys.Length; for (int i = 0; i < keyCount; i++) { Keyframe K = keys[i]; K.time = clipLength - K.time; var tmp = -K.inTangent; K.inTangent = -K.outTangent; K.outTangent = tmp; keys[i] = K; } animCurve.keys = keys; clip.SetCurve(binding.path, binding.type, binding.propertyName, animCurve); } var events = AnimationUtility.GetAnimationEvents(clip); if (events.Length > 0) { for (int i = 0; i < events.Length; i++) { events[i].time = clipLength - events[i].time; } AnimationUtility.SetAnimationEvents(clip, events); } foreach (Animator anim in animators) { AnimationClip[] clips = AnimationUtility.GetAnimationClips(anim.gameObject); bool foundClip = false; foreach (AnimationClip c in clips) { if (c == originalClip) { foundClip = true; break; } } if (foundClip) { Debug.Log("Found the animator containing the original clip that was reversed, adding new clip to its state machine..."); AnimatorController controller = UnityEditor.AssetDatabase.LoadAssetAtPath <UnityEditor.Animations.AnimatorController>(UnityEditor.AssetDatabase.GetAssetPath(anim.runtimeAnimatorController)); AnimatorStateMachine asm = controller.layers[0].stateMachine; AnimatorState animState = asm.AddState(clip.name); animState.motion = clip; } } }
private static void copyController(AnimatorController originController, AnimatorController newController) { //parameter foreach (var parameter in originController.parameters) { if (parameter.type != AnimatorControllerParameterType.Trigger || containsMotion(parameter.name)) { newController.AddParameter(parameter.name, parameter.type); } else { EditorLogger.Log("忽略参数 {0}", parameter.name); } } //state AnimatorStateMachine newStateMachine = newController.layers[0].stateMachine; AnimatorStateMachine originStateMachine = originController.layers[0].stateMachine; newStateMachine.entryPosition = originStateMachine.entryPosition; newStateMachine.anyStatePosition = originStateMachine.anyStatePosition; newStateMachine.exitPosition = originStateMachine.exitPosition; foreach (ChildAnimatorState cstate in originStateMachine.states) { var statename = cstate.state.name; if (containsMotion(statename)) { var newState = newStateMachine.AddState(statename, cstate.position); newState.motion = motions[statename]; foreach (StateMachineBehaviour behaviour in cstate.state.behaviours) { newState.AddStateMachineBehaviour(behaviour.GetType()); } } else { EditorLogger.Log("忽略状态 {0}", statename); } } newStateMachine.defaultState = findState(originStateMachine.defaultState.name, newStateMachine); //transition foreach (ChildAnimatorState originChildState in originStateMachine.states) { AnimatorState newState = findState(originChildState.state.name, newStateMachine); if (newState != null) { foreach (AnimatorStateTransition originTransition in originChildState.state.transitions) { AnimatorState destState = findState(originTransition.destinationState.name, newStateMachine); if (destState != null) { var newTransition = newState.AddTransition(destState); copyTransition(originTransition, newTransition); } } } } foreach (AnimatorStateTransition anyTransition in originStateMachine.anyStateTransitions) { AnimatorState destState = findState(anyTransition.destinationState.name, newStateMachine); if (destState != null) { var newTransition = newStateMachine.AddAnyStateTransition(destState); copyTransition(anyTransition, newTransition); } } }
public static void CreateAnimFile(ArmatureEditor armatureEditor) { changedSpriteFramesKV = new Dictionary <string, SpriteFrame>(); changedSpriteMeshsKV = new Dictionary <string, SpriteMesh>(); string path = AssetDatabase.GetAssetPath(armatureEditor.animTextAsset); path = path.Substring(0, path.LastIndexOf('/')) + "/Anims"; if (!AssetDatabase.IsValidFolder(path)) { Directory.CreateDirectory(path); } path += "/"; Animator animator = armatureEditor.armature.gameObject.AddComponent <Animator>(); AnimatorController controller = AssetDatabase.LoadAssetAtPath <AnimatorController>(path + armatureEditor.armature.name + ".controller"); AnimatorStateMachine rootStateMachine = null; if (controller == null) { controller = AnimatorController.CreateAnimatorControllerAtPath(path + armatureEditor.armature.name + ".controller"); rootStateMachine = controller.layers[0].stateMachine; } animator.runtimeAnimatorController = controller; if (armatureEditor.armatureData.animDatas != null) { int len = armatureEditor.armatureData.animDatas.Length; for (int i = 0; i < len; ++i) { DragonBoneData.AnimationData animationData = armatureEditor.armatureData.animDatas[i]; string clipPath = path + animationData.name + ".anim"; if (len > 1) { clipPath = path + armatureEditor.armature.name + "_" + animationData.name + ".anim"; } AnimationClip clip = AssetDatabase.LoadAssetAtPath <AnimationClip>(clipPath); if (clip == null) { clip = new AnimationClip(); AssetDatabase.CreateAsset(clip, clipPath); } else { clip.ClearCurves(); } clip.name = animationData.name; clip.frameRate = armatureEditor.armatureData.frameRate; CreateAnimBoneAndSlot(armatureEditor, clip, animationData.boneDatas, armatureEditor.bonesKV, true); CreateAnimBoneAndSlot(armatureEditor, clip, animationData.slotDatas, armatureEditor.slotsKV, false); CreateAnimBoneAndSlot(armatureEditor, clip, animationData.ffdDatas, armatureEditor.slotsKV, false, true); SetDragonBoneArmature(armatureEditor); SetEvent(armatureEditor, clip, animationData.keyDatas); SerializedObject serializedClip = new SerializedObject(clip); AnimationClipSettings clipSettings = new AnimationClipSettings(serializedClip.FindProperty("m_AnimationClipSettings")); clipSettings.loopTime = animationData.playTimes == 0; serializedClip.ApplyModifiedProperties(); if (rootStateMachine != null) { AnimatorState state = rootStateMachine.AddState(clip.name); state.motion = clip; } } AssetDatabase.SaveAssets(); } if (rootStateMachine != null && rootStateMachine.states != null && rootStateMachine.states.Length > 0) { rootStateMachine.defaultState = rootStateMachine.states[0].state; } //createAvatar if (armatureEditor.createAvatar) { CreateAvatar(armatureEditor, animator, path); } }
private void Bake() { if (audioClipToBake.Count == 0) { EditorUtility.DisplayDialog("No AudioClip found", "You have not select a folder containing AudioClip. Please first specify a valid folder.", "OK"); } else { int animDataCount = 0; for (int i = 0; i < propertyNames.Length; ++i) { if (!string.IsNullOrEmpty(propertyNames[i])) { ++animDataCount; } else { break; } } if (animDataCount < currentVowels.Length) { EditorUtility.DisplayDialog("Incomplete animation data", "There is incomplete animation data. Please make sure you have filled all required data in the Animation Property Setting.", "OK"); } else { string path = ""; while (true) { path = EditorUtility.SaveFolderPanel("Save generated Animator to...", Application.dataPath, ""); if (path.IndexOf(Application.dataPath, 0) == 0) { path = path.Substring(Application.dataPath.Length - "Assets".Length); AnimatorController generatedAnimator = AnimatorController.CreateAnimatorControllerAtPath(path + "/" + animatorName + ".controller"); AnimatorStateMachine stateMachine = generatedAnimator.layers[0].stateMachine; if (AssetDatabase.IsValidFolder(path + "/GeneratedClips") == false) { AssetDatabase.CreateFolder(path, "GeneratedClips"); } LipSyncOfflineRecognizer recognizer = new LipSyncOfflineRecognizer(recognizerLanguage, amplitudeThreshold, windowSize, shiftStepSize); Dictionary <string, int> vowelToIndexDict = new Dictionary <string, int>(); for (int i = 0; i < currentVowels.Length; ++i) { vowelToIndexDict[currentVowels[i]] = i; } List <AnimationClip> tempClipList = new List <AnimationClip>(audioClipToBake.Count); for (int j = 0; j < audioClipToBake.Count; ++j) { AnimationClip clip = new AnimationClip(); AnimationCurve[] curveArray = new AnimationCurve[currentVowels.Length]; for (int jj = 0; jj < currentVowels.Length; ++jj) { curveArray[jj] = new AnimationCurve(); } float[] targetBlendValues = new float[currentVowels.Length]; float[] currentBlendValues = new float[currentVowels.Length]; string[] recognizeResult = recognizer.RecognizeAllByAudioClip(audioClipToBake[j]); float timeUnit = 1024.0f * (1.0f / (float)audioClipToBake[j].frequency); float blendValuesSum = 0.0f; for (int k = 0; k < recognizeResult.Length; ++k) { for (int kk = 0; kk < currentVowels.Length; ++kk) { targetBlendValues[kk] = 0; } if (recognizeResult[k] != null) { targetBlendValues[vowelToIndexDict[recognizeResult[k]]] = 1.0f; } blendValuesSum = 0.0f; for (int kk = 0; kk < currentVowels.Length; ++kk) { blendValuesSum += currentBlendValues[kk]; } for (int kk = 0; kk < currentVowels.Length; ++kk) { currentBlendValues[kk] = Mathf.MoveTowards(currentBlendValues[kk], targetBlendValues[kk], moveTowardsSpeed * timeUnit); Keyframe keyframe = new Keyframe(timeUnit * k, Mathf.Lerp(propertyMinValue, propertyMaxValue, currentBlendValues[kk])); curveArray[kk].AddKey(keyframe); } } for (int jj = 0; jj < currentVowels.Length; ++jj) { Keyframe keyframe = new Keyframe(timeUnit * recognizeResult.Length, 0); curveArray[jj].AddKey(keyframe); } for (int l = 0; l < currentVowels.Length; ++l) { clip.SetCurve(targetRelativePath, typeof(SkinnedMeshRenderer), "blendShape." + propertyNames[l], curveArray[l]); } tempClipList.Add(clip); } for (int m = 0; m < tempClipList.Count; ++m) { AssetDatabase.CreateAsset(tempClipList[m], path + "/GeneratedClips/" + audioClipToBake[m].name + "_anim.anim"); AnimatorState state = stateMachine.AddState(audioClipToBake[m].name + "_anim"); state.motion = tempClipList[m]; } EditorUtility.DisplayDialog("Complete Baking", "LipSync baking is completed. Please check the specified folder for result.", "OK"); break; } else if (path.Length == 0) { break; } else { Debug.Log(path); EditorUtility.DisplayDialog("Invalid path", "This folder is not contained in the asset path. Please make sure you choose a folder inside the \"Assets\" folder.", "OK"); } } } } }
private void InitController() { gameObject = dg_get_PreviewObject(); if (gameObject == null) { return; } var originalGameObject = uAvatarPreviewSelection.GetPreview(dg_get_animationClipType()); animator = dg_get_Animator(); animation = gameObject.GetComponent <Animation>(); if (originalGameObject != null) { transformPoseSave = new TransformPoseSave(originalGameObject); transformPoseSave.SetRootTransform(gameObject.transform.localPosition, originalGameObject.transform.localRotation, originalGameObject.transform.localScale); transformPoseSave.ChangeTransforms(gameObject); } else { transformPoseSave = new TransformPoseSave(gameObject); } blendShapeWeightSave = new BlendShapeWeightSave(gameObject); var clip = dg_get_m_SourcePreviewMotion(instance); if (clip.legacy || instance == null || !((UnityEngine.Object)animator != (UnityEngine.Object)null)) { if (animation != null) { animation.enabled = false; //If vaw.animation.enabled, it is not updated during execution. bug? } } else { if (m_Controller == null) { m_Controller = new UnityEditor.Animations.AnimatorController(); m_Controller.name = "Avatar Preview AnimatorController"; m_Controller.hideFlags |= HideFlags.HideAndDontSave; uAnimatorController.SetPushUndo(m_Controller, false); m_Controller.AddLayer("preview"); m_StateMachine = m_Controller.layers[0].stateMachine; uAnimatorStateMachine.SetPushUndo(m_StateMachine, false); m_StateMachine.hideFlags |= HideFlags.HideAndDontSave; } if (m_State == null) { m_State = m_StateMachine.AddState("preview"); uAnimatorState.SetPushUndo(m_State, false); m_State.motion = (Motion)clip; m_State.iKOnFeet = dg_get_ShowIKOnFeetButton() && dg_get_IKOnFeet(); m_State.hideFlags |= HideFlags.HideAndDontSave; } UnityEditor.Animations.AnimatorController.SetAnimatorController(animator, this.m_Controller); animator.applyRootMotion = EditorPrefs.GetBool(EditorPrefsApplyRootMotion, false); } dg_set_ShowIKOnFeetButton(animator != null && animator.isHuman && clip.isHumanMotion); #if !UNITY_2017_3_OR_NEWER mode2D = EditorPrefs.GetBool(EditorPrefs2D, false); #endif SetTime(uTimeControl.currentTime); ForceUpdate(); }
void ControllerBuild(HashSet <ClipIDPair> clips)//, int c) { { //if (clips == null) return; // Create the animator in the project AnimatorController controller = AnimatorController.CreateAnimatorControllerAtPath(saveDirectory + "AnimationsController.controller"); //add parameters AddParameters(controller); float t = Time.realtimeSinceStartup; { AnimatorControllerLayer[] layers = controller.layers; AnimatorControllerLayer layer = layers[0]; layer.iKPass = true; AnimatorStateMachine sm = layer.stateMachine; AnimatorState[] blendTrees = new AnimatorState[0]; if (usedLoopIDsPerLayer[0].Count > 0) { //make blend trees for looped animations (2 to smoothly transition between loops) blendTrees = new AnimatorState[2];//2]; for (int i = 0; i < 2; i++) { blendTrees[i] = AddBlendTree( controller, sm, 0, clips, CustomAnimator.loopNamesStrings[i], CustomAnimator.loopMirrorStrings[i], CustomAnimator.loopSpeedStrings[i], CustomAnimator.loopIndexStrings[i] ); } // blendTrees[i] = AddBlendTree(controller, 0, clips, CustomAnimator.sLoopNames[i], CustomAnimator.sLoopMirrors[i], CustomAnimator.sLoopSpeeds[i], c, CustomAnimator.sLoopIndicies[i]); // ConnectBlendTrees(0, blendTrees, 0); } // for (int i = 0; i < c; i++) // AddState(controller, sm, 0, clips[i], blendTrees); foreach (var c in clips) { AddState(0, controller, sm, 0, c, blendTrees); } controller.layers = layers; } Debug.Log("Time building layer 0: " + (Time.realtimeSinceStartup - t)); t = Time.realtimeSinceStartup; for (int l = 1; l < maxLayer + 1; l++) { controller.AddLayer("Layer" + l); AnimatorControllerLayer[] layers = controller.layers; AnimatorControllerLayer layer = layers[l]; layer.iKPass = true; layer.defaultWeight = 1.0f; AnimatorStateMachine sm = layer.stateMachine; bool anyLoops = usedLoopIDsPerLayer[l].Count > 0; AnimatorState[] blendTrees = new AnimatorState[anyLoops ? CustomAnimator.BLEND_TREES_PER_LAYER + 1 : 1]; // make the empty default state // AnimatorState state = sm.AddState(CustomAnimator.loopNamesStrings[l*3 + 0]); blendTrees[0] = sm.AddState("Blank");//CustomAnimator.loopNamesStrings[l*3 + 0]); blendTrees[0].motion = null; if (anyLoops) { for (int i = 0; i < CustomAnimator.BLEND_TREES_PER_LAYER; i++) { blendTrees[i + 1] = AddBlendTree( controller, sm, l, clips, CustomAnimator.loopNamesStrings[l * CustomAnimator.BLEND_TREES_PER_LAYER + (i)], CustomAnimator.loopMirrorStrings[l * CustomAnimator.BLEND_TREES_PER_LAYER + (i)], CustomAnimator.loopSpeedStrings[l * CustomAnimator.BLEND_TREES_PER_LAYER + (i)], //c, CustomAnimator.loopIndexStrings[l * CustomAnimator.BLEND_TREES_PER_LAYER + (i)] ); } // ConnectBlendTrees(-1, blendTrees, l); } // if (!upperLayersOnlyLoops) { // } // for (int i = 0; i < c; i++) // AddState(controller, sm, l, clips[i], blendTrees); foreach (var c in clips) { AddState(-1, controller, sm, l, c, blendTrees); } controller.layers = layers; } EditorUtility.SetDirty(controller); Debug.Log("Time building other layers: " + (Time.realtimeSinceStartup - t)); }
public override void OnInspectorGUI() { { skeletonDataAssetSaveId = AssetDatabase.GetAssetPath(target) + "_skeletonDataAssetId"; string skeletonDataAssetPath = PlayerPrefs.GetString(skeletonDataAssetSaveId); skeletonDataAsset = AssetDatabase.LoadAssetAtPath <SkeletonDataAsset>(skeletonDataAssetPath); skeletonDataAsset = (SkeletonDataAsset)EditorGUILayout.ObjectField("SkeletonDataAsset", skeletonDataAsset, typeof(SkeletonDataAsset)); PlayerPrefs.SetString(skeletonDataAssetSaveId, skeletonDataAsset ? AssetDatabase.GetAssetPath(skeletonDataAsset) : ""); } { string excelPathKey = AssetDatabase.GetAssetPath(target) + "_ExcelPath"; excelPath = PlayerPrefs.GetString(excelPathKey); PlayerPrefs.SetString(excelPathKey, EditorGUILayout.TextField("ExcelPath", excelPath)); } if (MyGUI.Button("更新状态机")) { string path = Path.GetDirectoryName(AssetDatabase.GetAssetPath(target)); JsonPath = path + "/" + target.name + ".json"; text = AssetDatabase.LoadAssetAtPath <TextAsset>(JsonPath); if (text == null) { if (MyGUI.Button("生成状态机模板")) { AssetDatabase.CopyAsset("Assets/Scripts/Tang/Edit/Editor/Animator/AnimatorControllerTemplate.json", JsonPath); } } if (text != null) { CreateAnimatorByJsonText(text.text); } } if (MyGUI.Button("添加帧事件支持")) { AnimatorController animatorController = target as AnimatorController; AnimatorControllerLayer[] animatorControllerLayers = animatorController.layers; AnimatorStateMachine animatorStateMachine = animatorControllerLayers[0].stateMachine; foreach (var state in animatorStateMachine.states) { if (state.state != null) { if (state.state.motion != null) { if (state.state.motion is UnityEditor.Animations.BlendTree) { var blendTree = state.state.motion as UnityEditor.Animations.BlendTree; if (blendTree.children.Length != 0) { FrameEventBehaviour frameEventBehaviour = state.state.AddStateBehaviour <FrameEventBehaviour>(); Motion motion = blendTree.children[0].motion; if (motion != null) { frameEventBehaviour.animName = motion.name; frameEventBehaviour.Parameter = blendTree.blendParameter; frameEventBehaviour.namelist.Clear(); for (int i = 0; i < blendTree.children.Length; i++) { UnityEditor.Animations.ChildMotion child = blendTree.children[i]; Motion childmotion = blendTree.children[i].motion; if (childmotion != null && childmotion.name != null && childmotion.name != "") { if (frameEventBehaviour.namelist.Count - 1 < (int)child.threshold) { int count = (int)child.threshold - (frameEventBehaviour.namelist.Count - 1); for (int c = 0; c < count; c++) { frameEventBehaviour.namelist.Add("null"); } } frameEventBehaviour.namelist.Insert((int)child.threshold, childmotion.name); } } } } } else { Motion motion = state.state.motion; FrameEventBehaviour frameEventBehaviour = state.state.AddStateBehaviour <FrameEventBehaviour>(); frameEventBehaviour.animName = motion.name; } } } } EditorUtility.SetDirty(animatorController); AssetDatabase.SaveAssets(); AssetDatabase.Refresh(); } if (MyGUI.Button("添加状态通知支持")) { SupportEventDispatch(); } if (MyGUI.Button("copy")) { AnimatorController oldAnimatorController = target as AnimatorController; string oldAnimatorControllerPath = AssetDatabase.GetAssetPath(oldAnimatorController); string newAnimatorControllerPath = oldAnimatorControllerPath.Substring(0, oldAnimatorControllerPath.IndexOf(".")); string newpath = newAnimatorControllerPath + "_new" + ".controller"; AnimatorController NewAnimatorController = AnimatorController.CreateAnimatorControllerAtPath(newpath); var unityAnimationClipTable = new Dictionary <string, Motion>(); Object[] objects = AssetDatabase.LoadAllAssetRepresentationsAtPath(oldAnimatorControllerPath); foreach (var item in objects) { //新建AnimationClip if (item is AnimationClip) { var clip = item as AnimationClip; AnimationClip newClip = new AnimationClip { name = clip.name }; AssetDatabase.AddObjectToAsset(newClip, NewAnimatorController); newClip.SetCurve("", typeof(GameObject), "dummy", AnimationCurve.Linear(0, 0, clip.length, 0)); var settings = AnimationUtility.GetAnimationClipSettings(newClip); settings.stopTime = clip.length; settings.loopTime = clip.isLooping; AnimationUtility.SetAnimationClipSettings(newClip, settings); AnimationUtility.SetAnimationEvents(newClip, clip.events); EditorUtility.SetDirty(newClip); unityAnimationClipTable.Add(clip.name, newClip); } else if (item is UnityEditor.Animations.BlendTree) { var additem = item as UnityEditor.Animations.BlendTree; string additemjson = Tools.Obj2Json <UnityEditor.Animations.BlendTree>(additem); UnityEditor.Animations.BlendTree blendTree = Tools.Json2Obj <UnityEditor.Animations.BlendTree>(additemjson); AssetDatabase.AddObjectToAsset(blendTree, NewAnimatorController); unityAnimationClipTable.Add(blendTree.name, blendTree); } } //新建AnimationClip保存 EditorUtility.SetDirty(NewAnimatorController); AssetDatabase.Refresh(); AssetDatabase.SaveAssets(); //转移动画AnimationClip引用 NewAnimatorController.parameters = oldAnimatorController.parameters; AnimatorControllerLayer[] oldAnimatorControllerLayers = oldAnimatorController.layers; AnimatorStateMachine oldAnimatorStateMachine = oldAnimatorControllerLayers[0].stateMachine; AnimatorControllerLayer[] NewAnimatorControllerLayers = NewAnimatorController.layers; AnimatorStateMachine NewAnimatorStateMachine = NewAnimatorControllerLayers[0].stateMachine; foreach (var oldChildenstate in oldAnimatorStateMachine.states) { if (oldChildenstate.state != null) { var oldChildAnimatorState = oldChildenstate.state; var oldStatemotion = oldAnimatorController.GetStateEffectiveMotion(oldChildAnimatorState, 0); UnityEditor.Animations.AnimatorState newState = NewAnimatorStateMachine.AddState(oldChildAnimatorState.name, oldChildenstate.position); newState.name = oldChildAnimatorState.name; newState.tag = oldChildAnimatorState.tag; if (oldStatemotion != null) { if (unityAnimationClipTable.ContainsKey(oldStatemotion.name)) { var Motion = unityAnimationClipTable[oldStatemotion.name]; NewAnimatorController.SetStateEffectiveMotion(newState, Motion); //NewAnimatorStateMachine.AddState(newState, oldChildenstate.position); } } } } AssetDatabase.Refresh(); AssetDatabase.SaveAssets(); foreach (var oldChildenstate in oldAnimatorStateMachine.states) { if (oldChildenstate.state != null) { var oldChildAnimatorState = oldChildenstate.state; UnityEditor.Animations.AnimatorState newState = NewAnimatorStateMachine.GetState(oldChildAnimatorState.name); if (newState != null) { foreach (var oldTransition in oldChildAnimatorState.transitions) { UnityEditor.Animations.AnimatorState tostate = NewAnimatorStateMachine.GetState(oldTransition.destinationState.name); var transition = newState.AddTransition(tostate); // transition.interruptionSource = UnityEditor.Animations.TransitionInterruptionSource.Destination; transition.interruptionSource = oldTransition.interruptionSource;// UnityEditor.Animations.TransitionInterruptionSource.Source; transition.hasExitTime = oldTransition.hasExitTime; transition.exitTime = oldTransition.exitTime; transition.duration = oldTransition.duration; transition.offset = oldTransition.offset; foreach (var conditionConfig in oldTransition.conditions) { transition.AddCondition(conditionConfig.mode, conditionConfig.threshold, conditionConfig.parameter); } } //newState.AddStateMachineBehaviour<RoleBaseStateMachineBehaviour>(); foreach (var item in oldChildAnimatorState.behaviours) { //string sd = item.GetType().FullName; //Type sda = Type.GetType(item.GetType().FullName); //if (sda == null) //{ // sda = Type.GetType(item.GetType().Namespace + "." + item.GetType().FullName); //} newState.AddStateMachineBehaviour(item.GetType()); } } } } //EditorUtility.SetDirty(NewAnimatorController); //AssetDatabase.SaveAssets(); EditorUtility.SetDirty(NewAnimatorController); AssetDatabase.Refresh(); AssetDatabase.SaveAssets(); System.IO.File.Delete(oldAnimatorControllerPath); System.IO.File.Move(newpath, oldAnimatorControllerPath); } if (MyGUI.Button("移除多余clip")) { AnimatorController animatorController = target as AnimatorController; AnimatorControllerLayer[] animatorControllerLayers = animatorController.layers; AnimatorStateMachine animatorStateMachine = animatorControllerLayers[0].stateMachine; var objList = AssetDatabase.LoadAllAssetRepresentationsAtPath(AssetDatabase.GetAssetPath(animatorController)); Dictionary <int, bool> tmp = new Dictionary <int, bool>(); foreach (var item in objList) { if (item != null) { if (tmp.ContainsKey(item.GetInstanceID())) { DestroyImmediate(item, true); } else { tmp.Add(item.GetInstanceID(), true); } } } foreach (var item in objList) { if (item != null) { bool needRemove = true; foreach (var state in animatorStateMachine.states) { if (state.state != null && state.state.motion != null && state.state.motion.Equals(item)) { needRemove = false; } } if (needRemove) { DestroyImmediate(item, true); } } } EditorUtility.SetDirty(animatorController); AssetDatabase.SaveAssets(); AssetDatabase.Refresh(); } if (MyGUI.Button("新的状态机生成")) { AnimatorCreator animatorCreator = new AnimatorCreator(AnimatorLoadExcel.GetJObjectFromExcel(excelPath).ToObject <RoleAnimator>()); try { // skeletonDataAsset.RoleAnimator = animatorCreator.RoleAnimator; // skeletonDataAsset.RoleAnimatorString = Tools.Obj2Json(animatorCreator.RoleAnimator); AnimatorController animatorController = target as AnimatorController; List <KeyValue <string, string> > RoleAnimatorStringList = null; try { RoleAnimatorStringList = JObject.Parse(skeletonDataAsset.RoleAnimatorString) .ToObject <List <KeyValue <string, string> > >(); } catch (Exception e) { Console.WriteLine(e); } if (RoleAnimatorStringList == null) { RoleAnimatorStringList = new List <KeyValue <string, string> >(); } RoleAnimatorStringList.RemoveAll(pair => pair.Key == animatorController.name); RoleAnimatorStringList.Add(new KeyValue <string, string>(animatorController.name, Tools.Obj2Json(animatorCreator.RoleAnimator))); skeletonDataAsset.RoleAnimatorString = Tools.Obj2Json(RoleAnimatorStringList); animatorCreator.Create(); CreateAnimatorByConfig(animatorCreator.GetConfig()); } catch (InvalidOperationException elements) { Debug.Log(elements); } } DrawDefaultInspector(); }
/************************************************************************************************/ public AnimatorController CreateAnimatorController() { // The new controller that will be created based on Manager animations AnimatorController newController = new AnimatorController(); newController.name = DEFAULT_CONTROLLER_NAME; newController.AddLayer("DefaultLayer"); // Add a parameter that will determine the animation states AnimatorControllerParameter animatorParameter = new AnimatorControllerParameter(); animatorParameter.type = AnimatorControllerParameterType.Int; animatorParameter.name = "TextAnimation"; animatorParameter.defaultInt = 999; newController.AddParameter(animatorParameter); // Add state machine AnimatorStateMachine rootStateMachine = newController.layers[0].stateMachine; AnimatorStateMachine stateMachine = rootStateMachine.AddStateMachine("TextAnimationStateMachine"); // Create a default state to prevent animation auto playing index 0 AnimatorState waitingState = stateMachine.AddState("Waiting"); //foreach (AnimationClip clip in DamageNumberManager.instance.animations) for (int i = 0; i < myScript.animations.Length; i++) { AnimationClip clip = myScript.animations[i]; // Add new state based on the AnimationClip AnimatorState state = stateMachine.AddState(clip.name); state.motion = clip; // Create transition from "Waiting" to the new state AnimatorStateTransition transition = waitingState.AddTransition(state, false); transition.AddCondition(AnimatorConditionMode.Equals, i, "TextAnimation"); } //// Save OR update the new AnimatorController as an asset (.controller) // Search if there is already an AnimatorController (and get its path if so) string assetPath = null; if (myScript.animatorOverrideController != null) { assetPath = AssetDatabase.GetAssetPath(myScript.animatorOverrideController.runtimeAnimatorController); } Object existingController = AssetDatabase.LoadAssetAtPath <Object>(assetPath); if (existingController == null) { // Create the new AnimatorController in the specified default directory AssetDatabase.CreateAsset(newController, DEFAULT_CONTROLLER_PATH + DEFAULT_CONTROLLER_NAME + ".controller"); existingController = newController; Debug.LogError("AnimatorController not found. Creating new one in " + DEFAULT_CONTROLLER_PATH + " directory."); } else { // Update the existing AnimatorController copy with latest data EditorUtility.CopySerialized(newController, existingController); Debug.Log("Updated existing AnimatorController found at " + assetPath + "."); } // Make sure the returned controller refers to the generated 'asset', not the controller 'within this scope' AnimatorController updatedController_asset = (AnimatorController)existingController; AssetDatabase.SaveAssets(); return(updatedController_asset); }
static void CreateController() { // Creates the controller AnimatorController controller = AnimatorController.CreateAnimatorControllerAtPath("Assets/Animations/Motion.controller"); // Add Animation Clips AnimationClip clip = new AnimationClip(); clip.frameRate = 24; AssetDatabase.CreateAsset(clip, "Assets/Animations/Motion.anim"); AssetDatabase.SaveAssets(); // Add parameters controller.AddParameter("TransitionNow", AnimatorControllerParameterType.Trigger); controller.AddParameter("Reset", AnimatorControllerParameterType.Trigger); controller.AddParameter("GotoB1", AnimatorControllerParameterType.Trigger); controller.AddParameter("GotoC", AnimatorControllerParameterType.Trigger); // Add StateMachines AnimatorStateMachine rootStateMachine = controller.layers[0].stateMachine; AnimatorStateMachine stateMachineA = rootStateMachine.AddStateMachine("smA"); AnimatorStateMachine stateMachineB = rootStateMachine.AddStateMachine("smB"); AnimatorStateMachine stateMachineC = stateMachineB.AddStateMachine("smC"); // Add Clip // Add States AnimatorState stateA1 = stateMachineA.AddState("stateA1"); AnimatorState stateB1 = stateMachineB.AddState("stateB1"); AnimatorState stateB2 = stateMachineB.AddState("stateB2"); stateMachineC.AddState("stateC1"); AnimatorState stateC2 = stateMachineC.AddState("stateC2"); // don’t add an entry transition, should entry to state by default // Add clip stateA1.motion = clip; // Add Transitions AnimatorStateTransition exitTransition = stateA1.AddExitTransition(); exitTransition.AddCondition(UnityEditor.Animations.AnimatorConditionMode.If, 0, "TransitionNow"); exitTransition.duration = 0; AnimatorStateTransition resetTransition = rootStateMachine.AddAnyStateTransition(stateA1); resetTransition.AddCondition(UnityEditor.Animations.AnimatorConditionMode.If, 0, "Reset"); resetTransition.duration = 0; AnimatorTransition transitionB1 = stateMachineB.AddEntryTransition(stateB1); transitionB1.AddCondition(UnityEditor.Animations.AnimatorConditionMode.If, 0, "GotoB1"); stateMachineB.AddEntryTransition(stateB2); stateMachineC.defaultState = stateC2; AnimatorStateTransition exitTransitionC2 = stateC2.AddExitTransition(); exitTransitionC2.AddCondition(UnityEditor.Animations.AnimatorConditionMode.If, 0, "TransitionNow"); exitTransitionC2.duration = 0; AnimatorTransition stateMachineTransition = rootStateMachine.AddStateMachineTransition(stateMachineA, stateMachineC); stateMachineTransition.AddCondition(UnityEditor.Animations.AnimatorConditionMode.If, 0, "GotoC"); rootStateMachine.AddStateMachineTransition(stateMachineA, stateMachineB); }