我使用脚本对象为Unity游戏创建项目。假设我创建了一根棍子,一把剑和一个头盔。现在要使用它们,我需要将它们拖到列表中,并在游戏开始时,为每个项目分配一个ID,该ID也是列表中的位置,因为我只是在列表中循环遍历以分配ID。现在,我可以使用它具有的索引来访问该项目,或者如大多数关于ScriptableObjects的教程中所示,然后我们可以将该项目和id添加到Dictionary中以更好地访问它们。
Stick是0,Sword是1,Helmet是2。现在我决定用补丁移除剑,使头盔的ID为1。现在,每一次保存游戏都随着剑变成头盔而被破坏。
在我真的想要再次分配固定ID时,该ID不会改变并且不会被另一个项目占用,该如何处理?我当然可以对我创建的每个ScriptableObject的ID进行硬编码,但是正如您可以想象的那样,管理硬编码的ID似乎不是一个好主意。
答案 0 :(得分:2)
创建一个字符串“ ID”变量,在可脚本编写的对象验证时检查它是否为空。如果为空,则创建一个GUID,否则为空。
public string UID;
private void OnValidate()
{
#if UNITY_EDITOR
if (UID == "")
{
UID = GUID.Generate().ToString();
UnityEditor.EditorUtility.SetDirty(this);
}
#endif
}
这是我的操作方式,它还将可脚本化的对象设置为脏对象,因此在您重新启动统一编辑器时不会重置。
您可以更进一步,将UID字段设置为只读,以防止意外更改。
答案 1 :(得分:0)
这是我的看法:
BaseScriptableObject.cs:
using System;
using UnityEditor;
using UnityEngine;
public class ScriptableObjectIdAttribute : PropertyAttribute { }
#if UNITY_EDITOR
[CustomPropertyDrawer(typeof(ScriptableObjectIdAttribute))]
public class ScriptableObjectIdDrawer : PropertyDrawer {
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) {
GUI.enabled = false;
if (string.IsNullOrEmpty(property.stringValue)) {
property.stringValue = Guid.NewGuid().ToString();
}
EditorGUI.PropertyField(position, property, label, true);
GUI.enabled = true;
}
}
#endif
public class BaseScriptableObject : ScriptableObject {
[ScriptableObjectId]
public string Id;
}
Weapon.cs:
using System;
using UnityEngine;
[CreateAssetMenu(fileName = "weapon", menuName = "Items/Weapon")]
public class Weapon : BaseScriptableObject {
public int Attack;
public int Defence;
}