在playmode期间创建ScriptableObject会在退出后丢失数组信息

时间:2018-04-19 20:35:38

标签: c# unity3d

所以我做了一个小编辑器脚本,帮助我为地下城生成器创建模板。但是当我想使用ScriptableObject中保存的信息时,数组似乎抛出了NullReferenceException。 此类创建一个可在游戏视图中编辑的网格,然后使用下一个类将信息转换为新的ScriptableObject。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
using RoomTypes;
using TileTypes;

public class CreateRoom : MonoBehaviour {
public GameObject tile;
public TileType curTileType;
public RoomType type;
public Tile[,] grid;
public int width;
public int height;

public TileButton[,] tileButtons;
private GameObject tileParent;

public void Create()
{
    for (int x = 0; x < width; x++)
    {
        for (int y = 0; y < height; y++)
        {
            grid[x, y] = new Tile( tileButtons[x, y].tileType ) ;
        }
    }
    CreateSORoom.CreateRoom(type, grid, width, height);
}

public void CreateGrid()
{
    tileButtons = new TileButton[width, height];
    DeleteGrid();
    FindObjectOfType<CreateRoomCamera>().SetCamera(width, height);
    if (!tileParent) tileParent = new GameObject("TileParent");
    grid = new Tile[width, height];
    for (int x = 0; x < width; x++)
    {
        for (int y = 0; y < height; y++)
        {
            GameObject newTile = Instantiate(tile, tileParent.transform);
            newTile.GetComponent<RectTransform>().anchoredPosition = new 
Vector3(0.5f + x, 0.5f + y);
            tileButtons[x, y] = newTile.GetComponent<TileButton>();
            tileButtons[x, y].xCoord = x;
            tileButtons[x, y].yCoord = y;
        }
    }
}
}

[CustomEditor(typeof(CreateRoom))]
public class CreateRoomEditor : Editor
{
public override void OnInspectorGUI()
{
    CreateRoom createRoom = (CreateRoom)target;

    base.OnInspectorGUI();
    if (GUILayout.Button("Create Grid"))
    {
        createRoom.CreateGrid();
    }
    if (GUILayout.Button("Create Room"))
    {
        createRoom.Create();
    }
}
}

这是创建Object的类。

using UnityEngine;
using UnityEditor;
using System.IO;
using RoomTypes;
using TileTypes;

public static class CreateSORoom
{
public static void CreateRoom(RoomType type, Tile[,] grid, int width, int 
height)
{
    Room room = ScriptableObject.CreateInstance<Room>();

    string path = "Assets/LevelGeneration/RoomCreation/Rooms/";
    string assetName = "";
    if (type == RoomType.LeftRight) assetName = "LeftRight";
    else if (type == RoomType.LeftDown) assetName = "LeftDown";
    else if (type == RoomType.RightDown) assetName = "DownRight";
    else if (type == RoomType.LeftUp) assetName = "LeftUp";
    else if (type == RoomType.UpRight) assetName = "UpRight";
    else if (type == RoomType.Start) assetName = "Start";
    else if (type == RoomType.End) assetName = "End";
    else if (type == RoomType.Bonus) assetName = "Bonus";
    else if (type == RoomType.Empty) assetName = "Empty";
    path += assetName;
    if (Path.GetExtension(path) != "")
    {
        path = path.Replace(Path.GetFileName(AssetDatabase.GetAssetPath(Selection.activeObject)), "");
    }

    string assetPathAndName = AssetDatabase.GenerateUniqueAssetPath(path + "/" + assetName + width + "x" + height + ".asset");

    room.Init(type, width, height, grid);
    AssetDatabase.CreateAsset(room, assetPathAndName);
    EditorUtility.SetDirty(room);
    AssetDatabase.SaveAssets();
    AssetDatabase.Refresh();
    EditorUtility.FocusProjectWindow();
    Selection.activeObject = room;
}

}

public class Room : ScriptableObject
{
public RoomType type;
public int width;
public int height;
public Tile[,] grid;

public void Init(RoomType _type, int _width, int _height, Tile[,] _grid)
{
    type = _type;
    width = _width;
    height = _height;
    grid = new Tile[width, height];
    for (int x = 0; x < width; x++)
    {
        for (int y = 0; y < height; y++)
        {
            grid[x, y] = _grid[x, y];
        }
    }
}

}

只要我不退出播放模式,创作就可以正常工作。退出并再次进入播放模式后,阵列不可用,但宽度和高度等其他信息仍然保存。

1 个答案:

答案 0 :(得分:0)

Unity无法序列化2D数组。您需要使用一维数组[width * height]并通过[x + y * width]访问元素。