我有以下可撰寫腳本的物件:
[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 = '\0';
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());
}
該物件是通過編輯器腳本成功創建的,它保存了所有資料,但是如果我關閉并重新打開編輯器,并嘗試加載欄位為空。用于保存和加載可撰寫腳本物件的腳本在場景中使用
我做錯了什么?
uj5u.com熱心網友回復:
檢查腳本序列化規則
特別是在你的情況下
-
Unity 中的序列化程式直接作用于C# 類的欄位,而不是它們的屬性,因此您的欄位必須遵守規則才能進行序列化。
-
注意:Unity 不支持多級型別的序列化(多維陣列、交錯陣列、字典和嵌套容器型別)
所以你的兩個屬性都沒有序列化(=保存)。
作為解決方案
為了
Crosswords確保型別
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 }然后寧愿有例如
public Table Table;
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/461624.html
