UGUI结合TexturePacker制作图集

工具

TexturePacker

TexturePacker使用

使用方法)

生成prefab

sprite信息类
using UnityEngine;
using System.Collections;
using System.Collections.Generic;

[System.Serializable]
public class SpriteAsset : MonoBehaviour
{
    /// <summary>
    /// 图片资源
    /// </summary>
    public Texture texSource;
    /// <summary>
    /// 所有sprite信息 SpriteAssetInfor类为具体的信息类
    /// </summary>
    public List<SpriteInfo> listSpriteInfor;

    //根据sprite名称获取Sprite
    public Sprite GetSpriteWithName(string name)
    {
        for(int i = 0; i < listSpriteInfor.Count;i++)
        {
            if(listSpriteInfor[i].name.Equals(name))
            {
                return listSpriteInfor[i].sprite;
            }
        }
        return null;
    }
}

[System.Serializable]
public class SpriteInfo
{
    /// <summary>
    /// ID
    /// </summary>
    public int ID;
    /// <summary>
    /// 名称
    /// </summary>
    public string name;
    /// <summary>
    /// 精灵
    /// </summary>
    public Sprite sprite;
}
创建图集prefab
using UnityEngine;
using System.Collections;
using UnityEditor;
using System.IO;
using System.Collections.Generic;

public static class CreateSpriteAsset
{
    [MenuItem("Assets/Create or Update Sprite Asset")]         //,false,10
    public static void main()
    {
        Object target = Selection.activeObject;

        Create(target,null);
    }

    public static void Create(Object target,string filePathWithName)
    {
        if (target == null || target.GetType() != typeof(Texture2D))
            return;

        Texture2D sourceTex = target as Texture2D;
        //整体路径
        if (string.IsNullOrEmpty(filePathWithName))
        {
            filePathWithName = AssetDatabase.GetAssetPath(sourceTex);
        }
        //带后缀的文件名
        string fileNameWithExtension = Path.GetFileName(filePathWithName);
        //不带后缀的文件名
        string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(filePathWithName);
        //不带文件名的路径
        string filePath = filePathWithName.Replace(fileNameWithExtension, "");

        string assetPath = filePath + fileNameWithoutExtension + ".prefab";
        SpriteAsset spriteAsset = AssetDatabase.LoadAssetAtPath(assetPath, typeof(SpriteAsset)) as SpriteAsset;
        if (spriteAsset == null)
        {
            GameObject prefab = null;
            GameObject tempGo = new GameObject(fileNameWithoutExtension);
            prefab = PrefabUtility.CreatePrefab(assetPath, tempGo);
            spriteAsset = prefab.AddComponent<SpriteAsset>();
            GameObject.DestroyImmediate(tempGo);
        }

        spriteAsset.texSource = sourceTex;
        spriteAsset.listSpriteInfor = GetSpritesInfor(sourceTex);
        EditorUtility.SetDirty(spriteAsset.gameObject);
        AssetDatabase.SaveAssets();
    }

    public static List<SpriteInfo> GetSpritesInfor(Texture2D tex)
    {
        List<SpriteInfo> m_sprites = new List<SpriteInfo>();

        string filePath = UnityEditor.AssetDatabase.GetAssetPath(tex);

        Object[] objects = UnityEditor.AssetDatabase.LoadAllAssetsAtPath(filePath);

        for (int i = 0; i < objects.Length; i++)
        {
            if (objects[i].GetType() == typeof(Sprite))
            {
                SpriteInfo temp = new SpriteInfo();
                Sprite sprite = objects[i] as Sprite;
                temp.ID = i;
                temp.name = sprite.name;
                temp.sprite = sprite;
                m_sprites.Add(temp);
            }
        }
        return m_sprites;
    }
}
//部分函数说明
//EditorUtility.SetDirty :这个函数告诉引擎,相关对象所属于的Prefab已经发生了更改。方便,当我们更改了自定义对象的属性的时候,自动更新到所属的Prefab中
运行时切换同一图集里的image
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

