private static void AddTransition(UnityEditor.Animations.AnimatorStateMachine machine, UnityEditor.Animations.AnimatorState from, UnityEditor.Animations.AnimatorState to, bool removedef, params object[] conditions) { UnityEditor.Animations.AnimatorStateTransition transition = null; transition = from == null?machine.AddAnyStateTransition(to) : from.AddTransition(to); //Unity5中默认是没有condition的 //if (removedef) transition.RemoveCondition(0); transition.offset = 0.0f; transition.duration = 0.0f; transition.hasExitTime = false; for (var i = 0; i < conditions.Length;) { if (conditions.Length - i < 2) { break; } //var cond = transition.AddCondition(); var mode = (UnityEditor.Animations.AnimatorConditionMode)conditions[i++]; var param = conditions[i++].ToString(); //cond.mode = mode; //cond.parameter = param; float threshold = 0f; if (i >= conditions.Length) { break; } if (mode != UnityEditor.Animations.AnimatorConditionMode.If && mode != UnityEditor.Animations.AnimatorConditionMode.IfNot) { threshold = (int)conditions[i++]; } transition.AddCondition(mode, threshold, param); } }
static void CreateAniController(string path, List <AnimationClip> clips, string fbxPath) { // 创建动画控制器 AnimatorController animatorController = AnimatorController.CreateAnimatorControllerAtPath(path + "Controller.controller"); AnimatorControllerLayer layer = null; if (animatorController.layers.Length > 0) { layer = animatorController.layers[0]; } AnimatorStateMachine layMachine = layer.stateMachine; Vector3 anyStatePosition = layMachine.anyStatePosition; float OFFSET_X = 220; float OFFSET_Y = 60; float ITEM_PER_LINE = 4; float originX = anyStatePosition.x - OFFSET_X * (ITEM_PER_LINE / 2.5f); float originY = -20; float x = originX; float y = originY; layMachine.anyStatePosition = new Vector3(-150, -150, 0); layMachine.entryPosition = new Vector3(150, -150, 0); UnityEditor.Animations.AnimatorState defAni = null; // 设置默认动作 AnimationClip defClip = clips.Find(m => m.name.Equals("Idle")); if (defClip != null) { UnityEditor.Animations.AnimatorState state = layMachine.AddState(defClip.name, new Vector3(0, -100, 0)); state.motion = defClip; layMachine.defaultState = state; defAni = state; } else { if (EditorUtility.DisplayDialog("", "未发现idle动作,请检查", "确定")) { /*return*/ } } foreach (AnimationClip newClip in clips) { if (newClip.name.Equals("Idle")) { continue; } UnityEditor.Animations.AnimatorState state = layMachine.AddState(newClip.name, new Vector3(x, y, 0)); state.motion = newClip; if (defAni != null) { if (newClip.name.Equals("Hit") || newClip.name.Equals("Attack") || newClip.name.Equals("Stun") || newClip.name.Equals("Skill1") || newClip.name.Equals("Skill2") || newClip.name.Equals("Skill3") || newClip.name.Equals("Skill4") || newClip.name.Equals("Skill5") || newClip.name.Equals("Skill6") || newClip.name.Equals("Skill7") || newClip.name.Equals("Attack1") || newClip.name.Equals("Attack2") || newClip.name.Equals("Attack3") || newClip.name.Equals("Attack4") || newClip.name.Equals("Attack5") || newClip.name.Equals("Attack6")) { AnimatorStateTransition ast = state.AddTransition(defAni); ast.hasExitTime = true; ast.exitTime = 0.99F; ast.duration = 0.1F; ast.offset = 0; } } x += OFFSET_X; if (x >= originX + OFFSET_X * ITEM_PER_LINE) { x = originX; y += OFFSET_Y; } } // 创建prefab string name = aniObjs.name; string prefabPath = "Assets/Game/Resources/PrefabUnit/" + aniObjs.name + ".prefab"; GameObject go = GameObject.Instantiate(AssetDatabase.LoadAssetAtPath(fbxPath, typeof(GameObject)) as GameObject); if (go == null) { return; } go.name = name; Animator animator = go.GetComponent <Animator>(); if (animator == null) { animator = go.AddComponent <Animator>(); } AnimatorManager aniManager = go.AddComponent <AnimatorManager>(); // 攻击点 GameObject shotPos = new GameObject(); shotPos.name = "ShotPos"; shotPos.transform.SetParent(go.transform); shotPos.transform.localEulerAngles = Vector3.zero; shotPos.transform.localPosition = Vector3.zero; shotPos.transform.localScale = Vector3.one; aniManager.ShotPos = shotPos.transform; // 攻击点 GameObject bloodPos = new GameObject(); bloodPos.name = "BloodPos"; bloodPos.transform.SetParent(go.transform); bloodPos.transform.localEulerAngles = Vector3.zero; bloodPos.transform.localPosition = new Vector3(0, 4, 0); bloodPos.transform.localScale = Vector3.one; // 受击点 GameObject anchorShotBy = new GameObject(); anchorShotBy.name = "AnchorShotBy"; anchorShotBy.transform.SetParent(go.transform); anchorShotBy.transform.localEulerAngles = Vector3.zero; anchorShotBy.transform.localPosition = new Vector3(0, 4, 0); anchorShotBy.transform.localScale = Vector3.one; animator.applyRootMotion = false; animator.runtimeAnimatorController = animatorController; GameObject resObj = PrefabUtility.CreatePrefab(prefabPath, go); GameObject.DestroyImmediate(go); AssetDatabase.SaveAssets(); if (EditorUtility.DisplayDialog("", "请调整攻击点,血条,受击点位置,prefab位置:" + prefabPath, "确定")) { /*return*/ Debug.Log("<color=red>" + prefabPath + "</color>"); } }
void OnGUI() { if (string.IsNullOrEmpty(TextureURL)) { saveURL = EditorPrefs.GetString(LineTool.GetProjectKey("AnimationSaveURL")); TextureURL = EditorPrefs.GetString(LineTool.GetProjectKey("AnimationTextureURL")); Samples = EditorPrefs.GetInt(LineTool.GetProjectKey("AnimationSamples")); } //Select folder contain textures EditorGUILayout.BeginHorizontal(); TextureURL = EditorGUILayout.TextField("Textures URL", TextureURL); if (GUILayout.Button("Browser...", GUILayout.Width(100))) { TextureURL = EditorUtility.OpenFolderPanel("Choose Textures File", TextureURL, ""); EditorPrefs.SetString(LineTool.GetProjectKey("AnimationTextureURL"), TextureURL); } EditorGUILayout.EndHorizontal(); EditorGUILayout.Space(); //Get all sprites in this folder var dataPath = Application.dataPath; List <Sprite> allSprites = new List <Sprite>(); if (!string.IsNullOrEmpty(TextureURL)) { string[] folder_paths = System.IO.Directory.GetDirectories(TextureURL); foreach (string folder_path in folder_paths) { var fs = System.IO.Directory.GetFiles(folder_path, "*.png"); foreach (var f in fs) { string shortPath = ""; if (f.Contains(dataPath)) { shortPath = f.Replace(dataPath, "Assets"); } var objects = UnityEditor.AssetDatabase.LoadAllAssetsAtPath(shortPath); var _sprites = objects.Where(q => q is Sprite).Cast <Sprite>(); allSprites.AddRange(_sprites); } } var files = System.IO.Directory.GetFiles(TextureURL, "*.png"); foreach (var f in files) { string shortPath = ""; if (f.Contains(dataPath)) { shortPath = f.Replace(dataPath, "Assets"); } var objects = UnityEditor.AssetDatabase.LoadAllAssetsAtPath(shortPath); var _sprites = objects.Where(q => q is Sprite).Cast <Sprite>(); allSprites.AddRange(_sprites); } EditorGUILayout.TextArea("Sprite Count: " + allSprites.Count); EditorGUILayout.BeginHorizontal(); GUILayout.Label("Samples", EditorStyles.boldLabel); Samples = EditorGUILayout.IntField(Samples); EditorPrefs.SetInt(LineTool.GetProjectKey("AnimationSamples"), Samples); EditorGUILayout.EndHorizontal(); } GUILayout.Space(10); //Generate animation GUILayout.BeginArea(new Rect((position.width - 100) / 2, 100, 100, 30)); if (GUILayout.Button("Generate", GUILayout.Width(100), GUILayout.Height(30))) { string existURL = string.IsNullOrEmpty(saveURL) ? Application.dataPath : saveURL; saveURL = EditorUtility.SaveFilePanel("Save Animation File", existURL, "Frames", "controller"); if (saveURL.Contains(dataPath)) { saveURL = saveURL.Replace(dataPath, "Assets"); } EditorPrefs.SetString(LineTool.GetProjectKey("AnimationSaveURL"), saveURL); //Create new animator controller var controller = UnityEditor.Animations.AnimatorController.CreateAnimatorControllerAtPath(saveURL); if (controller != null) { //Add parameter controller.AddParameter("idle", AnimatorControllerParameterType.Trigger); controller.AddParameter("walk", AnimatorControllerParameterType.Trigger); //Parameter for determine what anim to play controller.AddParameter("speed", AnimatorControllerParameterType.Float); controller.AddParameter("faceX", AnimatorControllerParameterType.Float); controller.AddParameter("faceY", AnimatorControllerParameterType.Float); } List <Sprite> sprites = new List <Sprite>(); sprites.AddRange(allSprites); var rootStateMachine = controller.layers[0].stateMachine; Dictionary <string, UnityEditor.Animations.AnimatorState> animStates = new Dictionary <string, UnityEditor.Animations.AnimatorState>(); var emptyState = rootStateMachine.AddState("Empty"); foreach (var poseandTrigger in poses) { var pose = poseandTrigger.Pose.ToLower(); var trigger = poseandTrigger.Trigger; //Change sprite name to lower to determine anim by name if (sprites.Any(xx => xx.name.ToLower().Contains(pose) || (xx.name.ToLower().Replace("_", "")).Contains(pose))) { UnityEditor.Animations.BlendTree blendTree; var currentState = controller.CreateBlendTreeInController(pose, out blendTree, 0); blendTree.name = pose; blendTree.blendType = UnityEditor.Animations.BlendTreeType.SimpleDirectional2D; blendTree.blendParameter = "faceX"; blendTree.blendParameterY = "faceY"; foreach (var dir in directions) { var sameDir = dir.Name.Replace("_", ""); var foundSprite = sprites.FindAll(xx => (xx.name.ToLower().Contains(pose) || (xx.name.ToLower().Replace("_", "")).Contains(pose)) && (xx.name.ToLower().Contains(dir.Name) || xx.name.ToLower().Contains(sameDir))); if (foundSprite == null || foundSprite.Count == 0) { continue; } string clipName = controller.name + "_" + pose + "_" + dir.Name; bool isLoop = trigger.Equals("idle") || trigger.Equals("walk"); Debug.Log(pose + " loop: " + isLoop); var clip = createAnimationClip(foundSprite, clipName, isLoop); AssetDatabase.AddObjectToAsset(clip, controller); //AssetDatabase.CreateAsset(clip, saveURL + clipName+ ".anim"); blendTree.AddChild(clip, dir.Position); if (!pose.Contains("fall")) { sprites.RemoveAll(xx => foundSprite.Contains(xx)); } Debug.Log("Sprites Count: " + sprites.Count); } animStates.Add(pose, currentState); } } //Make Transition UnityEditor.Animations.AnimatorState idle = null; if (animStates.ContainsKey("idle")) { idle = animStates["idle"]; } foreach (var animDict in animStates) { var pose = animDict.Key; var poseTrigger = poses.Find(x => x.Pose.ToLower().Equals(pose.ToLower())).Trigger; var animState = animDict.Value; if (pose.Equals("run")) { var walk = animDict.Value; var transStop = walk.AddTransition(idle); transStop.AddCondition(UnityEditor.Animations.AnimatorConditionMode.Less, 0.001f, "speed"); transStop.duration = 0; transStop.hasExitTime = true; var transWalk = idle.AddTransition(walk); transWalk.AddCondition(UnityEditor.Animations.AnimatorConditionMode.Greater, 0.001f, "speed"); transWalk.duration = 0; transWalk.hasExitTime = false; var trans = rootStateMachine.AddAnyStateTransition(animStates[pose]); trans.AddCondition(UnityEditor.Animations.AnimatorConditionMode.If, 0, poseTrigger); trans.AddCondition(UnityEditor.Animations.AnimatorConditionMode.Greater, 0.001f, "speed"); trans.duration = 0; } else if (poses.Any(x => x.Pose.ToLower().Equals(pose))) { //var poseTrigger = pose.Equals("attack") || pose.Equals("spell") ? "attack" : pose; controller.AddParameter(poseTrigger, AnimatorControllerParameterType.Trigger); var trans = rootStateMachine.AddAnyStateTransition(animState); trans.AddCondition(UnityEditor.Animations.AnimatorConditionMode.If, 0, poseTrigger); trans.duration = 0; } } if (!animStates.ContainsKey("run") && idle != null) { var trans = rootStateMachine.AddAnyStateTransition(idle); trans.AddCondition(UnityEditor.Animations.AnimatorConditionMode.If, 0, "walk"); trans.AddCondition(UnityEditor.Animations.AnimatorConditionMode.Greater, 0.001f, "speed"); trans.duration = 0; } AssetDatabase.SaveAssets(); AssetDatabase.Refresh(); Close(); } GUILayout.EndArea(); }
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(); }