/** * Computes the 'intensity' of each {@link MZRoom}. MZRooms generally Get more * intense the deeper they are into the dungeon. * * @param levels the keyLevel -> room-set mapping to update * @ if it fails * @see KeyLevelRoomMapping * @see MZRoom */ protected void ComputeIntensity(KeyLevelRoomMapping levels) { double nextLevelBaseIntensity = 0.0; for (int level = 0; level < levels.KeyCount(); ++level) { double intensity = nextLevelBaseIntensity * (1.0 - intensityEaseOff); foreach (MZRoom room in levels.GetRooms(level)) { if (room.GetParent() == null || !room.GetParent().GetPrecond(). Implies(room.GetPrecond())) { nextLevelBaseIntensity = Math.Max( nextLevelBaseIntensity, ApplyIntensity(room, intensity)); } } } NormalizeIntensity(); dungeon.FindBoss().SetIntensity(1.0); MZRoom goalRoom = dungeon.FindGoal(); if (goalRoom != null) { goalRoom.SetIntensity(0.0); } }
public void Add(MZRoom room) { rooms[room.id] = room; foreach (Vector2Int xy in room.GetCoords()) { if (xy.x < bounds.Left) { bounds = new MZRect(xy.x, bounds.Top, bounds.Right, bounds.Bottom); } if (xy.x >= bounds.Right) { bounds = new MZRect(bounds.Left, bounds.Top, xy.x + 1, bounds.Bottom); } if (xy.y < bounds.Top) { bounds = new MZRect(bounds.Left, xy.y, bounds.Right, bounds.Bottom); } if (xy.y >= bounds.Bottom) { bounds = new MZRect(bounds.Left, bounds.Top, bounds.Right, xy.y + 1); } } }
/** * Removes the given {@link MZRoom} and all its descendants from the given * list. * * @param rooms the list of MZRooms to remove nodes from * @param room the MZRoom whose descendants to remove from the list */ protected void RemoveDescendantsFromList(List <MZRoom> rooms, MZRoom room) { rooms.Remove(room); foreach (MZRoom child in room.GetChildren()) { RemoveDescendantsFromList(rooms, child); } }
/** * Adds extra conditions to the given {@link MZRoom}'s preconditions and all * of its descendants. * * @param room the MZRoom to Add extra preconditions to * @param cond the extra preconditions to Add */ protected void AddPrecond(MZRoom room, MZCondition cond) { room.SetPrecond(room.GetPrecond().And(cond)); foreach (MZRoom child in room.GetChildren()) { AddPrecond(child, cond); } }
/** * Fill the dungeon's space with rooms and doors (some locked). * Keys are not inserted at this point. * * @param levels the keyLevel -> room-set mapping to update * @ if it fails * @see KeyLevelRoomMapping */ protected void PlaceRooms(KeyLevelRoomMapping levels, int roomsPerLock) { // keyLevel: the number of keys required to Get to the new room int keyLevel = 0; MZSymbol latestKey = null; // condition that must hold true for the player to reach the new room // (the set of keys they must have). MZCondition cond = new MZCondition(); // Loop to place rooms and link them while (dungeon.RoomCount() < constraints.GetMaxRooms()) { bool doLock = false; // Decide whether we need to place a new lock // (Don't place the last lock, since that's reserved for the boss) if (ShouldAddNewLock(keyLevel, levels.GetRooms(keyLevel).Count, roomsPerLock)) { latestKey = new MZSymbol(keyLevel++); cond = cond.And(latestKey); doLock = true; } // Find an existing room with a free edge: MZRoom parentRoom = null; if (!doLock && UnityEngine.Random.Range(0, 10) > 0) { parentRoom = ChooseRoomWithFreeEdge(levels.GetRooms(keyLevel), keyLevel); } if (parentRoom == null) { parentRoom = ChooseRoomWithFreeEdge(new List <MZRoom>(dungeon.GetRooms()), keyLevel); doLock = true; } if (parentRoom == null) { throw new OutOfRoomsException(); } // Decide which direction to put the new room in relative to the // parent int nextId = ChooseFreeEdge(parentRoom, keyLevel); List <Vector2Int> coords = constraints.GetCoords(nextId); MZRoom room = new MZRoom(nextId, coords, parentRoom, null, cond); // Add the room to the dungeon dungeon.Add(room); parentRoom.AddChild(room); dungeon.Link(parentRoom, room, doLock ? latestKey : null); levels.AddRoom(keyLevel, room); } }
/** * Returns a path from the goal to the dungeon entrance, along the 'parent' * relations. * * @return a list of linked {@link MZRoom}s starting with the goal room and * ending with the start room. */ protected List <MZRoom> GetSolutionPath() { List <MZRoom> solution = new List <MZRoom>(); MZRoom room = dungeon.FindGoal(); while (room != null) { solution.Add(room); room = room.GetParent(); } return(solution); }
/** * Sets up the dungeon's entrance room. * * @param levels the keyLevel -> room-set mapping to update * @see KeyLevelRoomMapping */ protected void InitEntranceRoom(KeyLevelRoomMapping levels) { int id; List <int> possibleEntries = new List <int>(constraints.InitialRooms()); id = possibleEntries[UnityEngine.Random.Range(0, possibleEntries.Count)]; MZRoom entry = new MZRoom(id, constraints.GetCoords(id), null, new MZSymbol((int)MZSymbol.MZSymbolValue.Start), new MZCondition()); dungeon.Add(entry); levels.AddRoom(0, entry); }
/** * Randomly chooses a {@link Direction} in which the given {@link MZRoom} has * an adjacent empty space. * * @param room the room * @return the Direction of the empty space chosen adjacent to the MZRoom or * null if there are no adjacent empty spaces */ protected int ChooseFreeEdge(MZRoom room, int keyLevel) { List <KeyValuePair <Double, int> > neighbors = new List <KeyValuePair <Double, int> >( constraints.GetAdjacentRooms(room.id, keyLevel)); Shuffle(neighbors); while (neighbors.Count > 0) { int choice = neighbors[0].Value; if (dungeon.Get(choice) == null) { return(choice); } neighbors.RemoveAt(0); } throw new MZGenerationFailureException("Internal error: MZRoom doesn't have a free edge"); }
/** * Creates a MZRoom at the given coordinates, with the given parent, * containing a specific item, and having a certain pre-{@link MZCondition}. * <p> * The parent of a room is the parent node of this MZRoom in the initial * tree of the dungeon during * {@link generators.MZDungeonGenerator#Generate()}, and * before * {@link generators.MZDungeonGenerator#Graphify()}. * * @param coords the coordinates of the new room * @param parent the parent room or null if it is the root / entry room * @param item the symbol to place in the room or null if no item * @param precond the precondition of the room * @see MZCondition */ public MZRoom(int id, List <Vector2Int> coords, MZRoom parent, MZSymbol item, MZCondition precond) { this.id = id; this.coords = coords; this.item = item; this.edges = new List <MZEdge>(); this.precond = precond; this.intensity = 0.0; this.parent = parent; this.children = new List <MZRoom>(3); // all edges initially null int x = 0, y = 0; foreach (Vector2Int xy in coords) { x += xy.x; y += xy.y; } center = new Vector2Int(x / coords.Count, y / coords.Count); }
/** * Recursively applies the given intensity to the given {@link MZRoom}, and * higher intensities to each of its descendants that are within the same * keyLevel. * <p> * Intensities set by this method may (will) be outside of the normal range * from 0.0 to 1.0. See {@link #NormalizeIntensity} to correct this. * * @param room the room to set the intensity of * @param intensity the value to set intensity to (some randomn variance is * Added) * @see MZRoom */ protected double ApplyIntensity(MZRoom room, double intensity) { intensity *= 1.0 - intensityGrowthJitter / 2.0 + intensityGrowthJitter * UnityEngine.Random.value; room.SetIntensity(intensity); double maxIntensity = intensity; foreach (MZRoom child in room.GetChildren()) { if (room.GetPrecond().Implies(child.GetPrecond())) { maxIntensity = Math.Max(maxIntensity, ApplyIntensity(child, intensity + 1.0)); } } return(maxIntensity); }
/** * Randomly chooses a {@link MZRoom} within the given collection that has at * least one adjacent empty space. * * @param roomCollection the collection of rooms to choose from * @return the room that was chosen, or null if there are no rooms with * adjacent empty spaces */ protected MZRoom ChooseRoomWithFreeEdge(List <MZRoom> roomCollection, int keyLevel) { List <MZRoom> rooms = new List <MZRoom>(roomCollection); Shuffle(rooms); for (int i = 0; i < rooms.Count; ++i) { MZRoom room = rooms[i]; foreach (KeyValuePair <Double, int> next in constraints.GetAdjacentRooms(room.id, keyLevel)) { if (dungeon.Get(next.Value) == null) { return(room); } } } return(null); }
/** * Randomly locks descendant rooms of the given {@link MZRoom} with * {@link MZEdge}s that require the switch to be in the given state. * <p> * If the given state is Either, the required states will be random. * * @param room the room whose child to lock * @param givenState the state to require the switch to be in for the * child rooms to be accessible * @return true if any locks were Added, false if none were * Added (which can happen due to the way the random * decisions are made) * @see MZCondition.SwitchState */ protected bool SwitchLockChildRooms(MZRoom room, MZCondition.SwitchState givenState) { bool anyLocks = false; MZCondition.SwitchState state = givenState != MZCondition.SwitchState.Either ? givenState : (UnityEngine.Random.Range(0, 2) == 0 ? MZCondition.SwitchState.On : MZCondition.SwitchState.Off); foreach (MZEdge edge in room.GetEdges()) { int neighborId = edge.GetTargetRoomId(); MZRoom nextRoom = dungeon.Get(neighborId); if (room.GetChildren().Contains(nextRoom)) { if (room.GetEdge(neighborId).GetSymbol() == null && UnityEngine.Random.Range(0, 4) != 0) { dungeon.Link(room, nextRoom, state.ToSymbol()); AddPrecond(nextRoom, new MZCondition(state.ToSymbol())); anyLocks = true; } else { anyLocks |= SwitchLockChildRooms(nextRoom, state); } if (givenState == MZCondition.SwitchState.Either) { state = state.Invert(); } } } return(anyLocks); }
/** * Randomly links up some adjacent rooms to make the dungeon graph less of * a tree. * * @ if it fails */ protected void Graphify() { foreach (MZRoom room in dungeon.GetRooms()) { if (room.IsGoal() || room.IsBoss()) { continue; } foreach (KeyValuePair <Double, int> next in // Doesn't matter what the keyLevel is; later checks about // preconds ensure linkage doesn't trivialize the puzzle. constraints.GetAdjacentRooms(room.id, Int32.MaxValue)) { int nextId = next.Value; if (room.GetEdge(nextId) != null) { continue; } MZRoom nextRoom = dungeon.Get(nextId); if (nextRoom == null || nextRoom.IsGoal() || nextRoom.IsBoss()) { continue; } if (room.GetCoords()[0].x == -1 && room.GetCoords()[0].y == -3) { //Debug.Log(nextRoom.GetCoords()[0].x + " " + nextRoom.GetCoords()[0].y); Debug.Log(room.GetEdges().Count); } bool forwardImplies = room.GetPrecond().Implies(nextRoom.GetPrecond()), backwardImplies = nextRoom.GetPrecond().Implies(room.GetPrecond()); if (forwardImplies && backwardImplies) { // both rooms are at the same keyLevel. if (UnityEngine.Random.value >= constraints.EdgeGraphifyProbability(room.id, nextRoom.id)) { continue; } dungeon.Link(room, nextRoom); } else { MZSymbol difference = room.GetPrecond().SingleSymbolDifference( nextRoom.GetPrecond()); if (difference == null || (!difference.IsSwitchState() && UnityEngine.Random.value >= constraints.EdgeGraphifyProbability(room.id, nextRoom.id))) { continue; } dungeon.Link(room, nextRoom, difference); } } } }
/** * Makes some {@link MZEdge}s within the dungeon require the dungeon's switch * to be in a particular state, and places the switch in a room in the * dungeon. * * @ if it fails */ protected void PlaceSwitches() { // Possible TODO: have multiple switches on separate circuits // At the moment, we only have one switch per dungeon. if (constraints.GetMaxSwitches() <= 0) { return; } List <MZRoom> solution = GetSolutionPath(); for (int attempt = 0; attempt < 10; ++attempt) { List <MZRoom> rooms = new List <MZRoom>(dungeon.GetRooms()); Shuffle(rooms); Shuffle(solution); // Pick a base room from the solution path so that the player // will have to encounter a switch-lock to solve the dungeon. MZRoom baseRoom = null; foreach (MZRoom room in solution) { if (room.GetChildren().Count > 1 && room.GetParent() != null) { baseRoom = room; break; } } if (baseRoom == null) { throw new RetryException(); } MZCondition baseRoomCond = baseRoom.GetPrecond(); RemoveDescendantsFromList(rooms, baseRoom); MZSymbol switchSym = new MZSymbol((int)MZSymbol.MZSymbolValue.Switch); MZRoom switchRoom = null; foreach (MZRoom room in rooms) { if (room.GetItem() == null && baseRoomCond.Implies(room.GetPrecond()) && constraints.RoomCanFitItem(room.id, switchSym)) { switchRoom = room; break; } } if (switchRoom == null) { continue; } if (SwitchLockChildRooms(baseRoom, MZCondition.SwitchState.Either)) { switchRoom.SetItem(switchSym); return; } } throw new RetryException(); }
public MZRoom(int id, Vector2Int coords, MZRoom parent, MZSymbol item, MZCondition precond) : this(id, new List <Vector2Int> { coords }, parent, item, precond) { }
public void Link(MZRoom room1, MZRoom room2) { Link(room1, room2, null); }
/* * private int keyLevel; * * public AStarClient(int keyLevel) * { * this.keyLevel = keyLevel; * } * * public override List<int> GetNeighbors(int roomId) * { * List<int> ids = new List<int>(); * foreach (MZEdge edge in dungeon.Get(roomId).GetEdges()) * { * if (!edge.HasSymbol() || edge.GetSymbol().GetValue() < keyLevel) * { * ids.Add(edge.GetTargetRoomId()); * } * } * return ids; * } * public override Vector2Int GetVector2Int(int roomId) * { * return dungeon.Get(roomId).GetCenter(); * } * } */ /* * private List<int> AStar(int start, int goal, int keyLevel) * { * AStar<int> astar = new AStar<int>(); * return astar.Solve(); * } */ /** * Nonlinearity is measured as the number of rooms the player would have to * pass through multiple times to Get to the goal room (collecting keys and * unlocking doors along the way). * * Uses A* to find a path from the entry to the first key, from each key to * the next key and from the last key to the goal. * * @return The number of rooms passed through multiple times **/ public int MeasureNonlinearity() { List <MZRoom> keyRooms = new List <MZRoom>(constraints.GetMaxKeys()); for (int i = 0; i < constraints.GetMaxKeys(); ++i) { keyRooms.Add(null); } foreach (MZRoom room in dungeon.GetRooms()) { if (room.GetItem() == null) { continue; } MZSymbol item = room.GetItem(); if (item.GetValue() >= 0 && item.GetValue() < keyRooms.Count) { keyRooms.Insert(item.GetValue(), room); } } //for N >= 0: keyRooms[N] = location of key N MZRoom current = dungeon.FindStart(), goal = dungeon.FindGoal(); //clients may disable generation of the goal room if redundant, in which case the equivalent 'ending' room becomes the boss room if (goal == null) { goal = dungeon.FindBoss(); } Debug.Assert(current != null && goal != null); int nextKey = 0, nonlinearity = 0; List <int> visitedRooms = new List <int>(); while (current != goal) { MZRoom intermediateGoal; //Debug.Log("Current room ID: " + current.id); //Debug.Log("Max Keys:" + constraints.GetMaxKeys()); //Debug.Log("Next Key: " + nextKey); if (nextKey == constraints.GetMaxKeys()) { intermediateGoal = goal; } else { intermediateGoal = keyRooms[nextKey]; } //Debug.Log("Current goal ID: " + intermediateGoal.id); ///* //Debug.Log("Dungeon: " + dungeon.GetType()); //*/ //Debug.Log("A* running..."); List <int> steps = astar(current.id, intermediateGoal.id, nextKey, dungeon); //ちゃんとこれを作ってよ //Debug.Log("Reversing steps!"); steps.Reverse(); foreach (int id in steps) { Debug.Log("Visited Room: " + id); if (visitedRooms.Contains(id)) { ++nonlinearity; } } visitedRooms.AddRange(steps); nextKey++; current = dungeon.Get(steps[0]); MZRoom test = current; } return(nonlinearity); }
/** * Places the BOSS and GOAL rooms within the dungeon, in existing rooms. * These rooms are moved into the next keyLevel. * * @param levels the keyLevel -> room-set mapping to update * @ if it fails * @see KeyLevelRoomMapping */ protected void PlaceBossGoalRooms(KeyLevelRoomMapping levels) { List <MZRoom> possibleGoalRooms = new List <MZRoom>(dungeon.RoomCount()); MZSymbol goalSym = new MZSymbol((int)MZSymbol.MZSymbolValue.Goal), bossSym = new MZSymbol((int)MZSymbol.MZSymbolValue.Boss); foreach (MZRoom room in dungeon.GetRooms()) { if (room.GetChildren().Count > 0 || room.GetItem() != null) { continue; } MZRoom parent = room.GetParent(); if (parent == null) { continue; } if (IsGenerateGoal() && (parent.GetChildren().Count != 1 || !parent.GetPrecond().Implies(room.GetPrecond()))) { continue; } if (IsGenerateGoal()) { if (!constraints.RoomCanFitItem(room.id, goalSym) || !constraints.RoomCanFitItem(parent.id, bossSym)) { continue; } } else { if (!constraints.RoomCanFitItem(room.id, bossSym)) { continue; } } possibleGoalRooms.Add(room); } if (possibleGoalRooms.Count == 0) { throw new RetryException(); } MZRoom goalRoom = possibleGoalRooms[UnityEngine.Random.Range(0, possibleGoalRooms.Count)], bossRoom = goalRoom.GetParent(); if (!IsGenerateGoal()) { bossRoom = goalRoom; goalRoom = null; } if (goalRoom != null) { goalRoom.SetItem(goalSym); } bossRoom.SetItem(bossSym); int oldKeyLevel = bossRoom.GetPrecond().GetKeyLevel(), newKeyLevel = Math.Min(levels.KeyCount(), constraints.GetMaxKeys()); if (oldKeyLevel != newKeyLevel) { List <MZRoom> oklRooms = levels.GetRooms(oldKeyLevel); if (goalRoom != null) { oklRooms.Remove(goalRoom); } oklRooms.Remove(bossRoom); if (goalRoom != null) { levels.AddRoom(newKeyLevel, goalRoom); } levels.AddRoom(newKeyLevel, bossRoom); MZSymbol bossKey = new MZSymbol(newKeyLevel - 1); MZCondition precond = bossRoom.GetPrecond().And(bossKey); bossRoom.SetPrecond(precond); if (goalRoom != null) { goalRoom.SetPrecond(precond); } if (newKeyLevel == 0) { dungeon.Link(bossRoom.GetParent(), bossRoom); } else { dungeon.Link(bossRoom.GetParent(), bossRoom, bossKey); } if (goalRoom != null) { dungeon.Link(bossRoom, goalRoom); } } }
public bool RoomsAreLinked(MZRoom room1, MZRoom room2) { return(room1.GetEdge(room2.id) != null || room2.GetEdge(room1.id) != null); }
/** * Registers this MZRoom as a parent of another. * Does not modify the child room's parent property. * * @param child the room to parent */ public void AddChild(MZRoom child) { children.Add(child); }
public void AddRoom(int keyLevel, MZRoom room) { GetRooms(keyLevel).Add(room); }
public void Link(MZRoom room1, MZRoom room2, MZSymbol cond) { LinkOneWay(room1, room2, cond); LinkOneWay(room2, room1, cond); }
public void LinkOneWay(MZRoom room1, MZRoom room2, MZSymbol cond) { room1.SetEdge(room2.id, cond); }
public void CreateDungeon() { float roomRatio = 0.6875f; // 256x176 // Use CountConstraints to make a truly random map. /* * CountConstraints constraints = new CountConstraints((int)maxSpaces, (int)maxKeys, (int)maxSwitches); * Debug.Log("Constraints: " + maxSpaces + "," + maxKeys + "," + maxSwitches); */ // Use SpaceConstraints to make a map fitting to a shape. ///* MZSpaceMap spaceMap = new MZSpaceMap(); //random tile map //tileMap = tileMapObjects[Random.Range(0, tileMapObjects.Length)].GetComponentInChildren<Tilemap>(); tileMap = tileMapObjects[0].GetComponentInChildren <Tilemap>(); foreach (Vector3Int posWithZ in tileMap.cellBounds.allPositionsWithin.GetEnumerator()) { if (tileMap.HasTile(posWithZ)) { Vector2Int pos = new Vector2Int(posWithZ.x, posWithZ.y); spaceMap.Set(pos, true); } } SpaceConstraints constraints = new SpaceConstraints(spaceMap, (int)maxKeys, (int)maxSwitches); //*/ generator = new LinearDungeonGenerator(Random.Range(0, int.MaxValue), constraints, numberOfRooms, (int)maxGenerations); //generator = new DungeonGenerator(Random.Range(0, int.MaxValue), constraints, numberOfRooms); Debug.Log("Generate()"); generator.Generate(); dungeon = generator.GetMZDungeon(); foreach (MZRoom room in dungeon.GetRooms()) { MZSymbol item = room.GetItem(); GameObject toInstantiate = normalRoom; Color roomColor = new Color((float)room.GetIntensity(), 1.0f - (float)room.GetIntensity(), 0.5f - (float)room.GetIntensity() / 2); if (item != null) { switch (item.GetValue()) { case (int)MZSymbol.MZSymbolValue.Start: toInstantiate = entranceRoom; roomColor = Color.white; break; case (int)MZSymbol.MZSymbolValue.Boss: toInstantiate = bossRoom; break; case (int)MZSymbol.MZSymbolValue.Goal: toInstantiate = goalRoom; roomColor = Color.white; break; default: break; } if (item.GetValue() >= 0) { GameObject keyObjectInstance = Instantiate(key, new Vector3(room.GetCoords()[0].x, room.GetCoords()[0].y * roomRatio, 0), Quaternion.identity, transform); keyObjectInstance.GetComponent <SpriteRenderer>().color = keyColors[item.GetValue()]; keyObjectInstance.transform.localScale += new Vector3(2, 2, 2); instances.Add(keyObjectInstance); } else if (item.GetValue() == (int)MZSymbol.MZSymbolValue.Switch) { GameObject keyObjectInstance = Instantiate(roomSwitch, new Vector3(room.GetCoords()[0].x, room.GetCoords()[0].y * roomRatio, 0), Quaternion.identity, transform); keyObjectInstance.transform.localScale += new Vector3(2, 2, 2); instances.Add(keyObjectInstance); } } GameObject roomObject = Instantiate(toInstantiate, new Vector3(room.GetCoords()[0].x, room.GetCoords()[0].y * roomRatio, 0), Quaternion.identity, transform); roomObject.GetComponent <SpriteRenderer>().color = roomColor; instances.Add(roomObject); foreach (MZEdge edge in room.GetEdges()) { MZRoom targetRoom = dungeon.Get(edge.GetTargetRoomId()); Vector2Int edgeDir = targetRoom.GetCoords()[0] - room.GetCoords()[0]; toInstantiate = openDoor; GameObject keyObject = null; Color keyColor = Color.white; if (edge.GetSymbol() != null) { switch (edge.GetSymbol().GetValue()) { case (int)MZSymbol.MZSymbolValue.SwitchOn: toInstantiate = blockedDoor; keyObject = roomSwitchOn; break; case (int)MZSymbol.MZSymbolValue.SwitchOff: toInstantiate = blockedDoor; keyObject = roomSwitchOff; break; default: break; } if (edge.GetSymbol().GetValue() >= 0) { toInstantiate = lockedDoor; keyObject = key; keyColor = keyColors[edge.GetSymbol().GetValue()]; } } //this only works for identically sized rooms Vector3 pos = Vector3.zero; if (edgeDir == Vector2Int.right) { pos = new Vector3(room.GetCoords()[0].x + 0.5f, room.GetCoords()[0].y * roomRatio, 0); GameObject doorObject = Instantiate(toInstantiate, pos, Quaternion.identity, transform); instances.Add(doorObject); if (keyObject != null) { GameObject keyObjectInstance = Instantiate(keyObject, pos, Quaternion.identity, transform); instances.Add(keyObjectInstance); keyObjectInstance.GetComponent <SpriteRenderer>().color = keyColor; keyObjectInstance.transform.localScale += new Vector3(1, 1, 1); } } else if (edgeDir == Vector2Int.down) { pos = new Vector3(room.GetCoords()[0].x, room.GetCoords()[0].y * roomRatio - (roomRatio / 2), 0); Vector2Int relativePos = Vector2Int.zero + Vector2Int.up; float angle = Mathf.Atan2(relativePos.y, relativePos.x) * Mathf.Rad2Deg; Quaternion rotation = Quaternion.AngleAxis(angle, Vector3.forward); //90 degrees GameObject doorObject = Instantiate(toInstantiate, pos, rotation, transform); instances.Add(doorObject); if (keyObject != null) { GameObject keyObjectInstance = Instantiate(keyObject, pos, Quaternion.identity, transform); instances.Add(keyObjectInstance); keyObjectInstance.GetComponent <SpriteRenderer>().color = keyColor; keyObjectInstance.transform.localScale += new Vector3(1, 1, 1); } } } } foreach (var room in dungeon.GetRooms()) { foreach (var edge in room.GetEdges()) { //wrap this up laterino } } }
/** * @param parent the MZRoom to set this MZRoom's parent to * @see MZRoom#Room */ public void SetParent(MZRoom parent) { this.parent = parent; }
public void LinkOneWay(MZRoom room1, MZRoom room2) { LinkOneWay(room1, room2, null); }