ScriptableObject 对象化的运用
http://www.cnblogs.com/oldman/articles/2409554.html
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 是Unity3D整个引擎的设计中,最为出彩的地方。通过他我们将数据保存,数据和编辑器的交互以及数据在runtime的使用三部分很方便的联系在一起。这是一个容易被Unity3D的初学者们容易忽略的领域。
简单的说,你可以把ScriptableObject当作Unity3D下的xml。但是其存储格式为二进制。让我们从一个实际例子出发,来理解ScriptableObject在实际项目中的整个运用。
假设我们有AbilityInfo需要设置和保存,我们可以将AbilityInfo制作成ScriptableObject,如下:
public class AbilityInfo : ScriptableObject {
public enum Type {
Unknown,
FireBall,
FireWall,
IceBall,
DarkForce,
Heal,
Poison,
}
public Type type = Type.Unknown;
public float point = 10.0f;
public float affectRange = 100.0f;
}
创建ScriptableObject
ScriptableObject 可以通过 ScriptableObject.CreateInstance<T>() 动态创建。然而将它保存为Unity3D Asset是ScriptableObject的设计本意。一般的,我们通过这个函数来完成整个创建过程:
public static class AbilityInfoUtility {
public static AbilityInfo Create ( string _path, string _name ) {
//
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" );
//
AbilityInfo newAbilityInfo = ScriptableObject.CreateInstance<AbilityInfo>();
AssetDatabase.CreateAsset(newAbilityInfo, assetPath);
Selection.activeObject = newAbilityInfo;
return newAbilityInfo;
}
}
注意1: 这是一个在Editor下使用的函数,所以这份代码需要放在项目中名为 “Editor” 的文件夹中 (目录层次无所谓),并且需要在代码开头处引入: using UnityEditor;
注意2: ScriptableObject的脚本文件名必须和他的类名一致,并且一个脚本文件只能对应一个ScriptableObject定义。
注意3: ScriptableObject只能保存为后缀名为”.asset”的文件,其他格式Unity3D将不能正确读取。
将Asset的创建方式提供给用户
对于编辑器的使用者,自然需要有UI或者方便的执行脚本方法来帮助创建数据。我们使用[MenuItem]来完成操作。以下代码会将Asset的创建加入到Project Window的右键菜单中:
class AbilityInfoUtility {
...
[MenuItem ("Assets/Create/Ability Info")]
static void Create () {
// get current selected directory
string assetName = "New AbilityInfo";
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 ) {
AbilityInfo abilityInfo = AbilityInfoUtility.Create ( assetPath, assetName );
Selection.activeObject = abilityInfo;
// EditorGUIUtility.PingObject(border);
}
}
}

自定义编辑显示
ScriptableObject 可以通过自定义编辑器的方式进行特殊编辑。编辑器方面有EditorWindow和Editor两种方式。EditorWindow更多地用在一些复杂数 据的可视化编辑。对于一些小的行为改变,我们可以通过Editor来实现。本节我们也已介绍Editor的编辑为主。设我们需要为AbilityInfo 在Inspector中加入预览图标。我们先于提供预览图标的美术工作人员约定好图标的存放位置和名称,如Editor/Icons/Ability 目录内。这里我们通过简单的硬编码来存取这些图标 (更灵活的做法是提供一些辅助的设置gui等)。我们在AbilityInfoUtility中添加如下函数:
public static class AbilityInfoUtility {
...
public static Texture2D GetTextureByType ( AbilityInfo.Type _type ) {
switch ( _type ) {
case AbilityInfo.Type.Unknown:
return AssetDatabase.LoadAssetAtPath ( "Assets/Editor/Icons/Ability/Unknown.png", typeof(Texture2D) ) as Texture2D;
case AbilityInfo.Type.FireBall:
return AssetDatabase.LoadAssetAtPath ( "Assets/Editor/Icons/Ability/FireBall.png", typeof(Texture2D) ) as Texture2D;
case AbilityInfo.Type.FireWall:
return AssetDatabase.LoadAssetAtPath ( "Assets/Editor/Icons/Ability/FireWall.png", typeof(Texture2D) ) as Texture2D;
case AbilityInfo.Type.IceBall:
return AssetDatabase.LoadAssetAtPath ( "Assets/Editor/Icons/Ability/IceBall.png", typeof(Texture2D) ) as Texture2D;
case AbilityInfo.Type.DarkForce:
return AssetDatabase.LoadAssetAtPath ( "Assets/Editor/Icons/Ability/DarkForce.png", typeof(Texture2D) ) as Texture2D;
case AbilityInfo.Type.Heal:
return AssetDatabase.LoadAssetAtPath ( "Assets/Editor/Icons/Ability/Heal.png", typeof(Texture2D) ) as Texture2D;
case AbilityInfo.Type.Poison:
return AssetDatabase.LoadAssetAtPath ( "Assets/Editor/Icons/Ability/Poison.png", typeof(Texture2D) ) as Texture2D;
}
return null;
}
}
要自定义Inspector显示,只需要通过在派生的Editor中标记上[CustomEditor(Type)]这个Attribute即可,这里给出一个简单的示例:
[CustomEditor(typeof(AbilityInfo))]
public class AbilityInfoEditor : Editor {
public override void OnInspectorGUI () {
AbilityInfo editInfo = target as AbilityInfo;
GUI.DrawTexture ( new Rect( 20, 20, 40, 40 ), AbilityInfoUtility.GetTextureByType(editInfo.type) );
GUILayoutUtility.GetRect ( 40, 40 );
GUILayout.Space (5);
base.OnInspectorGUI();
}
}
注意: 这里的base.OnInspectorGUI()实际上是比较偷懒的做法。对于需要仔细定义每个属性用途和显示的数据,请参考Unity3D的EditorGUI, EditorGUILayout文档认真编写。

