Unity使用自定义资源(.asset)配置数据

本文原创版权归 强哥的私房菜 所有,此处为转载,如有再转,请于篇首位置标明原创作者及出处,以示尊重!

作者:强哥的私房菜

原文:http://blog.csdn.net/liqiangeastsun/article/details/50510615


在游戏开发中,经常会用到一些配置文件保存一些数据,然后项目运行中读取这些配置文件中的数据在游戏中使用。

如:配置血条:根据角色类型(人物、动物、怪物等)配置不同的血条,包括血条大小,血条名或血条预设,血条颜色等一些简单数据。

如:配置子弹:子弹类型(真子弹、假子弹、追踪子弹等),子弹速度,伤害数值,子弹关联的特效等。

诸如此类的配置很多种,可创建一个可序列化的类存储数据,或者创建 XML 、JSON 文件保存数据,创建 Excel 文件,创建 TXT 文件,皆可完成需求,灵活使用这些方法保存配置数据。

在此介绍一下使用可序列化类保存配置,并且将可序列化类保存成Unity的自定义文件(.asset),然后配置自定义文件(.asset)。

优点:
可以保存数据类型多样(int、string、Vector3、GameObject、Transform、Texture等)如关联预设,关联图片等资源数据,而XML、TXT等只能保存(int、string、Vector3 等基本数据类型)。

缺点:
如果配置数据中保存了(GameObject、Texture)等资源数据,当关联的资源被删除时,配置数据将丢失,需要重新将新的资源再次关联到配置数据上。

--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

下面做个简单的子弹配置数据:

[csharp]  view plain  copy
  1. // 创建一个可序列化的子弹类 Bullet.CS  
  2.   
  3. using UnityEngine;  
  4. using System.Collections;  
  5. using System;  
  6.   
  7. // 子弹类型枚举  
  8. public enum BulletType  
  9. {  
  10.     DirectAttack = 0,  // 直接攻击  
  11.     Phony,             // 假子弹  
  12.     Real,              // 真子弹  
  13.     Track,             // 追踪子弹  
  14. }  
  15.   
  16. /// <summary>  
  17. /// 可序列化  
  18. /// </summary>  
  19. [Serializable]  
  20. public class Bullet : ScriptableObject {  
  21.   
  22.     // Bullet 类直接继承自 ScriptableObject  
  23.   
  24.     // 子弹类型  
  25.     public BulletType bulletType = BulletType.DirectAttack;  
  26.   
  27.     // 子弹速度  
  28.     public int speed = 10;  
  29.   
  30.     // 伤害数值  
  31.     public int damage = 5;  
  32.   
  33.     // 子弹关联的特效  
  34.     public GameObject effectObj;  
  35. }  
创建一个编辑器类,在 菜单栏添加功能按钮,生成自定义资源:

[csharp]  view plain  copy
  1. using UnityEngine;  
  2. using System.Collections;  
  3. using UnityEditor;  
  4. using System.IO;  
  5.   
  6. public class CreateAsset : Editor {  
  7.   
  8.     // 在菜单栏创建功能项  
  9.     [MenuItem("CreateAsset/Asset")]  
  10.     static void Create()  
  11.     {  
  12.         // 实例化类  Bullet  
  13.         ScriptableObject bullet = ScriptableObject.CreateInstance<Bullet>();  
  14.   
  15.         // 如果实例化 Bullet 类为空,返回  
  16.         if (!bullet)  
  17.         {  
  18.             Debug.LogWarning("Bullet not found");  
  19.             return;  
  20.         }  
  21.   
  22.         // 自定义资源保存路径  
  23.         string path = Application.dataPath + "/BulletAeeet";  
  24.   
  25.         // 如果项目总不包含该路径,创建一个  
  26.         if (!Directory.Exists(path))  
  27.         {  
  28.             Directory.CreateDirectory(path);  
  29.         }  
  30.   
  31.         //将类名 Bullet 转换为字符串  
  32.         //拼接保存自定义资源(.asset) 路径  
  33.         path = string.Format("Assets/BulletAeeet/{0}.asset", (typeof(Bullet).ToString()));  
  34.   
  35.         // 生成自定义资源到指定路径  
  36.         AssetDatabase.CreateAsset(bullet, path);  
  37.     }  
  38. }  
如下:

点击 Asset 在指定路径生成自定义资源

查看生成资源如下:


为了省事,下面直接在编辑器类中加一个方法,读取自定义文件

修改如下:

