/// <summary> /// Initializes everything. /// </summary> void Start() { prevCameraPosition = MainCamera.transform.position; TilesToRemove = new List <OSPObject>(); PlacementHistory = new List <OSPRandomHistory>(); ParallaxPools = new List <OSPPool>(); // Grab the camera's bounds CamBounds = MainCamera.OrthographicBounds(); // Loops through the parallax layers and assigns an ID to each one, finds the maximum Z distance from the camera, // and sets the object pool amount. // This loop is mainly to determine the maximum Z distance because our parallax speed doe each layer depends on it. for (int i = 0; i < ParallaxObjects.Count; ++i) { var obj = ParallaxObjects[i]; obj.ObjectID = i; if (GetDistance(obj.transform.position.z, MainCamera.transform.position.z) > maxZ) { maxZ = obj.transform.position.z - MainCamera.transform.position.z; } obj.DeterminePoolAmount(CamBounds); } // Store the previous random state so we can go back to it after setting our seed in case your game has another seeded random state. Random.State oldState = Random.state; if (UseSeedForRandomization) { Random.InitState(RandomSeed); } // Loop through the parallax objects again foreach (var obj in ParallaxObjects) { // Set the parallax speed for the layer obj.ParallaxScalar = GetParallaxScalar(obj); // If we're randomizing anything, we create a new history object and initialize the offset values if (obj.RandomizeHorizontalDistance || obj.RandomizeVerticalDistance) { var newHist = new OSPRandomHistory { ID = obj.ObjectID, MaxHistorySize = obj.MaxPlacementHistorySize, UseRandomX = obj.RandomizeHorizontalDistance, UseRandomY = obj.RandomizeVerticalDistance, UseRandomHorizontalY = obj.RandomizeHorizontalYAxis, UseRandomVerticalX = obj.RandomizeVerticalXAxis, MinXOffset = obj.HorizontalDistanceMin, MaxXOffset = obj.HorizontalDistanceMax, MinYOffset = obj.VerticalDistanceMin, MaxYOffset = obj.VerticalDistanceMax, MinVerticalXOffset = obj.VerticalXMin, MaxVerticalXOffset = obj.VerticalXMax, MinHorizontalYOffset = obj.HorizontalYMin, MaxHorizontalYOffset = obj.HorizontalYMax }; // Only initialize the offset lists if we're actually storing history if (obj.UseRandomHistory) { newHist.InitializeOffsetHistory(); } PlacementHistory.Add(newHist); } // Create object pools for each layer and add them to the pool list if (obj.AutoTileX || obj.AutoTileY) { var pool = new OSPPool(obj); pool.CanGrow = false; ParallaxPools.Add(pool); } } // Restore the original random state Random.state = oldState; // Remove the pooled objects from the parallax list since we don't need to perform the same functionality on tiled and non-tiled objects foreach (var pool in ParallaxPools) { ParallaxObjects.Remove(pool.PooledObject); } }
/// <summary> /// Creates a new tile in the given direction. /// </summary> /// <param name="tile">The parallax tile object.</param> /// <param name="direction">The direction we're creating a new tile in.</param> /// <param name="historyList">The history list for that layer.</param> void CreateNewTile(OSPObject tile, TileDirection direction, OSPRandomHistory historyList) { // Grab the object pool for this layer OSPPool pool = ParallaxPools.SingleOrDefault(p => p.ObjectID == tile.ObjectID); // Sometimes, a large image will have a slight gap that shows up on camera movement. This isn't the best fix, but it works. float gapOffset = 0.05f; // Figure out the scale of the sprite so we can figure out how far to move it in order to tile float spriteScaleX = tile.transform.localScale.x; if (tile.transform.parent != null) { spriteScaleX *= tile.transform.parent.localScale.x; } float spriteScaleY = tile.transform.localScale.y; if (tile.transform.parent != null) { spriteScaleY *= tile.transform.parent.localScale.y; } if (direction == TileDirection.LEFT || direction == TileDirection.RIGHT) { #region Left/Right Tiles float posOffset = (tile.SpriteWidth * (direction == TileDirection.LEFT ? -1 : 1) * spriteScaleX); gapOffset *= direction == TileDirection.LEFT ? 1 : -1; Vector3 newPosition = new Vector3( tile.transform.position.x + posOffset + gapOffset, tile.transform.position.y, tile.transform.position.z); if (direction == TileDirection.RIGHT) { // If we're randomizing the horizontal distance, get the offset and add it to the position if (tile.RandomizeHorizontalDistance) { newPosition.x += historyList.GetXOffsetForColumn(tile.col, tile.UseRandomHistory); // If we're randomizing the Y offset, get the offset and add it to the position if (tile.RandomizeHorizontalYAxis) { newPosition.y += historyList.GetYOffsetForColumn(tile.col, tile.UseRandomHistory); } } else { newPosition.x += tile.HorizontalDistance; } } else if (direction == TileDirection.LEFT) { // If we're randomizing the horizontal distance, get the offset and add it to the position if (tile.RandomizeHorizontalDistance) { newPosition.x -= historyList.GetXOffsetForColumn(tile.col - 1, tile.UseRandomHistory); // If we're randomizing the Y offset, get the offset and add it to the position if (tile.RandomizeHorizontalYAxis) { newPosition.y += historyList.GetYOffsetForColumn(tile.col - 1, tile.UseRandomHistory); } } else { newPosition.x -= tile.HorizontalDistance; } } // Get the new tile from the object pool. Abandon ship if it couldn't get a tile. var newTile = pool.GetPooledObject(); if (newTile == null) { return; } newTile.transform.position = newPosition; newTile.transform.rotation = tile.transform.rotation; // Set the new column for this tile if (direction == TileDirection.RIGHT) { newTile.row = tile.row; newTile.col = tile.col + 1; } else { newTile.row = tile.row; newTile.col = tile.col - 1; } // Set the left, right, top, and bottom tiles that connect to this one pool.SetSiblings(newTile); // Now that we're in position, set this tile active newTile.gameObject.SetActive(true); #endregion } else { #region Up/Down Tiles float posOffset = (tile.SpriteHeight * (direction == TileDirection.DOWN ? -1 : 1) * spriteScaleY); gapOffset *= direction == TileDirection.DOWN ? 1 : -1; Vector3 newPosition = new Vector3( tile.transform.position.x, tile.transform.position.y + posOffset + gapOffset, tile.transform.position.z); if (direction == TileDirection.UP) { // If we're randomizing the vertical distance, get the offset and add it to the position if (tile.RandomizeVerticalDistance) { newPosition.y += historyList.GetYOffsetForRow(tile.row, tile.UseRandomHistory); // If we're randomizing the X offset, get the offset and add it to the position if (tile.RandomizeVerticalXAxis) { newPosition.x += historyList.GetXOffsetForRow(tile.row, tile.UseRandomHistory); } } else { newPosition.y += tile.VerticalDistance; } } else if (direction == TileDirection.DOWN) { // If we're randomizing the vertical distance, get the offset and add it to the position if (tile.RandomizeVerticalDistance) { newPosition.y -= historyList.GetYOffsetForRow(tile.row - 1, tile.UseRandomHistory); // If we're randomizing the X offset, get the offset and add it to the position if (tile.RandomizeVerticalXAxis) { newPosition.x += historyList.GetXOffsetForRow(tile.row - 1, tile.UseRandomHistory); } } else { newPosition.y -= tile.VerticalDistance; } } // Get the new tile from the object pool. Abandon ship if it couldn't get a tile. var newTile = pool.GetPooledObject(); if (newTile == null) { return; } newTile.transform.position = newPosition; newTile.transform.rotation = tile.transform.rotation; // Set the new row for this tile if (direction == TileDirection.DOWN) { newTile.row = tile.row + 1; newTile.col = tile.col; } else { newTile.row = tile.row - 1; newTile.col = tile.col; } // Set the left, right, top, and bottom tiles that connect to this one pool.SetSiblings(newTile); // Now that we're in position, set this tile active newTile.gameObject.SetActive(true); #endregion } }