利用ScriptableObject在U3D里优雅地实现自定义配置文件

因为我本人也是一个初学者,所以对于一些简单的设定相关的游戏内容时,为了将数据持久化,需要自己做轮子觉得很麻烦。

偶然看到ScriptableObject这么一个类,总算看到了一倒救星,原来在U3D里,并不是必须讲脚本挂载以实现实例化,存在着这么一个类,让我们可以在代码里实例化,又可以去调用U3D的一些API。

(http://blog.csdn.net/liqiangeastsun/article/details/50510615这是原文链接,感谢

强哥的私房菜

博主为我这样的小白带来便利

感觉豁然开朗,大惊以前的自己是那么蠢,百度以后做了一个测试工程。如下。

首先是数据类。

// 创建一个可序列化的子弹类 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;
    
    /// <summary>
    /// 子弹速度
    /// </summary>
    public int speed = 10;

    // 伤害数值
    public int damage = 5;

    // 子弹关联的特效
    public GameObject effectObj;
}
然后是拓展编辑器。
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) 路径
        string path2 = string.Format("Assets/BulletAeeet/{0}.asset", (typeof(Bullet).ToString()));

        // 生成自定义资源到指定路径
        AssetDatabase.CreateAsset(bullet, path2);
    }

    [MenuItem("ReadAsset/GetBulletAsset")]
    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);
        }
    }

}

为了能够让团队里其他人,可以在程序不在的时候预览到配置文件,再把inpector面板也修改成中文,毕竟这是我们的母语,瞄一眼就能很快理解。
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();
    }

}


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值