Unity UGUI教程:如何实现类似NGUI切换Sprite的方式

发表于2017-04-20
评论1 1.9k浏览

通常情况在NGUI中所有图片都打包在一个图集中,通过更改SpriteName就可以更改图片,so,为了方便调用UGUI的sprite,实现类似NGUI切换Sprite的方式,我们也同样需要为其创建一个asset文件,用于切换图片或者动态加载之类的情况。

  1. 首先准备一张图片

  2. 为我们准备创建的asset文件写一个脚本,他需要继承ScriptableObject,同时我们需要存储一些其他信息,所以需要一个信息脚本,这里需要将信息转为一个资源文件,所以需要使用[Serializable],大概目的就是序列化使其成为两者都能识别的信息

SpriteAsset脚本:

  1. using UnityEngine;  
  2. using System.Collections.Generic;  
  3.   
  4. public class UGUISpriteAsset : ScriptableObject  
  5. {  
  6.     ///   
  7.     /// 图片资源  
  8.     ///   
  9.     public Texture texSource;  
  10.     ///   
  11.     /// 所有sprite信息 SpriteAssetInfor类为具体的信息类  
  12.     ///   
  13.     public List listSpriteAssetInfor;  
  14. }  

sprite信息脚本:

  1. using UnityEngine;  
  2. using System;  
  3.   
  4. [Serializable]  
  5. public class SpriteAssetInfor  
  6. {  
  7.     ///   
  8.     /// ID  
  9.     ///   
  10.     public int ID;  
  11.     ///   
  12.     /// 名称  
  13.     ///   
  14.     public string name;  
  15.     ///   
  16.     /// 中心点  
  17.     ///   
  18.     public Vector2 pivot;  
  19.     ///   
  20.     ///坐标&宽高  
  21.     ///   
  22.     public Rect rect;  
  23.     ///   
  24.     /// 精灵  
  25.     ///   
  26.     public Sprite sprite;  
  27.   
  28. }  

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

  1. using UnityEngine;  
  2. using UnityEditor;  
  3. using System.Collections;  
  4. using System.IO;  
  5. using System.Collections.Generic;  
  6.   
  7. public static class UGUICreateSpriteAsset  
  8. {  
  9.     [MenuItem("Assets/Create/UGUI Sprite Asset"false, 10)]  
  10.     static void main()  
  11.     {  
  12.         Object target = Selection.activeObject;  
  13.         if (target == null || target.GetType() != typeof(Texture2D))  
  14.             return;  
  15.   
  16.         Texture2D sourceTex = target as Texture2D;  
  17.         //整体路径  
  18.         string filePathWithName = AssetDatabase.GetAssetPath(sourceTex);  
  19.         //带后缀的文件名  
  20.         string fileNameWithExtension = Path.GetFileName(filePathWithName);  
  21.         //不带后缀的文件名  
  22.         string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(filePathWithName);  
  23.         //不带文件名的路径  
  24.         string filePath = filePathWithName.Replace(fileNameWithExtension, "");  
  25.   
  26.         UGUISpriteAsset spriteAsset = AssetDatabase.LoadAssetAtPath(filePath + fileNameWithoutExtension + ".asset"typeof(UGUISpriteAsset)) as UGUISpriteAsset;  
  27.         bool isNewAsset = spriteAsset == null ? true : false;  
  28.         if (isNewAsset)  
  29.         {  
  30.             spriteAsset = ScriptableObject.CreateInstance();  
  31.             spriteAsset.texSource = sourceTex;  
  32.             spriteAsset.listSpriteAssetInfor = GetSpritesInfor(sourceTex);  
  33.             AssetDatabase.CreateAsset(spriteAsset, filePath + fileNameWithoutExtension + ".asset");  
  34.         }  
  35.     }  
  36.   
  37.     public static List GetSpritesInfor(Texture2D tex)  
  38.     {  
  39.         List m_sprites = new List();  
  40.   
  41.         string filePath = UnityEditor.AssetDatabase.GetAssetPath(tex);  
  42.   
  43.         Object[] objects = UnityEditor.AssetDatabase.LoadAllAssetsAtPath(filePath);  
  44.   
  45.         for (int i = 0; i < objects.Length; i++)  
  46.         {  
  47.             if (objects[i].GetType() == typeof(Sprite))  
  48.             {  
  49.                 SpriteAssetInfor temp = new SpriteAssetInfor();  
  50.                 Sprite sprite = objects[i] as Sprite;  
  51.                 temp.ID = i;  
  52.                 temp.name = sprite.name;  
  53.                 temp.pivot = sprite.pivot;  
  54.                 temp.rect = sprite.rect;  
  55.                 temp.sprite = sprite;  
  56.                 m_sprites.Add(temp);  
  57.             }  
  58.         }  
  59.         return m_sprites;  
  60.     }  
  61.   
  62. }  

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

  1. using UnityEngine;  
  2. using UnityEditor;  
  3. using System.Collections;  
  4.   
  5. [CustomEditor(typeof(UGUISpriteAsset))]  
  6. public class UGUISpriteAssetEditor : Editor {  
  7.   
  8.     UGUISpriteAsset spriteAsset;  
  9.   
  10.     public void OnEnable()  
  11.     {  
  12.         spriteAsset = (UGUISpriteAsset)target;  
  13.     }  
  14.     private Vector2 ve2ScorllView;  
  15.     public override void OnInspectorGUI()  
  16.     {  
  17.         ve2ScorllView = GUILayout.BeginScrollView(ve2ScorllView);  
  18.         GUILayout.Label("UGUI Sprite Asset");  
  19.         if (spriteAsset.listSpriteAssetInfor == null)  
  20.             return;  
  21.         for (int i = 0; i < spriteAsset.listSpriteAssetInfor.Count; i++)  
  22.         {  
  23.             GUILayout.Label("n");  
  24.             EditorGUILayout.ObjectField("",spriteAsset.listSpriteAssetInfor[i].sprite, typeof(Sprite));  
  25.             EditorGUILayout.IntField("ID:", spriteAsset.listSpriteAssetInfor[i].ID);  
  26.             EditorGUILayout.LabelField("name:", spriteAsset.listSpriteAssetInfor[i].name);  
  27.             EditorGUILayout.Vector2Field("povit:", spriteAsset.listSpriteAssetInfor[i].pivot);  
  28.             EditorGUILayout.RectField("rect:", spriteAsset.listSpriteAssetInfor[i].rect);  
  29.             GUILayout.Label("n");  
  30.         }  
  31.         GUILayout.EndScrollView();  
  32.     }  
  33.   
  34. }  

5.asset文件:


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

  1. using UnityEngine;  
  2. using UnityEngine.UI;  
  3. using System.Collections;  
  4.   
  5. public class ChangeUGUISprite : MonoBehaviour {  
  6.       
  7.     public UGUISpriteAsset usa;  
  8.     private float fTime = 0.0f;  
  9.       
  10.     // Update is called once per frame  
  11.     void Update () {  
  12.         fTime += Time.deltaTime;  
  13.         if (fTime >= 0.3f)  
  14.         {  
  15.             GetComponent().sprite = usa.listSpriteAssetInfor[Random.Range(0, usa.listSpriteAssetInfor.Count)].sprite;  
  16.             fTime = 0.0f;  
  17.         }  
  18.     }  
  19. }  

7.测试结果:


如社区发表内容存在侵权行为,您可以点击这里查看侵权投诉指引

0个评论