所以我做了一个小编辑器脚本,帮助我为地下城生成器创建模板。但是当我想使用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];
}
}
}
}
只要我不退出播放模式,创作就可以正常工作。退出并再次进入播放模式后,阵列不可用,但宽度和高度等其他信息仍然保存。
答案 0 :(得分:0)
Unity无法序列化2D数组。您需要使用一维数组[width * height]
并通过[x + y * width]
访问元素。