http://unity3d.9tech.cn/news/2014/0116/39639.html

通常,在游戏的开发过程中,最终会建立起一些组件,通过某种形式的配置文件接收一些数据。这些可能是程序级别生成系统的一些参数,或许是手势识别系统的手势集,或任何其他东西。如果你是在Unity内部开发,很可能以创建一个可序列化的类来开始这项任务,这个类被设计成简单的容器,存储你所需要的所有配置数据。

但是那又怎样?现实中你是怎样把数据放到那个类里的?你是创建一堆XML 或 JSON文件,当游戏启动时加载它们吗?或在需要数据的类里有数据类的公共实例,并且你是通过Inspector设置所有东西,然后创建很多预制,每个配置有一个。

在这篇文章中我将阐述一种简单的方法,把那些可序列化的数据容器类放入自定义资源文件中。这与使用XML或者其他一些外部文件格式相比有很多好处。例如,通常,文件大小会更小,并且Unity将会掌控所有的序列化和反序列化。

我觉得这种方法最好通过举例来解释。所以我假设我们在尝试建立一个JRPG类型的对话系统,就像《火焰之纹章》或者《牧场物语》或者其他的JRPG那样。这个类型有着很大的文本泡,从底部向上滑,然后左边或右边有个扁平的角色在说话。

好了,现在开始为每个单独的对话语言元素创建简单的可序列化数据容器,如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
[System.Serializable]
public class DialogueElement
{
   public enum Characters{ David, Megan};
   public enum AvatarPos{ left, right};
   public Characters Character;
   public AvatarPos CharacterPosition;
   public Texture2D CharacterPic;
   public string DialogueText;
   public GUIStyle DialogueTextStyle;
   public float TextPlayBackSpeed;
   public AudioClip PlayBackSoundFile;
}

上面有几个枚举来描述哪些角色和屏幕位置是有效地,展示角色的纹理,角色在对话气泡中究竟说了什么的字符串,GUIStyle为字符串设计样式,或许还有个浮点用来控制文本的消失速度,一个声音片段来为每个对话气泡加点背景声。

记住这仅仅是个例子,所以你应该学会举一反三,通过这个例子学会将技术应用于任何类型的数据容器。

接下来创建一个用于所有对话的类,它将含有那些DialogueElement对象的列表。我们不把它做成一个普通的序列化类,而是让它从ScriptableObject继承。ScriptableObject类可以把对话类转变成我们自己的自定义资源文件。

1
2
3
4
public class Dialogue: ScriptableObject
{
   public List<DialogueElement> DialogItems;
}

现在可以从那个对话类里做出自定义对话资源了,首先要把CustomAssetUtility类保存在工程文件夹的某个位置。

CustomAssetUtility类

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
using UnityEngine;
using UnityEditor;
using System.IO;
 
public static class CustomAssetUtility
{
    public static void CreateAsset<T> () where T : ScriptableObject
    {
        T asset = ScriptableObject.CreateInstance<T> ();
         
        string path = AssetDatabase.GetAssetPath (Selection.activeObject);
        if (path == "")
        {
            path = "Assets";
        }
        else if (Path.GetExtension (path) != "")
        {
            path = path.Replace (Path.GetFileName (AssetDatabase.GetAssetPath (Selection.activeObject)), "");
        }
         
        string assetPathAndName = AssetDatabase.GenerateUniqueAssetPath (path + "/New " + typeof(T).ToString() + ".asset");
         
        AssetDatabase.CreateAsset (asset, assetPathAndName);
         
        AssetDatabase.SaveAssets ();
        EditorUtility.FocusProjectWindow ();
        Selection.activeObject = asset;
    }
}

在项目中安装了这个之后,只需要几行就可以把对话类,或者任何从ScriptableObject继承的类转变成自定义资源。

制作一个新的类/文件,命名为DialogueAsset.cs,并保证它是在Editor文件夹内的。然后在该类中为新资源创建一个新的菜单项,从已下载的工具类调用CreateAsset:

1
2
3
4
5
6
7
8
9
10
11
12
using UnityEngine;
using UnityEditor;
using System;
 
public class DialogueAsest
{
    [MenuItem("Assets/Create/Dialogue")]
    public static void CreateAsset ()
    {
        ScriptableObjectUtility.CreateAsset<Dialogue> ();
    }
}

