ManiaMap.Unity
Procedural generation of metroidvania style maps for Unity.
RoomComponent.cs
1using MPewsey.Common.Collections;
2using MPewsey.ManiaMap;
3using MPewsey.ManiaMap.Exceptions;
4using System.Collections.Generic;
5using UnityEngine;
6using UnityEngine.AddressableAssets;
7using UnityEngine.Events;
8using UnityEngine.ResourceManagement.AsyncOperations;
9
11{
23 public class RoomComponent : MonoBehaviour
24 {
25 [SerializeField]
26 private RoomTemplateResource _roomTemplate;
30 public RoomTemplateResource RoomTemplate { get => _roomTemplate; set => _roomTemplate = value; }
31
32 [SerializeField]
33 private string _name = "<None>";
37 public string Name { get => _name; set => _name = value; }
38
39 [SerializeField]
40 private RoomType _roomType;
44 public RoomType RoomType { get => _roomType; set => _roomType = value; }
45
46 [SerializeField]
47 private Vector2Int _size = Vector2Int.one;
51 public Vector2Int Size { get => _size; set => SetSizeField(ref _size, value); }
52
53 [SerializeField]
54 private Vector3 _cellSize = new Vector3(1, 1, 0.001f);
58 public Vector3 CellSize { get => _cellSize; set => _cellSize = Vector3.Max(value, 0.001f * Vector3.one); }
59
60 [HideInInspector]
61 [SerializeField]
62 private List<ActiveCellsRow> _activeCells = new List<ActiveCellsRow>();
66 public List<ActiveCellsRow> ActiveCells { get => _activeCells; set => _activeCells = value; }
67
68 [SerializeField]
69 private UnityEvent _onInitialize = new UnityEvent();
73 public UnityEvent OnInitialize { get => _onInitialize; set => _onInitialize = value; }
74
75 [SerializeField]
76 private UnityEvent _onInitialized = new UnityEvent();
80 public UnityEvent OnInitialized { get => _onInitialized; set => _onInitialized = value; }
81
82 [SerializeField]
83 private CellAreaTriggerEvent _onCellAreaEntered = new CellAreaTriggerEvent();
87 public CellAreaTriggerEvent OnCellAreaEntered { get => _onCellAreaEntered; set => _onCellAreaEntered = value; }
88
89 [SerializeField]
90 private CellAreaTriggerEvent _onCellAreaExited = new CellAreaTriggerEvent();
94 public CellAreaTriggerEvent OnCellAreaExited { get => _onCellAreaExited; set => _onCellAreaExited = value; }
95
99 public bool IsInitialized { get; private set; }
100
104 public LayoutPack LayoutPack { get; private set; }
105
109 public Room RoomLayout { get; private set; }
110
114 public RoomState RoomState { get; private set; }
115
119 public int Rows { get => Size.x; set => Size = new Vector2Int(value, Size.y); }
120
124 public int Columns { get => Size.y; set => Size = new Vector2Int(Size.x, value); }
125
126 private void SetSizeField(ref Vector2Int field, Vector2Int value)
127 {
128 field = Vector2Int.Max(value, Vector2Int.one);
130 }
131
132 private void OnValidate()
133 {
134 Size = Size;
136 }
137
138 private void OnDrawGizmos()
139 {
140 var activeFillColor = new Color(0, 0, 1, 0.2f);
141 var inactiveFillColor = new Color(1, 0, 0, 0.2f);
142 var lineColor = new Color(0, 0, 0);
143 DrawCells(activeFillColor, lineColor, true);
144 DrawCells(inactiveFillColor, lineColor, false);
145 }
146
153 private void DrawCells(Color fillColor, Color lineColor, bool activity)
154 {
155 var cellSize = GridToLocalPosition(CellSize);
156
157 for (int i = 0; i < ActiveCells.Count; i++)
158 {
159 var row = ActiveCells[i].Values;
160
161 for (int j = 0; j < row.Count; j++)
162 {
163 if (row[j] == activity)
164 {
165 var center = CellCenterGlobalPosition(i, j);
166 Gizmos.color = fillColor;
167 Gizmos.DrawCube(center, cellSize);
168 Gizmos.color = lineColor;
169 Gizmos.DrawWireCube(center, cellSize);
170 }
171 }
172 }
173 }
174
183 public static AsyncOperationHandle<GameObject> InstantiateRoomAsync(Uid id, LayoutPack layoutPack,
184 AssetReferenceGameObject prefab, Transform parent = null,
185 bool assignLayoutPosition = false)
186 {
187 var roomLayout = layoutPack.Layout.Rooms[id];
188 var roomState = layoutPack.LayoutState.RoomStates[id];
189 var cellLayer = layoutPack.Settings.CellLayer;
190 var triggeringLayers = layoutPack.Settings.TriggeringLayers;
191 return InstantiateRoomAsync(prefab, parent, layoutPack, roomLayout, roomState, cellLayer, triggeringLayers, assignLayoutPosition);
192 }
193
205 public static AsyncOperationHandle<GameObject> InstantiateRoomAsync(AssetReferenceGameObject prefab, Transform parent,
206 LayoutPack layoutPack, Room roomLayout, RoomState roomState,
207 int cellLayer, LayerMask triggeringLayers, bool assignLayoutPosition)
208 {
209 var handle = prefab.InstantiateAsync(parent);
210
211 handle.Completed += handle => handle.Result.GetComponent<RoomComponent>()
212 .Initialize(layoutPack, roomLayout, roomState, cellLayer, triggeringLayers, assignLayoutPosition);
213
214 return handle;
215 }
216
225 public static RoomComponent InstantiateRoom(Uid id, LayoutPack layoutPack, GameObject prefab, Transform parent = null,
226 bool assignLayoutPosition = false)
227 {
228 var roomLayout = layoutPack.Layout.Rooms[id];
229 var roomState = layoutPack.LayoutState.RoomStates[id];
230 var cellLayer = layoutPack.Settings.CellLayer;
231 var triggeringLayers = layoutPack.Settings.TriggeringLayers;
232 return InstantiateRoom(prefab, parent, layoutPack, roomLayout, roomState, cellLayer, triggeringLayers, assignLayoutPosition);
233 }
234
246 public static RoomComponent InstantiateRoom(GameObject prefab, Transform parent,
247 LayoutPack layoutPack, Room roomLayout, RoomState roomState,
248 int cellLayer, LayerMask triggeringLayers, bool assignLayoutPosition)
249 {
250 var room = Instantiate(prefab, parent).GetComponent<RoomComponent>();
251 room.Initialize(layoutPack, roomLayout, roomState, cellLayer, triggeringLayers, assignLayoutPosition);
252 return room;
253 }
254
264 public bool Initialize(LayoutPack layoutPack, Room roomLayout, RoomState roomState,
265 int cellLayer, LayerMask triggeringLayers, bool assignLayoutPosition)
266 {
267 if (IsInitialized)
268 return false;
269
270 LayoutPack = layoutPack;
271 RoomLayout = roomLayout;
272 RoomState = roomState;
273
274 if (assignLayoutPosition)
276
277 CreateCellAreas(cellLayer, triggeringLayers);
278 IsInitialized = true;
279 OnInitialize.Invoke();
280 OnInitialized.Invoke();
281 return true;
282 }
283
287 private void MoveToLayoutPosition()
288 {
289 var x = CellSize.x * RoomLayout.Position.Y;
290 var y = CellSize.y * RoomLayout.Position.X;
291 var z = CellSize.z * RoomLayout.Position.Z;
292 transform.localPosition = GridToLocalPosition(new Vector3(x, y, z));
293 }
294
300 private void CreateCellAreas(int cellLayer, LayerMask triggeringLayers)
301 {
302 for (int i = 0; i < Rows; i++)
303 {
304 for (int j = 0; j < Columns; j++)
305 {
306 if (GetCellActivity(i, j))
307 CellArea.InstantiateCellArea(i, j, this, cellLayer, triggeringLayers);
308 }
309 }
310 }
311
315 public void SizeActiveCells()
316 {
317 while (ActiveCells.Count > Rows)
318 {
319 ActiveCells.RemoveAt(ActiveCells.Count - 1);
320 }
321
322 foreach (var row in ActiveCells)
323 {
324 while (row.Values.Count > Columns)
325 {
326 row.Values.RemoveAt(row.Values.Count - 1);
327 }
328
329 while (row.Values.Count < Columns)
330 {
331 row.Values.Add(true);
332 }
333 }
334
335 while (ActiveCells.Count < Rows)
336 {
337 ActiveCells.Add(new ActiveCellsRow(Columns, true));
338 }
339 }
340
349 public bool SetCellActivities(Vector2Int startIndex, Vector2Int endIndex, CellActivity activity)
350 {
351 if (activity == CellActivity.None || !CellIndexRangeExists(startIndex, endIndex))
352 return false;
353
354 var startRow = Mathf.Min(startIndex.x, endIndex.x);
355 var endRow = Mathf.Max(startIndex.x, endIndex.x);
356 var startColumn = Mathf.Min(startIndex.y, endIndex.y);
357 var endColumn = Mathf.Max(startIndex.y, endIndex.y);
358
359 for (int i = startRow; i <= endRow; i++)
360 {
361 for (int j = startColumn; j <= endColumn; j++)
362 {
363 SetCellActivity(i, j, activity);
364 }
365 }
366
367 return true;
368 }
369
378 public void SetCellActivity(int row, int column, CellActivity activity)
379 {
380 if (!CellIndexExists(row, column))
381 throw new System.IndexOutOfRangeException($"Index out of range: ({row}, {column})");
382
383 switch (activity)
384 {
385 case CellActivity.None:
386 break;
387 case CellActivity.Activate:
388 ActiveCells[row].Values[column] = true;
389 break;
390 case CellActivity.Deactivate:
391 ActiveCells[row].Values[column] = false;
392 break;
393 case CellActivity.Toggle:
394 ActiveCells[row].Values[column] = !ActiveCells[row].Values[column];
395 break;
396 default:
397 throw new System.NotImplementedException($"Unhandled cell activity: {activity}.");
398 }
399 }
400
408 public void SetCellActivity(int row, int column, bool activity)
409 {
410 if (!CellIndexExists(row, column))
411 throw new System.IndexOutOfRangeException($"Index out of range: ({row}, {column})");
412
413 ActiveCells[row].Values[column] = activity;
414 }
415
422 public bool GetCellActivity(int row, int column)
423 {
424 if (!CellIndexExists(row, column))
425 throw new System.IndexOutOfRangeException($"Index out of range: ({row}, {column})");
426
427 return ActiveCells[row].Values[column];
428 }
429
435 public bool CellIndexExists(int row, int column)
436 {
437 return (uint)row < (uint)Rows && (uint)column < (uint)Columns;
438 }
439
445 public bool CellIndexRangeExists(Vector2Int startIndex, Vector2Int endIndex)
446 {
447 return CellIndexExists(startIndex.x, startIndex.y) && CellIndexExists(endIndex.x, endIndex.y);
448 }
449
453 public int AutoAssign()
454 {
455 Size = Size;
456 var children = GetComponentsInChildren<CellChild>();
457
458 foreach (var child in children)
459 {
460 child.AutoAssign(this);
461 }
462
463 return children.Length;
464 }
465
470 public Quaternion GetCellViewDirection()
471 {
472 switch (RoomType)
473 {
474 case RoomType.TwoDimensional:
475 case RoomType.ThreeDimensionalXY:
476 return Quaternion.Euler(0, 0, 0);
477 case RoomType.ThreeDimensionalXZ:
478 return Quaternion.Euler(90, 0, 0);
479 default:
480 throw new System.ArgumentException($"Unhandled room type: {RoomType}.");
481 }
482 }
483
487 public Vector3 CenterGridPosition()
488 {
489 return new Vector3(Columns * CellSize.x, Rows * CellSize.y, CellSize.z) * 0.5f;
490 }
491
495 public Vector3 CenterLocalPosition()
496 {
498 }
499
503 public Vector3 CenterGlobalPosition()
504 {
505 return CenterLocalPosition() + transform.position;
506 }
507
512 public Vector3 LocalCellSize()
513 {
514 switch (RoomType)
515 {
516 case RoomType.TwoDimensional:
517 case RoomType.ThreeDimensionalXY:
518 return CellSize;
519 case RoomType.ThreeDimensionalXZ:
520 return new Vector3(CellSize.x, CellSize.z, CellSize.y);
521 default:
522 throw new System.ArgumentException($"Unhandled room type: {RoomType}.");
523 }
524 }
525
531 public Vector3 GridToLocalPosition(Vector3 gridPosition)
532 {
533 switch (RoomType)
534 {
535 case RoomType.TwoDimensional:
536 case RoomType.ThreeDimensionalXY:
537 return new Vector3(gridPosition.x, -gridPosition.y, -gridPosition.z);
538 case RoomType.ThreeDimensionalXZ:
539 return new Vector3(gridPosition.x, gridPosition.z, -gridPosition.y);
540 default:
541 throw new System.ArgumentException($"Unhandled room type: {RoomType}.");
542 }
543 }
544
550 public Vector3 LocalToGridPosition(Vector3 localPosition)
551 {
552 switch (RoomType)
553 {
554 case RoomType.TwoDimensional:
555 case RoomType.ThreeDimensionalXY:
556 return new Vector3(localPosition.x, -localPosition.y, -localPosition.z);
557 case RoomType.ThreeDimensionalXZ:
558 return new Vector3(localPosition.x, -localPosition.z, localPosition.y);
559 default:
560 throw new System.ArgumentException($"Unhandled room type: {RoomType}.");
561 }
562 }
563
569 public Vector3 GlobalToGridPosition(Vector3 globalPosition)
570 {
571 return LocalToGridPosition(globalPosition - transform.position);
572 }
573
579 public Vector3 CellCenterGridPosition(int row, int column)
580 {
581 return new Vector3(CellSize.x * column, CellSize.y * row, 0) + 0.5f * CellSize;
582 }
583
589 public Vector3 CellCenterGlobalPosition(int row, int column)
590 {
591 return CellCenterLocalPosition(row, column) + transform.position;
592 }
593
599 public Vector3 CellCenterLocalPosition(int row, int column)
600 {
601 return GridToLocalPosition(CellCenterGridPosition(row, column));
602 }
603
609 public Vector2Int GridPositionToCellIndex(Vector3 position)
610 {
611 var row = Mathf.FloorToInt(position.y / CellSize.y);
612 var column = Mathf.FloorToInt(position.x / CellSize.x);
613
614 if (CellIndexExists(row, column))
615 return new Vector2Int(row, column);
616
617 return new Vector2Int(-1, -1);
618 }
619
625 public Vector2Int LocalPositionToCellIndex(Vector3 position)
626 {
628 }
629
635 public Vector2Int GlobalPositionToCellIndex(Vector3 position)
636 {
637 return LocalPositionToCellIndex(position - transform.position);
638 }
639
645 public RoomTemplate GetMMRoomTemplate(int id, string name)
646 {
647 var cells = GetMMCells();
648 AddMMDoors(cells);
649 AddMMFeatures(cells);
650 var spots = GetMMCollectableSpots();
651 var template = new RoomTemplate(id, name, cells, spots);
652 template.Validate();
654 return template;
655 }
656
660 private Array2D<Cell> GetMMCells()
661 {
662 var cells = new Array2D<Cell>(Rows, Columns);
663
664 for (int i = 0; i < cells.Rows; i++)
665 {
666 for (int j = 0; j < cells.Columns; j++)
667 {
668 if (GetCellActivity(i, j))
669 cells[i, j] = Cell.New;
670 }
671 }
672
673 return cells;
674 }
675
680 private void AddMMDoors(Array2D<Cell> cells)
681 {
682 foreach (var door in GetComponentsInChildren<DoorComponent>())
683 {
684 var cell = cells[door.Row, door.Column];
685 cell.SetDoor(door.Direction, door.GetMMDoor());
686 }
687 }
688
693 private void AddMMFeatures(Array2D<Cell> cells)
694 {
695 foreach (var feature in GetComponentsInChildren<Feature>())
696 {
697 var cell = cells[feature.Row, feature.Column];
698 cell.AddFeature(feature.Name);
699 }
700 }
701
705 private Dictionary<int, CollectableSpot> GetMMCollectableSpots()
706 {
707 var spots = GetComponentsInChildren<CollectableSpotComponent>();
708 var result = new Dictionary<int, CollectableSpot>(spots.Length);
709
710 foreach (var spot in spots)
711 {
712 result.Add(spot.Id, spot.GetMMCollectableSpot());
713 }
714
715 return result;
716 }
717
722 public void ValidateRoomFlags()
723 {
724 var set = new HashSet<int>();
725
726 foreach (var flag in GetComponentsInChildren<RoomFlag>())
727 {
728 if (!set.Add(flag.Id))
729 throw new DuplicateIdException($"Duplicate room flag ID {flag.Id} for object {flag}.");
730 }
731 }
732
737 public Vector2Int FindClosestActiveCellIndex(Vector3 position)
738 {
739 var fastIndex = GlobalPositionToCellIndex(position);
740
741 if (CellIndexExists(fastIndex.x, fastIndex.y) && GetCellActivity(fastIndex.x, fastIndex.y))
742 return fastIndex;
743
744 var index = Vector2Int.zero;
745 var minDistance = float.PositiveInfinity;
746 var gridPosition = GlobalToGridPosition(position);
747
748 for (int i = 0; i < Rows; i++)
749 {
750 for (int j = 0; j < Columns; j++)
751 {
752 if (GetCellActivity(i, j))
753 {
754 Vector2 delta = CellCenterGridPosition(i, j) - gridPosition;
755 var distance = delta.sqrMagnitude;
756
757 if (distance < minDistance)
758 {
759 minDistance = distance;
760 index = new Vector2Int(i, j);
761 }
762 }
763 }
764 }
765
766 return index;
767 }
768
775 public DoorDirection FindClosestDoorDirection(int row, int column, Vector3 position)
776 {
777 System.Span<DoorDirection> directions = stackalloc DoorDirection[]
778 {
779 DoorDirection.North,
780 DoorDirection.East,
781 DoorDirection.South,
782 DoorDirection.West,
783 DoorDirection.Top,
784 DoorDirection.Bottom,
785 };
786
787 System.Span<Vector3> vectors = stackalloc Vector3[]
788 {
789 new Vector3(0, -1, 0),
790 new Vector3(1, 0, 0),
791 new Vector3(0, 1, 0),
792 new Vector3(-1, 0, 0),
793 new Vector3(0, 0, 1),
794 new Vector3(0, 0, -1),
795 };
796
797 var index = 0;
798 var maxDistance = float.NegativeInfinity;
799 var count = RoomType == RoomType.TwoDimensional ? 4 : vectors.Length;
800 var delta = GlobalToGridPosition(position) - CellCenterGridPosition(row, column);
801 delta.x /= CellSize.x;
802 delta.y /= CellSize.y;
803 delta.z /= CellSize.z;
804
805 for (int i = 0; i < count; i++)
806 {
807 var distance = Vector3.Dot(delta, vectors[i]);
808
809 if (distance > maxDistance)
810 {
811 maxDistance = distance;
812 index = i;
813 }
814 }
815
816 return directions[index];
817 }
818 }
819}
The base class for cell trigger areas.
Definition: CellArea.cs:9
static CellArea InstantiateCellArea(int row, int column, RoomComponent room, int cellLayer, LayerMask triggeringLayers)
Instantiates a new cell area within the specified room.
Definition: CellArea.cs:34
A manager for maintaining the current map data and state.
Definition: LayoutPack.cs:12
LayoutState LayoutState
The layout state.
Definition: LayoutPack.cs:21
ManiaMapSettings Settings
The applied settings.
Definition: LayoutPack.cs:26
LayerMask TriggeringLayers
The physics layers that trigger room cell area triggers.
int CellLayer
The physics layer assigned to room cell area triggers.
A component for creating a room.
Vector3 GridToLocalPosition(Vector3 gridPosition)
Converts the specified grid coordinate to local coordinates.
bool CellIndexExists(int row, int column)
Returns true if the cell index exists.
Vector3 CenterGlobalPosition()
Returns the center of the cell grid in global coordinates.
Vector3 LocalCellSize()
Returns the cell size in local coordinates.
static AsyncOperationHandle< GameObject > InstantiateRoomAsync(AssetReferenceGameObject prefab, Transform parent, LayoutPack layoutPack, Room roomLayout, RoomState roomState, int cellLayer, LayerMask triggeringLayers, bool assignLayoutPosition)
Instantiates and initializes a room asynchronously. Returns the operation handle.
void SetCellActivity(int row, int column, bool activity)
Sets the cell activity for the specified index.
void SizeActiveCells()
Sizes the active cells list to match the room size.
int AutoAssign()
Runs auto assign on the room's cell children. Returns the number of children.
Vector2Int GridPositionToCellIndex(Vector3 position)
Converts the specified grid position to the containing cell index. If the cell index does not exist,...
void MoveToLayoutPosition()
Sets the room's local position to its position in the layout.
static RoomComponent InstantiateRoom(GameObject prefab, Transform parent, LayoutPack layoutPack, Room roomLayout, RoomState roomState, int cellLayer, LayerMask triggeringLayers, bool assignLayoutPosition)
Instantiates and initializes a room and returns it.
bool Initialize(LayoutPack layoutPack, Room roomLayout, RoomState roomState, int cellLayer, LayerMask triggeringLayers, bool assignLayoutPosition)
Initializes the room. Returns false if the room has already been initialized.
UnityEvent OnInitialize
An event invoked when the room is initialized.
Vector2Int GlobalPositionToCellIndex(Vector3 position)
Converts the specified global position to the containing cell index. If the cell index does not exist...
Vector3 CenterLocalPosition()
Returns the center of the cell grid in local coordinates.
Array2D< Cell > GetMMCells()
Returns the Mania Map cells used by the procedural generator.
Dictionary< int, CollectableSpot > GetMMCollectableSpots()
Returns the Mania Map collectable spots by ID.
Vector2Int LocalPositionToCellIndex(Vector3 position)
Converts the specified local position to the containing cell index. If the cell index does not exist,...
Vector3 LocalToGridPosition(Vector3 localPosition)
Converts the specified local coordinate to grid coordinates.
static RoomComponent InstantiateRoom(Uid id, LayoutPack layoutPack, GameObject prefab, Transform parent=null, bool assignLayoutPosition=false)
Instantiates and initializes a room and returns it.
Vector3 CellCenterGridPosition(int row, int column)
Returns the cell center for the specified index in grid coordinates.
UnityEvent OnInitialized
The event invoked after the room has completed initialization.
Vector3 CellCenterLocalPosition(int row, int column)
Returns the cell center for the specified index in local coordinates.
void AddMMFeatures(Array2D< Cell > cells)
Adds the cell features to the cells array.
Vector2Int Size
The size of the room grid in rows (x) and columns (y).
void AddMMDoors(Array2D< Cell > cells)
Adds the Mania Map doors to the cells array.
Vector3 CellSize
The size of each cell within the grid coordinate system.
bool CellIndexRangeExists(Vector2Int startIndex, Vector2Int endIndex)
Returns true if both cell indexes exist.
RoomTemplateResource RoomTemplate
The room template.
void DrawCells(Color fillColor, Color lineColor, bool activity)
Draws the cell cube gizmos for the specified cell activity.
void ValidateRoomFlags()
Validates that the room flag ID's are unique.
DoorDirection FindClosestDoorDirection(int row, int column, Vector3 position)
Returns the closest door direction based on the specified global position.
CellAreaTriggerEvent OnCellAreaEntered
The event invoked when a room cell has been entered. Message includes the enterered cell and the coll...
Vector3 CenterGridPosition()
Returns the center of the cell grid in grid coordinates.
RoomState RoomState
The room state.
bool SetCellActivities(Vector2Int startIndex, Vector2Int endIndex, CellActivity activity)
Sets the cell activities for the specified index range. No action is taken if one of the indexes is o...
void SetCellActivity(int row, int column, CellActivity activity)
Sets the cell activity for the specified index.
Vector2Int FindClosestActiveCellIndex(Vector3 position)
Returns the closest active cell index for the specified global position.
bool IsInitialized
True if the room has been initialized.
Quaternion GetCellViewDirection()
Returns the quaternion angle perpendicular to the cell plane.
RoomTemplate GetMMRoomTemplate(int id, string name)
Returns the Mania Map room template used by the procedural generator.
List< ActiveCellsRow > ActiveCells
A list of active cell rows.
CellAreaTriggerEvent OnCellAreaExited
The event invoked when a room cell has been exited. Message includes the exited cell and the collidin...
Vector3 GlobalToGridPosition(Vector3 globalPosition)
Converts the specified global position to grid coordinates.
Vector3 CellCenterGlobalPosition(int row, int column)
Returns the cell center for the specified index in global coordinates.
bool GetCellActivity(int row, int column)
Returns the cell activity for the specified index.
void CreateCellAreas(int cellLayer, LayerMask triggeringLayers)
Creates the cell area triggers as children of the room.
static AsyncOperationHandle< GameObject > InstantiateRoomAsync(Uid id, LayoutPack layoutPack, AssetReferenceGameObject prefab, Transform parent=null, bool assignLayoutPosition=false)
Instantiates and initializes a room asynchronously. Returns the operation handle.
A container for storing a serialized room template.
CellActivity
The cell activity.
Definition: CellActivity.cs:7
RoomType
The type of room.
Definition: RoomType.cs:9
The row of the RoomComponent active cells list.