Пример #1
0
        public VoxelInfo( Index setIndex, Index setAdjacentIndex, Chunk setChunk )
        {
            this.index = setIndex;
            this.adjacentIndex = setAdjacentIndex;

            this.chunk = setChunk;
        }
Пример #2
0
        public void Update()
        {
            // don't load chunks if engine isn't initialized yet
            if (!Engine.Initialized || !ChunkManager.Initialized) {
            return;
            }

            // don't load chunks if multiplayer is enabled but the connection isn't established yet
            if (Engine.EnableMultiplayer) {
            if (!Network.isClient && !Network.isServer) {
                return;
            }
            }

            // track which chunk we're currently in. If it's different from previous frame, spawn chunks at current position.

            currentPos = Engine.PositionToChunkIndex (transform.position);

            if (currentPos.IsEqual(LastPos) == false) {
            ChunkManager.SpawnChunks(currentPos.x, currentPos.y, currentPos.z);

            // (Multiplayer) update server position
            if (Engine.EnableMultiplayer && Engine.MultiplayerTrackPosition && Engine.UniblocksNetwork != null) {
                UniblocksClient.UpdatePlayerPosition (currentPos);
            }
            }

            LastPos = currentPos;
        }
Пример #3
0
        // ==== maintenance ===========================================================================================
        public void Awake()
        {
            // chunk initialization (load/generate data, set position, etc.)

            // Set variables
            ChunkIndex = new Index (transform.position);
            SideLength = Engine.ChunkSideLength;
            SquaredSideLength = SideLength * SideLength;
            NeighborChunks = new Chunk [6]; // 0 = up, 1 = down, 2 = right, 3 = left, 4 = forward, 5 = back
            MeshCreator = GetComponent<ChunkMeshCreator>();
            Fresh = true;

            // Register chunk
            ChunkManager.RegisterChunk (this);

            // Clear the voxel data
            VoxelData = new ushort[SideLength*SideLength*SideLength];

            // Set actual position
            transform.position = ChunkIndex.ToVector3() * SideLength;

            // multiply by scale
            transform.position = new Vector3 (transform.position.x * transform.localScale.x, transform.position.y * transform.localScale.y, transform.position.z * transform.localScale.z);

            // Grab voxel data
            if (Engine.EnableMultiplayer && !Network.isServer) {
            StartCoroutine (RequestVoxelData());	// if multiplayer, get data from server
            }
            else if (Engine.SaveVoxelData && TryLoadVoxelData() == true ) {
            // data is loaded through TryLoadVoxelData()
            }
            else {
            GenerateVoxelData();
            }
        }
        public void Update()
        {
            // check if chunk is not null
            GameObject chunkObject = Engine.PositionToChunk (transform.position);
            if (chunkObject == null) return;

            // get the voxelInfo from the transform's position
            Chunk chunk = chunkObject.GetComponent<Chunk>();
            Index voxelIndex = chunk.PositionToVoxelIndex (transform.position);
            VoxelInfo voxelInfo = new VoxelInfo (voxelIndex, chunk);

            // create a local copy of the collision voxel so we can call functions on it
            GameObject voxelObject = Instantiate ( Engine.GetVoxelGameObject (voxelInfo.GetVoxel()) ) as GameObject;

            VoxelEvents events = voxelObject.GetComponent<VoxelEvents>();
            if (events != null ) {

            // OnEnter
            if ( chunk != LastChunk || voxelIndex.IsEqual(LastIndex) == false) {
                events.OnBlockEnter (this.gameObject, voxelInfo);
            }

            // OnStay
            else {
                events.OnBlockStay(this.gameObject, voxelInfo);
            }
            }

            LastChunk = chunk;
            LastIndex = voxelIndex;

            Destroy(voxelObject);
        }
Пример #5
0
        public override void OnBlockDestroy( VoxelInfo voxelInfo )
        {
            // if the block above is tall grass, destroy it
            Index indexAbove = new Index (voxelInfo.index.x, voxelInfo.index.y+1, voxelInfo.index.z);

            if ( voxelInfo.chunk.GetVoxel(indexAbove) == 8 ) {
            voxelInfo.chunk.SetVoxel(indexAbove, 0, true);
            }
        }
Пример #6
0
 public static Chunk GetChunkComponent(Index index)
 {
     string indexString = index.ToString();
     if ( ChunkManager.Chunks.ContainsKey (indexString) ) {
     return ChunkManager.Chunks [indexString];
     }
     else {
     return null;
     }
 }
Пример #7
0
        public override void OnBlockPlace( VoxelInfo voxelInfo )
        {
            // if the block below is grass, change it to dirt
            Index indexBelow = new Index (voxelInfo.index.x, voxelInfo.index.y-1, voxelInfo.index.z);

            if ( voxelInfo.GetVoxelType ().VTransparency == Transparency.solid
            && voxelInfo.chunk.GetVoxel(indexBelow) == 2) {
            voxelInfo.chunk.SetVoxel(indexBelow, 1, true);
            }
        }
