【Unity3d】ScriptableObject的简单用法

 

ScriptableObject非常适合小数量的游戏数值。

使用ScriptableObject的时候需要注意,生成ScriptableObject数据文件需要自己写Editor代码实现。

大概的工作流程是:写一个ScriptableObject(继承ScriptableObject的类,相当于数据模板) → 使用自己写的Editor代码生成一个实现该模板的数据文件 → Inspector面板中编辑数据。

给出我的Editor代码:

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
using UnityEngine;
using System.IO;
using System.Collections;
using UnityEditor;
 
public class Scriptablity : MonoBehaviour {
 
    public static T Create<T> ( string _path, string _name) where T : ScriptableObject {
         
        if ( new DirectoryInfo(_path).Exists == false ) {
            Debug.LogError ( "can't create asset, path not found" );
            return null;
        }
        if ( string.IsNullOrEmpty(_name) ) {
            Debug.LogError ( "can't create asset, the name is empty" );
            return null;
        }
        string assetPath = Path.Combine( _path, _name + ".asset" );
         
        T newT = ScriptableObject.CreateInstance<T>();
        AssetDatabase.CreateAsset(newT, assetPath);
        Selection.activeObject = newT;
        return newT;
    }
     
    public static void  Create<T>() where T : ScriptableObject {
         
        string assetName = "New " + typeof(T).Name;
        string assetPath = "Assets";
        if(Selection.activeObject) {
            assetPath = AssetDatabase.GetAssetPath(Selection.activeObject);
            if (Path.GetExtension(assetPath) != "")
            {
                assetPath = Path.GetDirectoryName(assetPath);
            }
        }
         
        bool doCreate = true;
        string path = Path.Combine( assetPath, assetName + ".asset" );
        FileInfo fileInfo = new FileInfo(path);
        if ( fileInfo.Exists ) {
            doCreate = EditorUtility.DisplayDialog( assetName + " already exists.",
                                                    "Do you want to overwrite the old one?",
                                                    "Yes", "No" );
        }
        if ( doCreate ) {
            T T_info = Create<T> ( assetPath, assetName );
            Selection.activeObject = T_info;
        }
    }
     
    public static void Create() {
         
        Debug.LogError("You should call 'Create' method like this : Create<ExampleData>();");
    }
}

使用方法:

1.写个ScriptableObject。

1
2
3
4
public class Example : ScriptableObject {
        public int id;
        public string name;
}

 

2.写个MonoBehavior调用Create方法生成Example格式的数据。

1
2
3
4
5
6
7
8
9
public class ExampleItem: MonoBehaviour {
 
        [MenuItem("Example/Create/Example Data")]
        static void CreatExample() {
 
                Scriptablity.Create<Example>();
        }
         
}

 

3.在Inspector面板编辑数据。

 

4.使用该数据

 

1
2
3
4
5
6
7
8
9
public class ExampleUsage : MonoBehavior {
       public Example exampleInfo;
 
       void Start()
       {
               Debug.Log(exampleInfo.name);
       }
 
}

posted on   B1ncer  阅读(2551)  评论(0编辑  收藏  举报

编辑推荐:
· 一次Java后端服务间歇性响应慢的问题排查记录
· dotnet 源代码生成器分析器入门
· ASP.NET Core 模型验证消息的本地化新姿势
· 对象命名为何需要避免'-er'和'-or'后缀
· SQL Server如何跟踪自动统计信息更新?
阅读排行:
· 官方的 MCP C# SDK:csharp-sdk
· 一款 .NET 开源、功能强大的远程连接管理工具,支持 RDP、VNC、SSH 等多种主流协议!
· “你见过凌晨四点的洛杉矶吗?”--《我们为什么要睡觉》
· 提示词工程师自白:我如何用一个技巧解放自己的生产力
· C#/.NET/.NET Core技术前沿周刊 | 第 31 期(2025年3.17-3.23)

导航

< 2025年3月 >
23 24 25 26 27 28 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 1 2 3 4 5
点击右上角即可分享
微信分享提示