public bool CanBeConnectedAndSpawned(TileConnector myConnector, TileConnector otherConnector, out BareTransform targetTransform) { Debug.Assert(connectors.Contains(myConnector)); var bounds = this.physicalBounds; // Allow for marginal overlap const float minExtent = 0.5f; bounds.extents = new Vector3 { x = Mathf.Max(minExtent, bounds.extents.x - 0.5f), y = Mathf.Max(minExtent, bounds.extents.y - 0.5f), z = Mathf.Max(minExtent, bounds.extents.z - 0.5f) }; var matchTransform = GetTransformToMatch(myConnector, otherConnector); // We check against rotated AABB - this can further optimized // for OBB or split into checks for multiple children colliders if (Physics.OverlapBox(matchTransform.position, bounds.extents, matchTransform.rotation) .Where(col => col.transform.root.GetInstanceID() != otherConnector.transform.root.GetInstanceID()) .Count() <= 0) { targetTransform.position = matchTransform.position; targetTransform.rotation = matchTransform.rotation; return(true); } else { targetTransform.position = Vector3.zero; targetTransform.rotation = Quaternion.identity; return(false); } }
void Reset() { m_tile = GetComponentInParent <Tile>(); m_state = State.Open; var conn = m_connection; m_connection = null; if (conn) { conn.Reset(); } }
public override void BuildBeforeNavMesh(Vector3 origin) { GameObject startTile = SpawnTile(startingTile, origin, startingTile.transform.rotation); var openConnectors = new List <TileConnector>(startTile.GetComponentsInChildren <TileConnector>()); if (openConnectors.Count == 0) { Debug.LogWarning("Starting tile doesn't have any MapTileConnector objects!"); } for (int i = 0; i < iterationCount; ++i) { var nextOpenConnectors = new List <TileConnector>(); foreach (var openConnector in openConnectors) { // Pick a fitting tile Tile spawnedTile = null; var shuffledTiles = new List <Tile>(tileSet.Select(obj => obj.GetComponent <Tile>()).Shuffle()); foreach (Tile prefabTile in shuffledTiles) { BareTransform targetTransform = new BareTransform(); TileConnector myConnector = null; if (prefabTile.connectors.Any(conn => { return(prefabTile.CanBeConnectedAndSpawned(conn, openConnector, out targetTransform) && (myConnector = conn)); })) { spawnedTile = SpawnTile(prefabTile.gameObject, targetTransform.position, targetTransform.rotation).GetComponent <Tile>(); int connectorIndex = System.Array.IndexOf(prefabTile.connectors, myConnector); openConnector.Connect(spawnedTile.connectors[connectorIndex]); nextOpenConnectors.AddRange(spawnedTile.connectors.Where(conn => conn.state == TileConnector.State.Open)); break; } } // No tile fits, mark this connector as rejected if (!spawnedTile) { openConnector.Reject(); } } openConnectors = nextOpenConnectors; } }
public BareTransform GetTransformToMatch(TileConnector mine, TileConnector target) { Debug.Assert(connectors.Contains(mine)); // Calculate rotation of parent tile around child connector to match other connector's rotation var matchingRotation = Quaternion.LookRotation(-target.transform.forward, target.transform.up); Vector3 connectorToTileOffset = this.transform.position - mine.transform.position; Quaternion matchRotate = matchingRotation * Quaternion.Inverse(mine.transform.rotation); Vector3 rotatedRootWorldOffset = matchRotate * connectorToTileOffset; // Use local rotated tile offset from connector to calculate tile world position from target connector return(new BareTransform { position = target.transform.position + rotatedRootWorldOffset, rotation = matchRotate * this.transform.rotation, }); }
public override void BuildBeforeNavMesh(Vector3 origin) { arenaOrigin = origin; SpawnAuxiliaryObject(spawnPoint, origin, Quaternion.identity); var originTile = SpawnTile(PickRandomTile(), origin, Quaternion.identity); var openConnectors = new List <TileConnector>(originTile.GetComponent <Tile>().connectors); while (openConnectors.Count > 0) { var nextOpenConnectors = new List <TileConnector>(); foreach (var openConnector in openConnectors) { // Discard on tile level, not only on connector level if (!ShouldProcessGeneration(origin, openConnector.transform.position)) { continue; } Tile spawnedTile = null; var shuffledTiles = new List <Tile>(tileSet.Select(obj => obj.GetComponent <Tile>()).Shuffle()); foreach (Tile prefabTile in shuffledTiles) { BareTransform targetTransform = new BareTransform(); TileConnector myConnector = null; if (prefabTile.connectors.Any(conn => { return(prefabTile.CanBeConnectedAndSpawned(conn, openConnector, out targetTransform) && (myConnector = conn)); })) { spawnedTile = SpawnTile(prefabTile.gameObject, targetTransform.position, targetTransform.rotation).GetComponent <Tile>(); int connectorIndex = Array.IndexOf(prefabTile.connectors, myConnector); openConnector.Connect(spawnedTile.connectors[connectorIndex]); if (ShouldProcessGeneration(origin, spawnedTile.transform.position)) { nextOpenConnectors.AddRange(spawnedTile.connectors.Where(conn => conn.state == TileConnector.State.Open)); } break; } } // No tile fits, mark this connector as rejected if (!spawnedTile) { openConnector.Reject(); } } openConnectors = nextOpenConnectors; } BuildWalls(); #if UNITY_EDITOR DebugColorTiles(); #endif }
public void Connect(TileConnector other) { m_state = other.m_state = State.Connected; m_connection = other; other.m_connection = this; }