예제 #1
0
파일: Tile.cs 프로젝트: heroarthur/IO2017
        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);
            }
        }
예제 #2
0
        void Reset()
        {
            m_tile  = GetComponentInParent <Tile>();
            m_state = State.Open;

            var conn = m_connection;

            m_connection = null;
            if (conn)
            {
                conn.Reset();
            }
        }
예제 #3
0
        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;
            }
        }
예제 #4
0
파일: Tile.cs 프로젝트: heroarthur/IO2017
        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,
            });
        }
예제 #5
0
        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
        }
예제 #6
0
 public void Connect(TileConnector other)
 {
     m_state            = other.m_state = State.Connected;
     m_connection       = other;
     other.m_connection = this;
 }