Search Unity

Uniblocks: cube-based infinite voxel terrain engine

Discussion in 'Assets and Asset Store' started by RawLionWorkshop, Feb 2, 2014.

  1. RawLionWorkshop

    RawLionWorkshop

    Joined:
    Jan 29, 2014
    Posts:
    206
    In theory there should be no limit until you run out of integer range for the x,y,z values of the chunk's index (x, y or z greater than 2147483647).

    However, it's possible there is something that would prevent chunks from being loaded properly past a certain distance (one guess would be the position of the chunks not being set properly because of float precision errors). As soon as I have some time I'll do some proper testing for this, and I'll let you know if I find anything.
     
  2. JohnChase

    JohnChase

    Joined:
    Mar 31, 2016
    Posts:
    1
    Maap,

    Any idea if/when there might be an update to the multiplayer core? It seems the multiplayer in the current build is being deprecated in the near future.

    Love the engine so far! Great work!
     
  3. RedEyeFox

    RedEyeFox

    Joined:
    Jan 8, 2013
    Posts:
    27
    hi and sorry if my english is too bad, is there any solution to save/load with PlayerPrefs because i want to make my game for webplayer/webgl, i make alot of test for loading the world but without success :(, i think there has some problem with the encoding to utf8, when i save the world data to PlayerPrefs and try to load it i get Uniblocks:Corrupt chunk data for chunk:"*****".Has the data been saved using a different chunk size?" when i get the PlayerPrefs string for some chunk there has only from one to three symbols , i already check the results sended to the PlayerPrefs and they are corect, i am not sure what's happening and why they are not saved properly in the PlayerPrefs, pls help
     
    Last edited: Apr 5, 2016
  4. RawLionWorkshop

    RawLionWorkshop

    Joined:
    Jan 29, 2014
    Posts:
    206
    I'm sorry, I don't have a solution for using PlayerPrefs for saving and loading. The system is pretty complex and coming up with a working solution is not an easy thing.

    In theory, it should work fine if you just change the location of the region files, so that they're read and written to PlayerPrefs instead of a regular file. To do this you'd just need to change the StreamReader and StreamWriter in LoadRegionData and WriteRegionFile functions to point to the region's PlayerPrefs instead.
    But of course in practice you'll probably come across all kinds of problems.

    By the way, a chunk string only having a few symbols is normal - if it's empty or only has a few different blocks, it will be heavily compressed.


    It is coming, but I'm afraid I can't give you a specific time yet.
     
  5. VasyaCullin

    VasyaCullin

    Joined:
    Feb 17, 2014
    Posts:
    8
    Question on Mobility Management:

    Could you suggest how best to implement a button to destroy / place block? (For android)
     
  6. Safebox

    Safebox

    Joined:
    Mar 20, 2014
    Posts:
    8
    Another quicky, sorry; how would I go about procedurally placing a block above another one if it's outside the chunk. I'm trying to make use of the adjacentIndex code but I haven't fully explored it yet.
     
  7. Firlefanz73

    Firlefanz73

    Joined:
    Apr 2, 2015
    Posts:
    1,316
    chunk.SetVoxel places a block I belive also in the correct neighbor if it is not in the chunk but in the neighbor,
    and chunk.SetVoxelSimple just places it in the chunk itself.

    Does that help?
     
  8. Endzone

    Endzone

    Joined:
    Dec 18, 2014
    Posts:
    119
    Hey maap,
    I was wondering is their a way i can tell if im not looking at a voxel ?
     
  9. RawLionWorkshop

    RawLionWorkshop

    Joined:
    Jan 29, 2014
    Posts:
    206
    Since the functionality to place and destroy blocks is already there for mouse input, all you'd really need to do is replace the mouse buttons with your own button. The mouse input is processed in CameraEventsSender. You should be able to just replace the Input.OnMouseButton lines with references to your button instead.

    If you want to place the blocks in the terrain generator, currently there is no easy way to access other chunks during terrain generation. That's because terrain is generated at the same time as new chunks are being spawned, so the neighbor chunks aren't guaranteed to exist yet. If you really need to this during terrain generation, it would be best to wait until chunks are fully loaded and then place your blocks with SetVoxel outside of the TerrainGenerator's GenerateVoxelData() function.

    If you don't need the blocks to be placed during terrain generation, you can just use SetVoxel. The neighbor chunk will be accessed automatically if the index exceeds the chunk's range.

    You can use Engine.VoxelRaycast from the player camera forward to check which voxel is being looked at. The VoxelRaycast will return a VoxelInfo of the voxel being looked at, or null if you're not looking at any voxel. Check the script reference for more details on VoxelRaycast.
     
  10. Firlefanz73

    Firlefanz73

    Joined:
    Apr 2, 2015
    Posts:
    1,316
    Hey Maap,

    I found a free asset that seems to be good for multi-threading:

    https://www.assetstore.unity3d.com/en/#!/content/15717

    Could this be useful for some Chunk-Spawning in Threads update for Uniblocks?

    After reducing my materials in chunk to under 30 my drawing framerate got much better, thank you!
    But still the spawning is a bit too slow...
     
  11. picstruck

    picstruck

    Joined:
    Jan 20, 2014
    Posts:
    3
    I want to use this framework for a game I'm creating for Android, I know there is an android demo but would it be possible for you to release an android demo where it shows the fps? I want to see how much it lags when creating chunks or when destroying blocks before I buy this.
     
    Last edited: Apr 20, 2016
  12. RawLionWorkshop

    RawLionWorkshop

    Joined:
    Jan 29, 2014
    Posts:
    206
    Sorry for the long wait, here's an Android demo with FPS display:
    https://www.dropbox.com/s/esb6xcebbm148kk/Uniblocks 1-4-1 Android Demo.apk?dl=0

    I've had some problems with the Android SDK, and I don't have any Android devices to test the build, so there is a good chance this doesn't work properly, but unfortunately that's all I can do right now. Let me know something doesn't work, and I'll see if I can fix it.


    It does look useful, thank you. However multi-threading is still a huge issue that I probably won't be able to implement any time soon...
     
  13. Firlefanz73

    Firlefanz73

    Joined:
    Apr 2, 2015
    Posts:
    1,316
    Hello everybody,

    does anybody already have experience with adding Monsters or npc on the uniblocks landscape?
    I did and it is working for Basic collisions.

    But now I added water and Lava. Those should not have a collider or can they have just a trigger or something?

    I want my Monsters to not even enter the Lava or the water. How to do that (with a good Performance)?

    I could detect the voxel in front of them or I could use a raycast. What do you think is better? Or is there an other way?

    Thanks a lot for some hints and have a nice Weekend!
     
  14. nuonical

    nuonical

    Joined:
    Feb 28, 2015
    Posts:
    46
    Hey Firlefanz73,

    I would raycast. Place an empty gameobject about 1 meter (up to you) in front of your enemy, then raycast down to check the voxel id. This way you can check the voxel id, but also check how far away that voxel is. So if it's 5 blocks down, then you could say that's a ledge and is to be avoided. You could then do another raycast from another spot, say 3 meters ahead of your enemy and down, to potentially attempt jumping the ledge. That could be a fun mechanic to experiment with. Have fun!
     
    Firlefanz73 likes this.
  15. Firlefanz73

    Firlefanz73

    Joined:
    Apr 2, 2015
    Posts:
    1,316
    Hello nuonical,

    this sounds like a great idea and should be perfect to detect holes / ledges.

    Do you talk about this Engine.VoxelRayCast that return a voxelinfo?
    VoxelInfo VoxelInforaycast=Engine.VoxelRaycast(...position, ...transform.forward, Range, false);

    Does it also detect voxels that have no collider? My water and Lava has no collider so the Player can sink into it...

    If so, this sounds like a great Point to start with. I will try, thanks.
     
  16. RawLionWorkshop

    RawLionWorkshop

    Joined:
    Jan 29, 2014
    Posts:
    206
    VoxelRaycast is indeed the best tool for your situation. It will detect voxels with no collider too. In fact voxels with no collider do actually have a collider specifically for picking up raycasts, it just uses a different layer so that it doesn't collide with anything else.

    By the way, you can also detect when something enters your water and lava blocks using the OnBlockEnter event from VoxelEvents - it will work on voxels without colliders too. For example, DefaultVoxelEvents will display a debug message whenever the player enters a block; you can see this when you walk over the tall grass (which has no collider). If you need to make entities float when they enter water, you can do it using this function.
     
    Firlefanz73 likes this.
  17. Firlefanz73

    Firlefanz73

    Joined:
    Apr 2, 2015
    Posts:
    1,316
    Hi maap,

    that hint with OnBlockEnter is good. Didn't use it yet.

    But I have a Problem with my own Player still. OnBlockEnter is the block the Player is Standing on, right?

    I try to detect if Player is in Lava. Lava is 160-169 in my world.

    Code (CSharp):
    1.     public virtual void OnBlockEnter ( GameObject enteringObject, VoxelInfo voxelInfo ) {
    2.             ushort voxel = voxelInfo.GetVoxel();
    3.             if (voxel > 160 && voxel < 170) {
    4.                 Globals.Playerdata.BurnTime += Time.deltaTime;
    5.                 if (Globals.PlayerController.HurtTime <=0)
    6.                 {
    7.                     Globals.PlayerController.Hit(Globals.PlayerTransform.position, 1);
    8.                     Globals.PlayerController.HurtTime = 0.5f;
    9.                 }
    10.             }
    11.     }
    Seems to deliver the block the Player is Standing on. Maybe nice for ice-gliding later...
    Useless for water and Lava then because they have no collider.

    I tried before like this to detect Lava for the Player which is 2 blocks high:

    Code (CSharp):
    1.                     Index index = Engine.PositionToChunkIndex (transform.position);
    2.                     Chunk chunk = ChunkManager.GetChunkComponent (index);
    3.                     if (chunk != null) // && chunk.isActiveAndEnabled)
    4.                     {
    5.                         ushort v = chunk.GetVoxel ((int)transform.position.x, (int)transform.position.y, (int)transform.position.z); //y-2
    6.                         if (v < 65535)
    7.                             Globals.Playerdata.GroundVoxel = v;
    8.                         v = chunk.GetVoxel ((int)transform.position.x, (int)transform.position.y+1, (int)transform.position.z);
    9.                         if (v < 65535)
    10.                             Globals.Playerdata.LowerVoxel = v;
    11.                         v = chunk.GetVoxel ((int)transform.position.x, (int)transform.position.y+2, (int)transform.position.z);
    12.                         if (v < 65535)
    13.                             Globals.Playerdata.UpperVoxel = v;
    14.  
    15.                         // Lava
    16.                         if ((Globals.Playerdata.GroundVoxel>=160 && Globals.Playerdata.GroundVoxel<170)
    17.                             ||(Globals.Playerdata.LowerVoxel>=160 && Globals.Playerdata.LowerVoxel<170)
    18.                             ||(Globals.Playerdata.UpperVoxel>=160 && Globals.Playerdata.UpperVoxel<170))
    19.                         {
    20.                             Globals.Playerdata.BurnTime += Time.deltaTime;
    21.                             if (Globals.PlayerController.HurtTime <=0)
    22.                             {
    23.                                 Globals.PlayerController.Hit(Globals.PlayerTransform.position, 1);
    24.                                 Globals.PlayerController.HurtTime = 0.5f;
    25.                             }
    26.                         }
    27.  
    This is from my Player controller. But this is also not working, I guess there is something wrong with getting the voxel from the Player Position this way? v is always 65535 (ushort max)...

    What is most performant and correct way to get a voxel from a certain real world Position?

    Thanks a lot and have a nice Weekend!
     
  18. Firlefanz73

    Firlefanz73

    Joined:
    Apr 2, 2015
    Posts:
    1,316
    PS: I found the solution by myself, from other older Code:
    I post it in case somebody is interested too:

    Code (CSharp):
    1.                     Index index = Engine.PositionToChunkIndex (transform.position);
    2.                     Chunk chunk = ChunkManager.GetChunkComponent (index);
    3.                     if (chunk != null) // && chunk.isActiveAndEnabled)
    4.                     {
    5.                         Index voxelIndex = chunk.PositionToVoxelIndex (transform.position+Vector3.up);
    6.                         VoxelInfo voxelInfo = new VoxelInfo (voxelIndex, chunk);
    7.                         Globals.Playerdata.LowerVoxel=voxelInfo.GetVoxel();
    8.                         voxelIndex = chunk.PositionToVoxelIndex (transform.position+Vector3.up*2);
    9.                         voxelInfo = new VoxelInfo (voxelIndex, chunk);
    10.                         Globals.Playerdata.UpperVoxel=voxelInfo.GetVoxel();
    11.                         // Lava
    12.                         if ((Globals.Playerdata.GroundVoxel>=160 && Globals.Playerdata.GroundVoxel<170)
    13.                             ||(Globals.Playerdata.LowerVoxel>=160 && Globals.Playerdata.LowerVoxel<170)
    14.                             ||(Globals.Playerdata.UpperVoxel>=160 && Globals.Playerdata.UpperVoxel<170))
    15.                         {
    16.                             Globals.Playerdata.BurnTime += Time.deltaTime;
    17.                             if (Globals.PlayerController.HurtTime <=0)
    18.                             {
    19.                                 Globals.PlayerController.Hit(Globals.PlayerTransform.position, 1);
    20.                                 Globals.PlayerController.HurtTime = 0.5f;
    21.                             }
    22.                         }
    23. ...
    Okay that solves my Player Problems, thanks. I will see if I get it working with raycast for Monsters to avoid Lava :)
     
  19. Grinchi

    Grinchi

    Joined:
    Apr 19, 2014
    Posts:
    130
    Hello guys :) i am using this plugin and i have some problems on mobile device mostly with lag when new chunks are spawned. any performance tricks will help me i have 2 materials on chunks one transparent/cutout and one just transparent.
     
  20. nuonical

    nuonical

    Joined:
    Feb 28, 2015
    Posts:
    46
    You're most likely running into allocation issues due to heavy instantiate and destroy operations. To fix this you would typically use an object pool where you can recycle these objects.

    Unfortunately, there is currently no object pooling implemented in this plugin, and I don't believe any improvements to this plugin are planned.

    You could try having a loading screen hide some of the initial hiccups if you don't expect your player to travel very far. Having a simpler terrain generation algorithm can also help increase your overall frame rate. Try using the flat terrain generation and see if you notice an increase in performance.

    You can also lower the chunk spawning distance and see if you can get away with fewer chunks. You could also play around with the size of the chunk to see if you can take a greater hit up front with a loading screen. However, in my experience this doesn't work well. Other than that, I think you'd have to look into pooling the chunks yourself or lowering the chunk distance and trying to work your game around that.
     
  21. Grinchi

    Grinchi

    Joined:
    Apr 19, 2014
    Posts:
    130
    Thanks for answer :) one question do anyone have some solution for AI movement or path-find. do not want to write from scratch :). also i am going to rewrite Engine to make it multi-thread lets see what i can do, because on mobile performance is really poor now
     
  22. RawLionWorkshop

    RawLionWorkshop

    Joined:
    Jan 29, 2014
    Posts:
    206
    Thank you nuonical for the detailed response. Chunk pooling is something that has been requested a lot and it's definitely planned, but I can't promise it anytime soon, unfortunately.

    Just a few more things regarding the performance issues - if your game freezes periodically while loading, you should try reducing the chunk size. The game will freeze if a chunk is too big to be generated in one frame.

    If you're getting generally low fps while loading, try increasing the target fps value in the engine settings. On weaker systems your game might actually run a lot slower than the target fps value, so setting it to something much higher (for example 120 instead of the default 70) can actually improve the framerate.


    Unfortunately I don't know any pre-made voxel pathfinding solutions, for advanced pathfinding you will probably need to develop your own. Check a few posts above, there's a discussion about some pathfinding solutions which you might find useful if you want to do your own pathfinding.
     
  23. Grinchi

    Grinchi

    Joined:
    Apr 19, 2014
    Posts:
    130
    i was thinking of ThreadPool to use it when you are running lots of calculation(RebuildMesh()) and to send them to thread and then send it back to main thread and just do mesh creation and instantiate them.
     
  24. Firlefanz73

    Firlefanz73

    Joined:
    Apr 2, 2015
    Posts:
    1,316
    Hey StormBringer,

    sounds interesting. If you can enhance the spawning or the updating of the chunks etc let us know :)
     
  25. GabeXD

    GabeXD

    Joined:
    Feb 2, 2015
    Posts:
    1
    Hi!:) It is possible to set this engine for 2.5d game ?
     
  26. RawLionWorkshop

    RawLionWorkshop

    Joined:
    Jan 29, 2014
    Posts:
    206
  27. RedEyeFox

    RedEyeFox

    Joined:
    Jan 8, 2013
    Posts:
    27



    Uniblocks is the best voxel engine, exactly what i need for my game, now my players can creat own maps and play them with friends, but i just cant find a way to creat block in the space , i meen to create a block without click on existing one, just in some position, sorry for my bad english, is there someone that know how i can do that? pls help
     
  28. nuonical

    nuonical

    Joined:
    Feb 28, 2015
    Posts:
    46
    I'm experiencing some significant performance spikes caused by the GC, and have tracked it down to this "Resources.UnloadUnusedAssets();" function call. I have a smooth follow camera on a third person character, and it is especially noticeable. If I comment out that line, everything is fine.

    I'm worried about the implications of commenting out this line, however. It seems like this is a patch for a memory leak - if I comment this out, it sounds like I'm going to have bigger problems down the road. Is that correct? Is there a proper fix for this?

    Thanks!
     
  29. JasonBricco

    JasonBricco

    Joined:
    Jul 15, 2013
    Posts:
    956
    @nuonical - You shouldn't really have to use it. It's probably referring to the fact that duplicated materials don't get freed by themselves and you have to call Destroy on them. It would probably be better to call destroy where appropriate instead of relying on UnloadUnusedAssets.
     
  30. nuonical

    nuonical

    Joined:
    Feb 28, 2015
    Posts:
    46
    @JasonBricco - Thanks, Jason. I was actually just re-reading your earlier comments on pooling and such. I'll comment this out for now and figure out a solution to free up the materials when appropriate. Wish this stuff was built-in!
     
  31. nuonical

    nuonical

    Joined:
    Feb 28, 2015
    Posts:
    46
    For what it's worth, I was able to get my chunk loading of 1500 chunks down from an average of 17.6 seconds to 8.2 seconds. Those stats are in the editor, with an Engine FPS setting of 45. That tends to keep the frame rate above 30 during chunk creation. The threading also alleviates quite a bit of stuttering and those fps drops that were originally in there as well. When I'm running around the world the chunks now load in front of me, instead of generally around my feet.

    This is just from threading the ChunkMeshCreator, or more specifically the RebuildMesh function. See Stone-Legion's previous comments regarding performance of this function. Instead of running that immediately, I add it to a queue for the thread to handle. The thread will loop through this queue and do all of the mesh calculations. When it's done it then fires off a callback on each chunk that then creates the mesh and drops it into Unity.

    In order to get all of this thread safe I had to modify a slew of the Uniblocks functions. One snag I ran into was that the Calc Meshes function wanted to access any custom meshes data (ex: mesh.vertices). What I did to solve this probalem was cache this data (since it's not going to change) on Start. Run through the Uniblocks items and if it uses a custom mesh, add that data to a list. Then in the thread we can just access this static data. This is probably a good idea to do even if you're not threading, so you won't have to keep checking the actual mesh data over and over. This function gets called thousands of times, so these little optimizations can help quite a bit.

    Also if you are placing or removing a block in-game, then just go ahead and force the rebuildMesh call - no reason to send it to the thread queue.

    Hopefully this helps others who are looking into multithreading.
     
    Firlefanz73 and JasonBricco like this.
  32. Firlefanz73

    Firlefanz73

    Joined:
    Apr 2, 2015
    Posts:
    1,316
    I am highly interested. Can you send me your Code for trying? I tried a lot for myself but did not get it working good.

    If you like too you can PM me if you want something in Exchange ;-)

    Of Course it would be great to have something like that in the package itself....

    Thanks :)
     
  33. nuonical

    nuonical

    Joined:
    Feb 28, 2015
    Posts:
    46
    @Firlefanz73 Thanks Firlefanz73. I'll reply in a pm, but I will say that the code modifications span a range of Uniblocks files. I basically just started hacking away at the core, and when things broke or looked unoptimized I fixed them directly in the source code. I didn't see a clean way of abstracting the optimizations, so I sort of just went for it, you could say :)

    So for example, instead of calling GetComponent<> on every single Voxel just to get the VoxelType, I cache it in a List on startup and just check that list whenever I need the type :

    On startup:

    Code (CSharp):
    1. // Cache Voxel Objects
    2. voxelStorage = new Dictionary<int, Voxel>();
    3. for (ushort i = 0; i < engineBlockLength; i++) {
    4.     if (Engine.Blocks[i] != null) {
    5.         voxelStorage.Add(i, Engine.Blocks[i].GetComponent<Voxel>());
    6.     }
    7. }
    And GetVoxelType:

    Code (CSharp):
    1.  
    2. public static Voxel GetVoxelType ( ushort voxelId ) {
    3.         try {
    4.             if (voxelId == ushort.MaxValue)    voxelId = 0;
    5.  
    6.             // Modified to not use GetComponent - use a cached lookup instead
    7.             Voxel voxel = voxelStorage[(int)voxelId];
    8.  
    9.             // Stock implementation :
    10.             //Voxel voxel = Engine.Blocks [(int)voxelId].GetComponent <Voxel>();
    11.  
    12.  
    13.             if (voxel == null) {
    14.                 Debug.LogError ("Uniblocks: Voxel id " + voxelId + " does not have the Voxel component attached!");
    15.                 return null;
    16.             }
    17.             else {
    18.                 return voxel;
    19.             }
    20.          
    21.         }
    22.         catch (System.Exception) {
    23.             Debug.LogError ("Uniblocks: Invalid voxel id: "+voxelId);
    24.             return null;
    25.         }
    26.     }
    I do the same thing for getting mesh data. Instead of getting the Verts, UVs, Faces, etc etc directly from the mesh object every single time you need it, just cache it once on Start and check that. This is necessary for threading as well, since you can't call those functions outside of the main Unity thread.

    Code (CSharp):
    1. public class VoxelDefinitions : MonoBehaviour  {
    2.  
    3.     static Dictionary<ushort, VoxelDefinition> CachedVoxels;
    4.  
    5.     void Start() {
    6.         VoxelDefinitions.CachedVoxels = new Dictionary<ushort, VoxelDefinition>();
    7.         TryAddVoxelType (8);// go ahead and add the stock Uniblocks tall grass as it is a custom mesh
    8.  
    9.         // How many blocks should loop through to check for custom meshes?
    10.         int voxelCount = Engine.Blocks.Length - 1;
    11.         //  Uniblocks Custom Voxels start at 70 for some reason
    12.         ushort startVoxel = 70;
    13.         for(ushort x = startVoxel; x < voxelCount; x++) {
    14.             TryAddVoxelType(x);
    15.         }
    16.     }
    17.  
    18.     static void TryAddVoxelType (ushort voxel)
    19.     {
    20.         Voxel voxelType = Engine.GetVoxelType (voxel);
    21.         if (voxelType != null && voxelType.VCustomMesh == true) {
    22.             VoxelDefinitions.CachedVoxels.Add (voxel, new VoxelDefinition () {
    23.                 Vertices = voxelType.VMesh.vertices,
    24.                 UVs = voxelType.VMesh.uv,
    25.                 Faces = voxelType.VMesh.triangles,
    26.                 VertexCount = voxelType.VMesh.vertexCount
    27.             });
    28.         }
    29.     }
    30.  
    31.     public static VoxelDefinition GetVoxelType(ushort voxel) {
    32.         if(VoxelDefinitions.CachedVoxels.ContainsKey(voxel)) {
    33.             return VoxelDefinitions.CachedVoxels[voxel];
    34.         }
    35.         else {
    36.             Debug.LogError("No Mesh Data Found for : " + voxel);
    37.             return new VoxelDefinition();
    38.         }
    39.     }
    40. }
    41.  
    42. public class VoxelDefinition {
    43.     public Vector3[] Vertices;
    44.     public Vector2[] UVs;
    45.     public int[] Faces;
    46.     public int VertexCount;
    47. }
    Keep in mind these functions are called potentially thousands of times, so every little bit of optimization you can squeeze out can go a long way.
     
  34. Firlefanz73

    Firlefanz73

    Joined:
    Apr 2, 2015
    Posts:
    1,316
    Hi!

    Thanks for your Infos and Code!

    I added your changes to GetVoxelType. I must try and see if it already does any significant Change :)

    I didn't add the second part yet, I am having lots of custom meshes.
    It is 481 blocks Overall. Most of them custom meshes.
    Since I reduced number of materials to 13, the Rendering Performance is okay,
    but the spawning Performance is still bad...
     
  35. HermesonBF

    HermesonBF

    Joined:
    Jun 21, 2016
    Posts:
    22
    I need the chunks around the player are spawn in the form of a cube.
    Example 5x5 chunks how I need:
    *****
    *****
    *****
    *****
    *****
    Example 5x5 chunks as it comes in Uniblocks:
    **
    ****
    *****
    ****
    **

    (Cutting chunks in bounds assuming "squared form")
     
  36. lucasfera15

    lucasfera15

    Joined:
    Sep 25, 2016
    Posts:
    2
    How do I create a different material for each block?Exemple:material 1# to dirt and material 2# to wood?
     
  37. Sirvoid

    Sirvoid

    Joined:
    Oct 30, 2016
    Posts:
    1
    How can I do a block ignoring raycast ?
    I tried the Ignore Transparent but with water this is completly bugged when you are in the water you can only break a block under you :s

    Thanks.

    EDIT:
    I did it ! :D
    For People who have that problem you just need to do that in Engine.cs :

    Code (CSharp):
    1.                 if (ignoreTransparent) { // punch through transparent voxels by raycasting again when a transparent voxel is hit
    2.                     ushort hitVoxel = hitObject.GetComponent<Chunk>().GetVoxel(hitIndex.x, hitIndex.y, hitIndex.z);
    3.                     if ( Engine.GetVoxelType(hitVoxel).VTransparency != Transparency.solid ) { // if the hit voxel is transparent
    4.                         Vector3 newOrigin = hit.point;
    5.                         newOrigin +=  Camera.main.transform.forward * 0.1f; //here you replace the things
    6.                             return Engine.VoxelRaycast ( newOrigin, Camera.main.transform.forward, range - hit.distance, true ); //and here
    7.                     }
    8.                 }
     
    Last edited: Nov 7, 2016
  38. vladk

    vladk

    Joined:
    Jul 10, 2008
    Posts:
    167
    Hi, Maap.

    I need help with Uniblocks - doing a project for the client and stumbled upon a weird behavior. When I load a scene on Android device - the very first chunk (the on that suppose to be under player's feet) is missing. When I play the same build on PC or inside Unity Editor - everything works fine, but on Android it always "forgets" to put the very first chunk. All other chunks seem to be placed properly. And there is a square hole in the floor instead of very first one.
     
  39. RawLionWorkshop

    RawLionWorkshop

    Joined:
    Jan 29, 2014
    Posts:
    206
    Wow, okay, I'm really sorry for not replying to this thread for a while. For some strange reason (maybe someone has an explanation for this?) there is a duplicate thread which I've been monitoring, unaware that people have been posting here instead. That thread is linked from the asset description (https://community.unity.com/t5/Asse...ite-voxel-terrain-engine/td-p/1624121/page/33), but it looks like people have been posting both in that thread and here at the same time, somehow... I have no idea why there are two separate forums that have duplicate threads on them, it's very confusing and very frustrating.

    Again, really sorry, and I'll be replying here from now on. The posts above are from months ago so probably already solved or outdated, but if you still need an answer, please repost your questions. Thank you for your patience.
     
  40. RawLionWorkshop

    RawLionWorkshop

    Joined:
    Jan 29, 2014
    Posts:
    206
    Unfortunately I don't have access to a suitable Android device now so I can't test this myself, but I have some guesses. I vaguely remember having similar problems with some past versions. If it works on other platforms but not on Android, I suspect something is going wrong during loading, like a wrong script execution order, causing the first chunk to load before the engine is properly initialized.

    Can you try delaying the initial loading of chunks for a few frames/seconds? You can do this by having the ChunkLoader script on the player initially disabled, then loading it after some time has passed (2 frames should be enough, in theory).

    You could also try to force the chunk to load by deleting it first. I suspect the reason you can't manually load it with SpawnChunk is because it is already loaded, but something went wrong with building the mesh. You can get the chunk using ChunkManager.GetChunk(0,0,0), then you can just destroy the GameObject and do SpawnChunk(0,0,0) after that.


    If this doesn't work, the problem might be something else entirely, but I think I would need more information to figure it out. First, I would try moving the player to some other location at the start, far away from 0,0,0 to see if the issue still happens.


    As for the low performance, I think it might be caused by the same errors during loading, so hopefully fixing those will also fix the performance problems, but let me know if it doesn't.
     
  41. vladk

    vladk

    Joined:
    Jul 10, 2008
    Posts:
    167
    Thanks, Maap.

    Gonna try that, thank you.

    Actually I got "sort of" a solution too. It looks like the plugin quite badly reacts on the fact that you don't give an application a permission to write on disk. After I turned on the option Write Permission to "External (SD Card)" it solved the issue. Also I sorta optimized the Chunk script so it won't keep those arrays filled only with "0" or "1" - maybe it also helped.
     
  42. Firlefanz73

    Firlefanz73

    Joined:
    Apr 2, 2015
    Posts:
    1,316
    Hello maap,

    I am still having Problems with my lights. So I now thought I add them as a gameobject... seems to work good.

    Where do I add them so they are added like a voxel?
    So they are added if I spawn new landscape, or if I load it from file?

    Add where?
    Chunk.cs: public void SetVoxelSimple(int x,int y,int z,ushort data)
    ?

    I also Need to remove them. Where can I remove my lights if a chunk is released / removed from memory?
    ?

    These informations would be really helpful, thanks a lot!

    Best regards,

    Firlefanz
     
  43. Firlefanz73

    Firlefanz73

    Joined:
    Apr 2, 2015
    Posts:
    1,316
    In the asset store there is the other Forum thread linked, not this one.

    Still looking for a method to add my lights when chunks are spawned (or loaded) and remove my lights when chunks are destroyed, depending on a voxel data (like 200 is a torch for me)...

    Thanks and have happy winter Holidays :)
     
  44. RawLionWorkshop

    RawLionWorkshop

    Joined:
    Jan 29, 2014
    Posts:
    206
    I described a way to attach GameObjects to voxels here:
    https://forum.unity3d.com/threads/u...xel-terrain-engine.226014/page-5#post-2045493

    You can also do it in SetVoxelSimple, spawning a GameObject every time a voxel is modified, but then you'll also need some way to destroy the GameObjects when the voxel is set to something else (like when the player removes a light block, for example). The method I described would destroy and respawn the objects as needed every time a chunk is updated, which is simple but not very efficient. For a more efficient solution, you could check every light GameObject attached to a chunk whenever the chunk is updated, and determine if it needs to be destroyed or not (each GameObject would have its "parent" voxel index, if the voxel at that index is different than the light id after the chunk update, destroy the GameObject).

    Also you'll probably need to duplicate this function in both SetVoxelSimple and SetVoxel, because both can be used to place blocks (by default, SetVoxelSimple is used during terrain generation, while SetVoxel is used during gameplay when the player places blocks).

    Removing the GameObjects when a chunk is unloaded is simple, just make them children of the chunk transform. When the chunk is destroyed, all attached GameObjects will be destroyed too.
     
    Firlefanz73 likes this.
  45. Cakx

    Cakx

    Joined:
    Jan 6, 2017
    Posts:
    2
    Hey maap, i'm seachring all available voxelengines on the assetstore to find something i could use for learning and for my private projects.
    I tried out your Uniblocks 1.4 Demo and noticed a strange rendering issue.

    I've tested this several times, with a freshly unpacked demo with no world files and on different screen resolutions.
    When i start moving away from spawn (running mode on), lets say in a straight line for about 1 minute, i start to notice a weak flickering effect on the terrain. It gets stronger to further i walk. Its already pretty noticable when you are at 2 minutes of running deeper into the world. At about 6 Minutes away from spawn it is very strong and all around you.

    The blocks flicker between their standard color and some different darker color values when you move or just look around.
    It seems to be a lighting / shadowing issue.

    I've marked my spawn point with a big concrete wall and went about 6 minutes into the world.
    Then i moved back to the spawn till i reached my concrete wall again and the flickering was gone. Everything looked normal again.

    This makes me think that this issue has something to do with floating point precision errors. (?)

    I made some screenshots at 6 minutes into the world while locking around (left normal / right flicker):
    Uniblocks_RenderingBug.png
    Closeup: CloseUp.png

    The effect stays when i stop looking around in the right moment.

    So far thats my Major issue.

    Right now this prevents me from buying your asset. The rest feels pretty solid. I like, that removing/building blocks generates absolutly no lag spikes, the terrain generation speed is relativly fast. :)

    One secondary issue i noticed is, when i arrived back at my spawing location (after 12 minutes of running) i noticed frequent lag spikes while runnning around my concrete wall, i guess its due to the massive trail of loaded terrain i left behind me when returning to my spawn location. But it seems like the unloading of the chunks generated the spikes. Can't say for sure. Of course restarting the game fixed these lag spikes.

    By the way my systemspecs are: Intel i7 4720HQ 4x3,6 GHz, Nvidea GTX980m and 16 GB of Ram on Win8.1 (Gaming / Workstation Notebook) and besides the mentioned lag spikes your demo runs at constant 60 FPS, even at 4K resolution.

    Some other minor "bugs" i noticed:
    • Buiding a block below your feet can catapult you way up in the air
    • If you do this while their is a block above your head, you will fall down through the world into the void.
    • The player can fall into the void when rushing into an unloaded chunk.
    • The player can get stuck in a block when running into an unloaded chunk
    • The player can get stuck in a block when building the block right in his face (unable to remove the block then).

    I know that these "bugs" are just some minor problems that could be fixed by implementing some safty checks, but it would be cool if they where already implemented since they are commonly needed in every "typical minecraft clone" or any voxel building game.

    Let me know if there is any new demo version available! I'm really interested.
    I could record a video if this could help you identify/fix the problem.

    Greetings Marcel
     
  46. Firlefanz73

    Firlefanz73

    Joined:
    Apr 2, 2015
    Posts:
    1,316
    Hello maap,

    thanks a lot for the info!

    I have some Problems trying to add my light with chunk parent. Sometimes it seems to works, but sometimes the chunk I find is null, could you please have a look?

    For example when adding a new voxel in the game manually, I call this function with real world Position:

    How do I get the chunk?

    Code (CSharp):
    1.     /// <summary>
    2.     /// Adds the light.
    3.     /// </summary>
    4.     /// <param name="x">The x coordinate.</param>
    5.     /// <param name="y">The y coordinate.</param>
    6.     /// <param name="z">The z coordinate.</param>
    7.     public static void AddLight (int x, int y, int z, ushort voxel, Chunk chunk = null)
    8.     {
    9.         try {
    10.             Globals.TLightRec light = new Globals.TLightRec (){ x = x, y = y, z = z };
    11.  
    12.             if (!Globals.Lights.Exists (l => l.x == light.x && l.y == light.y && l.z == light.z)) {
    13.  
    14.                 Vector3 startVec = new Vector3 (x, y, z);
    15.                 //Chunk chunk = ChunkManager.GetChunkComponent(x,y,z); // always null
    16.                 if (chunk == null)
    17.                 {
    18.                     Index index = Engine.PositionToChunkIndex (startVec);
    19.                     if (index == null)
    20.                         Debug.LogError ("AddLight Error index null");
    21.                     chunk = ChunkManager.GetChunkComponent (index);
    22.                     if (chunk == null)
    23.                     {
    24.                         index = Engine.PositionToChunkIndex (startVec-Vector3.up);
    25.                         if (index == null)
    26.                             Debug.LogError ("AddLight Error index null");
    27.                         chunk = ChunkManager.GetChunkComponent (index);
    28.                         if (chunk == null)
    29.                             Debug.LogError ("AddLight Error chunk null");                      
    30.                     }
    31.                 }
    32.                
    33.                 Globals.Lights.Add (light);
    34.                 GameObject lightGameObject = new GameObject ("ChunkLight" + voxel);
    35.                 lightGameObject.transform.parent = chunk.transform;
    36.                 Light lightComp = lightGameObject.AddComponent<Light> ();
    37.                 lightComp.range = 8;
    38.                 lightComp.intensity = 2;
    39.                 lightComp.shadows = LightShadows.Soft;
    40.                 lightComp.enabled = true;
    41.                 lightComp.type = LightType.Point;
    42.                 Vector3 chunkPos = chunk.VoxelIndexToPosition(chunk.ChunkIndex);
    43.                 //lightGameObject.transform.position = new Vector3 (x-chunkPos.x, y-chunkPos.y, z-chunkPos.z); //?todo pos?
    44.                 lightGameObject.transform.position = new Vector3 (x, y, z); //todo pos?
    45.             }
    46.         }
    47.         catch (System.Exception ex) {
    48.             Debug.LogError ("AddLight Error: " + ex.ToString ());
    49.         }
    50.     }
     
  47. RawLionWorkshop

    RawLionWorkshop

    Joined:
    Jan 29, 2014
    Posts:
    206
    @Cakx
    Thank you for bringing up these issues. I've been able to reproduce the problems (the flickering and the lag spikes), but I don't have a fix for them yet. I'm working on figuring it out and hopefully have a patch out soon!

    As for the other minor bugs, I'm aware of them, but haven't fixed them until now because Uniblocks was always meant to be just a terrain package, not a game package, and the player controls were included just as a very rudimentary example. Ideally you'd want to implement your own player control and terrain interaction system. But many people have been requesting a better and more polished gameplay system to be included with Uniblocks, so I'll see what I can do, perhaps in the next update?


    I haven't looked through the whole code in detail, but there's one potential problem I noticed.
    You said you use world position for the x,y,z values in GetChunkComponent?
    GetChunkComponent actually looks up chunks by their index, not the world coordinates, so you'll need to convert the position to chunk index first:
    Code (CSharp):
    1. Index index = Engine.PositionToChunkIndex (worldPositionVector);
    2. Chunk chunk = ChunkManager.GetChunkComponent (index);
    I think this should return the chunk correctly.
     
    Firlefanz73 likes this.
  48. Firlefanz73

    Firlefanz73

    Joined:
    Apr 2, 2015
    Posts:
    1,316
    Hello maap,

    thanks a lot for your info! If you look into my Code at line 24 and 27 this is exactly what I am doing. And most times it works, sometimes not.

    If I add many lights, I can see around 3/4 of them.

    For the others, I get the error:

    Debug.LogError("AddLight Error chunk null");

    Do you have any idea, why the code returns null sometimes for getting the chunk?

    Is a chunk also added if it does not contain any voxels yet? Like putting a light on the ground maybe and it could be the first voxel in the chunk?

    Thanks :)
     
    Last edited: Jan 21, 2017
  49. jessejarvis

    jessejarvis

    Joined:
    Aug 9, 2013
    Posts:
    303
    Hello @maap ,

    I was taking a look at Uniblocks and I got to say I am impressed so far with the performance. I was just wondering a couple things, I noticed how this uses the old Unity multiplayer code and was wondering what scripts I would need to change in order to convert it to the new UNET.

    Also are you still working on this? I was waiting on TerrainEngine for a very long time but am considering this instead, even if development seems slowed or dead, just because of how well it's working right now.

    Also also lol, how would I go about changing the shader if say I wanted vertex colors instead of materials/textures for the blocks.

    Thanks.
     
  50. RawLionWorkshop

    RawLionWorkshop

    Joined:
    Jan 29, 2014
    Posts:
    206
    Yes, unfortunately the multiplayer code still uses the old system, but pretty much all the networking code is contained in the two scripts in the Multiplayer folder (UniblocksServer and UniblocksClient). If you'd like to convert these to UNET yourself, it shouldn't be too hard, with the help of the documentation.

    I'm currently not actively developing new features for Uniblocks, but I'm still supporting it, answering questions and fixing bugs if any are reported. So the project is not completely abandoned or anything, but to be totally honest it's just not at the top of my priority list at the moment.

    To change the shader you can just assign different materials with different shaders to the Chunk prefab. However, there's no built in system for using vertex colors instead of textures. You could assign a material which uses vertex lighting, but I'm not sure if that's exactly the solution you're looking for. But if you actually just want to change the shaders, that's very easy, you can even assign different materials/shaders to different block types. Everything is described in the user manual.



    Also I just noticed I completely missed the post above from a few months ago. I' m so sorry!
    It seems that maybe you were trying to get chunks that just haven't been spawned yet, that's why it was returning null.
    Chunks that contain only empty voxels will still spawn as normal. Basically the only way for a chunk to not exist is if it's outside of the current spawn range, and the other possibility is there's just something wrong with the logic in the code used to get that chunk.

    Well, since the reply is a few months late it's probably not relevant anymore, but, just in case...
    Sorry again!