根据图片自动生成动画

来源:互联网 发布:windows 内核漏洞 编辑:程序博客网 时间:2024/05/18 01:43

根据自己的情况 仿照 雨松MOMO 写了一个自动生成动画的脚本 原地址 http://www.xuanyusong.com/archives/3243


代码:

using UnityEngine;using System.Collections;using System.Collections.Generic;using UnityEditor;using System;using System.IO;using UnityEditor.Animations;public enum Orientation{    Down = 1, RightDown, Right, RightUp, Up, LeftUp, Left, LeftDown}public class BuildAnimation : Editor {    #region 常量    #endregion    #region 事件    #endregion    #region 字段    private static string m_prefabPath = "Assets/Resources/Prefabs";    private static string m_AnimationControllerPath = "Assets/AnimationController";    private static string m_animationPath = "Assets/Animation";    private static string m_rawImagePath = Application.dataPath + "/Raw";    #endregion    #region 属性    #endregion    #region 方法    [MenuItem("Assets/BuildAnimation")]    static void BuildAnimations() {        DirectoryInfo raw = new DirectoryInfo(m_rawImagePath);        foreach (DirectoryInfo directories in raw.GetDirectories())        {            List<AnimationClip> clips = new List<AnimationClip>();            foreach (DirectoryInfo ActionList in directories.GetDirectories())            {                List<AnimationClip> clipList = BuildAnimationList(ActionList);                foreach (AnimationClip clip in clipList)                {                    clips.Add(clip);                }            }            AnimatorController controller = BuildAnimationController(clips, directories.Name);            BuildPrefab(directories, controller);        }    }    /// <summary>    /// Build预设    /// </summary>    /// <param name="directories"></param>    /// <param name="animatorController"></param>    private static void BuildPrefab(DirectoryInfo directories, AnimatorController animatorController)    {        FileInfo _image = directories.GetDirectories()[0].GetFiles("*.png")[0];        GameObject _go = new GameObject();        _go.name = directories.Name;        SpriteRenderer _spriteRenderer = _go.AddComponent<SpriteRenderer>();        _spriteRenderer.sprite = AssetDatabase.LoadAssetAtPath<Sprite>(DataPathToAssetPath(_image.FullName));        Animator _animator = _go.AddComponent<Animator>();        _animator.runtimeAnimatorController = animatorController;        System.IO.Directory.CreateDirectory(m_prefabPath);        PrefabUtility.CreatePrefab(m_prefabPath + "/" + _go.name + ".prefab", _go);        DestroyImmediate(_go);    }    /// <summary>    /// Build控制器    /// </summary>    /// <param name="clips"></param>    /// <param name="name"></param>    /// <returns></returns>    private static AnimatorController BuildAnimationController(List<AnimationClip> clips, string name)    {        //string _parentName = System.IO.Directory.GetParent(directories.FullName).Name;        //创建文件夹        System.IO.Directory.CreateDirectory(m_AnimationControllerPath);        AnimatorController animatorController = AnimatorController.            CreateAnimatorControllerAtPath(m_AnimationControllerPath + "/" + name + ".controller");        AnimatorControllerLayer layer = animatorController.layers[0];        AnimatorStateMachine sm = layer.stateMachine;        foreach (AnimationClip newClip in clips)        {            AnimatorState state = sm.AddState(newClip.name);            state.motion = newClip;            //设置默认状态            if (state.name == "idle_Down")            {               sm.defaultState = state;            }            //_state.SetAnimationClip(newClip, _layer);            //AnimatorStateTransition trans = sm.AddAnyStateTransition(_state);            //trans.RemoveCondition(0);        }        AssetDatabase.SaveAssets();        return animatorController;    }    /// <summary>    /// build八个方向动画    /// </summary>    /// <param name="directories"></param>    /// <returns></returns>    private static List<AnimationClip> BuildAnimationList(DirectoryInfo directories)    {        string _animationName = directories.Name;        FileInfo[] _images = directories.GetFiles("*.png");        //创建unit文件夹        string _parentName = System.IO.Directory.GetParent(directories.FullName).Name;        System.IO.Directory.CreateDirectory(m_animationPath + "/" + _parentName);        Dictionary<int, List<FileInfo>> _Dic = new Dictionary<int, List<FileInfo>>();        List<AnimationClip> _dicClips = new List<AnimationClip>();        //创建方向文件夹        for (int i = 1; i < 9; i++)        {            string _enumName = EnumToString((Orientation)i);            System.IO.Directory.CreateDirectory(m_animationPath + "/" + _parentName + "/" + _enumName);            _Dic.Add(i, new List<FileInfo>());        }        for (int i = 0; i < _images.Length; i++)        {            //获取无扩展名的文件名            string _fileName = Path.GetFileNameWithoutExtension(_images[i].ToString());            int initial = (int)(_fileName[0]);            //根据首字母添加            // Debug.Log(_fileName[0]);            // Debug.Log(initial);            _Dic[initial - 48].Add(_images[i]);        }        foreach (int key in _Dic.Keys)        {            AnimationClip _clip = new AnimationClip();            _clip = BuildAnimationClip(_Dic[key]);            //动画循环            if (_animationName.IndexOf("idle") >= 0)            {                //设置idle文件为循环动画                SerializedObject serializedClip = new SerializedObject(_clip);                AnimationClipSetting clipSettings = new AnimationClipSetting(serializedClip.FindProperty("m_AnimationClipSettings"));                clipSettings.loopTime = true;                serializedClip.ApplyModifiedProperties();            }            string _enumName = EnumToString((Orientation)key);            System.IO.Directory.CreateDirectory(m_animationPath + "/" + _parentName + "/" + _enumName);            AssetDatabase.CreateAsset(_clip, m_animationPath + "/" + _parentName                + "/" + _enumName + "/" + _animationName + "_" + _enumName + ".anim");            _dicClips.Add(_clip);        }        return _dicClips;    }    static string EnumToString(Orientation ori)    {        return Enum.GetName(typeof(Orientation), ori);    }    /// <summary>    /// Build动画    /// </summary>    /// <param name="fi"></param>    /// <returns></returns>    static AnimationClip BuildAnimationClip(List<FileInfo> fi) {        AnimationClip _clipTemp = new AnimationClip();        _clipTemp.frameRate = 30;        //AnimationUtility.SetAnimationType(_clipTemp, ModelImporterAnimationType.Generic);        EditorCurveBinding _curveBinding = new EditorCurveBinding();        _curveBinding.type = typeof(SpriteRenderer);        _curveBinding.path = "";        _curveBinding.propertyName = "m_Sprite";        ObjectReferenceKeyframe[] _keyFrames = new ObjectReferenceKeyframe[fi.Count];        float _frameTime = 1 / 10f;        for (int i = 0; i < _keyFrames.Length; i++)        {            Sprite _sprite = AssetDatabase.LoadAssetAtPath<Sprite>(DataPathToAssetPath(fi[i].FullName));            //过时 Resources.LoadAssetAtPath<Sprite>(DataPathToAssetPath(_images[i].FullName));            _keyFrames[i] = new ObjectReferenceKeyframe();            _keyFrames[i].time = _frameTime * i;            _keyFrames[i].value = _sprite;        }        AnimationUtility.SetObjectReferenceCurve(_clipTemp, _curveBinding, _keyFrames);        AssetDatabase.SaveAssets();        return _clipTemp;    }    private static string DataPathToAssetPath(string path)    {        if (Application.platform == RuntimePlatform.WindowsEditor)        {            return path.Substring(path.IndexOf("Assets\\"));        }        else {            return path.Substring(path.IndexOf("Assets/"));        }    }    #endregion    #region Unity回调    #endregion    #region 事件回调    #endregion    #region 帮助方法    #endregion}class AnimationClipSetting{    private SerializedProperty m_Property;    private SerializedProperty Get(string property)    {        return m_Property.FindPropertyRelative(property);    }    public AnimationClipSetting(SerializedProperty prop)    {        this.m_Property = prop;    }    public float startTime {        get { return Get("m_StartTime").floatValue; }        set { Get("m_StartTime").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; }    }}



这样做有个问题,每一次点击BuildAnimation都会重新加载所有资源,如果数据量大的话,更新会很不方便。

有以下修改:
    [MenuItem("Assets/BuildAnimation")]    static void BuildAnimations()    {        //选中的文件夹,不包括子文件夹        UnityEngine.Object[] filter = Selection.GetFiltered(typeof(UnityEngine.Object), SelectionMode.TopLevel);        //路径中包含"Raw" 或者选中的是"Raw"        if (!AssetDatabase.GetAssetPath(filter[0]).Contains("Raw") || Path.GetFileNameWithoutExtension(AssetDatabase.GetAssetPath(filter[0])) == "Raw")        {            Debug.LogError("没有选中对的文件夹");            return;        }        DirectoryInfo[] filterInfo = new DirectoryInfo[filter.Length];        for (int i = 0; i < filter.Length; i++)        {            filterInfo[i] = new DirectoryInfo(Application.dataPath.Substring(0,Application.dataPath.LastIndexOf("/")) + "/" + AssetDatabase.GetAssetPath(filter[i]));        }        foreach (DirectoryInfo directories in filterInfo)        {            List<AnimationClip> clips = new List<AnimationClip>();            foreach (DirectoryInfo ActionList in directories.GetDirectories())            {                List<AnimationClip> clipList = BuildAnimationList(ActionList);                foreach (AnimationClip clip in clipList)                {                    clips.Add(clip);                }            }            AnimatorController controller = BuildAnimationController(clips, directories.Name);            BuildPrefab(directories, controller);        }    }

这样写,只会Build选中的文件夹。