官方:
A ScriptableObject is a data container that you can use to save large amounts of data, independent of class instances. One of the main use cases for ScriptableObjects is to reduce your Project’s memory usage by avoiding copies of values. This is useful if your Project has a Prefab
that stores unchanging data in attached MonoBehaviour scripts
.
Everytime you instantiate that Prefab, it will get its own copy of that
data. Instead of using the method, and storing duplicated data, you can
use a ScriptableObject to store the data and then access it by
reference from all of the Prefabs. This means that there is one copy of
the data in memory.
Just like MonoBehaviours, ScriptableObjects derive from the base
Unity Object but, unlike MonoBehaviours, you can not attach a
ScriptableObject to a GameObject
. Instead, you save them as Assets in your Project.
When using the Editor, you can save data to ScriptableObjects while editing and at run time because ScriptableObjects use the Editor namespace and Editor scripting. In a deployed build, however, you can’t use ScriptableObjects to save data, but you can use the saved data from the ScriptableObject Assets that you set up during development. Data that you save from Editor Tools to ScriptableObjects as an asset is written to disk and is therefore persistent between sessions.
使用:
public class Skill : ScriptableObject {
public int Id;
public string Name;
public float CD; }
编辑器扩展:
[MenuItem("BuildScriptableObject/MakeSkillAsset")] public static void MakeSkill() { //创建skill的asset Skill nameInfoObj = ScriptableObject.CreateInstance<Skill>(); nameInfoObj.Property.Id = EditorData.Instance.GetData("SkillAmount") + 1; //SkillAmount: UnityEditor.AssetDatabase.CreateAsset(nameInfoObj, "Assets/Resources/SkillAssets/Skill_" + nameInfoObj.Property.Id + ".asset"); EditorData.Instance.SetData("SkillAmount", nameInfoObj.Property.Id); }
private void OnGUI() { EditorGUILayout.LabelField("请将技能资源文件拖入下框中"); Skill skl = (Skill)EditorGUILayout.ObjectField(skill, typeof(Skill));
//修改
ScrollView = EditorGUILayout.BeginScrollView(ScrollView);
if (GUI.Button(new Rect(50, EditorGUILayout.GetControlRect().y + EditorGUIUtility.singleLineHeight, 50, EditorGUIUtility.singleLineHeight), "保存"))
{//保存修改后的文件(方法很笨,而且会报红,但是能达到预期的效果,不管怎么样,能跑起来就行~)
string path = "Assets/Resources/SkillAssets/" + skl.name + ".asset";
string tempPath = "Assets/Resources/SkillAssets/" + skl.name + "_tmp.asset";
AssetDatabase.CreateAsset(skill, tempPath);
skill = AssetDatabase.LoadAssetAtPath(tempPath, skill.GetType()) as Skill;
AssetDatabase.DeleteAsset(path);
AssetDatabase.CreateAsset(skill, path);
skill = AssetDatabase.LoadAssetAtPath(path, skill.GetType()) as Skill;
AssetDatabase.DeleteAsset(tempPath);
AssetDatabase.Refresh();
}
EditorGUILayout.LabelField("技能名");
skill.Property.Name = EditorGUILayout.TextField(skill.Property.Name);
EditorGUILayout.LabelField("技能cd");
skill.Property.CD = EditorGUILayout.FloatField(skill.Property.CD);
EditorGUILayout.EndScrollView(); }
[MenuItem("BuildScriptableObject/SkillEditor")]
public static void MyWindowsShow()
{
SkillScriptableEditor myWindow = EditorWindow.GetWindow<SkillScriptableEditor>();
myWindow.titleContent = new GUIContent("技能文件编辑");
myWindow.position = new Rect(600, 300, 500, 500);
myWindow.Show();
}
加载使用:
IdToSkill = new Dictionary<int, Skill>();
foreach(UnityEngine.Object obj in Resources.LoadAll(path)) { Skill skill = obj as Skill; IdToSkill.Add(skill.Id, skill); }
原文:https://www.cnblogs.com/rzy200205/p/12295315.html