• unity UGUI实现类似NGUI切换Sprite的方式


    很多都是使用NGUI的习惯,因为在NGUI中所有图片都打包在一个图集中,通过更改SpriteName就可以更改图片,so,为了方便调用UGUI的sprite,我们也同样需要为其创建一个asset文件。

    其实这个功能相当软肋,既然想到写,还是写出来吧,偶尔用于切换图片或者动态加载之类的还是有点意思

    1. 首先准备一张图片


    2. 为我们准备创建的asset文件写一个脚本,他需要继承ScriptableObject,同时我们需要存储一些其他信息,所以需要一个信息脚本,这里需要将信息转为一个资源文件,所以需要使用[Serializable],大概目的就是序列化使其成为两者都能识别的信息,网上查了一个序列化的解释:[Serializable]在C#中的作用-NET 中的对象序列化

    SpriteAsset脚本:

    using UnityEngine;
    using System.Collections.Generic;
    
    public class UGUISpriteAsset : ScriptableObject
    {
        /// <summary>
        /// 图片资源
        /// </summary>
        public Texture texSource;
        /// <summary>
        /// 所有sprite信息 SpriteAssetInfor类为具体的信息类
        /// </summary>
        public List<SpriteAssetInfor> listSpriteAssetInfor;
    }
    

    sprite信息脚本:

    using UnityEngine;
    using System;
    
    [Serializable]
    public class SpriteAssetInfor
    {
        /// <summary>
        /// ID
        /// </summary>
        public int ID;
        /// <summary>
        /// 名称
        /// </summary>
        public string name;
        /// <summary>
        /// 中心点
        /// </summary>
        public Vector2 pivot;
        /// <summary>
        ///坐标&宽高
        /// </summary>
        public Rect rect;
        /// <summary>
        /// 精灵
        /// </summary>
        public Sprite sprite;
    
    }
    

    3.写一个编辑类,用来创建asset文件,在文件夹中,选中第一步的资源图片,右键然后点击"Create/UGUI Sprite Asset",即可以创建一个同图片同名的.asset文件,UGUICreateSpriteAsset此编辑类需要放在Editor文件夹中

    using UnityEngine;
    using UnityEditor;
    using System.Collections;
    using System.IO;
    using System.Collections.Generic;
    
    public static class UGUICreateSpriteAsset
    {
        [MenuItem("Assets/Create/UGUI Sprite Asset", false, 10)]
        static void main()
        {
            Object target = Selection.activeObject;
            if (target == null || target.GetType() != typeof(Texture2D))
                return;
    
            Texture2D sourceTex = target as Texture2D;
            //整体路径
            string filePathWithName = AssetDatabase.GetAssetPath(sourceTex);
            //带后缀的文件名
            string fileNameWithExtension = Path.GetFileName(filePathWithName);
            //不带后缀的文件名
            string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(filePathWithName);
            //不带文件名的路径
            string filePath = filePathWithName.Replace(fileNameWithExtension, "");
    
            UGUISpriteAsset spriteAsset = AssetDatabase.LoadAssetAtPath(filePath + fileNameWithoutExtension + ".asset", typeof(UGUISpriteAsset)) as UGUISpriteAsset;
            bool isNewAsset = spriteAsset == null ? true : false;
            if (isNewAsset)
            {
                spriteAsset = ScriptableObject.CreateInstance<UGUISpriteAsset>();
                spriteAsset.texSource = sourceTex;
                spriteAsset.listSpriteAssetInfor = GetSpritesInfor(sourceTex);
                AssetDatabase.CreateAsset(spriteAsset, filePath + fileNameWithoutExtension + ".asset");
            }
        }
    
        public static List<SpriteAssetInfor> GetSpritesInfor(Texture2D tex)
        {
            List<SpriteAssetInfor> m_sprites = new List<SpriteAssetInfor>();
    
            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))
                {
                    SpriteAssetInfor temp = new SpriteAssetInfor();
                    Sprite sprite = objects[i] as Sprite;
                    temp.ID = i;
                    temp.name = sprite.name;
                    temp.pivot = sprite.pivot;
                    temp.rect = sprite.rect;
                    temp.sprite = sprite;
                    m_sprites.Add(temp);
                }
            }
            return m_sprites;
        }
    
    }
    

    4.选择.asset文件,你就会发现上面就会有一些你想要存储的信息,但是并不是很美观(其实我改过之后还是很一般),这里我们可以通过一个[CustomEditor]来自定义属性面板,他需要继承Editor,并在类名上声明他为哪个类自定义属性表,需要使用OnInspectorGUI函数来绘制,使用方法与OnGUI一样,注意关键字override,同样UGUISpriteAssetEditor类也需要放在Editor文件夹中

    using UnityEngine;
    using UnityEditor;
    using System.Collections;
    
    [CustomEditor(typeof(UGUISpriteAsset))]
    public class UGUISpriteAssetEditor : Editor {
    
        UGUISpriteAsset spriteAsset;
    
        public void OnEnable()
        {
            spriteAsset = (UGUISpriteAsset)target;
        }
        private Vector2 ve2ScorllView;
        public override void OnInspectorGUI()
        {
            ve2ScorllView = GUILayout.BeginScrollView(ve2ScorllView);
            GUILayout.Label("UGUI Sprite Asset");
            if (spriteAsset.listSpriteAssetInfor == null)
                return;
            for (int i = 0; i < spriteAsset.listSpriteAssetInfor.Count; i++)
            {
                GUILayout.Label("
    ");
                EditorGUILayout.ObjectField("",spriteAsset.listSpriteAssetInfor[i].sprite, typeof(Sprite));
                EditorGUILayout.IntField("ID:", spriteAsset.listSpriteAssetInfor[i].ID);
                EditorGUILayout.LabelField("name:", spriteAsset.listSpriteAssetInfor[i].name);
                EditorGUILayout.Vector2Field("povit:", spriteAsset.listSpriteAssetInfor[i].pivot);
                EditorGUILayout.RectField("rect:", spriteAsset.listSpriteAssetInfor[i].rect);
                GUILayout.Label("
    ");
            }
            GUILayout.EndScrollView();
        }
    
    }
    

    5.asset文件:


    6.写一个测试脚本,不停的切换图片,后面可以封装一下,通过名称或者ID来索引sprite

    using UnityEngine;
    using UnityEngine.UI;
    using System.Collections;
    
    public class ChangeUGUISprite : MonoBehaviour {
        
        public UGUISpriteAsset usa;
        private float fTime = 0.0f;
        
    	// Update is called once per frame
    	void Update () {
            fTime += Time.deltaTime;
            if (fTime >= 0.3f)
            {
                GetComponent<Image>().sprite = usa.listSpriteAssetInfor[Random.Range(0, usa.listSpriteAssetInfor.Count)].sprite;
                fTime = 0.0f;
            }
    	}
    }
    

    7.测试结果:


  • 相关阅读:
    【BZOJ5416】【NOI2018】冒泡排序(动态规划)
    【BZOJ4832】抵制克苏恩(矩阵快速幂,动态规划)
    【UOJ#340】【清华集训2017】小 Y 和恐怖的奴隶主(矩阵快速幂,动态规划)
    【BZOJ3142】[HNOI2013]数列(组合计数)
    【BZOJ3925】[ZJOI2015]地震后的幻想乡(动态规划)
    【Luogu4707】重返现世(min-max容斥)
    【UOJ#422】【集训队作业2018】小Z的礼物(min-max容斥,轮廓线dp)
    【APIO2018】铁人两项(圆方树,动态规划)
    【BZOJ4005】[JLOI2015] 骗我呢(容斥,组合计数)
    【LOJ#6072】苹果树(矩阵树定理,折半搜索,容斥)
  • 原文地址:https://www.cnblogs.com/liang123/p/6325890.html
Copyright © 2020-2023  润新知