Пример #8
0
 public static GameObject GetChunk(Index index)
 {
     Chunk chunk = ChunkManager.GetChunkComponent (index);
     if (chunk == null) {
     return null;
     }
     else {
     return chunk.gameObject;
     }
 }
Пример #9
0
        public bool IsEqual( Index to )
        {
            if (to == null) {
            return false;
            }

            if (this.x == to.x &&
            this.y == to.y &&
            this.z == to.z) {
                return true;
            }
            else return false;
        }
Пример #10
0
        public static bool Compare( Index a, Index b )
        {
            if (b == null) {
            return false;
            }

            if (a.x == b.x &&
            a.y == b.y &&
            a.z == b.z) {
                return true;
            }
            else return false;
        }
Пример #11
0
        public void ReceiveChangeBlock( NetworkPlayer sender, int x, int y, int z, int chunkx, int chunky, int chunkz, int data )
        {
            // receives a change sent by other client or server

            GameObject chunkObject = ChunkManager.GetChunk (chunkx,chunky,chunkz);
            if (chunkObject != null) {

            // convert back to VoxelInfo
            Index voxelIndex = new Index (x,y,z);
            VoxelInfo info = new VoxelInfo (voxelIndex, chunkObject.GetComponent<Chunk>());

            // apply change
            Voxel.ChangeBlockMultiplayer (info, (ushort)data, sender);
            }
        }
Пример #12
0
        public override void OnBlockPlace( VoxelInfo voxelInfo )
        {
            // switch to dirt if the block above isn't 0
            Index adjacentIndex = voxelInfo.chunk.GetAdjacentIndex (voxelInfo.index, Direction.up);
            if ( voxelInfo.chunk.GetVoxel(adjacentIndex) != 0 ) {
            voxelInfo.chunk.SetVoxel(voxelInfo.index, 1, true);
            }

            // if the block below is grass, change it to dirt
            Index indexBelow = new Index (voxelInfo.index.x, voxelInfo.index.y-1, voxelInfo.index.z);

            if ( voxelInfo.GetVoxelType ().VTransparency == Transparency.solid
            && voxelInfo.chunk.GetVoxel(indexBelow) == 2) {
            voxelInfo.chunk.SetVoxel(indexBelow, 1, true);
            }
        }
Пример #13
0
        public void Update()
        {
            // track which chunk we're currently in. If it's different from previous frame, spawn chunks at current position.

            currentPos = Engine.PositionToChunkIndex (transform.position);

            if (currentPos.IsEqual(LastPos) == false) {
            ChunkManager.SpawnChunks(currentPos.x, currentPos.y, currentPos.z);

            // (Multiplayer) update server position
            if (Engine.EnableMultiplayer && Engine.MultiplayerTrackPosition && Engine.UniblocksNetwork != null) {
                UniblocksClient.UpdatePlayerPosition (currentPos);
            }
            }

            LastPos = currentPos;
        }
Пример #14
0
 private static string GetRegionPath(Index regionIndex)
 {
     return Engine.WorldPath + ( regionIndex.ToString() + ",.region");
 }
Пример #15
0
        private static bool LoadRegionData(Index regionIndex)
        {
            // loads the region data into memory if file exists and it's not already loaded, returns true if data exists (and is loaded), else false

            string indexString = regionIndex.ToString();
            if (LoadedRegions.ContainsKey(indexString) == false) { // if not loaded

            // load data if region file exists
            string regionPath = GetRegionPath (regionIndex);
            if (File.Exists (regionPath)) {

                StreamReader reader = new StreamReader (regionPath);
                string[] regionData = reader.ReadToEnd().Split((char)ushort.MaxValue);
                reader.Close();
                LoadedRegions[indexString] = regionData;

                return true;

            }

            else {
                return false; // return false if region file doesn't exist
            }
            }

            return true; // return true if data is already loaded
        }
Пример #16
0
        private static Index GetParentRegion( Index index )
        {
            // returns the index of the region containing a specific chunk

            Index newIndex = new Index(index.x, index.y, index.z);

            if (index.x < 0) newIndex.x -= 9;
            if (index.y < 0) newIndex.y -= 9;
            if (index.z < 0) newIndex.z -= 9;

            int x = newIndex.x / 10;
            int y = newIndex.y / 10;
            int z = newIndex.z / 10;

            return new Index (x,y,z);
        }
Пример #17
0
        private static string[] GetRegionData(Index regionIndex)
        {
            // loads region data and from file returns it, or returns null if region file is not found

            if (LoadRegionData(regionIndex) == true) {
            return LoadedRegions[regionIndex.ToString()];
            }
            else {
            return null;
            }
        }
Пример #18
0
        private static void CreateRegionFile(Index index)
        {
            // creates an empty region file

            Directory.CreateDirectory (Engine.WorldPath);
            StreamWriter writer = new StreamWriter (GetRegionPath(index));

            for (int i=0; i<999; i++) {
            writer.Write ((char)ushort.MaxValue);
            }

            writer.Flush();
            writer.Close();
        }
