I'm working on implementing room prefabs for my 2D procedural map generation algorithm.
Basically I made a tool which parses a scene's
- monsters, items, etc into an ObjectContainer prefab,
- and into a ScriptableObject containing the tilemap's TileDatas, EntryTiles, and the ObjectContainerPrefab.
It works well, but my problem occurs when I try to build the game, or just restart the editor.
The TileData array will be empty.
And thus for example the EntryTiles' TileData reference will be null.
Here 's how I use them:
[MenuItem("Custom Tools/Parse room prefab from scene")]
private static void ParseRoomPrefabFromScene()
{
var tilemap = GameObject.Find("Tilemap").GetComponent<Tilemap>();
RoomPrefab roomPrefab = ScriptableObject.CreateInstance<RoomPrefab>();
ParseTilemap(roomPrefab, tilemap);
ParseObjects(roomPrefab, tilemap);
ParseEntryTiles(roomPrefab, tilemap);
AssetDatabase.CreateAsset(roomPrefab, "xyz.asset");
AssetDatabase.SaveAssets();
}
// How I setup my scriptable object, i.e. in ParseTilemap:
var tileDatas = new List<TileData>();
...
var tileData = new TileData(coordinates, unityTile, isWall);
tileDatas.Add(tileData);
...
roomPrefab.tileDatas = tileDatas.ToArray();
Here are the classes:
public class RoomPrefab : ScriptableObject
{
public TileData[] tileDatas;
public EntryTile[] entryTiles;
public ObjectContainerPrefab ObjectContainerPrefab;
}
[Serializable]
public class TileData
{
public TileBase UnityTile
{
get;
private set;
}
public Vector2Int Coordinates
{
get;
set;
}
public bool IsWall
{
get;
private set;
}
public TileData(Vector2Int coordinates, TileBase unityTile, bool isWall)
{
Coordinates = coordinates;
UnityTile = unityTile;
IsWall = isWall;
}
...
[Serializable]
public class EntryTile
{
public TileData TileData
{
get;
private set;
}
public Vector2Int LeaveDirection
{
get;
private set;
}
public EntryTile(TileData tileData, Vector2Int leaveDirection)
{
TileData = tileData;
LeaveDirection = leaveDirection;
}
...
[Serializable]
public class ObjectContainerPrefab
{
public Vector2Int Coordinates
{
get;
private set;
}
public float Rotation
{
get;
private set;
}
public GameObject Prefab
{
get;
private set;
}
public ObjectContainerPrefab(Vector2Int coordinates, float rotation, GameObject prefab)
{
Coordinates = coordinates;
Rotation = rotation;
Prefab = prefab;
}
}
UPDATE: here is a freshly parsed scriptable object. In the Editor everything is fine, while in its file its tileDatas array is already empty. Why?
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!114 &11400000
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 30263215ad3a45a479bb2dd6409fb0a9, type: 3}
m_Name: TestRoom
m_EditorClassIdentifier:
tileDatas: []
entryTiles:
- DebugCube: {fileID: 0}
- DebugCube: {fileID: 0}