Unity Scriptable Object在编辑器关闭后不保留其值



我有以下可脚本化的对象:

[CreateAssetMenu(fileName = "Assets/Gladio Games/Resources/Levels/LEVLE_TMP", menuName = "Utils/Crossword/Generate Empty Level", order = 100)]
public class Level : ScriptableObject
{
public char[,] Table { get; protected set; }
public  List<Crossword> Crosswords { get; protected set; }
protected static char EMPTY_CHAR = '';

public Crossword GetCrosswordAtIndex(int x, int y, Direction direction)
{
//Ottieni la prima e l'unica parola che si trova sotto quell'indice
return Crosswords.First(crossword => crossword.Direction == direction && crossword.GetCrosswordIndexes().Contains(new Vector2(x, y)));
}
}
这是我用来保存Scriptable Object 的代码
private static void Save(Level level, string path)
{            
EditorUtility.SetDirty(level);
AssetDatabase.CreateAsset(level, path + ".asset");
AssetDatabase.SaveAssets();
AssetDatabase.Refresh();
EditorSceneManager.MarkSceneDirty(EditorSceneManager.GetActiveScene());
}

对象是通过编辑器脚本成功创建的,它保存了所有数据,但如果我关闭并重新打开编辑器,并尝试加载字段为空。用于保存和加载可脚本对象的脚本在场景

中使用。我做错了什么?

检查脚本序列化规则

特别是在你的情况下

  • Unity中的序列化器直接作用于字段c#类而不是它们的属性,因此您的字段必须符合一些规则才能序列化。

  • 注意:Unity不支持多层类型的序列化(多维数组)、锯齿数组、字典和嵌套容器类型)

所以你的属性没有序列化(=已保存)


作为解决方案

  • ForCrosswords

    • 确保类型Crossword本身为[Serializable]

    • 使用字段而不是

      public  List<Crossword> Crosswords;
      
  • 对于Table有多种途径

    我可能会简单地使用一个包装类,例如

    // Could of course make this generic but for the drawer it easier this way for now
    [Serializable]
    public class Table
    {
    [SerializeField]
    [Min(1)]
    private int xDimension = 1;
    [SerializeField]
    [Min(1)]
    private int yDimension = 1;
    [SerializeField]
    private char[] flatArray = new char[1];
    public Table() { }
    public Table(char[,] array)
    {
    xDimension = array.GetLength(0);
    yDimension = array.GetLength(1);
    flatArray = new char[xDimension * yDimension];
    for (var x = 0; x < xDimension; x++)
    {
    for (var y = 0; y < yDimension; y++)
    {
    flatArray[x * yDimension + y] = array[x, y];
    }
    }
    }
    public Table(int x, int y)
    {
    xDimension = x;
    yDimension = y;
    flatArray = new char[x * y];
    }
    public Table(char[] array, int x, int y)
    {
    xDimension = x;
    yDimension = y;
    flatArray = array;
    }
    public char this[int x, int y]
    {
    get => flatArray[x * yDimension + y];
    set => flatArray[x * yDimension + y] = value;
    }
    #if UNITY_EDITOR
    [CustomPropertyDrawer(typeof(Table))]
    private class TableDrawer : PropertyDrawer
    {
    private const int k_elementSpacing = 5;
    public override float GetPropertyHeight(SerializedProperty property, GUIContent label)
    {
    var height = 1f;
    if (property.isExpanded)
    {
    height += property.FindPropertyRelative(nameof(Table.xDimension)).intValue * 1.5f;
    }
    return height * EditorGUIUtility.singleLineHeight;
    }
    public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
    {
    var foldoutRect = position;
    foldoutRect.height = EditorGUIUtility.singleLineHeight;
    foldoutRect.width = EditorGUIUtility.labelWidth;
    property.isExpanded = EditorGUI.Foldout(foldoutRect, property.isExpanded, label);
    if (property.isExpanded)
    {
    var xRect = position;
    xRect.height = EditorGUIUtility.singleLineHeight;
    xRect.x += foldoutRect.width;
    xRect.width -= foldoutRect.width;
    xRect.width *= 0.5f;
    var yRect = xRect;
    yRect.x += xRect.width;
    var xDimension = property.FindPropertyRelative(nameof(Table.xDimension));
    var yDimension = property.FindPropertyRelative(nameof(Table.yDimension));
    var array = property.FindPropertyRelative(nameof(Table.flatArray));
    using (var changeCheck = new EditorGUI.ChangeCheckScope())
    {
    EditorGUI.PropertyField(xRect, xDimension, GUIContent.none);
    EditorGUI.PropertyField(yRect, yDimension, GUIContent.none);
    if (changeCheck.changed)
    {
    array.arraySize = xDimension.intValue * yDimension.intValue;
    }
    }
    position.y += EditorGUIUtility.singleLineHeight * 1.5f;
    EditorGUI.indentLevel++;
    var elementRect = EditorGUI.IndentedRect(position);
    EditorGUI.indentLevel--;
    var elementWidth = elementRect.width / yDimension.intValue - k_elementSpacing;
    var elementHeight = EditorGUIUtility.singleLineHeight;
    var currentPosition = elementRect;
    currentPosition.width = elementWidth;
    currentPosition.height = elementHeight;
    for (var x = 0; x < xDimension.intValue; x++)
    {
    for (var y = 0; y < yDimension.intValue; y++)
    {
    var element = array.GetArrayElementAtIndex(x * yDimension.intValue + y);
    EditorGUI.PropertyField(currentPosition, element, GUIContent.none);
    currentPosition.x += elementWidth + k_elementSpacing;
    }
    currentPosition.x = elementRect.x;
    currentPosition.y += elementHeight * 1.5f;
    }
    }
    }
    }
    #endif
    }
    

    然后rather有e.g.

    public Table Table;
    

相关内容

  • 没有找到相关文章

最新更新