[csharp]  view plain  copy
  1. using UnityEngine;  
  2. using System.Collections;  
  3. using UnityEditor;  
  4. using System.IO;  
  5. using System;  
  6.   
  7. public class CreateAsset : Editor {  
  8.   
  9.     [MenuItem("CreateAsset/Asset")]  
  10.     static void Create()  
  11.     {  
  12.         // 实例化类  Bullet  
  13.         ScriptableObject bullet = ScriptableObject.CreateInstance<Bullet>();  
  14.   
  15.         // 如果实例化 Bullet 类为空,返回  
  16.         if (!bullet)  
  17.         {  
  18.             Debug.LogWarning("Bullet not found");  
  19.             return;  
  20.         }  
  21.   
  22.         // 自定义资源保存路径  
  23.         string path = Application.dataPath + "/BulletAeeet";  
  24.   
  25.         // 如果项目总不包含该路径,创建一个  
  26.         if (!Directory.Exists(path))  
  27.         {  
  28.             Directory.CreateDirectory(path);  
  29.         }  
  30.   
  31.         //将类名 Bullet 转换为字符串  
  32.         //拼接保存自定义资源(.asset) 路径  
  33.         path = string.Format("Assets/BulletAeeet/{0}.asset", (typeof(Bullet).ToString()));  
  34.   
  35.         // 生成自定义资源到指定路径  
  36.         AssetDatabase.CreateAsset(bullet, path);  
  37.     }  
  38.   
  39.   
  40.     [MenuItem("CreateAsset/GetAsset")]  
  41.     static void GetAsset()  
  42.     {  
  43.         //读取 .asset 文件, 直接转换为 类  Bullet  
  44.         Bullet bullet = AssetDatabase.LoadAssetAtPath<Bullet>("Assets/BulletAeeet/Bullet.asset");  
  45.   
  46.         // 打印保存的数据  
  47.         Debug.Log("BulletType  :" + Enum.GetName(typeof(BulletType), bullet.bulletType));  
  48.         Debug.Log("Speed       :" + bullet.speed);  
  49.         Debug.Log("damage      :" + bullet.damage);  
  50.   
  51.         if (bullet.effectObj)  
  52.         {  
  53.             Debug.Log("EffectObj   :" + bullet.effectObj.name);  
  54.         }  
  55.     }  
  56. }  
打印结果如下:


如果想自定义 文件的 Inspector面板,使用编辑器类重写 Bullet.cs 的Inspector面板, 代码如下:

[csharp]  view plain  copy
  1. using UnityEngine;  
  2. using System.Collections;  
  3. using UnityEditor;  
  4.   
  5. [CustomEditor(typeof(Bullet))]  
  6. public class BulletInspector : Editor {  
  7.   
  8.     // 子弹类型  
  9.     public SerializedProperty bulletType;  
  10.   
  11.     // 子弹速度  
  12.     public SerializedProperty speed;  
  13.   
  14.     // 伤害数值  
  15.     public SerializedProperty damage;  
  16.   
  17.     // 子弹关联的特效  
  18.     public SerializedProperty effectObj;  
  19.   
  20.     private void OnEnable()  
  21.     {  
  22.         bulletType = serializedObject.FindProperty("bulletType");  
  23.         speed = serializedObject.FindProperty("speed");  
  24.         damage = serializedObject.FindProperty("damage");  
  25.         effectObj = serializedObject.FindProperty("effectObj");  
  26.     }  
  27.   
  28.     public override void OnInspectorGUI()  
  29.     {  
  30.         serializedObject.Update();  
  31.   
  32.         EditorGUI.indentLevel = 1;  
  33.   
  34.         EditorGUILayout.PropertyField(bulletType, new GUIContent("子弹类型"));  
  35.         GUILayout.Space(5);  
  36.   
  37.         EditorGUILayout.PropertyField(speed, new GUIContent("子弹速度"));  
  38.         GUILayout.Space(5);  
  39.   
  40.         EditorGUILayout.PropertyField(damage, new GUIContent("伤害数值"));  
  41.         GUILayout.Space(5);  
  42.   
  43.         EditorGUILayout.PropertyField(effectObj, new GUIContent("特效对象"));  
  44.   
  45.         GUILayout.Space(10);  
  46.   
  47.         // 打印数据  
  48.         if (GUILayout.Button("Debug"))  
  49.         {  
  50.             Debug.Log("bulletType    :" + (BulletType)bulletType.enumValueIndex);  
  51.             Debug.Log("speed         :" + speed.intValue);  
  52.             Debug.Log("damage        :" + damage.intValue);  
  53.   
  54.             if (effectObj.objectReferenceValue)  
  55.             {  
  56.                 Debug.Log("effectObj    :" + effectObj.objectReferenceValue);  
  57.             }  
  58.         }  
  59.   
  60.         if (GUI.changed)  
  61.         {  
  62.             EditorUtility.SetDirty(target);  
  63.         }  
  64.   
  65.         serializedObject.ApplyModifiedProperties();  
  66.     }  
  67.   
  68. }  

再看效果,自定义的:


到此将序列化类生成自定义文件 (.asset)成功,读取成功,重写Inspector面板结束。

猜你喜欢

转载自blog.csdn.net/kenkao/article/details/79062566