Unity 使用自定義資源(.asset)配置數據

在遊戲開發中,經常會用到一些配置文件保存一些數據,然後項目運行中讀取這些配置文件中的數據在遊戲中使用。

如:配置血條:根據角色類型(人物、動物、怪物等)配置不同的血條,包括血條大小,血條名或血條預設,血條顏色等一些簡單數據。

如:配置子彈:子彈類型(真子彈、假子彈、追蹤子彈等),子彈速度,傷害數值,子彈關聯的特效等。

諸如此類的配置很多種,可創建一個可序列化的類存儲數據,或者創建 XML 、JSON 文件保存數據,創建 Excel 文件,創建 TXT 文件,皆可完成需求,靈活使用這些方法保存配置數據。

在此介紹一下使用可序列化類保存配置,並且將可序列化類保存成Unity的自定義文件(.asset),然後配置自定義文件(.asset)。

優點:
可以保存數據類型多樣(int、string、Vector3、GameObject、Transform、Texture等)如關聯預設,關聯圖片等資源數據,而XML、TXT等只能保存(int、string、Vector3 等基本數據類型)。

缺點:
如果配置數據中保存了(GameObject、Texture)等資源數據,當關聯的資源被刪除時,配置數據將丟失,需要重新將新的資源再次關聯到配置數據上。

下面做個簡單的子彈配置數據
// 創建一個可序列化的子彈類 Bullet.CS

using UnityEngine;
using System.Collections;
using System;

// 子彈類型枚舉
public enum BulletType
{
    DirectAttack = 0,  // 直接攻擊
    Phony,             // 假子彈
    Real,              // 真子彈
    Track,             // 追蹤子彈
}

/// <summary>
/// 可序列化
/// </summary>
[Serializable]
public class Bullet : ScriptableObject {

    // Bullet 類直接繼承自 ScriptableObject

    // 子彈類型
    public BulletType bulletType = BulletType.DirectAttack;

    // 子彈速度
    public int speed = 10;

    // 傷害數值
    public int damage = 5;

    // 子彈關聯的特效
    public GameObject effectObj;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
創建一個編輯器類,在 菜單欄添加功能按鈕,生成自定義資源
using UnityEngine;
using System.Collections;
using UnityEditor;
using System.IO;

public class CreateAsset : Editor {

    // 在菜單欄創建功能項
    [MenuItem("CreateAsset/Asset")]
    static void Create()
    {
        // 實例化類  Bullet
        ScriptableObject bullet = ScriptableObject.CreateInstance<Bullet>();

        // 如果實例化 Bullet 類爲空,返回
        if (!bullet)
        {
            Debug.LogWarning("Bullet not found");
            return;
        }

        // 自定義資源保存路徑
        string path = Application.dataPath + "/BulletAeeet";

        // 如果項目總不包含該路徑,創建一個
        if (!Directory.Exists(path))
        {
            Directory.CreateDirectory(path);
        }

        //將類名 Bullet 轉換爲字符串
        //拼接保存自定義資源(.asset) 路徑
        path = string.Format("Assets/BulletAeeet/{0}.asset", (typeof(Bullet).ToString()));

        // 生成自定義資源到指定路徑
        AssetDatabase.CreateAsset(bullet, path);
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39

如下 
這裏寫圖片描述

點擊 Asset 在指定路徑生成自定義資源

查看生成資源如下

這裏寫圖片描述

爲了省事,下面直接在編輯器類中加一個方法,讀取自定義文件

修改如下

using UnityEngine;
using System.Collections;
using UnityEditor;
using System.IO;
using System;

public class CreateAsset : Editor {

    [MenuItem("CreateAsset/Asset")]
    static void Create()
    {
        // 實例化類  Bullet
        ScriptableObject bullet = ScriptableObject.CreateInstance<Bullet>();

        // 如果實例化 Bullet 類爲空,返回
        if (!bullet)
        {
            Debug.LogWarning("Bullet not found");
            return;
        }

        // 自定義資源保存路徑
        string path = Application.dataPath + "/BulletAeeet";

        // 如果項目總不包含該路徑,創建一個
        if (!Directory.Exists(path))
        {
            Directory.CreateDirectory(path);
        }

        //將類名 Bullet 轉換爲字符串
        //拼接保存自定義資源(.asset) 路徑
        path = string.Format("Assets/BulletAeeet/{0}.asset", (typeof(Bullet).ToString()));

        // 生成自定義資源到指定路徑
        AssetDatabase.CreateAsset(bullet, path);
    }


    [MenuItem("CreateAsset/GetAsset")]
    static void GetAsset()
    {
        //讀取 .asset 文件, 直接轉換爲 類  Bullet
        Bullet bullet = AssetDatabase.LoadAssetAtPath<Bullet>("Assets/BulletAeeet/Bullet.asset");

        // 打印保存的數據
        Debug.Log("BulletType  :" + Enum.GetName(typeof(BulletType), bullet.bulletType));
        Debug.Log("Speed       :" + bullet.speed);
        Debug.Log("damage      :" + bullet.damage);

        if (bullet.effectObj)
        {
            Debug.Log("EffectObj   :" + bullet.effectObj.name);
        }
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57

打印結果如下 
這裏寫圖片描述

如果想自定義 文件的 Inspector面板,使用編輯器類重寫 Bullet.cs 的Inspector面板, 代碼如下

using UnityEngine;
using System.Collections;
using UnityEditor;

[CustomEditor(typeof(Bullet))]
public class BulletInspector : Editor {

    // 子彈類型
    public SerializedProperty bulletType;

    // 子彈速度
    public SerializedProperty speed;

    // 傷害數值
    public SerializedProperty damage;

    // 子彈關聯的特效
    public SerializedProperty effectObj;

    private void OnEnable()
    {
        bulletType = serializedObject.FindProperty("bulletType");
        speed = serializedObject.FindProperty("speed");
        damage = serializedObject.FindProperty("damage");
        effectObj = serializedObject.FindProperty("effectObj");
    }

    public override void OnInspectorGUI()
    {
        serializedObject.Update();

        EditorGUI.indentLevel = 1;

        EditorGUILayout.PropertyField(bulletType, new GUIContent("子彈類型"));
        GUILayout.Space(5);

        EditorGUILayout.PropertyField(speed, new GUIContent("子彈速度"));
        GUILayout.Space(5);

        EditorGUILayout.PropertyField(damage, new GUIContent("傷害數值"));
        GUILayout.Space(5);

        EditorGUILayout.PropertyField(effectObj, new GUIContent("特效對象"));

        GUILayout.Space(10);

        // 打印數據
        if (GUILayout.Button("Debug"))
        {
            Debug.Log("bulletType    :" + (BulletType)bulletType.enumValueIndex);
            Debug.Log("speed         :" + speed.intValue);
            Debug.Log("damage        :" + damage.intValue);

            if (effectObj.objectReferenceValue)
            {
                Debug.Log("effectObj    :" + effectObj.objectReferenceValue);
            }
        }

        if (GUI.changed)
        {
            EditorUtility.SetDirty(target);
        }

        serializedObject.ApplyModifiedProperties();
    }

}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69

再看效果,自定義的

這裏寫圖片描述

到此將序列化類生成自定義文件 (.asset)成功,讀取成功,重寫Inspector面板結束。

1
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章