193 lines
8.8 KiB
C#
193 lines
8.8 KiB
C#
|
//// Author: Blastom
|
|||
|
//// 修复选中区域中,有动画丢失的AnimationController
|
|||
|
//// 至少有一个路径正确的AnimationState有效就可以
|
|||
|
//
|
|||
|
//using System;
|
|||
|
//using System.Collections.Generic;
|
|||
|
//using UnityEditor;
|
|||
|
//using UnityEditor.Animations;
|
|||
|
//using UnityEngine;
|
|||
|
//
|
|||
|
//public class MecanimRefFix
|
|||
|
//{
|
|||
|
// // 丢失动画的状态,会试图修复状态;动画名称不对应动画状态,会试图修改动画名称;
|
|||
|
// [MenuItem("Assets/Animation/修复Mecanim动画机")]
|
|||
|
// public static void FixAnimatorControllers()
|
|||
|
// {
|
|||
|
// var animatorFix = new MecanimRefFix();
|
|||
|
// animatorFix.Start();
|
|||
|
// }
|
|||
|
//
|
|||
|
// private readonly string[] _controllers;
|
|||
|
// private int _index;
|
|||
|
// private readonly List<string> _errorList;
|
|||
|
// private readonly List<string> _renameList;
|
|||
|
// private readonly List<string> _copyList;
|
|||
|
// private readonly List<string> _handledClipList;
|
|||
|
// private AnimatorController _currentController;
|
|||
|
// private ChildAnimatorState[] _states;
|
|||
|
// private string _controllerPath;
|
|||
|
// private int _stateIndex;
|
|||
|
//
|
|||
|
// private MecanimRefFix()
|
|||
|
// {
|
|||
|
// var paths = EditorCommonUtility.GetPathsFromSelectByExtension(".controller");
|
|||
|
// _controllers = paths.ToArray();
|
|||
|
// _errorList = new List<string>();
|
|||
|
// _renameList = new List<string>();
|
|||
|
// _copyList = new List<string>();
|
|||
|
// _handledClipList = new List<string>();
|
|||
|
// }
|
|||
|
//
|
|||
|
// private void Start()
|
|||
|
// {
|
|||
|
// if (_controllers.Length > 0)
|
|||
|
// EditorApplication.update = Update;
|
|||
|
// }
|
|||
|
//
|
|||
|
// private void Stop()
|
|||
|
// {
|
|||
|
// EditorUtility.ClearProgressBar();
|
|||
|
// EditorApplication.update = null;
|
|||
|
// AssetDatabase.SaveAssets();
|
|||
|
// AssetDatabase.Refresh();
|
|||
|
// EditorUtility.UnloadUnusedAssetsImmediate(true);
|
|||
|
//
|
|||
|
// for (var i = 0; i < _renameList.Count; i++)
|
|||
|
// LogModule.DebugLog(_renameList[i]);
|
|||
|
// for (var i = 0; i < _copyList.Count; i++)
|
|||
|
// LogModule.WarningLog(_copyList[i]);
|
|||
|
// for (var i = 0; i < _errorList.Count; i++)
|
|||
|
// LogModule.ErrorLog(_errorList[i]);
|
|||
|
// }
|
|||
|
// private void Update()
|
|||
|
// {
|
|||
|
// var cancel = false;
|
|||
|
// // 每一帧处理一个State,使移动后的路径能够正常赋值
|
|||
|
// if (_currentController == null || _states == null || _stateIndex > _states.Length - 1)
|
|||
|
// {
|
|||
|
// if (_index > _controllers.Length - 1)
|
|||
|
// cancel = true;
|
|||
|
// else
|
|||
|
// {
|
|||
|
// _controllerPath = _controllers[_index];
|
|||
|
// _index++;
|
|||
|
// _currentController = AssetDatabase.LoadAssetAtPath<AnimatorController>(_controllerPath);
|
|||
|
// if (_currentController != null)
|
|||
|
// {
|
|||
|
// // ******** 检查动画层级数目 *******
|
|||
|
// if (_currentController.layers.Length > 1)
|
|||
|
// _errorList.Add(string.Format("动画控制器 {0} 拥有超过一个Layer!", _controllerPath));
|
|||
|
// // ******** 试图修复丢失的动画链接 ********
|
|||
|
// var pathRoot = string.Empty;
|
|||
|
// // 获得至少一个AnimationClip以获得搜索路径
|
|||
|
// for (var i = 0; i < _currentController.layers.Length; i++)
|
|||
|
// {
|
|||
|
// var states = _currentController.layers[i].stateMachine.states;
|
|||
|
// for (var j = 0; j < states.Length; j++)
|
|||
|
// {
|
|||
|
// var state = states[j];
|
|||
|
// if (state.state.motion != null)
|
|||
|
// {
|
|||
|
// pathRoot = AssetDatabase.GetAssetPath(state.state.motion).MoveUp();
|
|||
|
// break;
|
|||
|
// }
|
|||
|
// }
|
|||
|
// }
|
|||
|
// if (string.IsNullOrEmpty(pathRoot))
|
|||
|
// _errorList.Add(string.Format("AnimationController {0} 没有任何状态有Motion关联,需要手动修复!", _currentController.GetAssetPath()));
|
|||
|
// else
|
|||
|
// {
|
|||
|
// for (var i = 0; i < _currentController.layers.Length; i++)
|
|||
|
// {
|
|||
|
// var states = _currentController.layers[i].stateMachine.states;
|
|||
|
// for (var j = 0; j < states.Length; j++)
|
|||
|
// {
|
|||
|
// var state = states[j];
|
|||
|
// if (state.state.motion == null)
|
|||
|
// {
|
|||
|
// var motionName = state.state.name;
|
|||
|
// var motionPath = pathRoot.Combine(motionName + ".anim");
|
|||
|
// var motion = AssetDatabase.LoadAssetAtPath<Motion>(motionPath);
|
|||
|
// if (motion == null)
|
|||
|
// _errorList.Add(string.Format("动画控制器 {0} 状态 {1} 无法找到正确的Motion关联,需要手动修复!", _currentController.GetAssetPath(), motionName));
|
|||
|
// else
|
|||
|
// state.state.motion = motion;
|
|||
|
// }
|
|||
|
// }
|
|||
|
// }
|
|||
|
// }
|
|||
|
// // ******** 更新State信息 ********
|
|||
|
// _stateIndex = 0;
|
|||
|
// if (_currentController.layers.Length > 0)
|
|||
|
// {
|
|||
|
// _states = _currentController.layers[0].stateMachine.states;
|
|||
|
// if (_states.Length == 0)
|
|||
|
// {
|
|||
|
// _states = null;
|
|||
|
// _errorList.Add(string.Format("动画状态机 {0} 不包含状态!", _controllerPath));
|
|||
|
// }
|
|||
|
// }
|
|||
|
// else
|
|||
|
// _states = null;
|
|||
|
// }
|
|||
|
// }
|
|||
|
// }
|
|||
|
// if (!cancel)
|
|||
|
// cancel = EditorUtility.DisplayCancelableProgressBar("修复动画状态机", _controllerPath, (float)_index / (float)_controllers.Length);
|
|||
|
// if (cancel)
|
|||
|
// Stop();
|
|||
|
// else if (_states != null)
|
|||
|
// {
|
|||
|
// var state = _states[_stateIndex];
|
|||
|
// // ******** 处理动画文件被公用的情况,将会试图复制动画 ********
|
|||
|
// if (state.state.motion != null)
|
|||
|
// {
|
|||
|
// var path = AssetDatabase.GetAssetPath(state.state.motion);
|
|||
|
// // ******** 如果路径不统一,动画文件将被复制到动画机位置 ********
|
|||
|
// var controllerRoot = _controllerPath.MoveUp();
|
|||
|
//
|
|||
|
// if (!string.Equals(controllerRoot, path.MoveUp(), StringComparison.CurrentCultureIgnoreCase))
|
|||
|
// {
|
|||
|
// var newPath = controllerRoot + "/" + state.state.name + ".anim";
|
|||
|
// state.state.motion = CopyOneClip(path, newPath);
|
|||
|
// _handledClipList.Add(newPath);
|
|||
|
// }
|
|||
|
// else
|
|||
|
// {
|
|||
|
// var willCopyClip = _handledClipList.FindIndex(a => string.Equals(a, path, StringComparison.CurrentCultureIgnoreCase)) >= 0;
|
|||
|
// // 需要操作Motion的情况
|
|||
|
// if (willCopyClip || !string.Equals(state.state.motion.name, state.state.name,
|
|||
|
// StringComparison.CurrentCultureIgnoreCase))
|
|||
|
// {
|
|||
|
// var newPath = EditorCommonUtility.SwitchFileNameInPath(path, state.state.name);
|
|||
|
// LogModule.DebugLog(string.Format("{0} Clip From {1} to {2}", willCopyClip ? "Copy" : "Move", path, newPath));
|
|||
|
// if (willCopyClip)
|
|||
|
// state.state.motion = CopyOneClip(path, newPath);
|
|||
|
// else
|
|||
|
// MoveOneClip(path, newPath);
|
|||
|
// _handledClipList.Add(newPath);
|
|||
|
// }
|
|||
|
// else
|
|||
|
// _handledClipList.Add(path);
|
|||
|
// }
|
|||
|
// }
|
|||
|
// _stateIndex++;
|
|||
|
// }
|
|||
|
// }
|
|||
|
//
|
|||
|
// private Motion CopyOneClip(string path, string newPath)
|
|||
|
// {
|
|||
|
// EditorCommonUtility.RenameTargetFile(newPath);
|
|||
|
// AssetDatabase.CopyAsset(path, newPath);
|
|||
|
// _copyList.Add(string.Format("动画 {0} 被复制为 {1}, 源控制器 {2} ", path, newPath, _controllerPath));
|
|||
|
// return AssetDatabase.LoadAssetAtPath<Motion>(newPath);
|
|||
|
// }
|
|||
|
//
|
|||
|
// private void MoveOneClip(string path, string newPath)
|
|||
|
// {
|
|||
|
// EditorCommonUtility.RenameTargetFile(newPath);
|
|||
|
// AssetDatabase.MoveAsset(path, newPath);
|
|||
|
// _renameList.Add(string.Format("动画 {0} 被改名为 {1}, 源控制器 {2} ", path, newPath, _controllerPath));
|
|||
|
// }
|
|||
|
//}
|