/// <summary> /// Spawns a GameObject on many voxels in a chunk. /// </summary> /// <param name="chunk">Chunk.</param> /// <param name="chunkGridCoord">Chunk grid coordinate.</param> /// <param name="obj">Object.</param> void onManyVoxelPosition(Chunks chunk, Vec3Int chunkGridCoord, GameObject obj) { Vector3 chunkBCoords = new Vector3(chunkGridCoord.x, chunkGridCoord.y, chunkGridCoord.z) * vxe.chunk_size; Random.seed = (int)Time.frameCount; for (int x = 0; x < vxe.chunk_size; x++) { for (int z = 0; z < vxe.chunk_size; z++) { for (int y = vxe.chunk_size - 1; y >= 0; y--) { Voxel vx = chunk.getVoxel(new Vec3Int(x, y, z)); if (vx.isOccupied() && vxe.voxelHasSurface(vx, VF.VX_TOP_SHOWN)) { Vector3 voxelCoords = vxe.FromGridUnTrunc(chunkBCoords + new Vector3(x, y, z)); if (Random.Range(0, 20) == 0) { GameObject newObj = Instantiate(obj, voxelCoords + Vector3.up * vxe.voxel_size * 1.0f, Quaternion.AngleAxis(Random.Range(0, 360), Vector3.up)) as GameObject; newObj.transform.parent = obj.transform.parent; newObj.SetActive(true); spawns.push(newObj.GetComponent <SpawnObject> ()); spawnCount++; return; } } } } } }
bool checkForJumpPositions(Vector3 dir, out Vector3 out_minAngleDir) { Vec3Int jumpCoords = vxe.ToGrid(transform.position); bool canJump = false; float maxdotprod = float.MinValue; Vector3 minAngleDir = Vector3.zero; for (int i = -JUMP_RANGE; i <= JUMP_RANGE; i++) { for (int j = -JUMP_RANGE; j <= JUMP_RANGE; j++) { for (int k = MAX_JUMP_HEIGHT; k >= 1; k--) { Vec3Int vcoords = jumpCoords + new Vec3Int(i, k, j); Voxel vx = vxe.grid.getVoxel(vcoords); if (vx.isOccupied() && vxe.voxelHasSurface(vx, VF.VX_TOP_SHOWN)) { Vector3 wrldcoords = vxe.FromGridUnTrunc(vcoords.ToVec3() + new Vector3(0.5f, 1.0f, 0.5f)); Vector3 vdir = Vector3.ProjectOnPlane((wrldcoords - transform.position), Vector3.up).normalized; float dotprod = Vector3.Dot(dir, vdir); if (dotprod > 0) { canJump = true; if (dotprod > maxdotprod) { maxdotprod = dotprod; minAngleDir = vdir; jumpPosition = wrldcoords; } } } } } } out_minAngleDir = minAngleDir; return(canJump); }
IEnumerator SpawnItems() { yield return(new WaitForSeconds(5.0f)); Vector3 coords = Vector3.zero, norm = Vector3.zero; bool hitsomething = false; while (!hitsomething) { hitsomething = vxe.RayCast(camera.transform.position, Vector3.down, 64, ref coords, ref norm, 1.0f); yield return(null); } Random.seed = System.DateTime.Now.Millisecond; floorChunkY = vxe.getChunkCoords(coords).y; Vec3Int prevcc = new Vec3Int(vxe.num_chunks_x / 2, vxe.num_voxels_y / 2, vxe.num_chunks_z / 2); Vector2 prevdir = Vector2.zero; for (int s = 0; s < stages.Length; s++) { currentStage = s; ItemInfo[] items = stages[s].items; nextStage = false; for (int i = 0; i < items.Length; i++) { int biomeIndex = (int)items[i].biome; IndexStack <Vec3Int> occupiedChunks = items[i].biome == BIOMES.none ? vxe.occupiedChunks : BiomeScript.Instance.biomeOccupiedChunks[biomeIndex]; bool spawned = false; int maxdist = 3; int attempts = 0; while (!spawned) { int chunkx; int chunkz; while (true) { int count = occupiedChunks.getCount(); int period = Random.Range(0, count); Vec3Int randomCC = occupiedChunks.peek(period); chunkx = randomCC.x; chunkz = randomCC.z; bool isFarEnough = true; int start = Mathf.Max(0, prevpositions.getCount() - 3); for (int k = start; k < prevpositions.getCount(); k++) { Vec3Int pcc = prevpositions.peek(k); int dist = (chunkx - pcc.x) * (chunkx - pcc.x) + (chunkz - pcc.z) * (chunkz - pcc.z); Debug.Log(dist); if (dist < maxdist * maxdist) { isFarEnough = false; break; } } if (SpawnCount == 0 || isFarEnough) { break; } attempts++; if (attempts % 20 == 0) { if (maxdist > 1) { maxdist--; } } yield return(null); } Chunks chunk = null; for (int k = floorChunkY + range; k >= floorChunkY; k--) { chunk = vxe.grid.voxelGrid [chunkx, k, chunkz]; Chunks chunkup = vxe.grid.voxelGrid [chunkx, k + 1, chunkz]; bool isthereUp = (chunkup != null && chunkup.voxel_count > 3); if (!isthereUp && chunk != null && chunk.voxel_count > 60 && vxe.isChunkASurface(DIR.DIR_UP, chunk, 0.5f)) { Vector3 chunkBaseCoords = new Vector3(chunkx, k, chunkz) * vxe.chunk_size; for (int ox = 0; ox < vxe.chunk_size; ox++) { int x = (ox + vxe.chunk_size / 2 - 1) % vxe.chunk_size; for (int oz = 0; oz < vxe.chunk_size; oz++) { int z = (oz + vxe.chunk_size / 2 - 1) % vxe.chunk_size; for (int y = vxe.chunk_size - 1; y >= 0; y--) { Voxel vx = chunk.getVoxel(new Vec3Int(x, y, z)); if (vx.isOccupied() && vxe.voxelHasSurface(vx, VF.VX_TOP_SHOWN)) { Vector3 voxelCoords = vxe.FromGridUnTrunc(chunkBaseCoords + new Vector3(x, y, z)); if (voxelCoords.y < coords.y + items [i].minSpawnHeightOffFloor * vxe.voxel_size || voxelCoords.y > coords.y + items [i].maxSpawnHeightOffFloor * vxe.voxel_size) { continue; } GameObject newItem = (GameObject)Instantiate(items [i].item, voxelCoords + new Vector3(0, vxe.voxel_size, 0), Quaternion.identity); newItem.SetActive(true); newItem.GetComponent <VoxelParent>().chunkCoords = new Vec3Int(chunkx, k, chunkz); prevpositions.push(new Vec3Int(chunkx, 0, chunkz)); SpawnCount++; spawned = true; Debug.Log("spawned!"); canSpawn = false; goto imout; } yield return(null); } } } } } imout: if (spawned && !stages[s].allAtOnce) { while (!canSpawn) { yield return(new WaitForSeconds(1.0f)); } } else { yield return(null); } } } while (stages[s].stageWait && !nextStage) { yield return(new WaitForSeconds(1.0f)); } } }