在MonoBehavior中引用数据
现在我们只需要在MonoBehavior中引用这份数据,在读取场景的时候,就会自动帮助我们完成数据的序列化操作。
public class MyBehavior : MonoBehavior {
public AbilityInfo normalSkill1;
public AbilityInfo normalSkill2;
public AbilityInfo specialSkill;
}
ScriptableObject 对象化的运用的更多相关文章
- ScriptableObject本地序列化后重启Unity后报The associated script can not be loaded.Please fix any compile errors and assign a valid script的坑
踩坑 做编辑器一些设置序列化存在本地的时候,继承自ScriptableObject的类通过 创建的asset文件. 在重启Unity后查看这个asset发现上面的所有序列化属性丢失,报的错就是 在不存 ...
- unity, 由scriptableObject创建.asset
由继承自scriptableObject的类X创建.asset文件. 假设类X的定义为: [System.Serializable] public class X : ScriptableObject ...
- [cb]ScriptableObject 序列化
ScriptableObject ScriptableObject是一个类,它允许你存储大量用于共享的数据独立脚本实例,不要迷惑这个类同样可以叫做 SerializableObject,可以理解成是一 ...
- Unity ScriptableObject的使用
ScriptableObject主要实现对象序列化的保存,因为是Unity自己的序列化,所以比xml,json序列化方便很多,但相对可控性也比较差 1.Editor下写入和读取测试: using Un ...
- EditorWindow edit ScriptableObject
using UnityEngine; [System.Serializable] public class Weapon { //[SerializeField] public string weap ...
- Unity3D之ScriptableObject学习笔记
不同与C#提供的Serializable序列化功能,ScriptableObject是Unity3D提供的一个数据存储类,我们接下来学习一下这个类的功能. 官方文档 http://docs.unity ...
- C语言对象化编程
以下为一个引子: C中struct的函数实现,只能用函数指针成员. C结构体内不能有函数的代码,但可以有函数的指针. C/C code Code highlighting produced by Ac ...
- 用DELPHI的RTTI实现数据集的简单对象化
在<强大的DELPHI RTTI--兼谈需要了解多种开发语言>一文中,我说了一下我用DELPHI的RTTI实现了数据集的简单对象化.本文将详细介绍一下我的实现方法. 首先从一个简单 ...
- 自定义ScriptableObject属性显示
自定义ScriptableObject属性显示的三种方式 1. 继承Editor,重写OnInspectorGUI方法 Editor官方文档 需求 将TestClass中intData属性和strin ...
随机推荐
- [BZOJ4825][HNOI2017]单旋(线段树+Splay)
4825: [Hnoi2017]单旋 Time Limit: 10 Sec Memory Limit: 256 MBSubmit: 667 Solved: 342[Submit][Status][ ...
- HDU 5298 Solid Geometry Homework 暴力
Solid Geometry Homework 题目连接: http://acm.hdu.edu.cn/showproblem.php?pid=5298 Description Yellowstar ...
- 05-树6. Path in a Heap (25) 小根堆
05-树6. Path in a Heap (25) Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://www.patest.cn/contes ...
- mysql sql优化及注意事项
sql优化分析 通过slow_log等方式可以捕获慢查询sql,然后就是减少其对io和cpu的使用(不合理的索引.不必要的数据访问和排序)当我们面对具体的sql时,首先查看其执行计划A.看其是否使用索 ...
- axios 与 Jquery-ajax 的使用区别
axios 和 ajax 的使用方法基本一样,只有个别参数不同: 附:axios 中文文档 一.axios axios({ url: 'http://jsonplaceholder.typicode. ...
- OC中NSLog函数输出格式详解
OC中NSLog函数输出格式详解 %@ 对象 • %d, %i 整数 • %u 无符整形 • %f 浮点/双字 • %x, %X 二进制整数 • %o 八进制整数 • %zu size_t • %p ...
- oc/object-c/ios哪种遍历NSArray/NSDictionary方式快?测试报告
做app的时候,总免不了要多次遍历数组或者字典.究竟哪种遍历方式比较快呢?我做了如下测试:首先定义测试用宏: ? 1 2 3 4 5 6 7 8 9 #define MULogTimeinterval ...
- HDU 4675 GCD of Sequence (2013多校7 1010题 数学题)
GCD of Sequence Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 65535/65535 K (Java/Others)T ...
- 利用Lucene与Nutch构建简单的全文搜索引擎
文章地址 1.简介 本次实现分为两个部分,第一个部分是利用Lucene构建一个全文的搜索引擎,另外一部分则是利用Nutch实现同样的功能.由于Lucene并不是一个可以直接运行的程序,且不具备爬虫和文 ...
- cocos2d3.0 Scale9Sprite
使用Scale9Sprite须要引入以下的头文件 #include "extensions/cocos-ext.h" USING_NS_CC; USING_NS_CC_EXT; 一 ...