现在当你从menu选择Assets -> Create,或者在project视图中点击创建按钮的时候,就能看到创建新对话的选项。

当点击新创建的资源文件的时候,Inspector视图将会出现DialogueElements的列表以及它们的所有公共变量。和实例化的DialogueElements不同,由于这些是在它们自己的资源文件夹中的,你对它们所做的任何改变都将会贯彻到底,无论是在编辑器状态还是运行状态。所以如果游戏运行时在preview模式下,你对值做了改变,即使停止运行游戏还会保留。这种技术本质上是GUISkin和Unity的其他内置资产的工作原理。

为了从另一个类中访问数据,假设你正在写的类实际上在对话屏幕上显示,就做一个对话的公共实例吧。

1
2
3
4
5
6
public class DialogWindow : MonoBehaviour
{
   public Dialogue DialogueFile;
 
   //The rest of your awesome code to playback
   //your dialogues or use your customs assets

接下来只要通过Inspector指定它。通过单击小圆,从列表中选择它,或者在开口槽(open slot)中拖放一个新建的资源文件。

如果你雄心勃勃,或者仅仅想采取额外的步骤,写一个自定义的Inspector类,来配置资源在Inspector中如何展示。如果是这样,创建一个新的类/文件,命名为DialogueEditor.cs之类的,确保在Editor文件夹下。然后开始写那个类,像是这个样子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
using UnityEngine;
using UnityEditor;
 
[CustomEditor(typeof(Dialogue))]
public class DialogueEditor : Editor
{
   private Dialogue D; //Make an easy shortcut to the Dialogue your editing
   void Awake()
   {
      D=(Dialogue)target;
   }
 
