2023-04-03 11:04:31 +08:00

226 lines
7.5 KiB
C#

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEditor;
using System.IO;
namespace BFEditor.Resource
{
public static class FrameAnimationTools
{
const float FRAME_TIME = 0.1f; // 每帧间隔
struct CheckResult
{
public bool legal;
public GameObject gameObject;
public Image image;
public string spritePath;
public string animationPath;
public string controllerPath;
}
public static void CreateFrameAnimation(bool parentAni = false)
{
var result = CheckLegal(parentAni);
if (!result.legal)
{
return;
}
if (!File.Exists(result.animationPath))
{
var bindingPath = parentAni ? result.gameObject.name : "";
CreateAnimation(result.spritePath, result.animationPath, bindingPath);
}
else
{
var bindingPath = parentAni ? result.gameObject.name : "";
ModifyAnimaiton(result.spritePath, result.animationPath, bindingPath);
}
if (!File.Exists(result.controllerPath))
{
var gameObject = parentAni ? result.gameObject.transform.parent.gameObject : result.gameObject;
CreateController(gameObject, result.animationPath, result.controllerPath);
}
else
{
Debug.Log(result.controllerPath + "已经存在");
}
AssetDatabase.SaveAssets();
AssetDatabase.Refresh();
}
static CheckResult CheckLegal(bool parentAni = false)
{
var result = new CheckResult();
var obj = (GameObject)Selection.activeObject;
result.gameObject = obj;
if (ReferenceEquals(obj, null))
{
EditorUtility.DisplayDialog("提示", "当前没有选中的gameObject", "ok");
result.legal = false;
return result;
}
if (parentAni)
{
var parent = obj.transform.parent;
if (parent == null)
{
EditorUtility.DisplayDialog("提示", "当前没有选中的gameObject没有父物体", "ok");
result.legal = false;
return result;
}
}
var image = obj.GetComponent<Image>();
result.image = image;
if (ReferenceEquals(image, null))
{
EditorUtility.DisplayDialog("提示", "当前选中的gameObject没有image组件", "ok");
result.legal = false;
return result;
}
var sprite = image.sprite;
if (ReferenceEquals(sprite, null))
{
EditorUtility.DisplayDialog("提示", "image.sprite为空", "ok");
result.legal = false;
return result;
}
var path = AssetDatabase.GetAssetPath(sprite).Replace("\\", "/");
result.spritePath = path;
if (string.IsNullOrEmpty(path))
{
EditorUtility.DisplayDialog("提示", "找不到sprite路径", "ok");
result.legal = false;
return result;
}
var textureImproter = (TextureImporter)AssetImporter.GetAtPath(path);
if (textureImproter.spriteImportMode != SpriteImportMode.Multiple)
{
EditorUtility.DisplayDialog("提示", "spriteImportMode设置不正确", "ok");
result.legal = false;
return result;
}
result.animationPath = path.Replace("png", "anim");
result.controllerPath = path.Replace("png", "controller");
if (File.Exists(result.animationPath))
{
var tips = string.Format("已经存在{0}\n确定重置序列帧曲线吗?", result.animationPath);
if (!EditorUtility.DisplayDialog("提示", tips, "确定", "取消"))
{
result.legal = false;
return result;
}
}
result.legal = true;
return result;
}
/// <summary>
/// 创建animation
/// </summary>
static void CreateAnimation(string spritePath, string animationPath, string bindingPath = "")
{
var clip = new AnimationClip();
clip.frameRate = 60;
var clipSettingss = AnimationUtility.GetAnimationClipSettings(clip);
clipSettingss.loopTime = true;
AnimationUtility.SetAnimationClipSettings(clip, clipSettingss);
var curveBuilding = GetCurveBinding(bindingPath);
var keyFrames = GetKeyFrames(spritePath);
AnimationUtility.SetObjectReferenceCurve(clip, curveBuilding, keyFrames);
AssetDatabase.CreateAsset(clip, animationPath);
}
/// <summary>
/// 修改animation
/// </summary>
static void ModifyAnimaiton(string spritePath, string animationPath, string bindingPath = "")
{
var keyFrames = GetKeyFrames(spritePath);
var clip = AssetDatabase.LoadAssetAtPath<AnimationClip>(animationPath);
foreach (var binding in AnimationUtility.GetObjectReferenceCurveBindings(clip))
{
if (binding.path == bindingPath && binding.propertyName == "m_Sprite")
{
AnimationUtility.SetObjectReferenceCurve(clip, binding, keyFrames);
Debug.Log("重置序列帧曲线");
return;
}
}
var curveBuilding = GetCurveBinding(bindingPath);
AnimationUtility.SetObjectReferenceCurve(clip, curveBuilding, keyFrames);
}
static ObjectReferenceKeyframe[] GetKeyFrames(string spritePath)
{
// 获取切割出来的sprite
var spriteList = new List<Sprite>();
var objs = AssetDatabase.LoadAllAssetsAtPath(spritePath);
foreach (var obj in objs)
{
if (obj is Sprite)
{
spriteList.Add(obj as Sprite);
}
}
// 创建序列帧曲线
var keyFrames = new ObjectReferenceKeyframe[spriteList.Count];
for (int i = 0; i < spriteList.Count; i++)
{
var keyFrame = new ObjectReferenceKeyframe();
keyFrame.time = FRAME_TIME * i;
keyFrame.value = spriteList[i];
keyFrames[i] = keyFrame;
}
return keyFrames;
}
static EditorCurveBinding GetCurveBinding(string bindingPath = "")
{
var curveBuilding = new EditorCurveBinding();
curveBuilding.path = bindingPath;
curveBuilding.propertyName = "m_Sprite";
curveBuilding.type = typeof(Image);
return curveBuilding;
}
/// <summary>
/// 创建controller
/// </summary>
static void CreateController(GameObject gameObject, string animationPath, string controllerPath)
{
var animator = gameObject.GetComponent<Animator>();
if (animator == null)
{
animator = gameObject.AddComponent<Animator>();
}
var controller = UnityEditor.Animations.AnimatorController.CreateAnimatorControllerAtPath(controllerPath);
var layer = controller.layers[0];
var machine = layer.stateMachine;
var stateName = Path.GetFileNameWithoutExtension(animationPath);
var animState = machine.AddState(stateName);
var clip = AssetDatabase.LoadAssetAtPath<AnimationClip>(animationPath);
animState.motion = clip;
machine.AddAnyStateTransition(animState);
machine.defaultState = animState;
animator.runtimeAnimatorController = AssetDatabase.LoadAssetAtPath<RuntimeAnimatorController>(controllerPath);
}
}
}