版權說明:本文為博主原創(chuàng)文章甩挫,轉載需注明出處
環(huán)境 Unity 2018.3.9f1
??2D游戲中避免不了幀動畫的存在钮惠,當游戲中有大量角色的時候怕膛,手動創(chuàng)建Sprite Animation再整合到AnimatorController中可以說是要死人的庶溶,所以寫了個簡單的自動創(chuàng)建Animation和AnimatorController的Demo進行分享朴上。
??先上文件層級
文件層級.png
??每張圖片文件末位以數字結尾垒棋,用于標識在Animation動畫中的前后位置。
??創(chuàng)建AnimatorController代碼
using System;
using System.Collections.Generic;
using System.IO;
using UnityEditor;
using UnityEditor.Animations;
using UnityEngine;
public class AutoCreateAnimationEditor : Editor
{
//生成出的AnimationController的路徑
private static string _animationControllerPath = "Assets/Animation";
//生成出的Animation的路徑
private static string _animationPath = "Assets/Animation";
//美術給的原始圖片路徑
private static string _spriteRootPath = "Assets/Texture";
[MenuItem("Tools/CreateAnimatorController")]
static void CreateAnimation()
{
DirectoryInfo root = new DirectoryInfo(_spriteRootPath);
foreach (DirectoryInfo roleFolder in root.GetDirectories())
{
List<AnimationClip> clipsList = new List<AnimationClip>();
foreach (DirectoryInfo actionFolder in roleFolder.GetDirectories())
{
foreach (DirectoryInfo unitActionFolder in actionFolder.GetDirectories())
{
clipsList.Add(CreateAnimationClip(unitActionFolder));
}
}
CreateAnimationController(clipsList, roleFolder.Name);
}
}
static AnimationClip CreateAnimationClip(DirectoryInfo unitActionFolder)
{
string animationName = unitActionFolder.Name.ToLower();
FileInfo[] sprites = unitActionFolder.GetFiles("*.png");
Array.Sort(sprites, new FileComparer());
AnimationClip clip = new AnimationClip();
EditorCurveBinding curveBinding = new EditorCurveBinding
{
type = typeof(SpriteRenderer),
path = "",
propertyName = "m_Sprite"
};
string roleFolderName = unitActionFolder.Parent.Parent.Name;
string actionFolderName = unitActionFolder.Parent.Name;
ObjectReferenceKeyframe[] keyFrames = new ObjectReferenceKeyframe[sprites.Length];
// 動畫幀率 表示一秒播放幾張圖片
int frame = 10;
float frameTime = 1f / frame;
for (int i = 0; i < sprites.Length; i++)
{
Sprite sprite = AssetDatabase.LoadAssetAtPath<Sprite>(
$"{_spriteRootPath}/{roleFolderName}/{actionFolderName}/{unitActionFolder.Name}/{sprites[i].Name}");
keyFrames[i] = new ObjectReferenceKeyframe
{
time = frameTime * i,
value = sprite
};
}
clip.frameRate = frame;
// 設置循環(huán)播放
AnimationClipSettings clipSetting = AnimationUtility.GetAnimationClipSettings(clip);
clipSetting.loopTime = true;
AnimationUtility.SetAnimationClipSettings(clip, clipSetting);
AnimationUtility.SetObjectReferenceCurve(clip, curveBinding, keyFrames);
// 創(chuàng)建文件夾
string animationClipPath = $"{_animationPath}/{roleFolderName}/{actionFolderName}";
Directory.CreateDirectory($"{animationClipPath}");
// 創(chuàng)建AnimationClip文件
string file = $"{animationClipPath}/{roleFolderName}_{animationName}.anim";
AssetDatabase.CreateAsset(clip, file);
AssetDatabase.SaveAssets();
return clip;
}
static void CreateAnimationController(List<AnimationClip> clipsList, string role)
{
string animatorControllerPath = $"{_animationControllerPath}/{role}/{role}_animator_ctrl.controller";
AnimatorController animatorController =
AnimatorController.CreateAnimatorControllerAtPath(animatorControllerPath);
// 添加參數
animatorController.AddParameter(new AnimatorControllerParameter()
{
name = "Run", type = AnimatorControllerParameterType.Bool, defaultBool = false
});
AnimatorControllerLayer layer = animatorController.layers[0];
AnimatorStateMachine sm = layer.stateMachine;
foreach (AnimationClip clip in clipsList)
{
AnimatorState state = sm.AddState(clip.name);
state.motion = clip;
state.writeDefaultValues = false;
if (clip.name.Contains("idle"))
{
sm.defaultState = state;
}
// 設置參數 這里只設置了 不能過渡到自身 以及 過渡時間
AnimatorStateTransition trans = sm.AddAnyStateTransition(state);
trans.canTransitionToSelf = false;
trans.duration = 0;
// 添加Animation條件
trans.AddCondition(
clip.name.IndexOf("run", StringComparison.Ordinal) > 0
? AnimatorConditionMode.If
: AnimatorConditionMode.IfNot, 0,
"Run");
}
AssetDatabase.SaveAssets();
}
}
??文件排序接口實現
public class FileComparer : IComparer<FileInfo>
{
public int Compare(FileInfo a, FileInfo b)
{
int index_a_dot = a.Name.LastIndexOf('.');
int index_a__ = a.Name.LastIndexOf('_');
int num_a = Convert.ToInt32(a.Name.Substring(index_a__ + 1, index_a_dot - index_a__ - 1));
int index_b_dot = b.Name.LastIndexOf('.');
int index_b__ = b.Name.LastIndexOf('_');
int num_b = Convert.ToInt32(b.Name.Substring(index_b__ + 1, index_b_dot - index_b__ - 1));
return num_a < num_b ? -1 : 1;
}
}
?
??這樣就完成了痪宰,點擊Tools/AnimatorController即可創(chuàng)建出Animation和AnimatorController叼架,效果圖如下:
Result.gif
??同理,如果想創(chuàng)建UGUI動畫衣撬,在Image上播放的話乖订,將EditorCurveBinding
的type
設置為Image
就可以了。
image.png
??以上具练。