Пример #19
0
        private static int GetChunkRegionIndex( Index index )
        {
            // returns the 1d index of a chunk's data in the region file

            Index newIndex = new Index (index.x, index.y, index.z);
            if (newIndex.x < 0) newIndex.x = -newIndex.x - 1;
            if (newIndex.y < 0) newIndex.y = -newIndex.y - 1;
            if (newIndex.z < 0) newIndex.z = -newIndex.z - 1;

            int flatIndex =  (newIndex.z * 100) + (newIndex.y * 10) + newIndex.x;

            while (flatIndex > 999) {
            flatIndex -= 1000;
            }

            return flatIndex;
        }
Пример #20
0
 GameObject DoSpawnChunk(Index index)
 {
     GameObject chunkObject = Instantiate(ChunkObject, index.ToVector3(), transform.rotation) as GameObject;
     Chunk chunk = chunkObject.GetComponent<Chunk>();
     AddChunkToUpdateQueue (chunk);
     return chunkObject;
 }
Пример #21
0
 public static Index PositionToChunkIndex( Vector3 position )
 {
     Index chunkIndex = new Index (Mathf.RoundToInt(position.x / Engine.ChunkScale.x) / Engine.ChunkSideLength,
                               Mathf.RoundToInt(position.y / Engine.ChunkScale.y) / Engine.ChunkSideLength,
                               Mathf.RoundToInt(position.z / Engine.ChunkScale.z) / Engine.ChunkSideLength);
     return chunkIndex;
 }
Пример #22
0
        bool IsWithinRange( NetworkPlayer player, Index chunkIndex )
        {
            // checks if the player is within the range of the chunk

            if ( Mathf.Abs ( PlayerPositions [player].x - chunkIndex.x ) > PlayerChunkSpawnDistances[player] ) {
            return false;
            }
            if ( Mathf.Abs ( PlayerPositions [player].y - chunkIndex.y ) > PlayerChunkSpawnDistances[player] ) {
            return false;
            }
            if ( Mathf.Abs ( PlayerPositions [player].z - chunkIndex.z ) > PlayerChunkSpawnDistances[player] ) {
            return false;
            }

            return true;
        }
Пример #23
0
        private string GetChunkData(Index index)
        {
            // returns the chunk data (from memory or from file), or an empty string if data can't be found

            // try to load from TempChunkData
            string indexString = index.ToString();
            if (TempChunkData.ContainsKey (indexString)) {
            return TempChunkData[indexString];
            }

            // try to load from region, return empty if not found
            int regionIndex = GetChunkRegionIndex (index);
            string[] regionData = GetRegionData (GetParentRegion(index));
            if (regionData == null) {
            return "";
            }
            return regionData[regionIndex];
        }
Пример #24
0
        public static GameObject SpawnChunk( Index index )
        {
            // spawns a single chunk (only if it's not already spawned)

            GameObject chunk = ChunkManager.GetChunk (index);
            if (chunk == null) {
            return Engine.ChunkManagerInstance.DoSpawnChunk(index);
            }
            else return chunk;
        }
Пример #25
0
 public void UpdatePlayerPosition( NetworkPlayer player, int chunkx, int chunky, int chunkz )
 {
     // sent by client
     PlayerPositions [player] = new Index (chunkx, chunky, chunkz);
     if (EnableDebugLog) Debug.Log ("UniblocksServer: Updated player position. Player "+player.ToString() + ", position: " + new Vector3(chunkx,chunky,chunkz).ToString());
 }
Пример #26
0
 public static GameObject SpawnChunkFromServer( Index index )
 {
     // spawns a chunk and disables mesh generation and enables timeout (used by the server in multiplayer)
     GameObject chunk = ChunkManager.GetChunk (index);
     if (chunk == null) {
     chunk = Engine.ChunkManagerInstance.DoSpawnChunk(index);
     Chunk chunkComponent =chunk.GetComponent<Chunk>();
     chunkComponent.EnableTimeout = true;
     chunkComponent.DisableMesh = true;
     return chunk;
     }
     else return chunk; // don't disable mesh generation and don't enable timeout for chunks that are already spawned
 }
Пример #27
0
 private void TrySpawnChunks( int x, int y, int z )
 {
     if (Done == true) { // if we're not spawning chunks at the moment, just spawn them normally
     StartSpawnChunks (x,y,z);
     }
     else { // if we are spawning chunks already, flag to spawn again once the previous round is finished using the last requested position as origin.
     LastRequest = new Index(x,y,z);
     SpawnQueue = 1;
     StopSpawning = true;
     ChunkUpdateQueue.Clear ();
     }
 }
Пример #28
0
 private void TrySpawnChunks( Index index )
 {
     TrySpawnChunks (index.x, index.y, index.z);
 }
Пример #29
0
 private void WriteChunkData(Index index, string data)
 {
     // writes the chunk data to the TempChunkData dictionary
     TempChunkData[index.ToString()] = data;
 }
Пример #30
0
 public static void SpawnChunks( Index index )
 {
     Engine.ChunkManagerInstance.TrySpawnChunks (index.x, index.y, index.z);
 }