Unity自定义Atlas图集实现加载图集中的小图

Posted 围墙外的世界

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Unity自定义Atlas图集实现加载图集中的小图相关的知识,希望对你有一定的参考价值。

Unity没有提供加载图集里面小图的API,下面是我学习框架课程(因为这个框架课程没有封装LoadAllAsset的方法)所学到的加载方法。

1.封装UIAtlas类,保存序列化的图集


 /*******************
  *  Title:CW_FrameWark
  *  Author:CW
  *  ScriptName:  UIAtlas
  *  Des:自定义Atlas
  ******************/
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using UnityEngine.UI;

namespace CW_FrameWark
{
   public class UIAtlas : ScriptableObject
   {
        public Texture2D MainTexture;
        public List<Sprite> SpriteList = new List<Sprite>();

        /// <summary>
        /// 根据名字去获取Sprite
        /// </summary>
        /// <param name="spriteName"></param>
        /// <returns></returns>
        public Sprite GetSprite(string spriteName)
        {
            return SpriteList.Find(
                (Sprite s)=>
                {
                    return s.name == spriteName;
                }
                );
        }
        /// <summary>
        /// 设置Image的Sprite
        /// </summary>
        /// <param name="image"></param>
        /// <param name="spriteName"></param>
        /// <param name="isSetNative"></param>
        public void SetSprite(ref Image image,string spriteName,bool isSetNative=false)
        {
            if(image==null)
            {
                return;
            }

            Sprite sp = GetSprite(spriteName);
            if(sp!=null)
            {
                image.sprite = sp;
                if(isSetNative)
                {
                    image.SetNativeSize();
                }
            }
            else
            {
                Log.Error(string.Format("你要设置的SpriteName:{0}没有在这个图集里面"+spriteName));
            }
        }
    
   }
}
2 编写编辑器脚本将图集序列化预设Atlas


 /*******************
  *  Title:CW_FrameWark
  *  Author:CW
  *  ScriptName:  CreateAtlasTool
  *  Des:创建自定义的Atlas
  ******************/
using UnityEngine;
using System.Collections;
using UnityEditor;
namespace CW_FrameWark
{
   public class CreateAtlasTool
   {
        [MenuItem("Assets/Create/MyAtlas prefab")]
        public static void CreateAtlasPrefab()
        {
            if(Selection.activeObject!=null)
            {
                string path = AssetDatabase.GetAssetPath(Selection.activeObject);
                TextureImporter impoter = AssetImporter.GetAtPath(path) as TextureImporter;
                //判断选择的类型是一个图集
                if(impoter!=null&&impoter.textureType==TextureImporterType.Sprite
                    &&impoter.spriteImportMode==SpriteImportMode.Multiple
                    )
                {
                    UIAtlas atlas = ScriptableObject.CreateInstance<UIAtlas>();
                    Object[] objs = AssetDatabase.LoadAllAssetsAtPath(path);

                    atlas.SpriteList.Clear();

                    foreach (Object obj in objs)
                    {
                        if(obj.GetType()==typeof(Texture2D))
                        {
                            atlas.MainTexture = obj as Texture2D;
                        }else if(obj.GetType()==typeof(Sprite))
                        {
                            atlas.SpriteList.Add(obj as Sprite);
                        }
                    }
                    AssetDatabase.CreateAsset(atlas, path.Replace(".png", "_Atlas.prefab"));
                    AssetDatabase.Refresh();
                }
                else
                {
                    Log.Error("当前选中的不是图集图片!");
                }
            }
        }      
   }
}
3 这样我们就大体的创建了一个自定义的Atlas了,但是这个Atlas在这个Inspector面板中我们可以随意将图片指定给这个Atlas,容易造成“误操作”,所有我们自定义Atlas的Inspector面板。


/*******************
 *  Title:CW_FrameWark
 *  Author:CW
 *  ScriptName:  UIAtlasInspector
 *  Des:重新自定义Atlas Inspector面板
 ******************/
using UnityEngine;
using System.Collections;
using UnityEditor;
namespace CW_FrameWark
{
    [CustomEditor(typeof(UIAtlas))]
   public class UIAtlasInspector : Editor
   {
        public override void OnInspectorGUI()
        {
            UIAtlas atlas = target as UIAtlas;
            atlas.MainTexture = EditorGUILayout.ObjectField("MainTexture", atlas.MainTexture, typeof(Texture2D)) as Texture2D;

            if(GUILayout.Button("刷新数据"))
            {
                if(atlas.MainTexture==null)
                {
                    string path= EditorUtility.OpenFilePanel("选着一张图集", Application.dataPath, "png");
                    if(!string.IsNullOrEmpty(path))
                    {
                        atlas.MainTexture = AssetDatabase.LoadAssetAtPath(path, typeof(Texture2D)) as Texture2D;

                    }
                }
                if(atlas.MainTexture!=null)
                {
                    string path = AssetDatabase.GetAssetPath(atlas.MainTexture);
                    TextureImporter importer = AssetImporter.GetAtPath(path) as TextureImporter;
                    if (importer != null && importer.textureType == TextureImporterType.Sprite
                        && importer.spriteImportMode == SpriteImportMode.Multiple)
                    {
                        Object[] objs = AssetDatabase.LoadAllAssetsAtPath(AssetDatabase.GetAssetPath(atlas.MainTexture));
                        atlas.SpriteList.Clear();
                        foreach (Object o in objs)
                        {
                            if (o.GetType() == typeof(Texture2D))
                            {
                                atlas.MainTexture = o as Texture2D;
                            }
                            else if (o.GetType() == typeof(Sprite))
                            {
                                atlas.SpriteList.Add(o as Sprite);
                            }
                        }
                    }
                    else
                    {
                        atlas.MainTexture = null;
                    }
                }
            }
            if(atlas.SpriteList.Count>0)
            {
                foreach (Sprite s in atlas.SpriteList)
                {
                    EditorGUILayout.ObjectField(s.name, s, typeof(Sprite));
                }
            }
        }

    }
}

4 下面我们就如何使用这个我们自定义的Atlas

   
    void Awake()
    {
        Image img=GetComponent<Image>();x
        UIAtlas atlas=Resources.Load<UIAtlas>("1AtlAS")
        atlas.SetSprite(ref img,"1");
    }

 

以上是关于Unity自定义Atlas图集实现加载图集中的小图的主要内容,如果未能解决你的问题,请参考以下文章

什么叫新建图集

unity中sprite是啥意思

Unity AssetBundle(3):图集Atlas与AB包

unity动态图集 dynamic atlas (runtime atlas)

Unity中关于NGUI的知识点

unity 怎么使用sprite packer图集