226 lines
7.5 KiB
C#
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);
|
|
}
|
|
}
|
|
}
|