[RequireComponent(typeof(Image))]
public class AtlasImage : MonoBehaviour
{
    public SpriteAsset Atlas;
    public Image SourceImage;
    private string m_catche = string.Empty;
    private bool m_catchMakePerfect = false;
    // Use this for initialization
    void Start ()
    {
        if (SourceImage == null)
        {
            SourceImage = GetComponent<Image>();
        }
        if (!string.IsNullOrEmpty(m_catche))
        {
            Sprite = m_catche;
            m_catche = string.Empty;
        }
        if (m_catchMakePerfect)
        {
            MakePixelPerfect();
            m_catchMakePerfect = false;
        }
    }

    public void SetAtlas(SpriteAsset atlas)
    {
        Atlas = atlas;
    }

    public string Sprite
    {
        get
        {
            if (SourceImage!=null)
            {
                return SourceImage.sprite.name;
            }
            return string.Empty;
        }
        set
        {
            if (SourceImage == null)
            {
                SourceImage = GetComponent<Image>();
            }

            if (SourceImage!=null && Atlas!=null)
            {
                SourceImage.sprite = Atlas.GetSpriteWithName(value);
            }
            else
            {
                m_catche = value;
            }
        }
    }

    public void MakePixelPerfect()
    {
        if (SourceImage != null)
        {
            SourceImage.SetNativeSize();
        }
        else
        {
            m_catchMakePerfect = true;
        }
    }
}

使用示例:
//手动或运行时挂载AtlasImage脚本
m_titleIcon = m_title.GetComponent(“AtalsImage”);
//传入需要设置的sprite名称
m_titleIcon.Sprite = SpriteName;

优化替换Image方案

思路:

  • 运行时加载图集资源(可以打成bundle并将路径维护在一份表里)
  • 将加载过的图集保存在缓存里
    示例代码:
--lua代码,因项目为lua,故lua实现,c#思路一样。

--[[说明,方便动态设定图集内的sprite
@param:image 控件上的 Image
@param:assetId 图集 respath id
@param:iconName 图集中sprite名字
@param:keepNativeSize 使用图片原大小
]]
def.static("userdata","number","string","boolean").SetOverrideSpriteFromAtlas = function  (image,assetId,iconName,keepNativeSize)
    assert(image ~= nil,"image should not nil")
    assert(iconName ~= nil,"需要指定一个spriteName");

    if image.overrideSprite and image.overrideSprite.name == iconName then
        --print("Set a same sprite when SetOverrideSpriteFromAtlas!!!")
        return
    end

    local function setSprite(_image,asset,name)
        local sprite = asset:GetSpriteWithName(name)
        _image.overrideSprite = sprite
        if keepNativeSize then
            _image:SetNativeSize()
        end
    end
    --先在缓存里查找
    local spriteAsset = _G.PreloadSpriteAsset[assetId]
    if spriteAsset == nil then
        --维护一份资源id表,根据资源id获取资源路径
        local path = GetResPathById(assetId)
        -- 异步加载图集
        GameUtil.AsyncLoad(path,function  (obj)
            local spriteAsset = obj:GetComponent("SpriteAsset")
            assert(spriteAsset ~= nil,"spriteAsset should not nil")
            _G.PreloadSpriteAsset[assetId] = spriteAsset
            setSprite(image,spriteAsset,iconName)
        end)
    else
        setSprite(image,spriteAsset,iconName)
    end
end
//c#实现部分思路伪代码
public static List<SpriteAsset> spriteAssets = new List<SpriteAsset>();
public static void SetOverrideSpriteFromAtlas(Image image,SpriteAsset spriteAsset,string iconName,bool keepNativeSize)
{
    if(image.overrideSprite and image.overrideSprite.name == iconName)
    {
         //print("Set a same sprite when SetOverrideSpriteFromAtlas!!!")
        return;
    }   
    if(!spriteAssets.Contains(spriteAsset))
    {
        //根据资源id或者路径加载图集,并保存到缓存
    }
    Sprite sprite = spriteAsset.GetSpriteWithName(name);
    image.overrideSprite = sprite;
    if(keepNativeSize)
    {
        image:SetNativeSize();  
    }
} 
优化思路
  • TexturePacker提供命令行打图集方式,可写命令行导出.tpsheet和.png文件。
其他可借鉴网址:
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值