//TODO: trees //TODO: water //TODO: rivers: https://www.reddit.com/r/proceduralgeneration/comments/3twed7/early_infinite_perlin_terrain/ //TODO: fix building block colliding with player //TODO: Fix physics bug //TODO: Custom render pipeline //TODO: separate mesh for solid and transparent voxels //TODO: split all meshes to one long array per each side so it can be mesh instanced? //TODO: make alpha setting for shader per vertex so it can be only one shader? protected override void Enter() { base.Enter(); Random.InitState(WorldSettings.Seed); WorldRenderer.Init(); //Create player _playerView = AssetManager.GetGameObject <PlayerView>(ResourcePath.PLAYER_PREFAB); Vector3 initPosition; if (SaveLoadManager.LoadedGame.IsLoaded) { initPosition = SaveLoadManager.LoadedGame.InitPosition; } else { initPosition = new Vector3(0.5f, WorldModel.GetTerrainHeight(new Vector3(0, 0, 0)) + 1, 0.5f); } _playerView.transform.position = initPosition; var playerCoords = WorldModelHelper.GetChunkCoordsFromWorldPosition(initPosition); GenerateWorld(playerCoords); var camera = ViewConfig.Camera3d; camera.nearClipPlane = 0.01f; camera.farClipPlane = GeometryConsts.VIEW_DISTANCE; Updater.EveryFrame(UpdateView); }
private void UpdateMining() { if (WorldRaycaster.IsHit && Input.GetMouseButtonDown(1)) { var playerPosition = WorldModelHelper.FloorPositionToVector3Int(_playerBody.Transform.position); if (WorldRaycaster.LastPosition != playerPosition && WorldRaycaster.LastPosition != playerPosition + Vector3Int.up) { WorldModel.EditVoxel(WorldRaycaster.LastPosition, (byte)InventoryModel.SelectedBlockType); } } if (!_isMining) { //check if we could start mining if (WorldRaycaster.IsHit && Input.GetMouseButton(0)) { //START MINING _isMining = true; UpdateCursorsVisibility(); _miningStartedTime = Time.time; } } else { if (!WorldRaycaster.IsHit || !Input.GetMouseButton(0)) { //STOP MINING _isMining = false; UpdateCursorsVisibility(); _mineBlockCursor.SetMiningProgress(0); _pick.transform.localRotation = Quaternion.identity; return; } var miningLength = Time.time - _miningStartedTime; var hits = Mathf.FloorToInt(miningLength / _playerSettings.MiningInterval); var blockHardness = _minedBlockType.Hardness; var animProgress = _playerSettings.PickMovementCurve.Evaluate((miningLength % _playerSettings.MiningInterval) / _playerSettings.MiningInterval); _pick.transform.localRotation = Quaternion.Euler(new Vector3(-45 * animProgress, 0, 0)); //blockHardness == means indestructible //finish mining (remove block) if (hits >= blockHardness && blockHardness != 0) { WorldModel.EditVoxel(_lastMinePosition, BlockTypeByte.AIR); UpdateCursorsVisibility(); return; } //anim block if (blockHardness > 0) { _mineBlockCursor.SetMiningProgress(hits / (float)blockHardness); } } }
private void UpdateView() { var newCoords = WorldModelHelper.GetChunkCoordsFromWorldPosition(_playerView.transform.position); if (newCoords.x == _lastPlayerCoords.x && newCoords.y == _lastPlayerCoords.y) { return; } //Remove unused data + view var watch = new Stopwatch(); watch.Start(); var removeDataCords = GetDataCoords(newCoords, MapBoundsLookup.MapDataRemove, true); var removeRenderCords = GetRenderCoords(newCoords, MapBoundsLookup.ChunkRemove, true); WorldModel.RemoveData(removeDataCords); WorldRenderer.RemoveChunks(removeRenderCords, removeDataCords); //Create map data + queue chunk render for newly discovered chunks var dataCords = GetDataCoords(newCoords, MapBoundsLookup.MapDataAdd); var renderCords = GetRenderCoords(newCoords, MapBoundsLookup.ChunkAdd); WorldModel.CreateChunkMaps(dataCords); WorldRenderer.RenderChunks(renderCords, dataCords); watch.Stop(); Debug.LogWarning($"<color=\"aqua\">GameAppState.UpdateView() : watch.ElapsedMilliseconds: {watch.ElapsedMilliseconds}</color>"); _lastPlayerCoords = newCoords; }