public TileProxy(GameObject prefab, bool ignoreSpriteRendererBounds, Vector3 upVector) { prefab.transform.localPosition = Vector3.zero; prefab.transform.localRotation = Quaternion.identity; Prefab = prefab; PrefabTile = prefab.GetComponent <Tile>(); if (PrefabTile == null) { PrefabTile = prefab.AddComponent <Tile>(); } Placement = new TilePlacementData(); // Add proxy doorways Doorways = new ReadOnlyCollection <DoorwayProxy>(doorways); var allDoorways = prefab.GetComponentsInChildren <Doorway>(); for (int i = 0; i < allDoorways.Length; i++) { var doorway = allDoorways[i]; Vector3 localPosition = doorway.transform.position; Quaternion localRotation = doorway.transform.rotation; var proxyDoorway = new DoorwayProxy(this, i, doorway.Socket, localPosition, localRotation); doorways.Add(proxyDoorway); if (PrefabTile.Entrance == doorway) { Entrance = proxyDoorway; } if (PrefabTile.Exit == doorway) { Exit = proxyDoorway; } } // Calculate bounds Bounds bounds; if (PrefabTile != null && PrefabTile.OverrideAutomaticTileBounds) { bounds = PrefabTile.TileBoundsOverride; } else { bounds = UnityUtil.CalculateProxyBounds(Prefab, ignoreSpriteRendererBounds, upVector); } // Let the user know if the automatically calculated bounds are incorrect if (bounds.size.x <= 0f || bounds.size.y <= 0f || bounds.size.z <= 0f) { Debug.LogError(string.Format("Tile prefab '{0}' has automatic bounds that are zero or negative in size. The bounding volume for this tile will need to be manually defined.", prefab), prefab); } Placement.LocalBounds = UnityUtil.CondenseBounds(bounds, Prefab.GetComponentsInChildren <Doorway>()); }
public static void Connect(DoorwayProxy a, DoorwayProxy b) { Debug.Assert(a.ConnectedDoorway == null, "Doorway 'a' is already connected to something"); Debug.Assert(b.ConnectedDoorway == null, "Doorway 'b' is already connected to something"); a.ConnectedDoorway = b; b.ConnectedDoorway = a; }
public void PositionBySocket(DoorwayProxy myDoorway, DoorwayProxy otherDoorway) { Quaternion targetRotation = Quaternion.LookRotation(-otherDoorway.Forward, otherDoorway.Up); Placement.Rotation = targetRotation * Quaternion.Inverse(Quaternion.Inverse(Placement.Rotation) * (Placement.Rotation * myDoorway.LocalRotation)); Vector3 targetPosition = otherDoorway.Position; Placement.Position = targetPosition - (myDoorway.Position - Placement.Position); }
public DoorwayPair(TileProxy previousTile, DoorwayProxy previousDoorway, TileProxy nextTemplate, DoorwayProxy nextDoorway, TileSet nextTileSet, float tileWeight, float doorwayWeight) { PreviousTile = previousTile; PreviousDoorway = previousDoorway; NextTemplate = nextTemplate; NextDoorway = nextDoorway; NextTileSet = nextTileSet; TileWeight = tileWeight; DoorwayWeight = doorwayWeight; }
public void MakeConnection(DoorwayProxy a, DoorwayProxy b) { Debug.Assert(a != null && b != null); Debug.Assert(a != b); Debug.Assert(!a.Used && !b.Used); DoorwayProxy.Connect(a, b); var conn = new ProxyDoorwayConnection(a, b); Connections.Add(conn); }
private bool IsValidDoorwayPairing(DoorwayProxy a, DoorwayProxy b, TileProxy nextTile, ref float weight) { // Enforce matching socket group if (!DoorwaySocket.CanSocketsConnect(a.Socket, b.Socket)) { return(false); } // Enforce facing-direction Vector3?forcedDirection = null; // If AllowRotation has been set to false, or if the tile to be placed disallows rotation, we must force a connection from the correct direction bool disallowRotation = (AllowRotation.HasValue && !AllowRotation.Value) || (nextTile != null && !nextTile.PrefabTile.AllowRotation); // Always enforce facing direction for vertical doorways const float angleEpsilon = 1.0f; if (Vector3.Angle(a.Forward, UpVector) < angleEpsilon) { forcedDirection = -UpVector; } else if (Vector3.Angle(a.Forward, -UpVector) < angleEpsilon) { forcedDirection = UpVector; } else if (disallowRotation) { forcedDirection = -a.Forward; } if (forcedDirection.HasValue) { float angleDiff = Vector3.Angle(forcedDirection.Value, b.Forward); const float maxAngleDiff = 1.0f; if (angleDiff > maxAngleDiff) { return(false); } } weight = CalculateDoorwayWeight(b); return(true); }
private float CalculateDoorwayWeight(DoorwayProxy doorway) { // Assign a random weight initially float weight = (float)RandomStream.NextDouble(); float straightenChance = (Archetype == null) ? 0.0f : Archetype.StraightenChance; bool shouldTryStraighten = straightenChance > 0 && IsOnMainPath && PreviousTile.UsedDoorways.Count() == 1 && PreviousTile.UsedDoorways.First().Forward == -doorway.Forward; if (shouldTryStraighten) { double rnd = RandomStream.NextDouble(); // Heavily scew weight in favour of picking doorways that would continue the dungeon in a straight line if (rnd < straightenChance) { weight *= 100; } } return(weight); }
public TileProxy(TileProxy existingTile) { Prefab = existingTile.Prefab; PrefabTile = existingTile.PrefabTile; Placement = new TilePlacementData(existingTile.Placement); // Copy proxy doorways Doorways = new ReadOnlyCollection <DoorwayProxy>(doorways); foreach (var existingDoorway in existingTile.doorways) { var doorway = new DoorwayProxy(this, existingDoorway.Index, existingDoorway.Socket, existingDoorway.LocalPosition, existingDoorway.LocalRotation); doorways.Add(doorway); if (existingTile.Entrance == existingDoorway) { Entrance = doorway; } if (existingTile.Exit == existingDoorway) { Exit = doorway; } } }
public ProxyDoorwayConnection(DoorwayProxy a, DoorwayProxy b) { A = a; B = b; }