void OnTerrainChunkVisibilityChanged(TerrainChunk chunk, bool isVisible) { if (isVisible) { _visibleTerrainChunks.Add(chunk); } else { _visibleTerrainChunks.Remove(chunk); } }
void UpdateVisibleChunks() { foreach (var terrainChunk in terrainChunksVisibleLastUpdate) { terrainChunk.SetVisible(false); } terrainChunksVisibleLastUpdate.Clear(); int currentChunkCoordX = Mathf.RoundToInt(viewerPosition.x / chunkSize); int currentChunkCoordY = Mathf.RoundToInt(viewerPosition.y / chunkSize); for (int yOffset = -chunksVisibleInViewDistance; yOffset <= chunksVisibleInViewDistance; yOffset++) { for (int xOffset = -chunksVisibleInViewDistance; xOffset <= chunksVisibleInViewDistance; xOffset++) { Vector2 viewedChunkCoord = new Vector2(currentChunkCoordX + xOffset, currentChunkCoordY + yOffset); if (terrainChunkDictionary.ContainsKey(viewedChunkCoord)) { TerrainChunk chunk = terrainChunkDictionary [viewedChunkCoord]; chunk.UpdateTerrainChunk(); } else { TerrainChunk chunk = new TerrainChunk(viewedChunkCoord, chunkSize, detailLevels, transform, mapMaterial); terrainChunkDictionary.Add(viewedChunkCoord, chunk); } } } }
private IEnumerator UpdateVisibleChunks() { while (true) { var currentchunkCoordX = Mathf.FloorToInt(player.position.x / chunkSize); var currentchunkCoordY = Mathf.FloorToInt(player.position.z / chunkSize); for (var yOffset = -chunksVisibleInViewDist; yOffset <= chunksVisibleInViewDist; yOffset++) for (var xOffset = -chunksVisibleInViewDist; xOffset <= chunksVisibleInViewDist; xOffset++) { var viewedChunkCoord = new Vector2(currentchunkCoordX + xOffset, currentchunkCoordY + yOffset); if (!terrainChunkDictionary.ContainsKey(viewedChunkCoord)) { var newTerrainChunk = new TerrainChunk(viewedChunkCoord, chunkSize); while (!newTerrainChunk.IsReady()) yield return null; terrainChunkDictionary.Add(viewedChunkCoord, newTerrainChunk); } } foreach (var terrainChunk in terrainChunkDictionary.Values) terrainChunk.UpdateChunkVisibility(); canStart = true; yield return new WaitForSeconds(0.5f); } }
public void GenerateStartingChunks() { int currentX = Mathf.RoundToInt(viewer.position.x / chunkSize.x); int currentY = Mathf.RoundToInt(viewer.position.y / chunkSize.y); int currentZ = Mathf.RoundToInt(viewer.position.z / chunkSize.z); int viewX = viewDist.x / 2; int viewY = viewDist.y / 2; int viewZ = viewDist.z / 2; for (int x = -viewX; x < viewX; x++) { for (int y = -viewY; y < viewY; y++) { for (int z = -viewZ; z < viewZ; z++) { Vector3 chunkCoord = new Vector3(currentX + x, currentY + y, currentZ + z); if (chunks.ContainsKey(chunkCoord)) { chunks[chunkCoord].SetRemove(false); } else { Vector3 worldPosition = new Vector3(chunkCoord.x * chunkSize.x, chunkCoord.y * chunkSize.y, chunkCoord.z * chunkSize.z); TerrainChunk chunk = new TerrainChunk(this, worldPosition, chunkSize, terrainMat); chunk.ScheduleValueJob(); chunk.CompleteValueJob(); chunks.Add(chunkCoord, chunk); } } } } }
private void UpdateVisibleChunks() { lastVisibleChunks.ForEach(chunk => chunk.SetVisible(false)); int currentXCoord = Mathf.RoundToInt(viewerPos.x / chunkSize); int currentYCoord = Mathf.RoundToInt(viewerPos.y / chunkSize); for (int yOffset = -chunksVisibleInViewDst; yOffset <= chunksVisibleInViewDst; yOffset++) { for (int xOffset = -chunksVisibleInViewDst; xOffset <= chunksVisibleInViewDst; xOffset++) { Vector2 viewedChunkCoord = new Vector2(currentXCoord + xOffset, currentYCoord + yOffset); if (posToChunk.ContainsKey(viewedChunkCoord)) { var chunk = posToChunk[viewedChunkCoord]; chunk.UpdateChunk(); } else { posToChunk[viewedChunkCoord] = new TerrainChunk(viewedChunkCoord, chunkSize, detailLevels, mapMaterial); } } } }
public void DrawToMesh(float x, float y, ChunkMesh msh, TerrainChunk chunk, int xi, int yi) { if (invisible) { return; } float xp = x * blockSize; float yp = y * blockSize; MakeFrontFace(xp, yp, msh); if (yi == TerrainChunk.ChunkHeight - 1 || chunk[xi, yi + 1].invisible) { MakeTopFace(xp, yp, msh); } if (yi == 0 || chunk[xi, yi - 1].invisible) { MakeBottomFace(xp, yp, msh); } if (xi == 0 || chunk[xi - 1, yi].invisible) { MakeLeftFace(xp, yp, msh); } if (xi == TerrainChunk.ChunkWidth - 1 || chunk[xi + 1, yi].invisible) { MakeRightFace(xp, yp, msh); } }
private void Update() { lock (ChunksAwaitingMeshApplying) { // When chunks are queued for re-generation run the below while (ChunksAwaitingMeshApplying.Count > 0) { if (_update >= _updatesPerFrame) { _update = 0; break; } TerrainChunk chunk = ChunksAwaitingMeshApplying.Dequeue(); chunk.GenerateChunkNeighbours(_generateChunkNeighboursSteps); if (!IsMultiThreaded) chunk.GenerateChunkMesh(chunk.LODLevel, true); // Check if a chunk should generation or delete objects if (MathUtility.CompareLodLevel(chunk.LODLevel, FarLodSize)) { ObjectManager.RemoveObjectsAtChunk(chunk); } else { if (chunk.IsForcedObjectGeneration) { chunk.IsForcedObjectGeneration = false; ObjectManager.PlaceObjectsAtChunk(chunk); } } chunk.UpdateChunkMesh(); _update++; } } }
public static void SetChunkVert(TerrainChunk chunk, int id, float height) { Vector3[] vertices = typeof(TerrainChunk).GetField("verticies", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(chunk) as Vector3[]; vertices[id].y = height; typeof(TerrainChunk).GetField("verticies", BindingFlags.Instance | BindingFlags.NonPublic).SetValue(chunk, vertices); }
Transform GenerateNbackObjectInGrid(int x, int y, Grid grid, TerrainChunk tc) { if (grid.containsObject(x, y)) { return(null); } Vector3 spawnPos = grid.GridToWorld(x, y) + tc.transform.position; Transform t = GenerateNbackObject(spawnPos.x, spawnPos.y); // Used to spawn randomly placed obstacles from floor to ceiling in levels 4 and 5 int r = Random.Range(-7, 5); int r2 = Random.Range(-7, 0); if (timer >= 360f && timer < 480f) { Transform i = GenerateObstacles(spawnPos.x + 5, r); } else if (timer >= 480) { Transform i = GenerateObstacles(spawnPos.x + 5, r2); } t.parent = tc.gameObject.transform; grid.MarkGrid(x, y); return(t); }
public NeighboringChunks(TerrainChunk left, TerrainChunk right, TerrainChunk above, TerrainChunk below) { Left = left; Right = right; Above = above; Below = below; }
void GenerateMissingChunks() { // positions of existing chunks List <Vector3> posns = new List <Vector3>(); // populate existing chunk positions foreach (TerrainChunk t in spawnedChunks) { posns.Add(t.transform.position); } List <Vector3> toSpawn = new List <Vector3>(); // generate chunks that are missing foreach (Vector3 pos in validChunkPosns) { if (!posns.Contains(pos)) { toSpawn.Add(pos); } } foreach (Vector3 s in toSpawn) { GameObject spawnedChunk = Instantiate(chunkPrefab, s, Quaternion.identity) as GameObject; TerrainChunk firstChunk = spawnedChunk.GetComponent <TerrainChunk>(); spawnedChunks.Add(firstChunk); } }
public void PopulateChunk(TerrainChunk chunk) { bool activeState = chunk.gameObject.activeSelf; if (!activeState) { chunk.gameObject.SetActive(true); } float scale = endlessTerrain.Scale; Vector2 areaSize = ((Vector2)chunk.terrainData.settings.unitSize) * scale; int successes = 0; for (int i = maxAttempts; i > 0; i--) { if (RandomlySpawnObject(chunk.gameObject, areaSize)) { successes++; } if (successes >= entitiesPerChunk) { break; } } if (!activeState) { chunk.gameObject.SetActive(false); } }
void UpdateVisibleChunks(int updatedistance) { //Reset all chunks foreach (TerrainChunk chunk in loaded) { chunk.setVisible(false); } loaded.Clear(); Vector2 viewerChunkCoord = new Vector2(Mathf.RoundToInt(viewer_pos.x / chunkSize), Mathf.RoundToInt(viewer_pos.y / chunkSize)); for (int j = -updatedistance; j <= updatedistance; j++) { for (int i = -updatedistance; i <= updatedistance; i++) { Vector2 newChunkPos = new Vector2((int)(viewerChunkCoord.x + i), (int)(viewerChunkCoord.y + j)); if (loaded_chunks.ContainsKey(newChunkPos)) //if the chunk has already been generated { TerrainChunk chunk = loaded_chunks[newChunkPos]; if (chunk.getDistanceToEdge(viewer_pos) < view_distance) { chunk.setVisible(true); loaded.Add(chunk); } } else { loaded_chunks.Add(newChunkPos, new TerrainChunk(newChunkPos)); //Generate a new chunk } } } }
// Converts the top cell to sand if certain criteria are met // This modifies terrain based on neighbor stacks // Thus it should only be called after all cell stacks are generated void AddSand(CellStack cellStack) { if (cellStack.Count() == terrain.waterLevel) { HexCoordinates[] neighbors = cellStack.coordinates.GetNeighbors(); for (int i = 0; i < 6; i++) { CellStack neighbor = GetCellStackFromWorldCoords(neighbors[i]); // The neighbor cell stack might not be in this chunk if (neighbor == null) { TerrainChunk neighborChunk = terrain.GetChunkFromWorldCoords(neighbors[i]); if (neighborChunk != null) { neighbor = neighborChunk.GetCellStackFromWorldCoords(neighbors[i]); } } if (neighbor != null) { if (neighbor.Count() < terrain.waterLevel) { cellStack.Pop(); cellStack.Push(CellType.Sand); break; } } } } }
TerrainChunkObject LoadChunk(ChunkPos cp, bool instant) { if (chunks.ContainsKey(cp)) { return(chunks[cp]); } TerrainChunk chunk = TerrainChunkGenerator.request(cp, instant); if (chunk == null) { return(null); } int xPos = cp.x; int zPos = cp.z; GameObject chunkGO = Instantiate(terrainChunkPrefab, new Vector3(xPos, 0, zPos), Quaternion.identity); TerrainChunkObject chunkObject = chunkGO.GetComponent <TerrainChunkObject>(); chunkObject.transform.parent = transform; chunkObject.name = "Chunk:" + cp; chunkObject.BuildMesh(chunk); WaterChunk wat = chunkObject.transform.GetComponentInChildren <WaterChunk>(); wat.SetLocs(chunk.blocks, chunkObject.Chunk); wat.BuildMesh(); chunks.Add(cp, chunkObject); return(chunkObject); }
public Transform GenerateWideGround(int x, int y, int wide, Grid grid, TerrainChunk tc) { for (int i = x; i < x + wide; ++i) { if (grid.containsObject(i, y)) { return null; } } Vector3 spawnPos = new Vector3 (0, 0, 0); for (int i = x; i < x + wide; ++i) { spawnPos += grid.GridToWorld(i, y); } spawnPos /= wide; spawnPos += tc.transform.position; //Vector3 spawnPos = grid.GridToWorld (x, y) + tc.transform.position; spawnPos.z = 0; Transform piece = wide == 3 ? ground3wide : (wide == 2 ? ground2wide : ground1wide); Transform t = GameObject.Instantiate (piece, spawnPos, Quaternion.identity) as Transform; for (int i = x; i < x + wide; ++i) { grid.MarkGrid(i, y); } Debug.Log ("Created in grid: " + x + ", " + y + "width: " + wide); return t; }
// Start is called before the first frame update void Start() { TerrainChunk chunk = new TerrainChunk(); List <Vector3> data = new List <Vector3>(); for (int x = -3; x < 3; x++) { for (int z = 0; z < 5; z++) { for (int y = 0; y < 4; y++) { if (y == 0 || x == -3 || x == 2 || z == 4) { data.Add(new Vector3(x, y, z)); } } } } chunk.children = data; TerrainManager.Instance.updateChunk(chunk); BindMainMenuScreen(); }
void UpdateVisibleChunks() { HashSet <Vector2> alreadyUpdatedChunkCoords = new HashSet <Vector2>(); for (int i = visibleTerrainChunks.Count - 1; i >= 0; i--) { alreadyUpdatedChunkCoords.Add(visibleTerrainChunks[i].coord); visibleTerrainChunks[i].UpdateTerrainChunk(); } int currentChunkCoordX = Mathf.RoundToInt(viewerPosition.x / meshWorldSize); int currentChunkCoordY = Mathf.RoundToInt(viewerPosition.y / meshWorldSize); for (int yOffset = -chunksVisibleInViewDst; yOffset < chunksVisibleInViewDst; yOffset++) { for (int xOffset = -chunksVisibleInViewDst; xOffset < chunksVisibleInViewDst; xOffset++) { Vector2 viewedChunkCoord = new Vector2(currentChunkCoordX + xOffset, currentChunkCoordY + yOffset); if (!alreadyUpdatedChunkCoords.Contains(viewedChunkCoord)) { if (terrainChunkDictionary.ContainsKey(viewedChunkCoord)) { terrainChunkDictionary[viewedChunkCoord].UpdateTerrainChunk(); } else { TerrainChunk newChunk = new TerrainChunk(viewedChunkCoord, heightMapSettings, meshSettings, detailLevels, colliderLODIndex, transform, viewer, mapMaterial); terrainChunkDictionary.Add(viewedChunkCoord, newChunk); newChunk.onVisibilityChanged += OnTerrainChunkVisibilityChanged; newChunk.Load(); } } } } }
//FOR N_Back! public void GenerateGrounds(Grid grid, TerrainChunk tc, int y = 0, bool ceiling = false) { // Generate ground and potholes //First and last cannot be a hole. for (int i = 0; i < grid.numCellsX; ++i) { if (grid.containsObject(i, y)) { continue; } //level is chance that there is a hole! Do not spawnground! //int rand = Random.Range (0, 101); //if(!(i ==0 || i == grid.numCellsX)) //{ if (initCeiling == 0) { initCeiling++; continue; } //} // Generate random width ground pieces varying from 1-3 int cap, roll; do { //cap = Mathf.Min (4, grid.numCellsX - i + 1); roll = 3; } while (!GenerateWideGround(i, y, roll, grid, tc, ceiling)); } }
/// <summary> /// Create a chunk /// </summary> /// <param name="postion"></param> /// <returns></returns> public TerrainChunk GenerateChunk(Vector3 position) { TerrainChunk chunk = Instantiate(ChunkPrefab, position, Quaternion.identity, ChunksParent).GetComponent<TerrainChunk>(); chunk.gameObject.transform.localScale = ChunkScale; chunk.Scale = ChunkScale; return chunk; }
/// <summary> /// /// </summary> /// <param name="terrainData"></param> private void ApplyTrees(TerrainData terrainData) { if (Setting.Trees.Count > 0) { int maxCounts = 5; int treeIndex = Random.Range(0, Setting.Trees.Count - 1); for (int i = 0; i < ChopPoint.Count; i++) { Vector3 treePoint = ChopPoint[i]; for (int j = 0; j < maxCounts; j++) { Vector3 random = new Vector3(Random.Range(treePoint.x - 0.1f, treePoint.x + 0.1f), -0.1f, Random.Range(treePoint.y - 0.1f, treePoint.y + 0.1f)); Vector3 position = Vector3.Scale(random, TerrainChunk.terrainData.size) + TerrainChunk.transform.position; position.y = TerrainChunk.SampleHeight(position); GameObject tree = GameObject.Instantiate(Setting.Trees[treeIndex]); tree.transform.position = position; tree.transform.parent = TerrainChunk.transform; } } List <TreePrototype> trees = new List <TreePrototype>(); for (int i = 0; i < Setting.Trees.Count; i++) { TreePrototype tree = new TreePrototype(); tree.prefab = Setting.Trees[i]; trees.Add(tree); } terrainData.treePrototypes = trees.ToArray(); for (int i = 0; i < TreePoint.Count; i++) { Vector3 vpos = TreePoint[i]; for (int j = 0; j < 10; j++) { TreeInstance tmpTreeInstances = new TreeInstance(); tmpTreeInstances.prototypeIndex = 3; tmpTreeInstances.position = new Vector3(Random.Range(vpos.x - 0.1f, vpos.x + 0.1f), -0.1f, Random.Range(vpos.y - 0.1f, vpos.y + 0.1f)); tmpTreeInstances.color = new Color(1, 1, 1, 1); tmpTreeInstances.lightmapColor = new Color(1, 1, 1, 1); float scale = Random.Range(0.8f, 1f); tmpTreeInstances.heightScale = scale; tmpTreeInstances.widthScale = scale; TerrainChunk.AddTreeInstance(tmpTreeInstances); } } TerrainCollider tc = TerrainChunk.GetComponent <TerrainCollider>(); tc.enabled = false; tc.enabled = true; } }
/// <summary> /// Creates the terrain. /// </summary> public void CreateTerrain() { Data = new TerrainData(); Data.heightmapResolution = Setting.HeightmapResolution; Data.alphamapResolution = Setting.AlphamapResolution; Data.SetHeights(0, 0, Heightmap); ApplyTextures(Data); Data.size = new Vector3(Setting.Length, Setting.Height, Setting.Length); GameObject newTerrainGameObject = Terrain.CreateTerrainGameObject(Data); newTerrainGameObject.transform.position = new Vector3(Position.X * Setting.Length, 0, Position.Z * Setting.Length); // create a new terrain chunk TerrainChunk = newTerrainGameObject.GetComponent <Terrain>(); TerrainChunk.heightmapPixelError = 8; TerrainChunk.materialType = UnityEngine.Terrain.MaterialType.Custom; TerrainChunk.materialTemplate = Setting.TerrainMaterial; TerrainChunk.reflectionProbeUsage = UnityEngine.Rendering.ReflectionProbeUsage.Off; TerrainChunk.Flush(); ApplyTrees(Data); }
public void SetLocs(BlockType[,,] blocks, TerrainChunk terrainChunk) { int y; for (int x = 0; x < 16; x++) { for (int z = 0; z < 16; z++) { locs[x, z] = 0; y = TerrainChunk.chunkHeight - 1; //find the ground while (y > 0 && blocks[x + 1, y, z + 1] == BlockType.Air) { y--; } if (y + 1 < waterHeight) { locs[x, z] = 1; //blocks[x+1, y+1, z+1] = BlockType.Water; while (y + 1 < waterHeight) { blocks[x + 1, y + 1, z + 1] = BlockType.Water; y++; } } } } }
private void ExpandTerrainFromChunk(TerrainChunk chunk) { if (!chunk.canExpandToNeighbours) { return; } foreach (var side in EnumUtil <CubeSide> .intValues) { if (chunk.hasNeighbourOnSide[side]) { continue; } // Skip expansions to sides that don't contain a surface, but only // when there already is a chunk with a surface in the terrain if (!chunk.hasSignChangeOnSide[side] && chunksWithSignChange > 0) { continue; } var newChunkOrigin = GetNeighbourChunkOrigin(chunk, (CubeSide)side); if (math.distance(playerTransform.position, (float3)newChunkOrigin * (TerrainChunk.CHUNK_SIZE * voxelSize)) > chunkDrawDistance * (TerrainChunk.CHUNK_SIZE * voxelSize)) { continue; } GetOrCreateChunkByKey(new ChunkKey { origin = newChunkOrigin }); } }
void Start() { TerrainChunk chunk = new TerrainChunk(Vector2.zero, settings.mapSize, settings, tilemap); chunk.onTerrainChunkLoaded += OnTerrainChunkLoaded; chunk.Load(); }
public Chunk CreateChunk(int x, int z, bool unLimited = false) { int chunkX = x >> 4; int chunkY = z >> 4; TerrainChunk chunkAtCell = subsystemTerrain.Terrain.GetChunkAtCoords(chunkX, chunkY); if (chunkAtCell == null) { if (!unLimited) { return(null); } chunkAtCell = subsystemTerrain.Terrain.AllocateChunk(chunkX, chunkY); while (chunkAtCell.ThreadState < TerrainChunkState.Valid) { subsystemTerrain.TerrainUpdater.UpdateChunkSingleStep(chunkAtCell, 15); } } Chunk chunk1 = new Chunk(chunkX, chunkY); chunk1.Cells = new int[chunkAtCell.Cells.Length]; for (int i = 0; i < chunkAtCell.Cells.Length; i++) { chunk1.Cells[i] = chunkAtCell.Cells[i]; } //Array.Copy(chunkAtCell.Cells,chunk1.Cells,chunkAtCell.Cells.Length); //chunk1.Cells = chunkAtCell.Cells; this.chunksData.Add(chunk1); return(chunk1); }
public void GenerateTerrain(Vector3 spawnPos) { grid.ClearGrid(); TerrainChunk tc = GameObject.Instantiate(terrainChunk, spawnPos, Quaternion.identity) as TerrainChunk; // Generate ground // Experimental: Generate ground separately for Nback // groundGen.GenerateGrounds(grid, tc); // Generate For Pattern if (gameMngr.Modes().Contains(GameModes.Pattern)) { //Platforms should also be spawned in cloud format! /*if(genPlatforms) * { * platformGen.GeneratePlatforms (grid, tc); * * } * if(genPlants) * { * collectibleGen.GenerateCollectibles (grid, tc); * }*/ } // Generate For Nback if (gameMngr.Modes().Contains(GameModes.Nback)) { nbackGen.GenerateNbackInGrid(grid, tc, groundGen); } else { groundGen.GenerateGrounds(grid, tc); } }
void UpdateVisibleChunks() { HashSet <Vector2> updatedChunks = new HashSet <Vector2>(); for (int i = _visibleTerrainChunks.Count - 1; i >= 0; i--) { _visibleTerrainChunks[i].UpdateTerrainChunk(); updatedChunks.Add(_visibleTerrainChunks[i].coord); } int currentChunkX = Mathf.RoundToInt(viewerPos.x / chunkSize); int currentChunkY = Mathf.RoundToInt(viewerPos.y / chunkSize); for (int yOffset = -chunksInViewDistance; yOffset <= chunksInViewDistance; yOffset++) { for (int xOffset = -chunksInViewDistance; xOffset <= chunksInViewDistance; xOffset++) { Vector2 viewChunkCoord = new Vector2(currentChunkX + xOffset, currentChunkY + yOffset); if (!updatedChunks.Contains(viewChunkCoord)) { if (!_chunks.ContainsKey(viewChunkCoord)) { _chunks[viewChunkCoord] = new TerrainChunk(viewChunkCoord, chunkSize, detailLevels, colliderLODIndex, transform, material); } else { _chunks[viewChunkCoord].UpdateTerrainChunk(); } } } } }
private void Update() { Ray ray = new Ray(transform.position, transform.forward); hasSth = Physics.Raycast(ray, maxDistance, modifyLayer); bool leftClick = Input.GetMouseButtonDown(0); if (leftClick) { RaycastHit hitInfo; if (Physics.Raycast(transform.position, transform.forward, out hitInfo, maxDistance, modifyLayer)) { Vector3 pointInTargetBlock = hitInfo.point + transform.forward * .01f; //move a little inside the block int cubePosX = Mathf.FloorToInt(pointInTargetBlock.x); int cubePosY = Mathf.FloorToInt(pointInTargetBlock.y); int cubePosZ = Mathf.FloorToInt(pointInTargetBlock.z); Debug.LogFormat("cubePosX:{0},PosY:{1},PosZ:{2}", cubePosX, cubePosY, cubePosZ); int chunkPosX = Mathf.FloorToInt(pointInTargetBlock.x / TerrainChunk.chunkWidth) * TerrainChunk.chunkWidth; int chunkPosZ = Mathf.FloorToInt(pointInTargetBlock.z / TerrainChunk.chunkWidth) * TerrainChunk.chunkWidth; Debug.LogFormat("ChunkPosX:{0},ChunkPosZ:{1}", cubePosX, cubePosZ); TerrainChunk chunk = TerrainGenerator.chunks[new ChunkPos(chunkPosX, chunkPosZ)]; chunk.blocks[cubePosX - chunkPosX, cubePosY, cubePosZ - chunkPosZ] = BlockType.Air; chunk.BuildMesh(); } } }
public void SetLocs(BlockType[,,] blocks, TerrainChunk terrainChunk) { int y; var chunkHeight = SettingsHolder.Instance.currentGenerationSettings.chunkHeight; var seaLevel = SettingsHolder.Instance.currentGenerationSettings.seaLevel; for (int x = 0; x < 16; x++) { for (int z = 0; z < 16; z++) { locs[x, z] = 0; y = chunkHeight - 1; //find the ground while (y > 0 && blocks[x + 1, y, z + 1] == BlockType.Air) { y--; } if (y + 1 < seaLevel) { locs[x, z] = 1; //blocks[x+1, y+1, z+1] = BlockType.Water; while (y + 1 < seaLevel) { blocks[x + 1, y + 1, z + 1] = BlockType.Water; y++; } } } } }
// Find targeted voxel, check its toughness points, remove voxel and create loot object void Dig(Vector3 p) { Voxel vox = null; TerrainChunk chunk = null; Terrain.instance.FindVoxel(p, ref vox, ref chunk); if (vox.IsSolid() && chunk != null) { /* * GameObject loot = Instantiate (pfLoot); * loot.transform.parent = chunk.transform; * loot.transform.localPosition = new Vector3(vox.position.x, vox.position.y, 0f) + new Vector3(VOXEL_SIZE * .5f, VOXEL_SIZE * .5f, 0f); + loot.transform.localRotation = Quaternion.Euler(0f, 0f, Random.Range(0f, 90f)); */ var itemPresetId = vox.GetBlockItemPresetId(); if (itemPresetId != Item.PresetId.Void) { inventory.AddAndStack(Item.Create(itemPresetId)); guiInventory.UpdateGuiElements(inventory); } Terrain.instance.EditVoxels(p); } }
void UpdateVisibleChunks() { // deactivate all previous chunks to avoid leaving active chunks behind foreach (TerrainChunk chunk in terrainChunksVisibleLastUpdate) { chunk.SetVisible(false); } terrainChunksVisibleLastUpdate.Clear(); int currentChunkCoordX = Mathf.RoundToInt(viewerPosition.x / chunkSize); int currentChunkCoordY = Mathf.RoundToInt(viewerPosition.y / chunkSize); for (int yOffset = -chunksVisibleInViewDst; yOffset <= chunksVisibleInViewDst; yOffset++) { for (int xOffset = -chunksVisibleInViewDst; xOffset <= chunksVisibleInViewDst; xOffset++) { Vector2 viewedChunkCoord = new Vector2(currentChunkCoordX + xOffset, currentChunkCoordY + yOffset); //Debug.Log("Generating chunks on " + viewedChunkCoord.x + ":" + viewedChunkCoord.y); if (terrainChunks.ContainsKey(viewedChunkCoord)) { TerrainChunk terrainChunk = terrainChunks[viewedChunkCoord]; terrainChunk.UpdateTerrainChunk(); } else { //Debug.Log("Adding new chunk on " + viewedChunkCoord.x + ":" + viewedChunkCoord.y); terrainChunks.Add(viewedChunkCoord, new TerrainChunk(viewedChunkCoord, chunkSize, detailLevels, transform, mapMaterial)); } } } }
private void OnChunkAdded(TerrainChunk chunk) { if (chunk.hasFloor) { if (UnityEngine.Random.value < 0.1f) { CreateForest(chunk); if (terrainChunks.Count >= 2) CreateForestWarningSign(terrainChunks[terrainChunks.Count - 2]); } } }
private void CreateForest(TerrainChunk chunk) { PolydrawObject floor = chunk.GetFirstFloor(); List<Vector2> points = floor.GetWorldBorderPoints(); foreach (Vector2 point in points) { GameObject tree = Instantiate(treePrefab); tree.transform.SetParent(floor.transform); tree.transform.position = point; } }
public void GenerateNbackInGrid(Grid grid, TerrainChunk tc, GroundGenerator ggen) { int difficulty = navigationDifficulty; int scale = 10; // Generate beginning so character doesnt fall if (generateCount == 0) { for (int i = 0; i < 5; ++i) { ggen.GenerateGround (i, 0, grid, tc); ggen.GenerateGround (i, 7, grid, tc); } } ++generateCount; // Entry for prototype platforms generation if (platforms) { GenerateNbackInGridPlatforms(grid, tc, ggen); return; } // Generate Nback collectibles int x = lastGridOffset; for ( ; x < grid.numCellsX; x += rate) { int rand = Random.Range(0, 2); int y = rand == 0 ? 1 : 6; Transform h = GenerateNbackObjectInGrid(x, y, grid, tc); } // Generate ground and potholes for (int i = 0; i < grid.numCellsX; ++i) { // For floor // Generate ground (NOT pothole) by scale and difficulty if (grid.containsObject(i, 0)) { Debug.Log ("Grid Contains at: " + i); continue; } int cap = Mathf.Min (4, grid.numCellsX - i + 1); int roll = Random.Range (1, cap); while (!ggen.GenerateWideGround(i, 0, roll, grid, tc)) { roll = Random.Range (1, 4); } // int rand = Random.Range(0, 100); // if (rand > difficulty * scale) { // ggen.GenerateGround (i, 0, grid, tc); // } // // // For Ceiling // rand = Random.Range(0, 100); // if (rand > difficulty * scale) { // //ggen.GenerateGround (i, 7, grid, tc); // } } lastGridOffset = x - grid.numCellsX; }
public Transform GenerateGround(int x, int y, Grid grid, TerrainChunk tc) { if (grid.containsObject(x, y)) { return null; } Vector3 spawnPos = grid.GridToWorld (x,y) + tc.transform.position; Transform t = GenerateGround (spawnPos.x, spawnPos.y); t.parent = tc.gameObject.transform; grid.MarkGrid (x, y); return t; }
public void GenerateGrounds(Grid grid, TerrainChunk tc) { for (int x = 0; x < grid.numCellsX; x++) { if (Random.value < pitSpawnChance && !previousHasPit) { previousHasPit = !grid.containsObject(x,0); continue; } GenerateGround (x, 0, grid, tc); if (Random.value < hillSpawnChance && !previousHasPit) { Transform h = GenerateGround (x, 1, grid, tc); h.tag = "Hill"; } previousHasPit = false; } }
// Generates platform of the specified type at the grid location (x,y) public Transform GeneratePlatform(int x, int y, int type, Grid grid, TerrainChunk tc) { for (int i = 0; i < platforms[type].numCells; i++) { if (grid.containsObject(x + i, y)) { return null; } } Vector3 offset = new Vector3 (((float)(platforms[type].numCells - 1)) * 0.5f * grid.cellSizeX, 0f, 0f); Vector3 spawnPos = grid.GridToWorld (x, y) + offset + tc.transform.position; for (int i = 0; i < platforms[type].numCells; i++) { grid.MarkGrid (x + i, y); } Transform t = GeneratePlatform (spawnPos.x, spawnPos.y, type); t.parent = tc.gameObject.transform; return t; }
public Transform GenerateWideGround(int x, int y, int wide, Grid grid, TerrainChunk tc, bool ceiling = false) { // Check grid spaces aren't currently occupied for (int i = x; i < x + wide; ++i) { if (grid.containsObject(i, y)) { return null; } } // Position piece by averaging the grid space positions Vector3 spawnPos = new Vector3 (0, 0, 0); for (int i = x; i < x + wide; ++i) { spawnPos += grid.GridToWorld(i, y); } spawnPos /= wide; spawnPos += tc.transform.position; //spawnPos.y = 0; spawnPos.z = 0; //Vector3 spawnPos = grid.GridToWorld (x, y) + tc.transform.position; // Create piece Transform piece; if (ceiling) { piece = ceiling3wide; if (y == 7) { float topY = Camera.main.ScreenToWorldPoint(new Vector3(0, Camera.main.pixelHeight, 0)).y; spawnPos.y = topY - (grid.cellSizeY / 2.0f) + 0.2f; }else{ Vector3 newPos = spawnPos; newPos.y = y-1.3f; Transform test = GameObject.Instantiate (ceiling3big, newPos, Quaternion.identity) as Transform; } } else { piece = ground3wide; } Transform t = GameObject.Instantiate (piece, spawnPos, Quaternion.identity) as Transform; // Mark grid spaces for (int i = x; i < x + wide; ++i) { grid.MarkGrid(i, y); } Destroy (t.gameObject, 15); return t; }
public void DrawToMesh(float x, float y, ChunkMesh msh, TerrainChunk chunk, int xi, int yi) { if(invisible) return; float xp = x * blockSize; float yp = y * blockSize; MakeFrontFace(xp, yp, msh); if(yi == TerrainChunk.ChunkHeight - 1 || chunk[xi, yi + 1].invisible) MakeTopFace(xp, yp, msh); if(yi == 0 || chunk[xi, yi - 1].invisible) MakeBottomFace(xp, yp, msh); if(xi == 0 || chunk[xi - 1, yi].invisible) MakeLeftFace(xp, yp, msh); if(xi == TerrainChunk.ChunkWidth - 1 || chunk[xi + 1, yi].invisible) MakeRightFace(xp, yp, msh); }
// Entry for prototype platforms generation public void GenerateNbackInGridPlatforms(Grid grid, TerrainChunk tc, GroundGenerator ggen) { int x = lastGridOffset; int topY = grid.numCellsY - 2; int midY = topY / 2; for ( ; x < grid.numCellsX; x += rate) { int roll = Random.Range (0, 4); int placement = roll == 0 ? 1 : (roll == 1 ? midY + 1: topY + 1); Transform h = GenerateNbackObjectInGrid(x, placement, grid, tc); } lastGridOffset = x - grid.numCellsX; for (int y = 0; y <= grid.numCellsY; ++y) { ggen.GenerateGround(y, topY, grid, tc); ggen.GenerateGround(y, midY, grid, tc); ggen.GenerateGround(y, 0, grid, tc); } return; }
public void SetRightChunk(TerrainChunk next) { nextChunk = next; }
private void OnLastChunkInSetAdded(TerrainChunk chunk) { if (chunk.hasFloor) CreateFloorArrowSign(chunk); else if (chunk.hasCeiling) CreateCeilingArrowSign(chunk); IncrementSet(); }
/// <summary> /// Attempt to deserialise the point data of the chunk. /// </summary> /// <param name="chunk">The chunk.</param> /// <returns>True if the terrain chunk was deserialised.</returns> public bool TryDeserialisePoints(TerrainChunk chunk) { // TODO: This is not yet implemented return false; }
public static TerrainChunk MakeShaftChunk(int diameter, float depth) { TerrainChunk output = new TerrainChunk(diameter, diameter); int center_x = diameter / 2; int center_y = diameter / 2; output.Map((x, y) => { int dx = (center_x - x); int dy = (center_y - y); float distance = Mathf.Sqrt(dx * dx + dy * dy); distance = 1 - (distance / (diameter / 2)); return 1 - (Mathf.Clamp(distance, 0, 1) * depth); }); return output; }
public TerrainChunk Clone() { TerrainChunk output = new TerrainChunk(0, 0); output.data = (float[,])this.data.Clone(); output.textureData = (float[,,])this.textureData.Clone(); return output; }
/// <summary> /// Serialise the point data of the chunk. /// </summary> /// <param name="chunk">The chunk.</param> public void SerialisePointData(TerrainChunk chunk) { // TODO throw new NotImplementedException(); }
public void SetLeftChunk(TerrainChunk prev) { previousChunk = prev; }
/// <summary> /// Updates the foreground density if the given density is larger than the point's. /// </summary> /// <param name="chunk">The chunk.</param> /// <param name="x">The x position.</param> /// <param name="y">The y position.</param> /// <param name="density">The foreground density.</param> private void UpdateForegroundIfGreaterDensity(TerrainChunk chunk, int x, int y, byte density) { TerrainPoint point = chunk.Points[x, y]; if (point.Foreground < density) { point.Foreground = density; } }
public void GenerateNbackInGrid(Grid grid, TerrainChunk tc, GroundGenerator ggen) { //Called from Terrainen int difficulty = navigationDifficulty; int scale = 10; // Generate beginning so character doesnt fall if (generateCount == 0) { for (int i = 0; i < 5; ++i) { //ggen.GenerateGround (i, 0, grid, tc); //ggen.GenerateGround (i, 7, grid, tc); } } ++generateCount; //Entry for prototype platforms generation /*if (platforms) { GenerateNbackInGridPlatforms(grid, tc, ggen); return; }*/ // Generate Nback collectibles on floor,ceiling, and random int x = lastGridOffset; int y = 3; for ( ; x < grid.numCellsX; x += rate) { int rand = Random.Range(0, 2); //int y = rand == 0 ? 1 : 6; if(timer >= 0f && timer < 40f){ y = 3; } else if (timer >= 40f && timer < 80f) { y = 5; } else if (timer >= 80f && timer < 120f) { y = 6; } else if (timer >= 120f && timer < 240f) { y = 1; } else if (timer >= 240f && timer < 280) { y = rand == 0 ? 1 : 5; } else if ((timer >= 280f && timer < 320f) || (timer >= 360f && timer < 480f)) { y = rand == 0 ? 1 : 6; } else if ((timer >= 320f && timer < 360f) || timer >= 480f) { y = rand == 0 ? 1 : 4; } // Used to create empty space between levels and updates current level int emptyspace = 0; if(timer >= 120 && timer < 125){ currentLevel = 2; emptyspace = 1; }else if(timer >= 240 && timer < 245){ currentLevel = 3; emptyspace = 1; }else if(timer >= 360 && timer < 365){ currentLevel = 4; emptyspace = 1; }else if(timer >= 480 && timer < 485){ currentLevel = 5; emptyspace = 1; }else if(timer >= 0 && timer < 120){ currentLevel = 1; emptyspace = 0; }else{ emptyspace = 0; } if(emptyspace == 0){ Transform h = GenerateNbackObjectInGrid(x, y, grid, tc); } } //GenerateGround ggen.GenerateGrounds (grid, tc, 0, false); //Generate Ceilings depending on timer if ((timer >= 0 && timer < 40) || (timer >= 200f && timer < 240f) || (timer >= 320f && timer < 360f) || timer >= 480f) { ggen.GenerateGrounds (grid, tc, 5, true); } else if ((timer >= 40f && timer < 80f) || (timer >= 160f && timer < 200f) || (timer >= 240f && timer < 280f)) { ggen.GenerateGrounds (grid, tc, 6, true); } else if ((timer >= 80f && timer < 160f) || (timer >= 280f && timer < 320f) || (timer >= 360f && timer < 480f)) { ggen.GenerateGrounds (grid, tc, 7, true); } lastGridOffset = x - grid.numCellsX; }
public TerrainChunk GenerateChunk(XZPair id) { int offsetX = id.X*_blockWidth*(_chunkWidthInBlocks); int offsetZ = id.Z*_blockWidth*(_chunkWidthInBlocks); var rawGeometry = new float[_chunkWidthInVerts*_chunkWidthInVerts*4]; var rawNormals = new ushort[_chunkWidthInVerts * _chunkWidthInVerts * 4]; var rawBinormals = new byte[_chunkWidthInVerts*_chunkWidthInVerts*4]; var rawTangents = new byte[_chunkWidthInVerts*_chunkWidthInVerts*4]; var rawUVCoords = new float[_chunkWidthInVerts*_chunkWidthInVerts*2]; var indicies = new int[(_chunkWidthInBlocks)*(_chunkWidthInBlocks)*8]; var activeVerts = new byte[_chunkWidthInVerts*_chunkWidthInVerts]; _terrainGenKernel.SetValueArgument(1, offsetX); _terrainGenKernel.SetValueArgument(2, offsetZ); _normalGenKernel.SetValueArgument(1, offsetX); _normalGenKernel.SetValueArgument(2, offsetZ); _cmdQueue.WriteToBuffer(_emptyVerts, _activeVerts, true, null); _cmdQueue.WriteToBuffer(_emptyIndices, _indicies, true, null); _cmdQueue.Execute(_terrainGenKernel, null, new long[]{_chunkWidthInVerts, _chunkWidthInVerts}, null, null); _cmdQueue.Execute(_normalGenKernel, null, new long[]{_chunkWidthInVerts, _chunkWidthInVerts}, null, null); for (int depth = 0; depth < 5; depth++){ _qTreeKernel.SetValueArgument(0, depth); _crossCullKernel.SetValueArgument(0, depth); int cellWidth = (int) Math.Pow(2, depth)*2; int qTreeWidth = _chunkWidthInBlocks/(cellWidth); _cmdQueue.Execute(_qTreeKernel, null, new long[]{(qTreeWidth) - 1, (qTreeWidth*2)}, null, null); _cmdQueue.Execute(_crossCullKernel, null, new long[]{_chunkWidthInBlocks/cellWidth, _chunkWidthInBlocks/cellWidth}, null, null); } _cmdQueue.Execute(_winderKernel, null, new long[]{(_chunkWidthInBlocks), (_chunkWidthInBlocks*2)}, null, null); _cmdQueue.ReadFromBuffer(_geometry, ref rawGeometry, true, null); _cmdQueue.ReadFromBuffer(_normals, ref rawNormals, true, null); _cmdQueue.ReadFromBuffer(_binormals, ref rawBinormals, true, null); _cmdQueue.ReadFromBuffer(_tangents, ref rawTangents, true, null); _cmdQueue.ReadFromBuffer(_uvCoords, ref rawUVCoords, true, null); _cmdQueue.ReadFromBuffer(_indicies, ref indicies, true, null); _cmdQueue.ReadFromBuffer(_activeVerts, ref activeVerts, true, null); _cmdQueue.Finish(); for (int v = 3; v < rawNormals.Length; v += 4){ rawNormals[v] = 1; } for (int v = 3; v < rawBinormals.Length; v += 4){ rawBinormals[v] = 1; } for (int v = 3; v < rawTangents.Length; v += 4){ rawTangents[v] = 1; } var texNormal = new Texture2D(Gbl.Device, _chunkWidthInVerts, _chunkWidthInVerts, false, SurfaceFormat.Rgba64); var texBinormal = new Texture2D(Gbl.Device, _chunkWidthInVerts, _chunkWidthInVerts, false, SurfaceFormat.Color); var texTangent = new Texture2D(Gbl.Device, _chunkWidthInVerts, _chunkWidthInVerts, false, SurfaceFormat.Color); texNormal.SetData(rawNormals); texBinormal.SetData(rawBinormals); texTangent.SetData(rawTangents); //var maxHeight = verts.Aggregate((agg, next) => next.Y > agg.Y ? next : agg).Y; //var minHeight = verts.Aggregate((agg, next) => next.Y < agg.Y ? next : agg).Y; //these functions take the raw buffer data from opencl and remove stride and empty fields var parsedUV = ParseUV(rawUVCoords); var parsedGeometry = ParseGeometry(rawGeometry); var parsedIndicies = ParseIndicies(indicies); var sw = new Stopwatch(); sw.Start(); int[] culledIndexes; VertexPositionTexture[] culledVertexes; CullVertexes(activeVerts, parsedIndicies.ToList(), parsedGeometry, parsedUV, out culledIndexes, out culledVertexes); sw.Stop(); double elapsed = sw.ElapsedMilliseconds; var chunkData = new TerrainChunk(id, culledVertexes, culledIndexes, texNormal, texBinormal, texTangent); return chunkData; }
void Update() { timeOfDay += Time.deltaTime; float dayProgress = timeOfDay / dayLength; float dayPeriod = (Mathf.PI * 2.0f) * dayProgress; float intensityPct = (Mathf.Cos(dayPeriod) + 1.0f) / 2.0f; sunLight.intensity = (intensityPct * maxSunIntensity) + minSunIntensity; Vector3 dayColor = new Vector3(daylightColor.r, daylightColor.g, daylightColor.b); Vector3 setColor = new Vector3(sunsetColor.r, sunsetColor.g, sunsetColor.b); Vector3 interpColor = Vector3.Lerp(dayColor, setColor, 1.0f - intensityPct); Color currentColor = new Color(interpColor.x, interpColor.y, interpColor.z); sunLight.color = currentColor; if(timeOfDay > dayLength) { StartOfNewDay(); } // Which chunk is the player currently in foreach(TerrainChunk chunk in worldGenerator.ChunkList()) { if(chunk.ContainsPoint(playerCharacter.transform.position)) { if(chunk != relevantChunk) { chunk.BecomeRelevant(); if(chunk.GetRightChunk() != null) { chunk.GetRightChunk().BecomeRelevant(); } } relevantChunk = chunk; break; } } }
public void AddChunk(TerrainChunk chunk, int start_x, int start_y, AddMode mode = AddMode.Add) { int minWidth = Mathf.Min(chunk.data.GetLength(0), this.data.GetLength(0) - start_x); int minHeight = Mathf.Min(chunk.data.GetLength(1), this.data.GetLength(1) - start_y); float centerValue = this.data[start_x + chunk.GetWidth() / 2, start_y + chunk.GetHeight() / 2]; for (int x = 0; x < minWidth; x++) { for (int y = 0; y < minHeight; y++) { int xc = start_x + x; int yc = start_y + y; if (xc < 0 || yc < 0) { continue; } switch (mode) { case AddMode.Add: this.data[xc, yc] = this.data[xc, yc] + chunk.data[x, y]; if (chunk.data[x, y] != 0) { for (int layer = 0; layer < TEXTURE_COUNT; layer++) { this.textureData[xc, yc, layer] = this.textureData[xc, yc, layer] + chunk.textureData[x, y, layer] * 4; } } break; case AddMode.Max: if (chunk.data[x, y] != 0 && chunk.data[x, y] > this.data[xc, yc]) { for (int layer = 0; layer < TEXTURE_COUNT; layer++) { this.textureData[xc, yc, layer] = chunk.textureData[x, y, layer]; } } this.data[xc, yc] = Mathf.Max(this.data[xc, yc], chunk.data[x, y]); break; case AddMode.Min: this.data[xc, yc] = Mathf.Min(this.data[xc, yc], chunk.data[x, y]); break; case AddMode.RelaMin: this.data[xc, yc] = Mathf.Min(this.data[xc, yc], centerValue - chunk.data[x, y]); break; } } } }
public void AddChunkAtPoints(TerrainPoint[] points, TerrainChunk chunk, AddMode mode = AddMode.Add) { for (int i = 0; i < points.Length; i++) { int x = points[i].x; int y = points[i].y; this.AddChunk(chunk, x - chunk.GetWidth() / 2, y - chunk.GetHeight() / 2, mode); } }
private void CreateForestWarningSign(TerrainChunk chunk) { if (chunk.hasFloor) CreateFloorWarningSign(chunk); else if (chunk.hasCeiling) CreateCeilingWarningSign(chunk); }
/// <summary> /// Creates a new chunk. /// </summary> /// <param name="chunk">The chunk.</param> /// <param name="surfaceHeights">The surface heights.</param> public void GeneratePoints(TerrainChunk chunk, float[] surfaceHeights) { int originX = chunk.Index.X * Metrics.ChunkWidth; int originY = chunk.Index.Y * Metrics.ChunkHeight; SurfacePosition? surfacePosition = null; for (int x = 0; x < Metrics.ChunkWidth; x++) { // Determine where the surface lies for this x position float surface = surfaceHeights[x]; // Update the on-going check for the surface position surfacePosition = this.CheckSurfacePosition(surfacePosition, surface, originY); for (int y = 0; y < Metrics.ChunkHeight; y++) { int worldX = originX + x; int worldY = originY + y; // Calculate the background and foreground densities byte background = this.GetBackgroundDensity(worldX, worldY, surface); // Get the cave densities for this point PointDensities densities = this.GetCaveDensitiesForPoint(worldX, worldY); if (densities.Origin < background) { // The density cannot be less than the background (ie. if the background is dug out, the // foreground cannot be filled in) densities.Origin = background; } // Update the densities byte foreground = densities.Origin > background ? densities.Origin : background; this.UpdateForegroundIfGreaterDensity(chunk, x, y, foreground); if (x < Metrics.ChunkWidth - 1) { this.UpdateForegroundIfGreaterDensity(chunk, x + 1, y, densities.Right); } if (y < Metrics.ChunkHeight - 1) { this.UpdateForegroundIfGreaterDensity(chunk, x, y + 1, densities.Up); } // Determine the material TerrainMaterial material = this.GetMaterial(worldX, worldY, surface); // TODO: Remove this int val = 255 - (int)(System.Math.Abs((float)worldY) * 8); byte lightTest = val > 0 ? (byte)val : (byte)0; var light = new Colour(lightTest, lightTest, lightTest); // TODO: Remove this // Update the point TerrainPoint point = chunk.Points[x, y]; point.Background = background; point.Material = material; point.Light = light; } } chunk.SurfacePosition = surfacePosition.Value; }
Transform GenerateNbackObjectInGrid(int x, int y, Grid grid, TerrainChunk tc) { if (grid.containsObject(x, y)) { return null; } Vector3 spawnPos = grid.GridToWorld (x,y) + tc.transform.position; Transform t = GenerateNbackObject (spawnPos.x, spawnPos.y); // Used to spawn randomly placed obstacles from floor to ceiling in levels 4 and 5 int r = Random.Range (-7, 5); int r2 = Random.Range (-7, 0); if (timer >= 360f && timer < 480f) { Transform i = GenerateObstacles (spawnPos.x+5, r); } else if (timer >= 480) { Transform i = GenerateObstacles (spawnPos.x+5, r2); } t.parent = tc.gameObject.transform; grid.MarkGrid (x, y); return t; }
/*public void Simplify(float amount) { int resolution = this.GetWidth() / amount; for (int x = 0; x < this.GetWidth(); x += resolution) { for (int y = 0; y < this.GetHeight(); y += resolution) { float ul = this.data[x, y]; float lr = this.data[x + resolution, y + resolution]; for (int x2 = x; x2 < x + resolution; x2++) { for (int y2 = y; y2 < y + resolution; y2++) { float xv = (x2 - x) / resolution; float yv = (y2 - y) / resolution; this.data[x2, y2] = this.data } } } } }*/ public void HeightBlend(TerrainChunk other) { float[] flat = this.data.Cast<float>().ToArray(); float min = Mathf.Min(flat); float max = Mathf.Max(flat); float v = Mathf.Clamp(max - min, 0.01f, 1.0f); for (int x = 0; x < this.GetWidth(); x++) { for (int y = 0; y < this.GetHeight(); y++) { float f = (this.data[x, y] - min) / v; this.data[x, y] = (this.data[x, y] * (1 - f)) + (other.data[x, y] * f); for (int layer = 0; layer < TEXTURE_COUNT; layer++) { this.textureData[x, y, layer] = (this.textureData[x, y, layer] * (1 - f)) + (other.textureData[x, y, layer] * f); } } } }
// Use this for initialization void Start() { rend = GetComponent<ChunkRenderer>(); rend.chunk = chunk = new TerrainChunk(fill); }
/******************************************* Polygon Utilities ***********************************************/ /** Gets a totally random point that is almost garunteed to be in the chunk */ public Vector2 RandomPointInChunk(TerrainChunk chunk) { int segmentIdx = Random.Range(0, chunk.NumTriangles()); Vector2[] tri = chunk.GetTriangle(segmentIdx); if(tri == null) { return chunk.GetCenter(); } // this 0 - 0.5 range actually seems to give the most even distribution, with some nice natural looking clumping float posA = Random.Range(0.0f, 0.5f); float posB = Random.Range(0.0f, 0.5f); Vector2 mirroredPoint = tri[0] + posA * (tri[1] - tri[0]) + posB * (tri[2] - tri[0]); Vector2 invertedV0 = tri[0] + (tri[1] - tri[0]) + (tri[2] - tri[0]); Vector2 pointInTri = tri[0] - (mirroredPoint - invertedV0); bool bInTriAlready = PointInTriangle(tri, mirroredPoint); Vector2 finalPos = bInTriAlready? mirroredPoint : pointInTri; return finalPos; }