1055 lines
39 KiB
C#
1055 lines
39 KiB
C#
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]
|
||
public class ResTool: SerializedScriptableObject
|
||
{
|
||
public static ResTool Instance;
|
||
|
||
private void OnEnable()
|
||
{
|
||
Instance = this;
|
||
InitAnimFrame();
|
||
}
|
||
|
||
[FolderPath]
|
||
[LabelText("生成出的EffectAnimation的路径")]
|
||
public string animationPath = "Assets/Download/Animators/RoleEffect";
|
||
|
||
[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";
|
||
string[] arr = File.ReadAllLines(path);
|
||
foreach (string str in arr)
|
||
{
|
||
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;
|
||
}
|
||
|
||
animationFrameDic.Clear();
|
||
Dictionary<long, AnimationConfig> dic = MongoHelper.FromJson<Dictionary<long, AnimationConfig>>(txtAnimationConfig.text);
|
||
foreach (AnimationConfig item in dic.Values)
|
||
{
|
||
// /sss.
|
||
// 0 4 4-0=4 1,3
|
||
string name = item.Name;
|
||
animationFrameDic.Add(name, item.Frame);
|
||
}
|
||
}
|
||
|
||
[MenuItem("Assets/资源操作/临时修改", false, 97)]
|
||
static void ModifyDir() => Instance.ModifyDirInternel();
|
||
|
||
private void ModifyDirInternel()
|
||
{
|
||
try
|
||
{
|
||
string[] strs = Selection.assetGUIDs;
|
||
string targetParentPath = Path.GetFullPath("Assets/Download/Texture/EffectSources/RoleEffect");
|
||
foreach (string item in strs)
|
||
{
|
||
string dirPath = AssetDatabase.GUIDToAssetPath(item);
|
||
foreach (FileInfo fielInfo in Utility.FileOpation.GetFiles(dirPath, "*.png", SearchOption.AllDirectories))
|
||
{
|
||
string pName = fielInfo.Name.Split('_')[0];
|
||
string ppName = pName.Substring(0, pName.Length - 1);
|
||
string path = $"{targetParentPath}/{ppName}/{pName}/";
|
||
string metaName = fielInfo.FullName + ".meta";
|
||
FileInfo meta = new FileInfo(metaName);
|
||
fielInfo.MoveTo(path + fielInfo.Name);
|
||
meta.MoveTo(path + fielInfo.Name + ".meta");
|
||
}
|
||
}
|
||
|
||
AssetDatabase.Refresh();
|
||
}
|
||
catch (Exception e)
|
||
{
|
||
Log.Error(e);
|
||
}
|
||
}
|
||
|
||
[MenuItem("Assets/资源操作/清空文件夹", false, 97)]
|
||
static void ClearDir() => Instance.ClearDirInternel();
|
||
|
||
private void ClearDirInternel()
|
||
{
|
||
string[] strs = Selection.assetGUIDs;
|
||
//Transform OBJ = GameObject.Find("OBJ").transform;
|
||
foreach (string item in strs)
|
||
{
|
||
string dirPath = AssetDatabase.GUIDToAssetPath(item);
|
||
Utility.FileOpation.ClearDirectory(dirPath);
|
||
}
|
||
|
||
AssetDatabase.Refresh();
|
||
}
|
||
|
||
[MenuItem("Assets/资源操作/删除文件夹", false, 99)]
|
||
static void DeleteDir() => Instance.DeleteDirInternel();
|
||
|
||
private void DeleteDirInternel()
|
||
{
|
||
string[] strs = Selection.assetGUIDs;
|
||
//Transform OBJ = GameObject.Find("OBJ").transform;
|
||
foreach (string item in strs)
|
||
{
|
||
string dirPath = AssetDatabase.GUIDToAssetPath(item);
|
||
Utility.FileOpation.DeleteDirectory(dirPath);
|
||
}
|
||
|
||
AssetDatabase.Refresh();
|
||
}
|
||
|
||
#region 特效
|
||
|
||
[MenuItem("Assets/资源操作/特效/规范文件名A", false, 97)]
|
||
private static void Modify() => Instance.ModifyInternel();
|
||
|
||
private void ModifyInternel()
|
||
{
|
||
try
|
||
{
|
||
string[] strs = Selection.assetGUIDs;
|
||
foreach (string item in strs)
|
||
{
|
||
string dirPath = AssetDatabase.GUIDToAssetPath(item);
|
||
if (Directory.Exists(dirPath))
|
||
{
|
||
FileInfo[] infoArr = Utility.FileOpation.GetFiles(dirPath, "*.png", SearchOption.AllDirectories);
|
||
SortAsFileName(infoArr);
|
||
Execute(infoArr);
|
||
}
|
||
}
|
||
|
||
AssetDatabase.Refresh();
|
||
|
||
void Execute(FileInfo[] fileInfoArr)
|
||
{
|
||
ModifyName("_A_");
|
||
ModifyName("_B_");
|
||
ModifyName("_C_");
|
||
ModifyName("_D_");
|
||
|
||
void ModifyName(string nameSign)
|
||
{
|
||
int i = 0;
|
||
foreach (FileInfo fileInfo in fileInfoArr)
|
||
{
|
||
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();
|
||
|
||
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>();
|
||
int count = 0, max = strs.Length;
|
||
foreach (string item in strs)
|
||
{
|
||
string dictorys = AssetDatabase.GUIDToAssetPath(item);
|
||
|
||
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)
|
||
{
|
||
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);
|
||
}
|
||
|
||
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);
|
||
}
|
||
// }
|
||
}
|
||
|
||
AssetDatabase.Refresh();
|
||
EditorUtility.ClearProgressBar();
|
||
EditorUtility.DisplayDialog("生成动画", "生成动画已经完成", "确定");
|
||
}
|
||
catch (Exception e)
|
||
{
|
||
Log.Error(e);
|
||
EditorUtility.ClearProgressBar();
|
||
}
|
||
}
|
||
|
||
[MenuItem("Assets/资源操作/特效/自动给Effect赋值动画", false, 99)]
|
||
static void AutoAddClipToEffect() => Instance.AutoAddClipToEffectInterner();
|
||
|
||
private void AutoAddClipToEffectInterner()
|
||
{
|
||
try
|
||
{
|
||
string animClipDirPath = "Assets/Download/Effect/RoleEffect";
|
||
string[] strs = Selection.assetGUIDs;
|
||
foreach (string item in strs)
|
||
{
|
||
string dirPath = AssetDatabase.GUIDToAssetPath(item);
|
||
if (string.IsNullOrEmpty(dirPath) || !Directory.Exists(dirPath))
|
||
continue;
|
||
var fileArr = Utility.FileOpation.GetFiles(dirPath, "*.anim", SearchOption.AllDirectories);
|
||
int count = 0;
|
||
int max = fileArr.Length;
|
||
foreach (FileInfo fileInfo in fileArr)
|
||
{
|
||
count++;
|
||
if (EditorUtility.DisplayCancelableProgressBar(string.Format("自动赋值动画{0}/{1}", count, max), fileInfo.Name,
|
||
count / (float) max))
|
||
break;
|
||
string prefabName = fileInfo.Name.Replace(fileInfo.Extension, string.Empty);
|
||
string prefabDirPath = animClipDirPath + "/" + Directory.GetParent(fileInfo.FullName).Name;
|
||
CreatePrefab(Utility.FileOpation.CreateDirectory(prefabDirPath), prefabName);
|
||
}
|
||
}
|
||
|
||
AssetDatabase.Refresh();
|
||
|
||
EditorUtility.ClearProgressBar();
|
||
EditorUtility.DisplayDialog("自动赋值动画", "自动赋值动画已经完成", "确定");
|
||
}
|
||
catch (Exception e)
|
||
{
|
||
Log.Error(e);
|
||
EditorUtility.ClearProgressBar();
|
||
}
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region 角色
|
||
|
||
[MenuItem("Assets/资源操作/角色/批量规范文件名", false, 97)]
|
||
static void MultiModify() => Instance.MultiModifyInternel();
|
||
|
||
private void MultiModifyInternel()
|
||
{
|
||
try
|
||
{
|
||
string[] strs = Selection.assetGUIDs;
|
||
foreach (string item in strs)
|
||
{
|
||
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();
|
||
|
||
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;
|
||
foreach (FileInfo fileInfo in _infoArr)
|
||
{
|
||
if (fileInfo.FullName.Contains("hurt") ||
|
||
fileInfo.FullName.Contains("hit") ||
|
||
fileInfo.FullName.Contains("Hurt") ||
|
||
fileInfo.FullName.Contains("Hit")
|
||
)
|
||
{
|
||
animHurtList.Add(fileInfo);
|
||
}
|
||
else if (fileInfo.FullName.Contains("run") ||
|
||
fileInfo.FullName.Contains("Run")
|
||
)
|
||
{
|
||
animRunList.Add(fileInfo);
|
||
}
|
||
else if (fileInfo.FullName.Contains("Idle") ||
|
||
fileInfo.FullName.Contains("idle")
|
||
)
|
||
{
|
||
animIdleList.Add(fileInfo);
|
||
}
|
||
else if (fileInfo.FullName.Contains("attack") ||
|
||
fileInfo.FullName.Contains("Attack")
|
||
)
|
||
{
|
||
animAttackList.Add(fileInfo);
|
||
}
|
||
else
|
||
{
|
||
Log.Error($"{fileInfo.Name} 命名错误");
|
||
}
|
||
}
|
||
|
||
int i = 0;
|
||
foreach (FileInfo animInfo in animHurtList)
|
||
{
|
||
string ext = "" + ++i;
|
||
if (i < 10)
|
||
ext = "0" + ext;
|
||
name = dirFilePath + "_Hurt_" + ext + extion;
|
||
|
||
animInfo.MoveTo(name);
|
||
}
|
||
|
||
i = 0;
|
||
foreach (FileInfo animInfo in animRunList)
|
||
{
|
||
string ext = "" + ++i;
|
||
if (i < 10)
|
||
ext = "0" + ext;
|
||
name = dirFilePath + "_Run_" + ext + extion;
|
||
animInfo.MoveTo(name);
|
||
}
|
||
|
||
i = 0;
|
||
foreach (FileInfo animInfo in animIdleList)
|
||
{
|
||
string ext = "" + ++i;
|
||
if (i < 10)
|
||
ext = "0" + ext;
|
||
name = dirFilePath + "_Idle_" + ext + extion;
|
||
animInfo.MoveTo(name);
|
||
}
|
||
|
||
i = 0;
|
||
foreach (FileInfo animInfo in animAttackList)
|
||
{
|
||
string ext = "" + ++i;
|
||
if (i < 10)
|
||
ext = "0" + ext;
|
||
name = dirFilePath + "_Attack_" + ext + extion;
|
||
animInfo.MoveTo(name);
|
||
}
|
||
}
|
||
}
|
||
|
||
AssetDatabase.Refresh();
|
||
}
|
||
catch (Exception e)
|
||
{
|
||
Log.Error(e);
|
||
}
|
||
}
|
||
|
||
[MenuItem("Assets/资源操作/角色/生成序列帧动画", false, 98)]
|
||
static void BuildRoleAniamtion() => Instance.BuildRoleAniamtionInterner();
|
||
|
||
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>();
|
||
int count = 0, max = strs.Length;
|
||
foreach (string item in strs)
|
||
{
|
||
string dictorys = AssetDatabase.GUIDToAssetPath(item);
|
||
|
||
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)
|
||
{
|
||
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);
|
||
}
|
||
}
|
||
|
||
AssetDatabase.Refresh();
|
||
EditorUtility.ClearProgressBar();
|
||
EditorUtility.DisplayDialog("生成动画", "生成动画已经完成", "确定");
|
||
}
|
||
catch (Exception e)
|
||
{
|
||
Log.Error(e);
|
||
EditorUtility.ClearProgressBar();
|
||
}
|
||
}
|
||
|
||
[MenuItem("Assets/资源操作/角色/自动给Role赋值动画", false, 99)]
|
||
static void AutoAddClip() => Instance.AutoAddClipInterner();
|
||
|
||
private void AutoAddClipInterner()
|
||
{
|
||
try
|
||
{
|
||
string[] strs = Selection.assetGUIDs;
|
||
foreach (string item in strs)
|
||
{
|
||
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);
|
||
int count = 0;
|
||
int max = fileArr.Length;
|
||
foreach (FileInfo fileInfo in fileArr)
|
||
{
|
||
count++;
|
||
if (EditorUtility.DisplayCancelableProgressBar(string.Format("自动赋值动画{0}/{1}", count, max), fileInfo.Name,
|
||
count / (float) max))
|
||
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;
|
||
}
|
||
|
||
foreach (FileInfo animInfo in arr)
|
||
{
|
||
string animName = Utility.Path.GetRegularPath(animInfo.FullName);
|
||
AnimationClip anim = AssetDatabase.LoadAssetAtPath<AnimationClip>(DataPathToAssetPath(animName));
|
||
ArrayUtility.Add(ref clipInfo, new AnimationClipInfo { AnimationClip = anim });
|
||
}
|
||
|
||
string prefanName = Utility.Path.GetRegularPath(fileInfo.FullName);
|
||
GameObject go = AssetDatabase.LoadAssetAtPath<GameObject>(DataPathToAssetPath(prefanName));
|
||
MonoAnimancer animancers = go.GetComponent<MonoAnimancer>();
|
||
animancers.Animator = go.GetComponentInChildren<Animator>();
|
||
animancers.SetClips(clipInfo);
|
||
AddSpriteInterner(animancers);
|
||
|
||
EditorUtility.SetDirty(go);
|
||
AssetDatabase.SaveAssets();
|
||
}
|
||
}
|
||
|
||
AssetDatabase.Refresh();
|
||
|
||
EditorUtility.ClearProgressBar();
|
||
EditorUtility.DisplayDialog("自动赋值动画", "自动赋值动画已经完成", "确定");
|
||
}
|
||
catch (Exception e)
|
||
{
|
||
Log.Error(e);
|
||
EditorUtility.ClearProgressBar();
|
||
}
|
||
}
|
||
|
||
#endregion
|
||
|
||
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();
|
||
curveBinding.type = typeof (SpriteRenderer);
|
||
curveBinding.path = "";
|
||
curveBinding.propertyName = "m_Sprite";
|
||
ObjectReferenceKeyframe[] keyFrames = new ObjectReferenceKeyframe[images.Count];
|
||
string dirPath = animationName.Substring(0, animationName.LastIndexOf('/'));
|
||
//动画长度是按秒为单位,1/10就表示1秒切10张图片,根据项目的情况可以自己调节
|
||
if (!animationFrameDic.TryGetValue(dirPath, out int frame))
|
||
{
|
||
frame = 12;
|
||
}
|
||
|
||
if (animationName.IndexOf("Attack") < 0)
|
||
{
|
||
frame = 12;
|
||
}
|
||
|
||
//帧率
|
||
string animationRealName = animationName.Substring(animationName.LastIndexOf('/') + 1).Replace(".anim", string.Empty);
|
||
Log.Info($"{animationRealName}");
|
||
if (animFrameDic.TryGetValue(animationRealName, out int newframe))
|
||
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;
|
||
}
|
||
|
||
//动画帧率,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();
|
||
}
|
||
|
||
AnimationUtility.SetObjectReferenceCurve(clip, curveBinding, keyFrames);
|
||
string dirFullPath = Path.GetFullPath(dirPath);
|
||
if (!Directory.Exists(dirFullPath))
|
||
{
|
||
Directory.CreateDirectory(dirFullPath);
|
||
}
|
||
|
||
AssetDatabase.CreateAsset(clip, animationName);
|
||
AssetDatabase.SaveAssets();
|
||
return clip;
|
||
}
|
||
|
||
[MenuItem("Assets/资源操作/自动赋值Sprite", false, 101)]
|
||
static void AutoAddSprite() => Instance.AutoAddSpriteInterner();
|
||
|
||
private void AutoAddSpriteInterner()
|
||
{
|
||
try
|
||
{
|
||
string[] strs = Selection.assetGUIDs;
|
||
foreach (string item in strs)
|
||
{
|
||
string dirPath = AssetDatabase.GUIDToAssetPath(item);
|
||
if (string.IsNullOrEmpty(dirPath) || !Directory.Exists(dirPath))
|
||
continue;
|
||
var fileArr = Utility.FileOpation.GetFiles(dirPath, "*.prefab", SearchOption.AllDirectories);
|
||
int count = 0;
|
||
int max = fileArr.Length;
|
||
foreach (FileInfo fileInfo in fileArr)
|
||
{
|
||
count++;
|
||
if (EditorUtility.DisplayCancelableProgressBar(string.Format("赋值Sprite{0}/{1}", count, max), fileInfo.Name,
|
||
count / (float) max))
|
||
break;
|
||
string prefabName = fileInfo.Name.Replace(fileInfo.Extension, string.Empty);
|
||
string prefanName = Utility.Path.GetRegularPath(fileInfo.FullName);
|
||
GameObject go = AssetDatabase.LoadAssetAtPath<GameObject>(DataPathToAssetPath(prefanName));
|
||
MonoAnimancer animancers = go.GetComponent<MonoAnimancer>();
|
||
AddSpriteInterner(animancers);
|
||
|
||
EditorUtility.SetDirty(go);
|
||
AssetDatabase.SaveAssets();
|
||
}
|
||
}
|
||
|
||
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;
|
||
}
|
||
|
||
|
||
AnimationClip clip = clipArr.ToList().Find(t => t.Key == AnimationKey.Idle).AnimationClip;
|
||
var keyArr = AnimationUtility.GetObjectReferenceCurve(clip, curveBinding);
|
||
if (keyArr == null)
|
||
{
|
||
Log.Error($"keyArr == null where name = fileInfo.Name");
|
||
return;
|
||
}
|
||
|
||
ObjectReferenceKeyframe key = keyArr[0];
|
||
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();
|
||
|
||
private void AddToAlatsInterner()
|
||
{
|
||
BulildAB bulildAB = AssetDatabase.LoadAssetAtPath<BulildAB>("Assets/Model/Cal/CalAssets/BulildAB.asset");
|
||
string[] strs = Selection.assetGUIDs;
|
||
foreach (string item in strs)
|
||
{
|
||
string dirPath = AssetDatabase.GUIDToAssetPath(item);
|
||
foreach (FileInfo fileInfo in Utility.FileOpation.GetFiles(dirPath, "*.*", SearchOption.AllDirectories))
|
||
{
|
||
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);
|
||
}
|
||
}
|
||
|
||
EditorUtility.SetDirty(bulildAB);
|
||
AssetDatabase.Refresh();
|
||
}
|
||
|
||
private void CreatePrefab(DirectoryInfo dirPath, string prefabName)
|
||
{
|
||
GameObject go = new GameObject(prefabName);
|
||
|
||
string prefabFilePath = Path.Combine(dirPath.FullName, go.name + ".prefab");
|
||
|
||
string clipPath = animationPath + "/" + dirPath.Name + "/" + prefabName + ".anim";
|
||
AnimationClipInfo[] clipInfo = new AnimationClipInfo[0];
|
||
string animName = Utility.Path.GetRegularPath(clipPath);
|
||
AnimationClip anim = AssetDatabase.LoadAssetAtPath<AnimationClip>(animName);
|
||
if (anim == null)
|
||
{
|
||
Log.Error($"anim == null where name = {prefabName}");
|
||
return;
|
||
}
|
||
|
||
ArrayUtility.Add(ref clipInfo, new AnimationClipInfo { Key = AnimationKey.Other, AnimationClip = anim });
|
||
|
||
prefabFilePath = Utility.Path.GetRegularPath(prefabFilePath);
|
||
MonoAnimancer animancers = go.AddComponent<MonoAnimancer>();
|
||
animancers.Animator = go.AddComponent<Animator>();
|
||
SpriteRenderer sr = go.AddComponent<SpriteRenderer>();
|
||
sr.sortingLayerName = "Effect";
|
||
sr.spriteSortPoint = SpriteSortPoint.Pivot;
|
||
animancers.SetClips(clipInfo);
|
||
//!赋值Sprite
|
||
AddSpriteInterner(animancers);
|
||
|
||
PrefabUtility.SaveAsPrefabAssetAndConnect(go, prefabFilePath, InteractionMode.AutomatedAction);
|
||
|
||
EditorUtility.SetDirty(go);
|
||
AssetDatabase.SaveAssets();
|
||
}
|
||
|
||
class AnimationClipSettings
|
||
{
|
||
SerializedProperty m_Property;
|
||
|
||
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;
|
||
}
|
||
}
|
||
}
|
||
|
||
static EditorCurveBinding curveBinding
|
||
{
|
||
get
|
||
{
|
||
EditorCurveBinding curveBinding = new EditorCurveBinding();
|
||
curveBinding.type = typeof (SpriteRenderer);
|
||
curveBinding.path = "";
|
||
curveBinding.propertyName = "m_Sprite";
|
||
return curveBinding;
|
||
}
|
||
}
|
||
|
||
private static void SortAsFileName(FileInfo[] arrFi)
|
||
{
|
||
Array.Sort(arrFi, new StringCompare());
|
||
}
|
||
|
||
public class StringCompare: IComparer<FileInfo>
|
||
{
|
||
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);
|
||
MatchCollection mcA = reg.Matches(a); //设定要查找的字符串
|
||
|
||
int intA = -1;
|
||
foreach (Match m in mcA)
|
||
{
|
||
intA = int.Parse(m.Groups[0].Value);
|
||
}
|
||
|
||
MatchCollection mcB = reg.Matches(b); //设定要查找的字符串
|
||
|
||
int intB = -1;
|
||
foreach (Match m in mcB)
|
||
{
|
||
intB = int.Parse(m.Groups[0].Value);
|
||
}
|
||
|
||
if (intA == -1 || intB == -1)
|
||
{
|
||
return a.CompareTo(b);
|
||
}
|
||
|
||
return intA.CompareTo(intB);
|
||
}
|
||
}
|
||
|
||
private static string DataPathToAssetPath(string path)
|
||
{
|
||
if (path.Contains("\\"))
|
||
return path.Substring(path.IndexOf("Assets\\"));
|
||
else
|
||
return path.Substring(path.IndexOf("Assets/"));
|
||
}
|
||
}
|
||
} |