Son*_*305 5 c# unity-game-engine
我使用可编写脚本的对象为我的 Unity 游戏创建项目。假设我创建了一根棍子、一把剑和一个头盔。现在要使用它们,我需要将它们拖到一个列表中,在游戏开始时,每个项目都会获得一个分配的 ID,这也是列表中的位置,因为我只需循环遍历列表来分配 ID。现在我可以通过使用它拥有的索引来访问该项目,或者,如大多数关于 ScriptableObjects 的教程所示,然后我们可以将项目和 id 添加到 Dictionary 以更好地访问它们。
Stick 为 0,Sword 为 1,Helmet 为 2。现在我决定用补丁移除剑,因此头盔的 ID 为 1。现在每个存档都被破坏了,因为剑变成了头盔。
我如何处理分配的固定 ID,这些 ID 在我真的想再次分配之前不会改变并且不会被另一个项目占用?我当然可以为我创建的每个 ScriptableObject 对 id 进行硬编码,但正如您想象的那样,管理硬编码的 ID 似乎不是一个好主意。
Blu*_*ssa 10
这是我的看法:
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;
}
Run Code Online (Sandbox Code Playgroud)
武器.cs:
using System;
using UnityEngine;
[CreateAssetMenu(fileName = "weapon", menuName = "Items/Weapon")]
public class Weapon : BaseScriptableObject {
public int Attack;
public int Defence;
}
Run Code Online (Sandbox Code Playgroud)
小智 6
创建一个字符串“ID”变量,在脚本对象验证时检查它是否为空。如果为空,则创建一个 GUID,如果不是,则不执行任何操作。
public string UID;
private void OnValidate()
{
#if UNITY_EDITOR
if (UID == "")
{
UID = GUID.Generate().ToString();
UnityEditor.EditorUtility.SetDirty(this);
}
#endif
}
Run Code Online (Sandbox Code Playgroud)
这就是我的做法,它还将可编写脚本的对象设置为脏,这样当您重新启动统一编辑器时它就不会重置。
您可以更进一步,将 UID 字段设为只读,以防止意外更改。