CTT/Unity/Assets/Editor/CalEditor/ResTool.cs

1054 lines
39 KiB
C#
Raw Normal View History

2021-04-08 20:09:59 +08:00
using Animancer;
using Animancer.Editor;
using Cal.DataTable;
using ET;
using Sirenix.OdinInspector;
using Sirenix.Utilities;
using Sirenix.Utilities.Editor;
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text.RegularExpressions;
using UnityEditor;
using UnityEditor.Sprites;
using UnityEngine;
using Component = UnityEngine.Component;
namespace ETEditor
{
[CreateAssetMenu]
[InitializeOnLoad]
2021-05-16 17:22:42 +08:00
public class ResTool: SerializedScriptableObject
2021-04-08 20:09:59 +08:00
{
public static ResTool Instance;
private void OnEnable()
{
Instance = this;
InitAnimFrame();
}
[FolderPath]
[LabelText("生成出的EffectAnimation的路径")]
public string animationPath = "Assets/Download/Animators/RoleEffect";
2021-05-16 17:22:42 +08:00
2021-04-08 20:09:59 +08:00
[FolderPath]
[LabelText("生成出的RoleAnimation的路径")]
public string animationRolePath = "Assets/Download/Animators";
public TextAsset txtAnimationConfig;
private Dictionary<string, int> animationFrameDic = new Dictionary<string, int>();
private Dictionary<string, int> animFrameDic = new Dictionary<string, int>();
[Button("生成动画帧率配置")]
void InitAnimFrame()
{
string path = "../Config/Anim.txt";
2021-04-11 19:50:39 +08:00
string[] arr = File.ReadAllLines(path);
foreach (string str in arr)
2021-04-08 20:09:59 +08:00
{
Cal.AnimFrame animFrame = MongoHelper.FromJson<Cal.AnimFrame>(str);
animFrameDic[animFrame.Name] = animFrame.FrameCount;
}
}
[Button("生成动画配置")]
private void CreateAnimationConfig()
{
if (txtAnimationConfig == null)
{
Log.Error($"txtAnimationConfig==null");
return;
}
2021-05-16 17:22:42 +08:00
2021-04-08 20:09:59 +08:00
animationFrameDic.Clear();
Dictionary<long, AnimationConfig> dic = MongoHelper.FromJson<Dictionary<long, AnimationConfig>>(txtAnimationConfig.text);
2021-04-11 19:50:39 +08:00
foreach (AnimationConfig item in dic.Values)
2021-04-08 20:09:59 +08:00
{
// /sss.
// 0 4 4-0=4 13
2021-04-11 19:50:39 +08:00
string name = item.Name;
2021-04-08 20:09:59 +08:00
animationFrameDic.Add(name, item.Frame);
}
}
[MenuItem("Assets/资源操作/临时修改", false, 97)]
static void ModifyDir() => Instance.ModifyDirInternel();
2021-05-16 17:22:42 +08:00
2021-04-08 20:09:59 +08:00
private void ModifyDirInternel()
{
try
{
string[] strs = Selection.assetGUIDs;
string targetParentPath = Path.GetFullPath("Assets/Download/Texture/EffectSources/RoleEffect");
2021-04-11 19:50:39 +08:00
foreach (string item in strs)
2021-04-08 20:09:59 +08:00
{
string dirPath = AssetDatabase.GUIDToAssetPath(item);
2021-04-11 19:50:39 +08:00
foreach (FileInfo fielInfo in Utility.FileOpation.GetFiles(dirPath, "*.png", SearchOption.AllDirectories))
2021-04-08 20:09:59 +08:00
{
2021-04-11 19:50:39 +08:00
string pName = fielInfo.Name.Split('_')[0];
string ppName = pName.Substring(0, pName.Length - 1);
2021-04-08 20:09:59 +08:00
string path = $"{targetParentPath}/{ppName}/{pName}/";
string metaName = fielInfo.FullName + ".meta";
2021-04-11 19:50:39 +08:00
FileInfo meta = new FileInfo(metaName);
2021-04-08 20:09:59 +08:00
fielInfo.MoveTo(path + fielInfo.Name);
meta.MoveTo(path + fielInfo.Name + ".meta");
}
}
2021-05-16 17:22:42 +08:00
2021-04-08 20:09:59 +08:00
AssetDatabase.Refresh();
}
catch (Exception e)
{
Log.Error(e);
}
}
2021-05-16 17:22:42 +08:00
2021-04-08 20:09:59 +08:00
[MenuItem("Assets/资源操作/清空文件夹", false, 97)]
static void ClearDir() => Instance.ClearDirInternel();
2021-05-16 17:22:42 +08:00
2021-04-08 20:09:59 +08:00
private void ClearDirInternel()
{
string[] strs = Selection.assetGUIDs;
//Transform OBJ = GameObject.Find("OBJ").transform;
2021-04-11 19:50:39 +08:00
foreach (string item in strs)
2021-04-08 20:09:59 +08:00
{
string dirPath = AssetDatabase.GUIDToAssetPath(item);
Utility.FileOpation.ClearDirectory(dirPath);
}
2021-05-16 17:22:42 +08:00
2021-04-08 20:09:59 +08:00
AssetDatabase.Refresh();
}
2021-05-16 17:22:42 +08:00
2021-04-08 20:09:59 +08:00
[MenuItem("Assets/资源操作/删除文件夹", false, 99)]
static void DeleteDir() => Instance.DeleteDirInternel();
2021-05-16 17:22:42 +08:00
2021-04-08 20:09:59 +08:00
private void DeleteDirInternel()
{
string[] strs = Selection.assetGUIDs;
//Transform OBJ = GameObject.Find("OBJ").transform;
2021-04-11 19:50:39 +08:00
foreach (string item in strs)
2021-04-08 20:09:59 +08:00
{
string dirPath = AssetDatabase.GUIDToAssetPath(item);
Utility.FileOpation.DeleteDirectory(dirPath);
}
2021-05-16 17:22:42 +08:00
2021-04-08 20:09:59 +08:00
AssetDatabase.Refresh();
}
#region 特效
2021-05-16 17:22:42 +08:00
2021-04-08 20:09:59 +08:00
[MenuItem("Assets/资源操作/特效/规范文件名A", false, 97)]
private static void Modify() => Instance.ModifyInternel();
2021-05-16 17:22:42 +08:00
2021-04-08 20:09:59 +08:00
private void ModifyInternel()
{
try
{
string[] strs = Selection.assetGUIDs;
2021-04-11 19:50:39 +08:00
foreach (string item in strs)
2021-04-08 20:09:59 +08:00
{
string dirPath = AssetDatabase.GUIDToAssetPath(item);
if (Directory.Exists(dirPath))
{
FileInfo[] infoArr = Utility.FileOpation.GetFiles(dirPath, "*.png", SearchOption.AllDirectories);
SortAsFileName(infoArr);
Execute(infoArr);
}
}
2021-05-16 17:22:42 +08:00
2021-04-08 20:09:59 +08:00
AssetDatabase.Refresh();
void Execute(FileInfo[] fileInfoArr)
{
ModifyName("_A_");
ModifyName("_B_");
ModifyName("_C_");
ModifyName("_D_");
void ModifyName(string nameSign)
{
int i = 0;
2021-04-11 19:50:39 +08:00
foreach (FileInfo fileInfo in fileInfoArr)
2021-04-08 20:09:59 +08:00
{
if (!fileInfo.Name.Contains(nameSign))
continue;
string dirPath = fileInfo.DirectoryName;
string ext = "" + ++i;
if (i < 10)
ext = "0" + ext;
DirectoryInfo directoryInfo = new DirectoryInfo(dirPath);
string name = directoryInfo.Parent.Name;
Regex reg = new Regex(@"[0-9]+", RegexOptions.IgnoreCase | RegexOptions.Singleline);
int index = int.Parse(reg.Match(directoryInfo.Name).Value);
name += index;
string metaName = fileInfo.FullName + ".meta";
FileInfo meta = new FileInfo(metaName);
name = dirPath + "/" + name + nameSign + ext + ".png";
fileInfo.MoveTo(name);
meta.MoveTo(name + ".meta");
}
}
}
}
catch (Exception e)
{
Log.Error(e);
}
}
[MenuItem("Assets/资源操作/特效/生成序列帧动画", false, 98)]
static void BuildAniamtion() => Instance.BuildAniamtionInterner();
2021-05-16 17:22:42 +08:00
2021-04-08 20:09:59 +08:00
private void BuildAniamtionInterner()
{
try
{
string[] strs = Selection.assetGUIDs;
List<FileInfo> animAList = new List<FileInfo>();
List<FileInfo> animBList = new List<FileInfo>();
List<FileInfo> animCList = new List<FileInfo>();
List<FileInfo> animDList = new List<FileInfo>();
2021-05-16 17:22:42 +08:00
int count = 0, max = strs.Length;
2021-04-11 19:50:39 +08:00
foreach (string item in strs)
2021-04-08 20:09:59 +08:00
{
2021-05-16 17:22:42 +08:00
string dictorys = AssetDatabase.GUIDToAssetPath(item);
2021-04-08 20:09:59 +08:00
2021-05-16 17:22:42 +08:00
DirectoryInfo directoryInfo = new DirectoryInfo(dictorys);
// var dirArr = raw.GetDirectories();
// int count = 0;
// int max = dirArr.Length;
// foreach (DirectoryInfo dictorys in dirArr)
// {
string parentName = directoryInfo.Parent.Name;
count++;
animAList.Clear();
animBList.Clear();
animCList.Clear();
animDList.Clear();
if (EditorUtility.DisplayCancelableProgressBar(string.Format("创建动画{0}/{1}", count, max), directoryInfo.Name, count / (float) max))
break;
FileInfo[] images = directoryInfo.GetFiles("*.png");
foreach (FileInfo info in images)
2021-04-08 20:09:59 +08:00
{
2021-05-16 17:22:42 +08:00
if (info.Name.Contains("_A_"))
animAList.Add(info);
else if (info.Name.Contains("_B_"))
animBList.Add(info);
else if (info.Name.Contains("_C_"))
animCList.Add(info);
else if (info.Name.Contains("_D_"))
animDList.Add(info);
}
string pngName = null;
if (animAList.Count > 0)
{
pngName = animAList[0].Name;
Generate(pngName,animAList);
}
if (animBList.Count > 0)
{
pngName = animBList[0].Name;
Generate(pngName,animBList);
2021-04-08 20:09:59 +08:00
}
2021-05-16 17:22:42 +08:00
if (animCList.Count > 0)
{
pngName = animCList[0].Name;
Generate(pngName,animCList);
}
if (animDList.Count > 0)
{
pngName = animDList[0].Name;
Generate(pngName,animDList);
}
void Generate(string pngName,List<FileInfo> list)
{
string animName = pngName.Substring(0, pngName.LastIndexOf("_"));
animName = $"{animationPath}/{parentName}/{animName}.anim";
BuildAnimationClip(list, animName);
}
// }
2021-04-08 20:09:59 +08:00
}
2021-05-16 17:22:42 +08:00
2021-04-08 20:09:59 +08:00
AssetDatabase.Refresh();
EditorUtility.ClearProgressBar();
EditorUtility.DisplayDialog("生成动画", "生成动画已经完成", "确定");
}
catch (Exception e)
{
Log.Error(e);
EditorUtility.ClearProgressBar();
}
}
[MenuItem("Assets/资源操作/特效/自动给Effect赋值动画", false, 99)]
static void AutoAddClipToEffect() => Instance.AutoAddClipToEffectInterner();
2021-05-16 17:22:42 +08:00
2021-04-08 20:09:59 +08:00
private void AutoAddClipToEffectInterner()
{
try
{
string animClipDirPath = "Assets/Download/Effect/RoleEffect";
string[] strs = Selection.assetGUIDs;
2021-04-11 19:50:39 +08:00
foreach (string item in strs)
2021-04-08 20:09:59 +08:00
{
string dirPath = AssetDatabase.GUIDToAssetPath(item);
if (string.IsNullOrEmpty(dirPath) || !Directory.Exists(dirPath))
continue;
var fileArr = Utility.FileOpation.GetFiles(dirPath, "*.anim", SearchOption.AllDirectories);
2021-05-16 17:22:42 +08:00
int count = 0;
int max = fileArr.Length;
2021-04-11 19:50:39 +08:00
foreach (FileInfo fileInfo in fileArr)
2021-04-08 20:09:59 +08:00
{
count++;
2021-05-16 17:22:42 +08:00
if (EditorUtility.DisplayCancelableProgressBar(string.Format("自动赋值动画{0}/{1}", count, max), fileInfo.Name,
count / (float) max))
2021-04-08 20:09:59 +08:00
break;
string prefabName = fileInfo.Name.Replace(fileInfo.Extension, string.Empty);
string prefabDirPath = animClipDirPath + "/" + Directory.GetParent(fileInfo.FullName).Name;
CreatePrefab(Utility.FileOpation.CreateDirectory(prefabDirPath), prefabName);
}
}
2021-05-16 17:22:42 +08:00
2021-04-08 20:09:59 +08:00
AssetDatabase.Refresh();
EditorUtility.ClearProgressBar();
EditorUtility.DisplayDialog("自动赋值动画", "自动赋值动画已经完成", "确定");
}
catch (Exception e)
{
Log.Error(e);
EditorUtility.ClearProgressBar();
}
}
#endregion
#region 角色
2021-05-16 17:22:42 +08:00
2021-04-08 20:09:59 +08:00
[MenuItem("Assets/资源操作/角色/批量规范文件名", false, 97)]
static void MultiModify() => Instance.MultiModifyInternel();
2021-05-16 17:22:42 +08:00
2021-04-08 20:09:59 +08:00
private void MultiModifyInternel()
{
try
{
string[] strs = Selection.assetGUIDs;
2021-04-11 19:50:39 +08:00
foreach (string item in strs)
2021-04-08 20:09:59 +08:00
{
string dirPath = AssetDatabase.GUIDToAssetPath(item);
FileInfo[] infoArr = Utility.FileOpation.GetFiles(dirPath, "*.png", SearchOption.AllDirectories);
Execute(infoArr, ".png");
infoArr = Utility.FileOpation.GetFiles(dirPath, "*.meta", SearchOption.AllDirectories);
Execute(infoArr, ".png.meta");
AssetDatabase.Refresh();
2021-05-16 17:22:42 +08:00
2021-04-08 20:09:59 +08:00
void Execute(FileInfo[] _infoArr, string extion)
{
SortAsFileName(_infoArr);
List<FileInfo> animHurtList = new List<FileInfo>();
List<FileInfo> animRunList = new List<FileInfo>();
List<FileInfo> animIdleList = new List<FileInfo>();
List<FileInfo> animAttackList = new List<FileInfo>();
string dirFilePath = _infoArr[0].DirectoryName;
string dirName = Directory.GetParent(_infoArr[0].FullName).Name;
dirFilePath += "/" + dirName;
2021-04-11 19:50:39 +08:00
foreach (FileInfo fileInfo in _infoArr)
2021-04-08 20:09:59 +08:00
{
if (fileInfo.FullName.Contains("hurt") ||
2021-05-16 17:22:42 +08:00
fileInfo.FullName.Contains("hit") ||
fileInfo.FullName.Contains("Hurt") ||
fileInfo.FullName.Contains("Hit")
)
2021-04-08 20:09:59 +08:00
{
animHurtList.Add(fileInfo);
}
else if (fileInfo.FullName.Contains("run") ||
2021-05-16 17:22:42 +08:00
fileInfo.FullName.Contains("Run")
)
2021-04-08 20:09:59 +08:00
{
animRunList.Add(fileInfo);
}
else if (fileInfo.FullName.Contains("Idle") ||
2021-05-16 17:22:42 +08:00
fileInfo.FullName.Contains("idle")
)
2021-04-08 20:09:59 +08:00
{
animIdleList.Add(fileInfo);
}
else if (fileInfo.FullName.Contains("attack") ||
fileInfo.FullName.Contains("Attack")
2021-05-16 17:22:42 +08:00
)
2021-04-08 20:09:59 +08:00
{
animAttackList.Add(fileInfo);
}
else
{
Log.Error($"{fileInfo.Name} 命名错误");
}
}
2021-05-16 17:22:42 +08:00
2021-04-08 20:09:59 +08:00
int i = 0;
2021-04-11 19:50:39 +08:00
foreach (FileInfo animInfo in animHurtList)
2021-04-08 20:09:59 +08:00
{
string ext = "" + ++i;
if (i < 10)
ext = "0" + ext;
name = dirFilePath + "_Hurt_" + ext + extion;
animInfo.MoveTo(name);
}
2021-05-16 17:22:42 +08:00
2021-04-08 20:09:59 +08:00
i = 0;
2021-04-11 19:50:39 +08:00
foreach (FileInfo animInfo in animRunList)
2021-04-08 20:09:59 +08:00
{
string ext = "" + ++i;
if (i < 10)
ext = "0" + ext;
name = dirFilePath + "_Run_" + ext + extion;
animInfo.MoveTo(name);
}
2021-05-16 17:22:42 +08:00
2021-04-08 20:09:59 +08:00
i = 0;
2021-04-11 19:50:39 +08:00
foreach (FileInfo animInfo in animIdleList)
2021-04-08 20:09:59 +08:00
{
string ext = "" + ++i;
if (i < 10)
ext = "0" + ext;
name = dirFilePath + "_Idle_" + ext + extion;
animInfo.MoveTo(name);
}
2021-05-16 17:22:42 +08:00
2021-04-08 20:09:59 +08:00
i = 0;
2021-04-11 19:50:39 +08:00
foreach (FileInfo animInfo in animAttackList)
2021-04-08 20:09:59 +08:00
{
string ext = "" + ++i;
if (i < 10)
ext = "0" + ext;
name = dirFilePath + "_Attack_" + ext + extion;
animInfo.MoveTo(name);
}
}
}
2021-05-16 17:22:42 +08:00
2021-04-08 20:09:59 +08:00
AssetDatabase.Refresh();
}
catch (Exception e)
{
Log.Error(e);
}
}
[MenuItem("Assets/资源操作/角色/生成序列帧动画", false, 98)]
static void BuildRoleAniamtion() => Instance.BuildRoleAniamtionInterner();
2021-05-16 17:22:42 +08:00
2021-04-08 20:09:59 +08:00
private void BuildRoleAniamtionInterner()
{
try
{
string[] strs = Selection.assetGUIDs;
List<FileInfo> animHurtList = new List<FileInfo>();
List<FileInfo> animRunList = new List<FileInfo>();
List<FileInfo> animIdleList = new List<FileInfo>();
List<FileInfo> animAttackList = new List<FileInfo>();
2021-05-16 17:22:42 +08:00
int count = 0, max = strs.Length;
2021-04-11 19:50:39 +08:00
foreach (string item in strs)
2021-04-08 20:09:59 +08:00
{
2021-05-16 17:22:42 +08:00
string dictorys = AssetDatabase.GUIDToAssetPath(item);
2021-04-08 20:09:59 +08:00
2021-05-16 17:22:42 +08:00
DirectoryInfo directoryInfo = new DirectoryInfo(dictorys);
string parentName = directoryInfo.Parent.Name;
count++;
animHurtList.Clear();
animRunList.Clear();
animIdleList.Clear();
animAttackList.Clear();
if (EditorUtility.DisplayCancelableProgressBar(string.Format("创建动画{0}/{1}", count, max), directoryInfo.Name, count / (float) max))
break;
FileInfo[] images = directoryInfo.GetFiles("*.png");
foreach (FileInfo info in images)
2021-04-08 20:09:59 +08:00
{
2021-05-16 17:22:42 +08:00
if (info.Name.Contains("_Attack_"))
animAttackList.Add(info);
else if (info.Name.Contains("_Hurt_"))
animHurtList.Add(info);
else if (info.Name.Contains("_Idle_"))
animIdleList.Add(info);
else if (info.Name.Contains("_Run_"))
animRunList.Add(info);
}
string pngName = null;
if (animAttackList.Count > 0)
{
pngName = animAttackList[0].Name;
Generate(pngName,animAttackList);
}
if (animHurtList.Count > 0)
{
pngName = animHurtList[0].Name;
Generate(pngName,animHurtList);
}
if (animIdleList.Count > 0)
{
pngName = animIdleList[0].Name;
Generate(pngName,animIdleList);
}
if (animRunList.Count > 0)
{
pngName = animRunList[0].Name;
Generate(pngName,animRunList);
}
void Generate(string pngName,List<FileInfo> list)
{
string animName = pngName.Substring(0, pngName.LastIndexOf("_"));
string animParentName = pngName.Substring(0, pngName.IndexOf("_"));
animName = $"{animationRolePath}/{parentName}/{animParentName}/{animName}.anim";
BuildAnimationClip(list, animName);
2021-04-08 20:09:59 +08:00
}
}
2021-05-16 17:22:42 +08:00
2021-04-08 20:09:59 +08:00
AssetDatabase.Refresh();
EditorUtility.ClearProgressBar();
EditorUtility.DisplayDialog("生成动画", "生成动画已经完成", "确定");
}
catch (Exception e)
{
Log.Error(e);
EditorUtility.ClearProgressBar();
}
}
[MenuItem("Assets/资源操作/角色/自动给Role赋值动画", false, 99)]
static void AutoAddClip() => Instance.AutoAddClipInterner();
2021-05-16 17:22:42 +08:00
2021-04-08 20:09:59 +08:00
private void AutoAddClipInterner()
{
try
{
string[] strs = Selection.assetGUIDs;
2021-04-11 19:50:39 +08:00
foreach (string item in strs)
2021-04-08 20:09:59 +08:00
{
string dirPath = AssetDatabase.GUIDToAssetPath(item);
if (string.IsNullOrEmpty(dirPath) || !Directory.Exists(dirPath))
continue;
string animClipDirPath = animationRolePath + "/" + Utility.FileOpation.CreateDirectory(dirPath).Name;
var fileArr = Utility.FileOpation.GetFiles(dirPath, "*.prefab", SearchOption.AllDirectories);
2021-05-16 17:22:42 +08:00
int count = 0;
int max = fileArr.Length;
2021-04-11 19:50:39 +08:00
foreach (FileInfo fileInfo in fileArr)
2021-04-08 20:09:59 +08:00
{
count++;
2021-05-16 17:22:42 +08:00
if (EditorUtility.DisplayCancelableProgressBar(string.Format("自动赋值动画{0}/{1}", count, max), fileInfo.Name,
count / (float) max))
2021-04-08 20:09:59 +08:00
break;
string prefabName = fileInfo.Name.Replace(fileInfo.Extension, string.Empty);
string clipDirPath = animClipDirPath + "/" + prefabName;
AnimationClipInfo[] clipInfo = new AnimationClipInfo[0];
var arr = Utility.FileOpation.GetFiles(clipDirPath, "*.anim", SearchOption.AllDirectories);
if (arr == null)
{
Log.Error($"arr == null where ame = {prefabName}");
continue;
}
2021-05-16 17:22:42 +08:00
2021-04-11 19:50:39 +08:00
foreach (FileInfo animInfo in arr)
2021-04-08 20:09:59 +08:00
{
2021-04-11 19:50:39 +08:00
string animName = Utility.Path.GetRegularPath(animInfo.FullName);
AnimationClip anim = AssetDatabase.LoadAssetAtPath<AnimationClip>(DataPathToAssetPath(animName));
2021-05-16 17:22:42 +08:00
ArrayUtility.Add(ref clipInfo, new AnimationClipInfo { AnimationClip = anim });
2021-04-08 20:09:59 +08:00
}
2021-05-16 17:22:42 +08:00
2021-04-11 19:50:39 +08:00
string prefanName = Utility.Path.GetRegularPath(fileInfo.FullName);
GameObject go = AssetDatabase.LoadAssetAtPath<GameObject>(DataPathToAssetPath(prefanName));
2021-04-08 20:09:59 +08:00
MonoAnimancer animancers = go.GetComponent<MonoAnimancer>();
animancers.Animator = go.GetComponentInChildren<Animator>();
animancers.SetClips(clipInfo);
AddSpriteInterner(animancers);
EditorUtility.SetDirty(go);
AssetDatabase.SaveAssets();
}
}
2021-05-16 17:22:42 +08:00
2021-04-08 20:09:59 +08:00
AssetDatabase.Refresh();
EditorUtility.ClearProgressBar();
EditorUtility.DisplayDialog("自动赋值动画", "自动赋值动画已经完成", "确定");
}
catch (Exception e)
{
Log.Error(e);
EditorUtility.ClearProgressBar();
}
}
2021-05-16 17:22:42 +08:00
2021-04-08 20:09:59 +08:00
#endregion
2021-05-16 17:22:42 +08:00
2021-04-08 20:09:59 +08:00
private AnimationClip BuildAnimationClip(List<FileInfo> images, string animationName, bool isLoop = false)
{
CreateAnimationConfig();
AnimationClip clip = new AnimationClip();
AnimationUtility.SetAnimationType(clip, ModelImporterAnimationType.Generic);
EditorCurveBinding curveBinding = new EditorCurveBinding();
2021-05-16 17:22:42 +08:00
curveBinding.type = typeof (SpriteRenderer);
2021-04-08 20:09:59 +08:00
curveBinding.path = "";
curveBinding.propertyName = "m_Sprite";
ObjectReferenceKeyframe[] keyFrames = new ObjectReferenceKeyframe[images.Count];
string dirPath = animationName.Substring(0, animationName.LastIndexOf('/'));
//动画长度是按秒为单位1/10就表示1秒切10张图片根据项目的情况可以自己调节
2021-04-11 19:50:39 +08:00
if (!animationFrameDic.TryGetValue(dirPath, out int frame))
2021-04-08 20:09:59 +08:00
{
frame = 12;
}
2021-05-16 17:22:42 +08:00
2021-04-08 20:09:59 +08:00
if (animationName.IndexOf("Attack") < 0)
{
frame = 12;
}
//帧率
2021-05-16 17:22:42 +08:00
string animationRealName = animationName.Substring(animationName.LastIndexOf('/') + 1).Replace(".anim", string.Empty);
2021-04-08 20:09:59 +08:00
Log.Info($"{animationRealName}");
2021-04-11 19:50:39 +08:00
if (animFrameDic.TryGetValue(animationRealName, out int newframe))
2021-04-08 20:09:59 +08:00
frame = newframe;
float frameTime = 1f / frame;
for (int i = 0; i < images.Count; i++)
{
Sprite sprite = AssetDatabase.LoadAssetAtPath<Sprite>(DataPathToAssetPath(images[i].FullName));
keyFrames[i] = new ObjectReferenceKeyframe();
keyFrames[i].time = frameTime * i;
keyFrames[i].value = sprite;
}
2021-05-16 17:22:42 +08:00
2021-04-08 20:09:59 +08:00
//动画帧率30比较合适
clip.frameRate = frame;
//有些动画我希望天生它就动画循环
if (isLoop || animationName.IndexOf("Idle") >= 0 || animationName.IndexOf("Run") >= 0)
{
//设置idle文件为循环动画
SerializedObject serializedClip = new SerializedObject(clip);
AnimationClipSettings clipSettings = new AnimationClipSettings(serializedClip.FindProperty("m_AnimationClipSettings"));
clipSettings.loopTime = true;
serializedClip.ApplyModifiedProperties();
}
2021-05-16 17:22:42 +08:00
2021-04-08 20:09:59 +08:00
AnimationUtility.SetObjectReferenceCurve(clip, curveBinding, keyFrames);
string dirFullPath = Path.GetFullPath(dirPath);
if (!Directory.Exists(dirFullPath))
{
Directory.CreateDirectory(dirFullPath);
}
2021-05-16 17:22:42 +08:00
2021-04-08 20:09:59 +08:00
AssetDatabase.CreateAsset(clip, animationName);
AssetDatabase.SaveAssets();
return clip;
}
2021-05-16 17:22:42 +08:00
2021-04-08 20:09:59 +08:00
[MenuItem("Assets/资源操作/自动赋值Sprite", false, 101)]
static void AutoAddSprite() => Instance.AutoAddSpriteInterner();
2021-05-16 17:22:42 +08:00
2021-04-08 20:09:59 +08:00
private void AutoAddSpriteInterner()
{
try
{
string[] strs = Selection.assetGUIDs;
2021-04-11 19:50:39 +08:00
foreach (string item in strs)
2021-04-08 20:09:59 +08:00
{
string dirPath = AssetDatabase.GUIDToAssetPath(item);
if (string.IsNullOrEmpty(dirPath) || !Directory.Exists(dirPath))
continue;
var fileArr = Utility.FileOpation.GetFiles(dirPath, "*.prefab", SearchOption.AllDirectories);
2021-05-16 17:22:42 +08:00
int count = 0;
int max = fileArr.Length;
2021-04-11 19:50:39 +08:00
foreach (FileInfo fileInfo in fileArr)
2021-04-08 20:09:59 +08:00
{
count++;
2021-05-16 17:22:42 +08:00
if (EditorUtility.DisplayCancelableProgressBar(string.Format("赋值Sprite{0}/{1}", count, max), fileInfo.Name,
count / (float) max))
2021-04-08 20:09:59 +08:00
break;
string prefabName = fileInfo.Name.Replace(fileInfo.Extension, string.Empty);
2021-04-11 19:50:39 +08:00
string prefanName = Utility.Path.GetRegularPath(fileInfo.FullName);
GameObject go = AssetDatabase.LoadAssetAtPath<GameObject>(DataPathToAssetPath(prefanName));
2021-04-08 20:09:59 +08:00
MonoAnimancer animancers = go.GetComponent<MonoAnimancer>();
AddSpriteInterner(animancers);
EditorUtility.SetDirty(go);
AssetDatabase.SaveAssets();
}
}
2021-05-16 17:22:42 +08:00
2021-04-08 20:09:59 +08:00
AssetDatabase.Refresh();
EditorUtility.ClearProgressBar();
EditorUtility.DisplayDialog("自动赋值Sprite", "自动赋值Sprite已经完成", "确定");
}
catch (Exception e)
{
Log.Error(e);
EditorUtility.ClearProgressBar();
}
}
/// <summary>
/// 将Animancers中第一个动画的第一帧赋值给Sprite
/// </summary>
/// <param name="animancers"></param>
private void AddSpriteInterner(MonoAnimancer animancers)
{
try
{
var clipArr = animancers.GetClips();
if (clipArr == null)
{
Log.Error($"clipArr == null where name = {animancers.name}");
return;
}
2021-05-16 17:22:42 +08:00
2021-04-08 20:09:59 +08:00
AnimationClip clip = clipArr[0].AnimationClip;
var keyArr = AnimationUtility.GetObjectReferenceCurve(clip, curveBinding);
if (keyArr == null)
{
Log.Error($"keyArr == null where name = fileInfo.Name");
return;
}
2021-05-16 17:22:42 +08:00
2021-04-11 19:50:39 +08:00
ObjectReferenceKeyframe key = keyArr[0];
2021-04-08 20:09:59 +08:00
Sprite sprite = key.value.As<Sprite>();
animancers.GetComponent<SpriteRenderer>().sprite = sprite;
}
catch (Exception e)
{
Log.Error(e);
}
}
[MenuItem("Assets/资源操作/加入图集", false, 110)]
static void AddToAlats() => Instance.AddToAlatsInterner();
2021-05-16 17:22:42 +08:00
2021-04-08 20:09:59 +08:00
private void AddToAlatsInterner()
{
BulildAB bulildAB = AssetDatabase.LoadAssetAtPath<BulildAB>("Assets/Model/Cal/CalAssets/BulildAB.asset");
string[] strs = Selection.assetGUIDs;
2021-04-11 19:50:39 +08:00
foreach (string item in strs)
2021-04-08 20:09:59 +08:00
{
string dirPath = AssetDatabase.GUIDToAssetPath(item);
2021-04-11 19:50:39 +08:00
foreach (FileInfo fileInfo in Utility.FileOpation.GetFiles(dirPath, "*.*", SearchOption.AllDirectories))
2021-04-08 20:09:59 +08:00
{
if (fileInfo.Extension.Equals(".meta"))
continue;
string path = fileInfo.DirectoryName;
if (string.IsNullOrEmpty(path) || !Directory.Exists(path))
continue;
if (bulildAB.atlasPaths.Contains(path))
continue;
bulildAB.atlasPaths.Add(path);
}
}
2021-05-16 17:22:42 +08:00
2021-04-08 20:09:59 +08:00
EditorUtility.SetDirty(bulildAB);
AssetDatabase.Refresh();
}
private void CreatePrefab(DirectoryInfo dirPath, string prefabName)
{
2021-04-11 19:50:39 +08:00
GameObject go = new GameObject(prefabName);
2021-04-08 20:09:59 +08:00
2021-04-11 19:50:39 +08:00
string prefabFilePath = Path.Combine(dirPath.FullName, go.name + ".prefab");
2021-04-08 20:09:59 +08:00
string clipPath = animationPath + "/" + dirPath.Name + "/" + prefabName + ".anim";
AnimationClipInfo[] clipInfo = new AnimationClipInfo[0];
2021-04-11 19:50:39 +08:00
string animName = Utility.Path.GetRegularPath(clipPath);
AnimationClip anim = AssetDatabase.LoadAssetAtPath<AnimationClip>(animName);
2021-04-08 20:09:59 +08:00
if (anim == null)
{
Log.Error($"anim == null where name = {prefabName}");
return;
}
2021-05-16 17:22:42 +08:00
ArrayUtility.Add(ref clipInfo, new AnimationClipInfo { Key = AnimationKey.Other, AnimationClip = anim });
2021-04-08 20:09:59 +08:00
prefabFilePath = Utility.Path.GetRegularPath(prefabFilePath);
MonoAnimancer animancers = go.AddComponent<MonoAnimancer>();
animancers.Animator = go.AddComponent<Animator>();
2021-04-11 19:50:39 +08:00
SpriteRenderer sr = go.AddComponent<SpriteRenderer>();
2021-04-08 20:09:59 +08:00
sr.sortingLayerName = "Effect";
sr.spriteSortPoint = SpriteSortPoint.Pivot;
animancers.SetClips(clipInfo);
//!赋值Sprite
AddSpriteInterner(animancers);
PrefabUtility.SaveAsPrefabAssetAndConnect(go, prefabFilePath, InteractionMode.AutomatedAction);
EditorUtility.SetDirty(go);
AssetDatabase.SaveAssets();
}
2021-05-16 17:22:42 +08:00
2021-04-08 20:09:59 +08:00
class AnimationClipSettings
{
SerializedProperty m_Property;
2021-05-16 17:22:42 +08:00
private SerializedProperty Get(string property)
{
return m_Property.FindPropertyRelative(property);
}
public AnimationClipSettings(SerializedProperty prop)
{
m_Property = prop;
}
public float startTime
{
get
{
return Get("m_StartTime").floatValue;
}
set
{
Get("m_StartTime").floatValue = value;
}
}
public float stopTime
{
get
{
return Get("m_StopTime").floatValue;
}
set
{
Get("m_StopTime").floatValue = value;
}
}
public float orientationOffsetY
{
get
{
return Get("m_OrientationOffsetY").floatValue;
}
set
{
Get("m_OrientationOffsetY").floatValue = value;
}
}
public float level
{
get
{
return Get("m_Level").floatValue;
}
set
{
Get("m_Level").floatValue = value;
}
}
public float cycleOffset
{
get
{
return Get("m_CycleOffset").floatValue;
}
set
{
Get("m_CycleOffset").floatValue = value;
}
}
public bool loopTime
{
get
{
return Get("m_LoopTime").boolValue;
}
set
{
Get("m_LoopTime").boolValue = value;
}
}
public bool loopBlend
{
get
{
return Get("m_LoopBlend").boolValue;
}
set
{
Get("m_LoopBlend").boolValue = value;
}
}
public bool loopBlendOrientation
{
get
{
return Get("m_LoopBlendOrientation").boolValue;
}
set
{
Get("m_LoopBlendOrientation").boolValue = value;
}
}
public bool loopBlendPositionY
{
get
{
return Get("m_LoopBlendPositionY").boolValue;
}
set
{
Get("m_LoopBlendPositionY").boolValue = value;
}
}
public bool loopBlendPositionXZ
{
get
{
return Get("m_LoopBlendPositionXZ").boolValue;
}
set
{
Get("m_LoopBlendPositionXZ").boolValue = value;
}
}
public bool keepOriginalOrientation
{
get
{
return Get("m_KeepOriginalOrientation").boolValue;
}
set
{
Get("m_KeepOriginalOrientation").boolValue = value;
}
}
public bool keepOriginalPositionY
{
get
{
return Get("m_KeepOriginalPositionY").boolValue;
}
set
{
Get("m_KeepOriginalPositionY").boolValue = value;
}
}
public bool keepOriginalPositionXZ
{
get
{
return Get("m_KeepOriginalPositionXZ").boolValue;
}
set
{
Get("m_KeepOriginalPositionXZ").boolValue = value;
}
}
public bool heightFromFeet
{
get
{
return Get("m_HeightFromFeet").boolValue;
}
set
{
Get("m_HeightFromFeet").boolValue = value;
}
}
public bool mirror
{
get
{
return Get("m_Mirror").boolValue;
}
set
{
Get("m_Mirror").boolValue = value;
}
}
2021-04-08 20:09:59 +08:00
}
static EditorCurveBinding curveBinding
{
get
{
EditorCurveBinding curveBinding = new EditorCurveBinding();
2021-05-16 17:22:42 +08:00
curveBinding.type = typeof (SpriteRenderer);
2021-04-08 20:09:59 +08:00
curveBinding.path = "";
curveBinding.propertyName = "m_Sprite";
return curveBinding;
}
}
2021-05-16 17:22:42 +08:00
2021-04-08 20:09:59 +08:00
private static void SortAsFileName(FileInfo[] arrFi)
{
Array.Sort(arrFi, new StringCompare());
}
2021-05-16 17:22:42 +08:00
public class StringCompare: IComparer<FileInfo>
2021-04-08 20:09:59 +08:00
{
public int Compare(FileInfo x, FileInfo y)
{
string a = x.Name.Trim();
string b = y.Name.Trim();
string r = @"[0-9]+";
Regex reg = new Regex(r, RegexOptions.IgnoreCase | RegexOptions.Singleline);
2021-05-16 17:22:42 +08:00
MatchCollection mcA = reg.Matches(a); //设定要查找的字符串
2021-04-08 20:09:59 +08:00
int intA = -1;
foreach (Match m in mcA)
{
intA = int.Parse(m.Groups[0].Value);
}
2021-05-16 17:22:42 +08:00
MatchCollection mcB = reg.Matches(b); //设定要查找的字符串
2021-04-08 20:09:59 +08:00
int intB = -1;
foreach (Match m in mcB)
{
intB = int.Parse(m.Groups[0].Value);
}
2021-05-16 17:22:42 +08:00
2021-04-08 20:09:59 +08:00
if (intA == -1 || intB == -1)
{
return a.CompareTo(b);
}
return intA.CompareTo(intB);
}
}
2021-05-16 17:22:42 +08:00
2021-04-08 20:09:59 +08:00
private static string DataPathToAssetPath(string path)
{
if (path.Contains("\\"))
return path.Substring(path.IndexOf("Assets\\"));
else
return path.Substring(path.IndexOf("Assets/"));
}
}
}