// generates the tiles public void GenerateLevel() { // if there are no tile if (blockOptions.Count == 0) { return; } // area size not set if (areaSize.x == 0 && areaSize.z == 0) { return; } // blocks to be positioned. GameObject[] blocks = GameObject.FindGameObjectsWithTag("Block"); // finds all blocks // block offsets Vector3 offset; // the amount of available spaces int spaces = 0; // if negative, it moves aorund the existing blocks only if (blockCount <= 0) { blockCount = blocks.Length; } // TODO: change this to generate positions first, then make blocks afterwards. // gets block size (originally was in Start(), but I did this to refresh // this will need to be moved. { // this goes off of BlockA. In a more efficient program this would be dependent on each bue. // gets the renderer MeshRenderer renderer = blockOptions[0].GetComponent <MeshRenderer>(); // gets the size of the object offset = renderer.bounds.size; // / 2.0F; // this assumes the center is the middle. offset += new Vector3(2, 2, 2); } // VARIABLES // the value at the given index determines how high the blocks in a given place are int[,] grid = new int[areaSize.z, areaSize.x]; // y-axis is filled by height // gets the current cell Vector2Int currCell = new Vector2Int(Random.Range(0, areaSize.z), Random.Range(0, areaSize.x)); // randomizes the direction Vector2Int dir; // finds starting direction. { // randomizes the direction int randNum = Random.Range(0, 5); switch (randNum) { case 1: // left first dir = Vector2Int.left; break; case 2: // up first dir = Vector2Int.up; break; case 3: // right first dir = Vector2Int.right; break; case 4: // down first default: dir = Vector2Int.down; break; } } // goes in all four directions using al oop for (int i = 0; i < 4; i++) { Vector2Int cycleDir = dir; // the direction for the current iteration Vector2Int cycleCell = currCell; // the cycel cell int cycle = 0; // number of cycles // while the amount of desired cycles has not been surpassed. while (cycle < cycles) { // gets two random numbers for the direction chance and spread chance float r1 = Random.Range(0.0F, 1.0F); float r2 = Random.Range(0.0F, 1.0F); // if the direction should change if (r1 <= direcChangeChance) { cycleDir = RotateVector2Int(cycleDir, 90.0F); } // a spread shot should be used, which fills adjacent tiles. if (r2 <= spreadChance) { // one left if (cycleCell.x - 1 > 0) { grid[cycleCell.x - 1, cycleCell.y]++; spaces++; } // one right if (cycleCell.x + 1 < areaSize.z) { grid[cycleCell.x + 1, cycleCell.y]++; spaces++; } // one up if (cycleCell.y + 1 < areaSize.x) { grid[cycleCell.x, cycleCell.y + 1]++; spaces++; } // one down if (cycleCell.y - 1 > 0) { grid[cycleCell.x, cycleCell.y - 1]++; spaces++; } // TODO: fill diagonal? } // increments current cell grid[cycleCell.x, cycleCell.y]++; spaces++; // goes onto new cell, making said cell the current cell. cycleCell += cycleDir; // TODO: have it change direction instead of breaking? // if the cell is out of bounds, break. if (cycleCell.x < 0 || cycleCell.x >= areaSize.z || cycleCell.y < 0 || cycleCell.y >= areaSize.x) { break; } else { cycle++; // next cycle } } // rotates to go to the next direction dir = RotateVector2Int(dir, 90.0F); } // instatiates objects and places blocks. { // the current block int currBlock = 0; // if the block count is less than or equal to 0, it's set to the maximum amount of spaces. if (blockCount <= 0) { // blocks should fill all spaces blockCount = spaces; } // spawns items for (int row = 0; row < areaSize.z; row++) { for (int col = 0; col < areaSize.x; col++) { // generates platforms in accordance with tile for (int n = 0; n < grid[row, col] && n < areaSize.y; n++) { // object being generated or altered GameObject go; // generates new base position Vector3 newPos = new Vector3(offset.x * col, offset.y * n, offset.z * row); // moves to align object with origin newPos -= Vector3.Scale(Vector3.Scale(areaSize, areaOrigin), offset); // generates new position // Vector3 newPos = Vector3.Scale(Vector3.Scale(areaSize, areaOrigin), offset); // if there is a block available. if (currBlock < blocks.Length) { go = blocks[currBlock]; blocks[currBlock].SetActive(true); blocks[currBlock].transform.position = newPos; } else { int rint = Random.Range(0, blockOptions.Count); go = Instantiate(blockOptions[rint], newPos, new Quaternion(0, 0, 0, 1)); } // if the parents should be perserved if not set if (addParents && blockParent != null) { // if there is no parent, or if there is a parent and it should be overridded. if (go.transform.parent == null || (go.transform.parent != null && !preserveParents)) { go.transform.parent = blockParent.transform; } } // resets spawn position to the object's new position. go.GetComponent <CubeBehaviour>().SetSpawnPosToCurrentPos(); currBlock++; // if the block count has been reached, break. if (currBlock == blockCount) { break; } } // if the block count has been reached, break. if (currBlock == blockCount) { break; } } } // if the amount of blocks in the list exceeds how many block were made. while (blocks.Length > currBlock) { int index = blocks.Length - 1; // gets index GameObject blk = blocks[index]; // gets block System.Array.Resize <GameObject>(ref blocks, index); // removes block GameObject.Destroy(blk); // destroys block } // repositions player, and scales up ground to hold all blocks { GameObject player = GameObject.FindGameObjectWithTag("Player"); // player object GameObject ground = GameObject.FindGameObjectWithTag("Ground"); // ground object // Ground // creates ground if it doesn't exist if (ground == null) { ground = Instantiate((GameObject)Resources.Load("Prefabs/Ground")); // adds parent to new ground. if (ground != null && addParents && blockParent != null) { ground.transform.parent = blockParent.transform; } } // Ground if (ground != null) { MeshRenderer groundMr = ground.GetComponent <MeshRenderer>(); // gets the ground's mesh renderer if (groundMr != null) // mesh renderer not set. { // new position for ground // Vector3 newPos = Vector3.Scale(Vector3.Scale(areaSize, areaOrigin), offset); // new position // newPos.y = 0 - areaOrigin.y * offset.y; // generates new base position Vector3 newPos = new Vector3(offset.x * areaSize.x / 2, 0, offset.z * areaSize.z / 2); // moves to align object with origin newPos -= Vector3.Scale(Vector3.Scale(areaSize, areaOrigin), offset); // the new scale, which is multiplied by the offset. // scale = desired size / current size Vector3 newScale = new Vector3( areaSize.x * offset.x / groundMr.bounds.size.x * ground.transform.localScale.x, areaSize.y * offset.y / groundMr.bounds.size.y * ground.transform.localScale.y, areaSize.z * offset.z / groundMr.bounds.size.z * ground.transform.localScale.z ); // y scale should stay the same. newScale.y = ground.transform.localScale.y; // increases scale by 3 to ensure extra space. newScale += new Vector3(3, 0, 3); // sets position and scale ground.transform.position = newPos; ground.transform.localScale = newScale; // moves the death plane CubeBehaviour.deathPlaneY = newPos.y += CubeBehaviour.deathPlaneY; } } // Player if (player != null) { Vector3 newPos; // random spot in scene newPos.x = Random.Range(0, areaSize.x) * offset.x; newPos.y = areaSize.y * (offset.y + 1); newPos.z = Random.Range(0, areaSize.z) * offset.z; // offset for origin newPos -= Vector3.Scale(Vector3.Scale(areaSize, areaOrigin), offset); player.transform.position = newPos; // sets new position player.GetComponent <CubeBehaviour>().SetSpawnPosToCurrentPos(); // resets to current position } } // tries to find collision manager if not set. if (colManager == null) { colManager = FindObjectOfType <CollisionManager>(); // does not exist if (colManager == null) { return; } } // clears the cube list and marks it for refresh. colManager.ClearCubeList(); resetBlocks = true; refreshCD = 1; } }