实现unity自定义资源

  在游戏开发中,经常会用到一些配置文件保存一些数据,然后项目运行中读取这些配置文件中的数据在游戏中使用。 如:配置血条:根据角色类型(人物、动物、怪物等)配置不同的血条,包括血条大小,血条名或血条预设,血条颜色等一些简单数据。 如:配置子弹:子弹类型(真子弹、假子弹、追踪子弹等),子弹速度,伤害数值,子弹关联的特效等。 诸如此类的配置很多种,可创建一个可序列化的类存储数据,或者创建 XML 、JSON 文件保存数据,创建 Excel 文件,创建 TXT 文件,皆可完成需求,灵活使用这些方法保存配置数据。 在此介绍一下使用可序列化类保存配置,并且将可序列化类保存成Unity的自定义文件(.asset),然后配置自定义文件(.asset)。 优点: 可以保存数据类型多样(int、string、Vector3、GameObject、Transform、Texture等)如关联预设,关联图片等资源数据,而XML、TXT等只能保存(int、string、Vector3 等基本数据类型)。 缺点: 如果配置数据中保存了(GameObject、Texture)等资源数据,当关联的资源被删除时,配置数据将丢失,需要重新将新的资源再次关联到配置数据上。 下面做个简单的子弹配置数据

 1 using UnityEngine;
 2 using System.Collections;
 3 using System;
 4 
 5 // 子弹类型枚举
 6 public enum BulletType
 7 {
 8     DirectAttack = 0,  // 直接攻击
 9     Phony,             // 假子弹
10     Real,              // 真子弹
11     Track,             // 追踪子弹
12 }
13 
14 /// <summary>
15 /// 可序列化
16 /// </summary>
17 [Serializable]
18 public class Bullet : ScriptableObject {
19 
20     // Bullet 类直接继承自 ScriptableObject
21 
22     // 子弹类型
23     public BulletType bulletType = BulletType.DirectAttack;
24 
25     // 子弹速度
26     public int speed = 10;
27 
28     // 伤害数值
29     public int damage = 5;
30 
31     // 子弹关联的特效
32     public GameObject effectObj;
33 }
 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         Bullet bullet = new Bullet();
15 
16         // 如果实例化 Bullet 类为空,返回
17         if (!bullet)
18         {
19             Debug.LogWarning("Bullet not found");
20             return;
21         }
22 
23         // 自定义资源保存路径
24         string path = Application.dataPath + "/BulletAeeet";
25 
26         // 如果项目总不包含该路径,创建一个
27         if (!Directory.Exists(path))
28         {
29             Directory.CreateDirectory(path);
30         }
31 
32         //将类名 Bullet 转换为字符串
33         //拼接保存自定义资源(.asset) 路径
34         path = string.Format("Assets/BulletAeeet/{0}.asset", (typeof(Bullet).ToString()));
35 
36         // 生成自定义资源到指定路径
37         AssetDatabase.CreateAsset(bullet, path);
38     }
39 
40 
41     [MenuItem("CreateAsset/GetAsset")]
42     static void GetAsset()
43     {
44         //读取 .asset 文件, 直接转换为 类  Bullet
45         Bullet bullet = AssetDatabase.LoadAssetAtPath<Bullet>("Assets/BulletAeeet/Bullet.asset");
46 
47         // 打印保存的数据
48         Debug.Log("BulletType  :" + Enum.GetName(typeof(BulletType), bullet.bulletType));
49         Debug.Log("Speed       :" + bullet.speed);
50         Debug.Log("damage      :" + bullet.damage);
51 
52         if (bullet.effectObj)
53         {
54             Debug.Log("EffectObj   :" + bullet.effectObj.name);
55         }
56     }
57 }
创建一个编辑器类,在 菜单栏添加功能按钮,生成自定义资源

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

查看生成资源如下

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

 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 }

posted @ 2018-01-10 11:29  智能化的代码  阅读(1257)  评论(0编辑  收藏  举报