//Return random tunnel tendency based on set distribution int SelectPieceIndex(TunnelTendency tend) { int ind = 0; switch (tend) { case TunnelTendency.up: //For up tunnel, more likely to select index 0 or 1 if (Random.Range(0f, 1f) < 0.25) //Ex. If value is set to 0.25, there is a 75% chance that we go to the else statement and select an upward sloping tunnel { ind = Random.Range(2, 5); } else { ind = Random.Range(0, 2); } break; case TunnelTendency.down: //For up tunnel, more likely to select index 3 or 4 if (Random.Range(0f, 1f) < 0.25) { ind = Random.Range(0, 3); } else { ind = Random.Range(3, 5); } break; default: //For normal tunnel, all pieces have equal chance of being selected ind = Random.Range(0, 5); break; } return ind; }
//Return random tunnel tendency based on set distribution float SelectNextPieceAngle(TunnelTendency tend) { float ang = 0f; switch (tend) { case TunnelTendency.up: //For up tunnel, more likely to select index 0 or 1 if (Random.Range(0f, 1f) < 0.25) //Ex. If value is set to 0.25, there is a 75% chance that we go to the else statement and select an upward sloping tunnel { ang = Random.Range(0, maxAngle); } else { ang = Random.Range(-maxAngle, 0); } break; case TunnelTendency.down: //For up tunnel, more likely to select index 3 or 4 if (Random.Range(0f, 1f) < 0.25) { ang = Random.Range(0, maxAngle); } else { ang = Random.Range(-maxAngle, 0); } break; default: //For normal tunnel, all pieces have equal chance of being selected ang = Random.Range(-maxAngle, maxAngle); break; } return ang; }
// Generate a mostly horizontal tunnel with some vertical shafts void GenerateTunnel(Vector3 startPos, int direction, TunnelTendency vertTend) { //Initialize int floorInd = 2; //Should be flat/neutral piece index int ceilingInd = 2; Vector3 floorPos; Vector3 ceilingPos; Vector3 prevFloorPos; Vector3 prevCeilingPos; floorPos = startPos; floorPos.x += 0.5f * direction; ceilingPos = floorPos; ceilingPos.y += 1f; List<Vector2[]> waterQuads = new List<Vector2[]>(); List<Vector2> waterSurface = new List<Vector2>(); bool upShaftAllowed = false; bool downShaftAllowed = false; int upCoolTimer = 0; int downCoolTimer = 0; branchCount++; int branchNum = branchCount; int biomeInd = SelectBiomeMaterial(); Material biomeMat = biomeMaterials[biomeInd]; bool startFreeSurface = false; bool endFreeSurface = false; bool startedFreeSurface = false; //if (branchCount > maxBranches) //If max branches has been reached, don't continue this function. (Other functions currently executing should still finish) // return; //Determine tunnel characteristics int tunnelLength = Random.Range(minTunnelLength, maxTunnelLength + 1); for (int i = 0; i < tunnelLength; i++) { //Chance to create a shaft shaftUp = false; shaftDown = false; if (upShaftAllowed) { if (Random.Range(0f, 1f) <= shaftFrequency) { //Debug.Log("ShaftUp on iter " + i); shaftUp = true; upShaftAllowed = false; } } else { upCoolTimer++; } if (upCoolTimer > shaftCooldown) { upCoolTimer = 0; upShaftAllowed = true; } if (downShaftAllowed) { if (Random.Range(0f, 1f) <= shaftFrequency) { //Debug.Log("ShaftDown on iter " + i); shaftDown = true; downShaftAllowed = false; } } else { downCoolTimer++; } if (downCoolTimer > shaftCooldown) { downCoolTimer = 0; downShaftAllowed = true; } //Determine next piece type and positions of next pieces prevFloorPos = floorPos; prevCeilingPos = ceilingPos; //Determine start position for next floor piece floorPos.y += yOffsets[floorInd] * direction; //This is y position of end point for previous piece //Determine start position for next ceiling piece ceilingPos.y += yOffsets[ceilingInd] * direction; //Account for offset of last piece that was placed. Gives y position at end of piece if (!shaftDown) { //Select next piece type if (i == 0) { floorInd = 2; } else { floorInd = SelectPieceIndex(vertTend); floorPos.y += yOffsets[floorInd] * direction; //Account for offset of next piece. Should now be y pos of where center of next piece should go } } else //If shaftDown { floorInd = 0; } if (!shaftUp) { //Select next piece type if (i == 0) { ceilingInd = 2; ceilingPos = floorPos; ceilingPos.y += tunnelHeight; } else { float yPosTest = 0; bool passed = false; int iter = 0; while (!passed) //Enforce that ceiling must be at least minimum height above floor { yPosTest = ceilingPos.y; ceilingInd = SelectPieceIndex(vertTend); yPosTest += yOffsets[ceilingInd] * direction; //Account for offset of next piece. Should now be y pos of where center of next piece should go float ht = yPosTest + yOffsets[ceilingInd] * direction - (floorPos.y + yOffsets[floorInd] * direction); //Calculate clearance height if (ht > 0.9f || iter >= 20) { passed = true; if (iter == 20) //If solution not reached, there might not be a solution. Next ceiling piece should be angled up as much as possible to try to create enough space between floor and ceiling { Debug.Log("Passed on iter " + iter + "; Height of " + ht); ceilingInd = 0; yPosTest = ceilingPos.y; yPosTest += yOffsets[ceilingInd] * direction; } } iter++; } ceilingPos.y = yPosTest; } } else //If shaftUp { ceilingInd = 0; } //For constant height tunnel //ceilingPos = floorPos; //ceilingPos.y += tunnelHeight; //ceilingInd = floorInd; //First check for interference //Check for overlap before placing anything Vector3 floorStart = floorPos; //Line 1 spans floor piece floorStart.x -= (0.5f - clearanceWidth/2) * direction; //Account for clearance of previous piece (previous vertical pieces can get collided with otherwise) floorStart.y -= yOffsets[floorInd] * direction + clearanceWidth / 2; //Use outside edge accounting for clearance Vector3 floorEnd = floorPos; floorEnd.x += (0.5f + clearanceWidth / 2) * direction; floorEnd.y += yOffsets[floorInd] * direction - clearanceWidth / 2; Vector3 ceilingStart = ceilingPos; //Line 2 spans ceiling piece ceilingStart.x -= (0.5f - clearanceWidth/2) * direction; ceilingStart.y -= yOffsets[ceilingInd] * direction - clearanceWidth / 2; Vector3 ceilingEnd = ceilingPos; ceilingEnd.x += (0.5f + clearanceWidth / 2) * direction; ceilingEnd.y += yOffsets[ceilingInd] * direction + clearanceWidth / 2; //Debug Lines //GameObject ln = GameObject.Instantiate(line); //ln.GetComponent<LineRenderer>().SetPosition(0, floorStart); //ln.GetComponent<LineRenderer>().SetPosition(1, floorEnd); //ln.GetComponent<LineRenderer>().SetPosition(2, ceilingEnd); //ln.GetComponent<LineRenderer>().SetPosition(3, ceilingStart); if (CheckForOverlap(floorStart, floorEnd, ceilingStart, ceilingEnd, floorEnd, ceilingEnd)) { Debug.Log("Found interference with tunnel placement #" + branchNum); goto EndTunnelActions; } //Keep track of water area using line positions from above //Vector4 quad = new Vector4(floorStart.y, ceilingStart.y, floorEnd.y, ceilingEnd.y); if (floorStart.y < waterElevation || floorEnd.y < waterElevation) { bool startWater = false; bool endWater = false; int numberOfQuads = 1; Vector2 waterBottomStart = floorStart; Vector2 waterBottomEnd = floorEnd; Vector2 waterTopStart = ceilingStart; Vector2 waterTopEnd = ceilingEnd; Vector2 waterBottomStart2 = floorStart; Vector2 waterBottomEnd2 = floorEnd; Vector2 waterTopStart2 = ceilingStart; Vector2 waterTopEnd2 = ceilingEnd; if (i == 0) { startFreeSurface = true; } if (ceilingStart.y < waterElevation && ceilingEnd.y > waterElevation) { startFreeSurface = true; numberOfQuads = 2; //First Quad waterTopEnd.y = waterElevation; waterTopEnd.x = ceilingEnd.x - (Mathf.Abs(waterElevation - ceilingEnd.y) * Mathf.Abs(ceilingEnd.x - ceilingStart.x) / Mathf.Abs(ceilingEnd.y - ceilingStart.y)); waterBottomEnd.x = waterTopEnd.x; //waterBottomEnd.y = /////Need to finish //Second Quad waterBottomStart2.x = waterTopStart2.x = waterTopEnd.x; waterTopStart2.y = waterTopEnd2.y = waterElevation; waterBottomStart.y = waterBottomEnd.y; } else if (ceilingStart.y > waterElevation && ceilingEnd.y < waterElevation) { endFreeSurface = true; numberOfQuads = 2; //First Quad waterTopStart.y = waterTopEnd.y = waterElevation; waterTopEnd.x = ceilingEnd.x - (Mathf.Abs(waterElevation - ceilingEnd.y) * Mathf.Abs(ceilingEnd.x - ceilingStart.x) / Mathf.Abs(ceilingEnd.y - ceilingStart.y)); waterBottomEnd.x = waterTopEnd.x; //waterBottomEnd.y = /////Need to finish //Second Quad waterBottomStart2.x = waterTopStart2.x = waterTopEnd.x; waterTopStart2.y = waterElevation; waterBottomStart.y = waterBottomEnd.y; } else if (ceilingStart.y > waterElevation && ceilingEnd.y > waterElevation) { waterTopStart.y = Mathf.Min(ceilingStart.y, waterElevation); //Don't allow water to be above water elevation waterTopEnd.y = Mathf.Min(ceilingEnd.y, waterElevation); } if (floorStart.y > waterElevation && floorEnd.y < waterElevation) { startWater = true; waterBottomStart.x = floorEnd.x - (Mathf.Abs(waterElevation - floorEnd.y) * Mathf.Abs(floorEnd.x - floorStart.x) / Mathf.Abs(floorEnd.y - floorStart.y)); waterTopStart.x = waterBottomStart.x; //waterTopStart.y = waterElevation; } else if (floorStart.y < waterElevation && floorEnd.y > waterElevation) { endWater = true; endFreeSurface = true; waterBottomEnd.x = floorEnd.x - (Mathf.Abs(waterElevation - floorEnd.y) * Mathf.Abs(floorEnd.x - floorStart.x) / Mathf.Abs(floorEnd.y - floorStart.y)); waterTopEnd.x = waterBottomStart.x; waterTopEnd.y = waterElevation; } //waterTopStart.y = Mathf.Min(ceilingStart.y, waterElevation); //Don't allow water to be above water elevation //waterTopEnd.y = Mathf.Min(ceilingEnd.y, waterElevation); if (startWater) { waterQuads.Clear(); waterSurface.Clear(); } Vector2[] quad = new Vector2[4]; quad[0] = waterBottomStart; quad[1] = waterTopStart; quad[2] = waterBottomEnd; quad[3] = waterTopEnd; waterQuads.Add(quad); if (numberOfQuads == 2) { Vector2[] quad2 = new Vector2[4]; quad2[0] = waterBottomStart2; quad2[1] = waterTopStart2; quad2[2] = waterBottomEnd2; quad2[3] = waterTopEnd2; waterQuads.Add(quad2); } //Debug.Log("Quad0 " + quad[0] + " Quad1 " + quad[1] + " Quad2 " + quad[2] + " Quad3 " + quad[3]); if (startFreeSurface) { if (numberOfQuads == 2) { waterSurface.Add(waterTopStart2); //Instantiate(marker, waterTopStart2, Quaternion.identity); } else { waterSurface.Add(waterTopStart); //Instantiate(marker, waterTopStart, Quaternion.identity); } startFreeSurface = false; startedFreeSurface = true; } if (startedFreeSurface && endFreeSurface) { waterSurface.Add(waterTopEnd); startFreeSurface = endFreeSurface = false; //Reset flags //Instantiate(marker, waterTopEnd, Quaternion.identity); startedFreeSurface = false; endFreeSurface = false; } if (endWater) { GameObject nothingObj2 = new GameObject(); createWater.CreateWaterBody(waterQuads, waterSurface, direction, nothingObj2); } } if (shaftDown) { floorPos = prevFloorPos; } if (shaftUp) { ceilingPos = prevCeilingPos; } //Place Background Vector3 bottomPos = floorPos; Vector3 topPos = ceilingPos; int bottomInd = floorInd; int topInd = ceilingInd; if (shaftDown) { bottomPos.y += yOffsets[floorInd] * direction; //Account for offset of last piece that was placed bottomInd = 2; Instantiate(marker, bottomPos, Quaternion.identity); } if (shaftUp) { topPos.y += yOffsets[ceilingInd] * direction; //Account for offset of last piece that was placed topInd = 2; Instantiate(marker, topPos, Quaternion.identity); } createBackground.CoverHeight(bottomPos, topPos, bottomInd, topInd, biomeInd); //Create floor if not doing a shaft if (!shaftDown) { //Place floor lastFloor = (GameObject)Instantiate(floorPieces[floorInd], floorPos, Quaternion.identity); Renderer[] rendArray = lastFloor.gameObject.GetComponentsInChildren<Renderer>(); foreach (Renderer rend in rendArray) { rend.material = biomeMat; } } else //Create an down shaft { Vector3 shaftStart = floorPos; shaftStart.x -= 0.5f * direction; shaftStart.y += yOffsets[floorInd] * direction; //Account for offset of last piece that was placed //Debug.Log("StartPos " + shaftStart); GenerateShaft(shaftStart, -1, direction, biomeInd); } //Create ceiling if not doing a shaft if (!shaftUp) { //Place ceiling lastCeiling = (GameObject)Instantiate(ceilingPieces[ceilingInd], ceilingPos, Quaternion.identity); Renderer[] rendArray = lastCeiling.gameObject.GetComponentsInChildren<Renderer>(); foreach (Renderer rend in rendArray) { rend.material = biomeMat; } } else //Create an up shaft { Vector3 shaftStart = ceilingPos; shaftStart.x -= 0.5f * direction; shaftStart.y += yOffsets[ceilingInd] * direction; //Account for offset of last piece that was placed GenerateShaft(shaftStart, 1, direction, biomeInd); } //Place background pieces //float highestElev = ceilingPos.y + Mathf.Abs(yOffsets[ceilingInd]); //float lowestElev = floorPos.y - Mathf.Abs(yOffsets[floorInd]); //Vector3 lowestPoint = floorPos; //lowestPoint.y = lowestElev; //float coverHeight = highestElev - lowestElev; floorPos.x += 1f * direction; ceilingPos.x += 1f * direction; } EndTunnelActions: GameObject nothingObj = new GameObject(); createWater.CreateWaterBody(waterQuads, waterSurface, direction, nothingObj); return; }
// Generate a mostly horizontal tunnel with some vertical shafts void GenerateTunnel(Vector3 startPos, int direction, TunnelTendency vertTend) { //Initialize float floorSlope = 0f; float ceilingSlope = 0f; float floorAngle = 0f; float ceilingAngle = 0f; Vector3 floorStartPos; Vector3 ceilingStartPos; Vector3 floorEndPos = new Vector3(); Vector3 ceilingEndPos = new Vector3();; Vector3 tunnelFloorStart; Vector3 tunnelCeilingStart; List<Vector3> floorEndPoints = new List<Vector3>(); List<Vector3> ceilingEndPoints = new List<Vector3>(); List<float> floorSlopeList = new List<float>(); List<float> ceilingSlopeList = new List<float>(); GameObject Tunnel = new GameObject("Tunnel"); GameObject FloorPieces = new GameObject("FloorPieces"); GameObject CeilingPieces = new GameObject("CeilingPieces"); GameObject WallPieces = new GameObject("WallPieces"); GameObject BackgroundPieces = new GameObject("BackgroundPieces"); FloorPieces.transform.SetParent(Tunnel.transform); CeilingPieces.transform.SetParent(Tunnel.transform); BackgroundPieces.transform.SetParent(Tunnel.transform); BackgroundPieces.AddComponent<CreateBackground5>(); CreateBackground5 createBackground; createBackground = BackgroundPieces.GetComponent<CreateBackground5>(); GameObject parentWaterObj = createWater.SetupWaterObjects(); floorStartPos = startPos; //floorPos.x += 0.5f * direction; ceilingStartPos = floorStartPos; ceilingStartPos.y += tunnelHeight; tunnelFloorStart = floorStartPos; tunnelCeilingStart = ceilingStartPos; //List<Vector2[]> waterQuads = new List<Vector2[]>(); //List<Vector2> waterSurface = new List<Vector2>(); bool upShaftAllowed = false; bool downShaftAllowed = false; int upCoolTimer = 0; int downCoolTimer = 0; branchCount++; int branchNum = branchCount; int biomeInd = SelectBiomeMaterial(); Material biomeMat = biomeMaterials[biomeInd]; //bool startFreeSurface = false; //bool endFreeSurface = false; //bool startedFreeSurface = false; //if (branchCount > maxBranches) //If max branches has been reached, don't continue this function. (Other functions currently executing should still finish) // return; //Determine tunnel characteristics int tunnelLength = Random.Range(minTunnelLength, maxTunnelLength + 1); for (int i = 0; i < tunnelLength; i++) { //Chance to create a shaft shaftUp = false; shaftDown = false; if (upShaftAllowed) { if (Random.Range(0f, 1f) <= shaftFrequency) { //Debug.Log("ShaftUp on iter " + i); shaftUp = true; upShaftAllowed = false; } } else { upCoolTimer++; } if (upCoolTimer > shaftCooldown) { upCoolTimer = 0; upShaftAllowed = true; } if (downShaftAllowed) { if (Random.Range(0f, 1f) <= shaftFrequency) { //Debug.Log("ShaftDown on iter " + i); shaftDown = true; downShaftAllowed = false; } } else { downCoolTimer++; } if (downCoolTimer > shaftCooldown) { downCoolTimer = 0; downShaftAllowed = true; } //Determine next piece type and positions of next pieces floorEndPos = floorStartPos; //Initialize ceilingEndPos = ceilingStartPos; floorEndPos.x += 1f * direction; ceilingEndPos.x += 1f * direction; //Determine start position for next floor piece ////floorPos.y += lastFloorSlope * pieceLength; //This is y position of end point for previous piece //Determine start position for next ceiling piece ////ceilingPos.y += lastCeilingSlope * pieceLength; //Account for offset of last piece that was placed. Gives y position at end of piece if (!shaftDown) { //Select next piece type if (i == 0) { floorAngle = 0f; } else { floorAngle = SelectNextPieceAngle(vertTend); } //floorSlope = Mathf.Tan(floorAngle * Mathf.Deg2Rad); } else //If shaftDown { floorAngle = 0f; } floorSlope = Mathf.Tan(floorAngle * Mathf.Deg2Rad); floorEndPos.y += floorSlope * pieceLength; //Account for offset of next piece. Should now be y pos of primary surface at end of this piece if (!shaftUp) { //Select next piece type if (i == 0) { floorAngle = 0f; ceilingStartPos = floorStartPos; ceilingStartPos.y += tunnelHeight; } else { float endPosTest = 0; bool passed = false; int iter = 0; while (!passed) //Enforce that ceiling must be at least minimum height above floor { endPosTest = ceilingStartPos.y; ceilingAngle = SelectNextPieceAngle(vertTend); //Select an angle for this piece ceilingSlope = Mathf.Tan(ceilingAngle * Mathf.Deg2Rad); endPosTest += ceilingSlope * pieceLength; //Should now be y pos of end of ceiling piece //Check where yPosTest is if having problems float ht = endPosTest - floorEndPos.y; //Calculate clearance height. Should be height between end points of floor and ceiling if (ht > 0.9f || iter >= 20) { passed = true; if (iter == 20) //If solution not reached, there might not be a solution. Next ceiling piece should be angled up as much as possible to try to create enough space between floor and ceiling { Debug.Log("Passed on iter " + iter + "; Height of " + ht); ceilingAngle = maxAngle; } } iter++; } //ceilingPos.y = yPosTest; } } else //If shaftUp { ceilingAngle = 0f; } ceilingSlope = Mathf.Tan(ceilingAngle * Mathf.Deg2Rad); ceilingEndPos.y += ceilingSlope * pieceLength; //For constant height tunnel //ceilingPos = floorPos; //ceilingPos.y += tunnelHeight; //ceilingInd = floorInd; //First check for interference //Check for overlap before placing anything //At this point floorPos should be end point for current/about to be placed piece. prevFloorPos should be start point for current/about to be placed piece Vector3 floorStart = floorStartPos; //Line 1 spans floor piece middle to end floorStart.x += clearanceWidth * direction; floorStart.y -= clearanceWidth; //Use outside edge accounting for clearance Vector3 floorEnd = floorEndPos; floorEnd.x += clearanceWidth * direction; floorEnd.y -= clearanceWidth; Vector3 ceilingStart = ceilingStartPos; //Line 2 spans ceiling piece middle to end ceilingStart.x += clearanceWidth * direction; ceilingStart.y += clearanceWidth; Vector3 ceilingEnd = ceilingEndPos; ceilingEnd.x += clearanceWidth * direction; ceilingEnd.y += clearanceWidth; //Debug Lines //GameObject ln = GameObject.Instantiate(line); //ln.GetComponent<LineRenderer>().SetPosition(0, floorStart); //ln.GetComponent<LineRenderer>().SetPosition(1, floorEnd); //ln.GetComponent<LineRenderer>().SetPosition(2, ceilingEnd); //ln.GetComponent<LineRenderer>().SetPosition(3, ceilingStart); if (CheckForOverlap(floorStart, floorEnd, ceilingStart, ceilingEnd, floorEnd, ceilingEnd)) { Debug.Log("Found interference with tunnel placement #" + branchNum); //floorEndPoints.RemoveAt(floorEndPoints.Count-1); //ceilingEndPoints.RemoveAt(floorEndPoints.Count - 1); //floorSlopeList.RemoveAt(floorEndPoints.Count - 1); //ceilingSlopeList.RemoveAt(floorEndPoints.Count - 1); floorEndPos = floorStartPos; //Set end point back to start and end tunnel there ceilingEndPos = ceilingStartPos; goto EndTunnelActions; } //Create floor if not doing a shaft if (!shaftDown) { //Place floor Vector3 objLoc = new Vector3(floorStartPos.x + pieceLength / 2f * direction, (floorStartPos.y + floorEndPos.y) / 2f, 0f); Vector3 meshStart = new Vector3(-pieceLength / 2f * direction, (floorStartPos.y - floorEndPos.y) / 2f, 0f); floorObj = (GameObject)Instantiate(tunnelPiecePrefab, objLoc, Quaternion.identity); floorObj.GetComponent<CreatePieceMesh>().InitializePiece(floorAngle, meshStart, direction, -1, pieceThickness, pieceThickness, 2.0f, biomeMat, 9); //Renderer[] rendArray = floorObj.gameObject.GetComponentsInChildren<Renderer>(); //foreach (Renderer rend in rendArray) //{ // rend.material = biomeMat; //} floorObj.transform.SetParent(FloorPieces.transform); } else //Create a down shaft { Vector3 shaftStart = floorStartPos; //shaftStart.x -= 0.5f * direction; ////shaftStart.y += yOffsets[floorInd] * direction; //Account for offset of last piece that was placed //Debug.Log("StartPos " + shaftStart); GenerateShaft(shaftStart, -1, direction, biomeInd, parentWaterObj); } //Create ceiling if not doing a shaft if (!shaftUp) { //Place ceiling Vector3 objLoc = new Vector3(ceilingStartPos.x + pieceLength / 2f * direction, (ceilingStartPos.y + ceilingEndPos.y) / 2f, 0f); Vector3 meshStart = new Vector3(-pieceLength / 2f * direction, (ceilingStartPos.y - ceilingEndPos.y) / 2f, 0f); ceilingObj = (GameObject)Instantiate(tunnelPiecePrefab, objLoc, Quaternion.identity); ceilingObj.GetComponent<CreatePieceMesh>().InitializePiece(ceilingAngle, meshStart, direction, 1, pieceThickness, pieceThickness, 2.0f, biomeMat, 9); //Renderer[] rendArray = ceilingObj.gameObject.GetComponentsInChildren<Renderer>(); //foreach (Renderer rend in rendArray) //{ // rend.material = biomeMat; //} ceilingObj.transform.SetParent(CeilingPieces.transform); } else //Create an up shaft { Vector3 shaftStart = ceilingStartPos; //shaftStart.x -= 0.5f * direction; //shaftStart.y += yOffsets[ceilingInd] * direction; //Account for offset of last piece that was placed GenerateShaft(shaftStart, 1, direction, biomeInd, parentWaterObj); } //Add to end points list that will be used for background generation floorEndPoints.Add(floorEndPos); ceilingEndPoints.Add(ceilingEndPos); floorSlopeList.Add(floorSlope); ceilingSlopeList.Add(ceilingSlope); floorStartPos = floorEndPos; //Starting point for next piece will be end point for current piece ceilingStartPos = ceilingEndPos; } EndTunnelActions: float endHt = ceilingEndPos.y - floorEndPos.y; int endPieceCount = (int)(endHt / pieceLength) + 1; for (int i = 0; i < endPieceCount; i++) { Vector3 objLoc = floorEndPos; objLoc.y += i * pieceLength + pieceLength / 2 - 0.2f; Vector3 meshStart = new Vector3(-pieceLength / 2, 0f, 0f); //Mesh start is relative to instantiated object float rotation; if (direction == 1) //If up shaft then end will be ceiling piece { rotation = -90f; } else { rotation = 90f; } GameObject thisObj = (GameObject)Instantiate(tunnelPiecePrefab, objLoc, Quaternion.identity); thisObj.GetComponent<CreatePieceMesh>().InitializePiece(0f, meshStart, 1, 1, 0.2f, 0.2f, 2.0f, biomeMat, 13); //Create a 0 degree piece with direction of 1 that will be turned by 90 degrees to become vertical piece //Renderer[] rendArray = thisObj.gameObject.GetComponentsInChildren<Renderer>(); //foreach (Renderer rend in rendArray) //{ // rend.material = biomeMat; //} thisObj.transform.Rotate(0f, 0f, rotation); thisObj.transform.SetParent(WallPieces.transform); worldResources.PopulateTunnel(Tunnel, direction); } createBackground.PlaceBackground(tunnelFloorStart, tunnelCeilingStart, floorEndPoints, floorSlopeList, ceilingEndPoints, ceilingSlopeList, direction, biomeInd, BackgroundPieces); createWater.CreateTunnelWater(tunnelFloorStart, tunnelCeilingStart, floorEndPoints, floorSlopeList, ceilingEndPoints, ceilingSlopeList, direction, parentWaterObj); //return; }