   public override void OnInspectorGUI()
   {
 
   //The rest of your awesome code to allow custom editing
   // of your dialogues or other customs assets you make
   .
   .
   .

然后用代码填充OnInspectorGUI功能,来显示编辑资源的选项。这将非常有利于清理和简化Inspector视图所显示的东西,或者隐藏你不想编辑的选项。对于团队来说也很有用。对于技术不是很娴熟的团队成员来说,例如写脚本的人,说“你看,这个的确很简单,只要点击创建对话并填好一切即可”。下面的截图说明了本项目创建自定义Inspector的用途。

但是,还有一个小小的告诫。如果你为编辑资源文件写了一个自定义Inspector类,或者在另一个MonoBehavior运行时修改自定义资源的值,就需要在你改变的对象上调用Unity的SetDirty方法,如下:

1
EditorUtility.SetDirty(yourInstanceOfACustomAsset);

之所以这样做是因为Unity将会知道对象的内容被修改了,需要重新序列化并保存到磁盘上。

现在,你应该了解如何制作属于你自己的自定义资源,并把它们作为配置文件使用。

原文链接:Unity Pro Tip: Use custom made assets as configuration files

专业版Unity技巧分享:使用定制资源配置文件 ScriptableObject的更多相关文章

  1. 专业版Unity技巧分享:使用定制资源配置文件

    http://unity3d.9tech.cn/news/2014/0116/39639.html 通常,在游戏的开发过程中,最终会建立起一些组件,通过某种形式的配置文件接收一些数据.这些可能是程序级 ...

  2. [翻译] C# 8.0 新特性 Redis基本使用及百亿数据量中的使用技巧分享(附视频地址及观看指南) 【由浅至深】redis 实现发布订阅的几种方式 .NET Core开发者的福音之玩转Redis的又一傻瓜式神器推荐

    [翻译] C# 8.0 新特性 2018-11-13 17:04 by Rwing, 1179 阅读, 24 评论, 收藏, 编辑 原文: Building C# 8.0[译注:原文主标题如此,但内容 ...

  3. Unity3D自定义资源配置文件

    http://blog.csdn.net/candycat1992/article/details/52181814 写在前面 我竟然最近两天才知道Unity中ScriptableObject的存在… ...

  4. SharePoint 2013技巧分享系列 - 同步Exchange显示高清用户照片

    在“SharePoint 2013技巧分享系列 - Active Directory同步显示用户照片”文中介绍了如何同步Active Directory显示用户照片,但是同步完成后,用户照片尺寸和清晰 ...

  5. 技巧分享:解决Word 2010当中“分页符”造成的空白行

    技巧分享:解决Word 2010当中“分页符”造成的空白行 P1:关于“分页符” 在Word当中插入“分页符”之后,后面的内容就会“更起一段”.就好像“换行符”(回车)会让后面的内容“另起一行”一样. ...

  6. [分享] 封装工具ES4配置文件解释

    [分享] 封装工具ES4配置文件解释 LiQiang 发表于 2015-2-3 14:41:21 https://www.itsk.com/thread-346132-1-4.html [分享] 封装 ...

  7. 批量删除wps文档里的回车符的方法!WPS使用技巧分享!

    有时候整理文档的时候,如果是从网上复制的文字,可能会因为复制而产生很多的回车符.怎样能批量去掉这些个回车符呢,下面马上告诉你批量删除wps文档里的回车符的方法!WPS使用技巧分享! 想要批量删除批量删 ...

  8. webstorm的中文教程和技巧分享

    webstorm是一款前端javascript开发编辑的神器,此文介绍webstorm的中文教程和技巧分享.webstorm8.0.3中文汉化版下载:百度网盘下载:http://pan.baidu.c ...

  9. [分享] 从定制Win7母盘到封装详细教程 By BILL ( 10月23日补充说明 )

    [分享] 从定制Win7母盘到封装详细教程 By BILL ( 10月23日补充说明 ) billcheung 发表于 2011-10-23 00:07:49 https://www.itsk.com ...

随机推荐

  1. Palindromic Tree 回文自动机-回文树 例题+讲解

    回文树,也叫回文自动机,是2014年被西伯利亚民族发明的,其功能如下: 1.求前缀字符串中的本质不同的回文串种类 2.求每个本质不同回文串的个数 3.以下标i为结尾的回文串个数/种类 4.每个本质不同 ...

  2. [bzoj3625][Codeforces 250 E]The Child and Binary Tree(生成函数+多项式运算+FFT)

    3625: [Codeforces Round #250]小朋友和二叉树 Time Limit: 40 Sec  Memory Limit: 256 MBSubmit: 650  Solved: 28 ...

  3. [BZOJ3139][HNOI2013]比赛(搜索)

    3139: [Hnoi2013]比赛 Time Limit: 20 Sec  Memory Limit: 128 MBSubmit: 1439  Solved: 719[Submit][Status] ...

  4. C程序运行的背后(1)

    一个成功的男人背后,至少有一个伟大的女人:一个不成功的男人,至少有一双手. 而一个C程序,无论成功不成功,它的背后一定有一个操作系统,一个shell,一套工具链. 世界本就不公平.隐藏在显而易见的事实 ...

  5. bzoj 2733: [HNOI2012]永无乡 -- 线段树

    2733: [HNOI2012]永无乡 Time Limit: 10 Sec  Memory Limit: 128 MB Description 永无乡包含 n 座岛,编号从 1 到 n,每座岛都有自 ...

  6. noip200807传纸条

    试题描述: 小渊和小轩是好朋友也是同班同学,他们在一起总有谈不完的话题.一次素质拓展活动中,班上同学安排做成一个m行n列的矩阵,而小渊和小轩被安排在矩阵对角线的两端,因此,他们就无法直接交谈了.幸运的 ...

  7. Centos7 下mysql大小写敏感问题

    在Centos7 下mysql大小写敏感问题,会导致程序运行时找不到对应的表. 解决办法: 第一步:编辑/etc/my.cnf文件,在[mysqld]节下 添加 lower_case_table_na ...

  8. Mysql -- 设置中国时区时间

       Mysql -- 设置中国时区时间 查看mysql的时区设置 mysql> show variables like '%time_zone%'; 修改mysql的时区设置, 注:mysql ...

  9. 开源数据库 H2, HSQLDB, DERBY, PostgreSQL, MySQL区别/对比图表( 附加翻译) h2数据库

    开源数据库 H2, HSQLDB, DERBY, PostgreSQL, MySQL区别/对比图表 浪天涯博主翻译: referential integrity 参考完整性transactions 事 ...

  10. 严重: StandardServer.await: create[8005]:

    严重: StandardServer.await: create[8005]: 2011-03-14 17:44:51| 分类: 默认分类 | 标签:tomcat java 端口 await crea ...