Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Map Magic World Generator - a node based procedural and infinite game map tool

Discussion in 'Assets and Asset Store' started by Wright, Mar 10, 2016.

  1. Poxican

    Poxican

    Joined:
    Oct 17, 2012
    Posts:
    37
    Excellent, thanks! No great rush, but have you got an ETA on that?
     
  2. Aress28

    Aress28

    Joined:
    Dec 12, 2015
    Posts:
    100
    Hi. Im getting spikes on my terrain when i try to remove sand from cliffs in shore line.....i done all seting like in tutorial...
     

    Attached Files:

  3. malkere

    malkere

    Joined:
    Dec 6, 2013
    Posts:
    1,212
    Try unpinning and pinning again.
     
  4. Lostlogic

    Lostlogic

    Joined:
    Sep 6, 2009
    Posts:
    693
    Do you guys ever get this message on startup? I wonder if its taking longer to generate than MM code allows for?

    MissingReferenceException: The object of type 'Terrain' has been destroyed but you are still trying to access it.
    Your script should either check if it is null or you should not destroy the object.
    MapMagic.SplatOutput+<Apply>c__Iterator2.MoveNext () (at Assets/MapMagic/Generators/OutputGenerators.cs:552)
    MapMagic.GeneratorsAsset+<Apply>c__Iterator1.MoveNext () (at Assets/MapMagic/Main/GeneratorsAsset.cs:565)
    MapMagic.Chunk+<ApplyRoutine>c__Iterator0.MoveNext () (at Assets/MapMagic/Main/Chunk.cs:242)
    MapMagic.ThreadWorker.CoroutineFn () (at Assets/MapMagic/Main/ThreadWorker.cs:604)
    MapMagic.ThreadWorker.UpdateApply () (at Assets/MapMagic/Main/ThreadWorker.cs:224)
    MapMagic.ThreadWorker.Refresh () (at Assets/MapMagic/Main/ThreadWorker.cs:143)
    MapMagic.MapMagic.Update () (at Assets/MapMagic/Main/MapMagic.cs:272)

    The code in outputgenerators.cs is failing at:

    TerrainData data = terrain.terrainData;
     
  5. malkere

    malkere

    Joined:
    Dec 6, 2013
    Posts:
    1,212
    nitrox just posted the same question. Wright asked:
    "Could you please clarify when you get this error? Is this happens on playmode change or do you remove tiles manually in playmode/editor?"
     
  6. Lostlogic

    Lostlogic

    Joined:
    Sep 6, 2009
    Posts:
    693
    Happens when I hit play and the scene loads. I have multiple scenes and the one with MM loads last. The scene loads, I can see MM has no terrain data yet and it throws that error. Then the terrain data shows up and the error does not happen again. It seems that MM is trying to access the terrain data before it exists.
     
  7. eaque

    eaque

    Joined:
    Aug 20, 2014
    Posts:
    755
    Hi,

    Maybe a stupid and obvious question: Till now i've been using 4 terrains ALWAYS rendered of 4000 each to create my 8/8km world.
    heightmap 2048
    splat res 2048
    Plus CTS and VS
    and was quite happy in terms of performance.(old 660 ti gpu and 120fps)

    I'm upgrading to U2018, try to chase any fps lost in the move :p

    -Do you think 16 terrains with some terrains disabled thanks to MM feature could improve that or maybe be worst?
    It's a common question about terrain management so in theory what would you chose?

    -another question, i would need to render and disable objects at the same time as the terrains is there any api or function included in MM to do that? (don't remember...)

    thx
     
  8. Wright

    Wright

    Joined:
    Feb 26, 2013
    Posts:
    2,267
    So this error occurs when you load the scene with the MM object additively?

    Are you going to use 16 terrains of lower resolution (512) and size instead of 4? Surely, in most cases disabling a terrain can improve the performance.

    If you are using pinned terrains then it's better just use the terrain as a parent for your objects. If you want a script then use MonoBehaviour's OnEnable attached to the terrain object.
     
    eaque likes this.
  9. Lostlogic

    Lostlogic

    Joined:
    Sep 6, 2009
    Posts:
    693
    Correct. I just tried it in a single scene and the error does not happen. I normally get these kind of errors when I have items in Awake() and not Start().
     
  10. Aress28

    Aress28

    Joined:
    Dec 12, 2015
    Posts:
    100
    Problem with Vegetation studio....when i add it i lost all textures what was set in CTS and i have some default textures from VS now...how to get back my textures from CTS?where i turn off textures from VS?
     
  11. eaque

    eaque

    Joined:
    Aug 20, 2014
    Posts:
    755
    Yes instead of the 4big!
    i suppose i can go to 1024 as res and the same for splatMap considering the size 2/2km
    Do you mean reducing the res will help more? the test i made in the past didn't show me great difference but i will definitely play with resolution !

    thanks
     
  12. Lostlogic

    Lostlogic

    Joined:
    Sep 6, 2009
    Posts:
    693
    I added Veg Studio and it wiped out my grass on Terrain 0,0 and it won't come back. Some strange behavior. I removed it but its still gone even when I reload the whole project and force a refresh.
     
  13. Wright

    Wright

    Joined:
    Feb 26, 2013
    Posts:
    2,267
    VS replaces the standard grass with it's own. Guess it's an expected behavior.

    You were talking about some terrains disabled. When using 8x8 512 terrains with view range of say 1km only 4x4 grid will be visible (16 terrains), while 48 terrains will be hidden. And while using 2x2 2K terrains all of them will be visible all the time.

    Are you adding Vegetation Studio the usual way (Window - Awesome Technologies - Add VS) ot by using VS output node?
     
  14. Lostlogic

    Lostlogic

    Joined:
    Sep 6, 2009
    Posts:
    693
    I am looking for a call to figure out which chunks are currently visible/generated?

    Also, can you make your own object output class? I can make a generator but need to customize actual object creation.
     
  15. Lostlogic

    Lostlogic

    Joined:
    Sep 6, 2009
    Posts:
    693
    I cannot figure out what changed... For some reason, all of my trees at Terrain 0,0 are below the terrain all on Y of 0. All other terrains generate just fine. I tried moving the camera and back, its still the same way. Reset Unity, same way. Any idea what setting in the graph I accidentally changed to force the trees in only that square to be messed up?
     
  16. Nitrox32

    Nitrox32

    Joined:
    May 9, 2017
    Posts:
    161
    Thanks!
     
  17. ksam2

    ksam2

    Joined:
    Apr 28, 2012
    Posts:
    1,079
    There is something wrong with Map Magic and RTP custom shader node, I can't enable "Instant Update" (Only works when I disable instance update. But I need this option to be enable) seems a bug. I'm really stuck please help.
     
    Last edited: Nov 9, 2018
  18. Wright

    Wright

    Joined:
    Feb 26, 2013
    Posts:
    2,267
    You can use OnApplyComplete event. Or just utilize assigned to terrain script's OnEnable.

    Me? Well, I can add a callback to objects output that will process the objects the way you like, but you will have to assign it via script. That doesn't seem to be very straightforward, though, especially if you are going to do something with prefabs, transforms or game objects - it all should be done in a main thread. So it's better use OnApplyCompleted event here too.
    No, there is no way to add an additional output if that is what you mean - at least without changing MM code. Each of the outputs is unique and works in it's own way, and all of them are the part of MM. They are not "plugins" like the generators.

    It's hard to say what's going on without seeing your graph. Are you using the adjust node? Have you tried un-pinning terrain and pinning it again?

    What are assets versions? Is there any error in the console?
     
  19. malkere

    malkere

    Joined:
    Dec 6, 2013
    Posts:
    1,212
    What do you need to customize? You can for example make MM spawn an empty GameObject with a script on it, then use that script to spawn something runtime custom, or put a custom generator before the object output node to run your own calculations. Should be a way to do just about anything.
     
  20. ksam2

    ksam2

    Joined:
    Apr 28, 2012
    Posts:
    1,079
    Last version of both assets. (Map Magic 1.9.3) It works with Legacy RTP node but not with custom shader node.

    Edit: It doesn't work with Legacy RTP node either! I though it work but after enabling Instant Updater It doesn't work correctly.
     
    Last edited: Nov 12, 2018
  21. shedworksdigital

    shedworksdigital

    Joined:
    Nov 7, 2016
    Posts:
    40
    You can add it manually, it's just one extra line of code. In Chunk.cs, after line 301, add

    terrain.drawInstanced = true;
    on a new line to force instancing on.
     
    camta005 likes this.
  22. Wright

    Wright

    Joined:
    Feb 26, 2013
    Posts:
    2,267
    Sure thing, they share the same method. Will look into it shortly. Something might have changed in RTP code recently.

    I will expose this to settings on the next update.
     
    camta005 likes this.
  23. dlstilts

    dlstilts

    Joined:
    Sep 29, 2017
    Posts:
    38
    Hi I have been using map magic for a while and I have been relying heavily on these extensions recently: https://unitylist.com/p/ua/Map-Magic-Extensions
    These allow me to randomize aspects of the terrain at run time. However, after updating to the new version of map magic I am getting a lot of errors from these extension scripts. I am not the best coder but is there any way you can let me know how to fix these errors so the extensions work in the new version? Thanks!
     
  24. NITO90

    NITO90

    Joined:
    Feb 5, 2015
    Posts:
    4
    Hi,

    I have a few a questions.
    How can i save and load non pinned map magic terrains?
    If a load game happens and i feed the seed number to map magic, all of the terrains will be the same?
    Object outputs will happen at the same place?
    If I travel far away, and return, the map will be the same?

    Thank you for your answer!
     
  25. camta005

    camta005

    Joined:
    Dec 16, 2016
    Posts:
    320
    Yes, everything will be the same each time with the same seed number.
     
    NITO90 likes this.
  26. dlstilts

    dlstilts

    Joined:
    Sep 29, 2017
    Posts:
    38
    Hi I realize with my last question I might have been asking too much with just a link. Here is the code for one of the randomize functions. It creates a node in the MapMagic editor to pick from a list of nodes randomly. If there is anything you can recommend to update the code to work on the new version I would be very grateful. Thank you.

    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3. using System.Collections.Generic;
    4.  
    5. namespace MapMagic
    6. {
    7.  
    8.     // Refer to CombineGenerator in ObjectGenerators.cs
    9.     [System.Serializable]
    10.     [GeneratorMenu (menu="Custom", name ="Chance", disengageable = true)]
    11.     public class ChanceMapGenerator : Generator
    12.     {
    13.         // Each output needs to have weight property associated with it, so we'll use
    14.         // an array of Layers rather than a simple array of Outputs.
    15.         public class Layer
    16.         {
    17.             public Output output = new Output(InoutType.Map);
    18.             public float weight = 1f;
    19.         }
    20.         public Layer[] layers = new Layer[] { new Layer(), new Layer() };
    21.  
    22.         // Only a single Input
    23.         public Input input = new Input("Input", InoutType.Map);
    24.      
    25.         public override IEnumerable<Input> Inputs() { yield return input; }
    26.         public override IEnumerable<Output> Outputs() { for (int i=0; i<layers.Length; i++) yield return layers[i].output; }
    27.      
    28.         public int outputsNum = 2;
    29.         public int seed = 12345;
    30.         public int guiSelected;
    31.      
    32.         public override void Generate (Chunk chunk, Biome biome = null)
    33.         {  
    34.             //return on stop/disable
    35.             if (chunk.stop || !enabled) return;
    36.  
    37.             InstanceRandom rnd = new InstanceRandom(MapMagic.instance.seed + seed/* + chunk.coord.x*1000 + chunk.coord.z*/);
    38.  
    39.             // Calculate the total weight of all layers
    40.             float sumOfWeights = 0f;
    41.             for (int i=0; i<layers.Length; i++){
    42.                 sumOfWeights += layers[i].weight;
    43.             }
    44.          
    45.             // Pick a random value less than the total weight
    46.             float rouletteSelection = rnd.Random(0, sumOfWeights);
    47.  
    48.             // Loop through the layers, keeping a running sum of weights
    49.             // The layer that contains the chosen rouletteWeight gets sent the input
    50.             // All other layers get sent the default matrix
    51.             float prevRunningWeight = 0f;
    52.             float nextRunningWeight = 0f;            
    53.             for (int i=0; i<layers.Length; i++){
    54.                 nextRunningWeight = prevRunningWeight + layers[i].weight;
    55.                 if(prevRunningWeight < rouletteSelection && nextRunningWeight > rouletteSelection) {
    56.                     layers[i].output.SetObject(chunk, (Matrix)input.GetObject(chunk));
    57.                 }
    58.                 else {
    59.                     layers[i].output.SetObject(chunk, chunk.defaultMatrix);
    60.                 }
    61.                 prevRunningWeight = nextRunningWeight;
    62.             }
    63.         }
    64.  
    65.         // Defines how the row element for each individual output layer is drawn
    66.         public void OnLayerGUI (Layer layer, Layout layout, int num, bool selected)
    67.         {
    68.             layout.margin += 10; layout.rightMargin +=5;
    69.             layout.Par(20);
    70.             layout.Label("Weight:", layout.Inset(0.4f));
    71.             layout.Field(ref layer.weight, rect:layout.Inset(0.5f));
    72.             layer.output.DrawIcon(layout);
    73.             layout.margin -= 10; layout.rightMargin -=5;
    74.         }
    75.      
    76.      
    77.         public override void OnGUI ()
    78.         {
    79.             //input
    80.             input.DrawIcon(layout, "Input");
    81.             layout.Par(16);
    82.             //params
    83.             layout.Field(ref seed, "Seed");
    84.             layout.Par(16);
    85.             //output layers
    86.             layout.Label("Layers:", layout.Inset(0.4f));
    87.             layout.DrawArrayAdd(ref layers, ref guiSelected, layout.Inset(0.15f), def:new Layer());
    88.             layout.DrawArrayRemove(ref layers, ref guiSelected, layout.Inset(0.15f));
    89.             layout.DrawArrayUp(ref layers, ref guiSelected, layout.Inset(0.15f));
    90.             layout.DrawArrayDown(ref layers, ref guiSelected, layout.Inset(0.15f));
    91.             layout.margin = 10;
    92.             layout.Par(5);
    93.             layout.DrawLayered(layers, ref guiSelected, min:0, max:layers.Length, reverseOrder:true, onLayerGUI:OnLayerGUI);
    94.         }
    95.     }
    96. }
     
    Wright likes this.
  27. shedworksdigital

    shedworksdigital

    Joined:
    Nov 7, 2016
    Posts:
    40
    I've just updated to 2018.3.0b9 and when I open the editor for the first time, I get this error:

    ArgumentException: Object of type 'UnityEngine.Object' cannot be converted to type 'UnityEngine.Texture2D'.
    System.RuntimeType.CheckValue (System.Object value, System.Reflection.Binder binder, System.Globalization.CultureInfo culture, System.Reflection.BindingFlags invokeAttr) (at <ac823e2bb42b41bda67924a45a0173c3>:0)
    System.Reflection.MonoMethod.ConvertValues (System.Reflection.Binder binder, System.Object[] args, System.Reflection.ParameterInfo[] pinfo, System.Globalization.CultureInfo culture, System.Reflection.BindingFlags invokeAttr) (at <ac823e2bb42b41bda67924a45a0173c3>:0)
    System.Reflection.MonoMethod.Invoke (System.Object obj, System.Reflection.BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) (at <ac823e2bb42b41bda67924a45a0173c3>:0)
    System.Reflection.MonoProperty.SetValue (System.Object obj, System.Object value, System.Reflection.BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] index, System.Globalization.CultureInfo culture) (at <ac823e2bb42b41bda67924a45a0173c3>:0)
    System.Reflection.PropertyInfo.SetValue (System.Object obj, System.Object value, System.Object[] index) (at <ac823e2bb42b41bda67924a45a0173c3>:0)
    MapMagic.CustomSerialization.ReadClass (System.Int32 slotNum, System.Collections.Generic.List`1[T] classes, System.Collections.Generic.List`1[T] objects, System.Collections.Generic.List`1[T] floats, System.Collections.Generic.List`1[T] references) (at Assets/MapMagic/Main/CustomSerialization.cs:485)
    MapMagic.CustomSerialization.ReadClass (System.Int32 slotNum, System.Collections.Generic.List`1[T] classes, System.Collections.Generic.List`1[T] objects, System.Collections.Generic.List`1[T] floats, System.Collections.Generic.List`1[T] references) (at Assets/MapMagic/Main/CustomSerialization.cs:384)
    MapMagic.CustomSerialization.ReadClass (System.Int32 slotNum, System.Collections.Generic.List`1[T] classes, System.Collections.Generic.List`1[T] objects, System.Collections.Generic.List`1[T] floats, System.Collections.Generic.List`1[T] references) (at Assets/MapMagic/Main/CustomSerialization.cs:384)
    MapMagic.CustomSerialization.ReadClass (System.Int32 slotNum, System.Collections.Generic.List`1[T] classes, System.Collections.Generic.List`1[T] objects, System.Collections.Generic.List`1[T] floats, System.Collections.Generic.List`1[T] references) (at Assets/MapMagic/Main/CustomSerialization.cs:384)
    MapMagic.CustomSerialization.ReadClass (System.Int32 slotNum, System.Collections.Generic.List`1[T] classes, System.Collections.Generic.List`1[T] objects, System.Collections.Generic.List`1[T] floats, System.Collections.Generic.List`1[T] references) (at Assets/MapMagic/Main/CustomSerialization.cs:384)
    MapMagic.GeneratorsAsset.OnAfterDeserialize () (at Assets/MapMagic/Main/GeneratorsAsset.cs:1142)

    It seems to delete all the generators in some of my biome assets.
     
  28. Lostlogic

    Lostlogic

    Joined:
    Sep 6, 2009
    Posts:
    693
    Has anyone successfully created rivers that span map chunks? Would be cool to be able to have a river that runs across 20 chunks for example.
     
  29. Wright

    Wright

    Joined:
    Feb 26, 2013
    Posts:
    2,267
    Unfortunately I can't fix them because I'm not the author, but I've looked through them and guess I will make something like 1D Scatter in the further versions. Speaking of Regular Spacing you can use Scatter in the Cell mode with Uniformity 1. And here you can find the Single node.

    Yes. MapMagic works in a deterministic way - as long as the graph and the seed are the same it will generate absolutely the same terrain on the same position.

    Do you have an original graphs backup in older Unity version? Could you email them to me?
    Strangely the error says that Texture2D isn't an Object anymore. That's very odd. Might be Unity's beta issue, but I'd like to have a look myself.

    I've been thinking about it for almost a year, and still got no worth ideas of how the chunk can get any information about the river without generating the other ones. How the chunk will know where the river will enter it and where will it leave? How it will know if there is any river at it at all without calculating the whole world? Any ideas?
     
    shedworksdigital and malkere like this.
  30. malkere

    malkere

    Joined:
    Dec 6, 2013
    Posts:
    1,212
    Implementing rivers has always been one of my dreams too. I think as Wright says it's only possible with foresight. My game calculates 8km chunks before it generates the 1km terrains within each chunk using MM. I believe I can use that to predetermine rivers -within- the 8km span, though I would still have to have access to the heightmaps to know where to start and end.. So basically you'd still have to generate everything. Not a big deal if you're just generate float arrays via threading, it'd take time though.
     
    Nunez-Torrijos likes this.
  31. Lostlogic

    Lostlogic

    Joined:
    Sep 6, 2009
    Posts:
    693
    Any idea how minecraft does it?
     
  32. Nihilus0

    Nihilus0

    Joined:
    Jan 25, 2017
    Posts:
    52
    Hi, @Wright
    I found something you need to modify to integrate VS Pro with MM.
    and I want to hear your opinion or a solution to this.

    The performance was not good when I tried to integrate VS and MM before.
    A few months later,
    When i tested the new VS Pro, it was amazing. It was a recommended performance. I share a very simple code that apply to MM with VS Pro.
    Code (CSharp):
    1. public class VSproMapmagicIntegration : MonoBehaviour
    2.     {
    3.         public MapMagic.MapMagic mapMagicInstance;
    4.  
    5.         private void Awake()
    6.         {
    7. #if UNITY_EDITOR
    8.             if (Application.isPlaying)
    9.             {
    10. #endif
    11.                 MapMagic.MapMagic.OnApplyCompleted += TerrainAddUT;
    12. #if UNITY_EDITOR
    13.             }
    14. #endif
    15.         }
    16.  
    17.         private void OnDestroy()
    18.         {
    19.             MapMagic.MapMagic.OnApplyCompleted -= TerrainAddUT;
    20.         }
    21.  
    22.         private void TerrainAddUT(Terrain terrain)
    23.         {
    24.             if (terrain.GetComponent<UnityTerrain>() == null)
    25.             {
    26.                 UnityTerrain newUnityTerrain = terrain.gameObject.AddComponent<UnityTerrain>();
    27.                 newUnityTerrain.TerrainPosition = terrain.GetPosition();
    28.                 newUnityTerrain.AutoAddToVegegetationSystem = true;
    29.                 newUnityTerrain.AddTerrainToVegetationSystem();
    30.             }
    31.         }
    32.  
    33.     }

    But this code has a critical bug. The bug is shown in the gif below.
    Honeycam 2018-11-16 21-47-53.gif unknown (5).png
    I personally confirm it is a bug from MM's output.
    The reason is that every time I passed the chunk, MM tried to recycle Terrain.

    If normal, the chunk of 'Terrain 4, 0' located in (4000, 0) is created, the chunk must be in the position (4000, 0) when the OnApplyComplete event occurs with the name of 'Terrain 4, 0'.
    However, when Terrain is recycled, the chunk that was created is named 'Terrain -3, 0', and in OnApplyComplete event, Terrain's location is also marked as position (-3000, 0). And the after, the Terrain of position (-3000, 0) moves to the position of position (4000, 0). This is the problem.

    20181116_212404_1.png

    It seems to have caused a problem because its location and name are still used while recycling Terrain. so, It seems to read normally in VS Pro. I am sure that this problem will be fixed by MapMagic set its moved normal position when the OnApplyComplete event occurs.

    P.S. I am not an English speaker. I used a translator. I am sorry my poor English.
     
    Last edited: Nov 16, 2018
  33. Nihilus0

    Nihilus0

    Joined:
    Jan 25, 2017
    Posts:
    52
    I also preload a pre-determined full size map before using MM. This is because it determines the flow of rivers and start/end of river. In fact, not only the rivers but also the mountains. The mountain range of noise Generator is certainly limited by size as well as reality. For this, I created a huge mountain range generator and implemented it in the form of MM loading. However, this is not exactly the way MM pursues it. The endless rivers and mountains have many things to think about.
    20180720_221056_2.png 20180721_170742_4.png 20180919_073937_1.png 20180919_073937_2.png

    Minecraft, on the other hand, has nothing to do with river flows. Since the chunk's structure is similar to the voxel, generator is just placed the water block. The flow of water (a waterfall) is designated as logic by itself when the chunk is completed. Thus, a river generator similar to Minecraft may be made as MM's Noise Generator.
     
    Last edited: Nov 17, 2018
    malkere likes this.
  34. Lostlogic

    Lostlogic

    Joined:
    Sep 6, 2009
    Posts:
    693
    Just thinking out loud. What if you generated a river object procedurally in world coordinates that received the onapply update from MM which then in turn would modify the height of any terrain present? Basically a second step to apply "outside" of MM. Make sense? Similar to the road asset that generates roads post terrain.
     
    malkere likes this.
  35. malkere

    malkere

    Joined:
    Dec 6, 2013
    Posts:
    1,212
    The only problem is that you still have to contain it within generated terrains. If Terrain 1 has the footholds of some mountains, then later Terrain 2 comes on and has a river up the mountain side, you can't change Terrain 1 to "accept" the river flow without changing what the player may have already been running around in/built on, etc. If you find a nice slope -within- a terrain and let it flow down until it finds a flat point, or nears the edge then just make an underground entrance or something for it to "go away" into then it would work.

    I think the end result is always though that it needs to be pre-generated somehow like Cosmograph shows. Otherwise you can never know what's on a neighbor terrain, unfortunately. That makes it limited by the size of your terrains as well.
     
  36. Crossway

    Crossway

    Joined:
    May 24, 2016
    Posts:
    507
    Hi Wright, did you find a solution for this? I have same issue :(
     
  37. dlstilts

    dlstilts

    Joined:
    Sep 29, 2017
    Posts:
    38
    Thanks @Wright from the errors it looks like they are referencing outdated code in an older version. I am particularly interested in being able to randomize textures and terrain aspects to get different terrain at each run and tile generation. Might be asking too much though. Cheers!
     
  38. Artaani

    Artaani

    Joined:
    Aug 5, 2012
    Posts:
    423
    Hello Wright
    Super great tool!

    Is there a way to "mass save" several terrains?
    For example I want to create 10x10 km landscape (each chunk 1x1 km) using Map Magic, and after I am happy with result, I want to "bake" it (save into terrain data files, not scene file)

    So I need to click "Save" on each chunk. However it requires 100 clicks and I need to enter file name 100 times.

    So, is there a way to save entire 10x10 chunks area into 100 data files automatically with a few clicks?
     
  39. Bodyclock

    Bodyclock

    Joined:
    May 8, 2018
    Posts:
    172
    Hi All,
    Does anyone know if there is a way to apply a global colour map to MM terrains? The case is I have a 5km x 5km terrain with a 2k heightmap generated in World Machine that I will use to generate 1k tiles in MM. I also have a 4k colour map generated in WM that I would like to use as a base. Is there a way to apply this to the whole terrain similar to the raw input node so that MM knows what part of the colour map to apply to what part of the generated terrain?
     
  40. Wright

    Wright

    Joined:
    Feb 26, 2013
    Posts:
    2,267
    Thanks Cosmoraph, Lostlogic and malkere for the ideas. There's a lot to think about, and your opinions are quite handy. I'm thinking more of a "big scale" world too, but it's not clear if it should be pre-generated or should be created on-the-go for several chunks. Or should it be created for each of the chunks (what about the performance then). I'd really like to hear a discussion or brainstorm, it will help not only to find out what do users expect, but to lead the way to splines and other between-chunk stuff features. And thanks again for your ideas!

    The same as when using the standard terrains. You have to use the custom terrain material with a shaders that apply color map multiplicatively. Unfortunately there's no way to do it out of the box since MM is not a terrain shader, it's a bit out of the scope of the asset.


    Thanks!
    Well, you can use this script:
    Code (CSharp):
    1. using UnityEngine;
    2. using UnityEditor;
    3. using System.IO;
    4. using System.Text;
    5.  
    6. public static class SaveAssetClass
    7. {
    8.     public static void SaveAsset (UnityEngine.Object asset, string savePath=null)
    9.     {
    10.         if (savePath==null) savePath = UnityEditor.EditorUtility.SaveFilePanel(
    11.                     "Save Data as Unity Asset",
    12.                     "Assets",
    13.                     "Asset",
    14.                     "asset");
    15.         if (savePath!=null && savePath.Length!=0)
    16.         {
    17.             savePath = savePath.Replace(Application.dataPath, "Assets");
    18.  
    19.             AssetDatabase.DeleteAsset(savePath);
    20.             UnityEditor.AssetDatabase.CreateAsset(asset, savePath);
    21.             UnityEditor.AssetDatabase.SaveAssets();
    22.         }
    23.     }
    24.  
    25.     public static void SaveTerrain (TerrainData terrainData, string savePath=null)
    26.     {
    27.         //backup splats
    28.         float[,,] splats = terrainData.GetAlphamaps(0,0,terrainData.alphamapResolution, terrainData.alphamapResolution);
    29.      
    30.         SaveAsset(terrainData, savePath);
    31.      
    32.         //re-assign splats
    33.         terrainData.SetAlphamaps(0,0,splats);
    34.         AssetDatabase.SaveAssets();
    35.     }
    36.  
    37.     public static void SaveTerrainsRecursively (GameObject obj, string saveDir)
    38.     {
    39.         Terrain terrain = obj.GetComponent<Terrain>();
    40.         if (terrain != null)
    41.             SaveTerrain(terrain.terrainData, savePath:saveDir + "\\" + obj.name + ".asset");
    42.  
    43.         for (int c=0; c<obj.transform.childCount; c++)
    44.             SaveTerrainsRecursively(obj.transform.GetChild(c).gameObject, saveDir);
    45.     }
    46.  
    47.  
    48.  
    49.     [MenuItem ("Edit/Save Asset/Terrain")]
    50.     static void SaveTerrain (string savePath=null)
    51.     {
    52.         Terrain terrain = Selection.activeGameObject.GetComponent<Terrain>();
    53.         SaveTerrain(terrain.terrainData);
    54.     }
    55.  
    56.  
    57.     [MenuItem ("Edit/Save Asset/Multiple Terrains")]
    58.     static void SaveTerrains ()
    59.     {
    60.         string saveDir = UnityEditor.EditorUtility.SaveFolderPanel(
    61.                     "Save Data as Unity Asset",
    62.                     "Assets",
    63.                     "Terrains");
    64.         for (int i=0; i<Selection.gameObjects.Length; i++)
    65.         {
    66.             GameObject obj = Selection.gameObjects[i];
    67.             SaveTerrainsRecursively(obj, saveDir);  
    68.         }
    69.     }
    This way you can save the terrain by selecting MapMagic and pressing Edit - Save Assets - Multiple Terrains.

    It's a part of an extended script I'm using to save all of the assets like meshes, obj file, materials, etc. I will attach it here in case someone will find it useful.

    I'm making an update, going to release it on Monday.
    EDIT: could not reproduce this issue. Everything seems to be working fine (Unity 2018.2, MM 1.9.3, RTP3.3n). Is there a way to reproduce it in a clear scene? Are there any errors in the console?

    Thanks for the code! But I'd like to mention that there's no official integration with VS Pro, I haven't looked into it yet. Its the other asset rather than non-pro VS, so use it at your own risk :)
    In your case I'd rather tried changing MapMagic.cs line 234, allowMove to false:
    if (chunksChange) chunks.Deploy(deployRects, removeRects, parent:this, allowMove:false);

    That will disable the terrain pool and will force terrains to re-create for each new tile.
    Guess I will expose this in settings.

    Are there any splines?
     

    Attached Files:

    Last edited: Nov 18, 2018
    Artaani, malkere and Crossway like this.
  41. Wright

    Wright

    Joined:
    Feb 26, 2013
    Posts:
    2,267
    PS Crossway, could not reproduce the RTP issue. Everything seems to be working fine (Unity 2018.2, MM 1.9.3, RTP3.3n). Is there a way to reproduce it in a clear scene? Are there any errors in the console?
     
  42. Nihilus0

    Nihilus0

    Joined:
    Jan 25, 2017
    Posts:
    52
    I got it. Thank you for your advice.
     
  43. secondsight_

    secondsight_

    Joined:
    Mar 2, 2014
    Posts:
    163
    Yes and no. As Wright mentioned, this does not work out of the box and you will get the best results with other terrain shaders.
    However... I made that work somehow on a prototype level I make a while ago. And depending an what you are aiming for, this could work out for out for you. Basically, you apply a second texture output with and scale the texture up. In some occations you can also use the colormap in one texture output as a base or overlay, but you have to tweak the opcactiy a lot and it can turn out blurry. Depending on the colors you are using for the colormap, you have to tweak the brightness and constrast a lot.

    This is what worked out for me:

     
    RadioactiveXP and camta005 like this.
  44. Bodyclock

    Bodyclock

    Joined:
    May 8, 2018
    Posts:
    172
    Thanks very much. I'll give this a try. :)
     
  45. Bodyclock

    Bodyclock

    Joined:
    May 8, 2018
    Posts:
    172
    Tile2.png
    Unless I'm missing something, close but no cigar - I need the colour map to show on all the tiles but it repeats. As you can see, one tile is correctly scaled and positioned, but is then repeated. But in theory this is what I'm after.
    Ignore the colours, this was just a test. :)
    Graph.png
     
  46. malkere

    malkere

    Joined:
    Dec 6, 2013
    Posts:
    1,212
    I'm pretty sure Minecraft pregenerates sections of the world to determine biomes, structures, and waterfalls. That's one of the reasons the game goes into "building terrain" when you start a new world, before it actually generates anything to render. Probably multi-threaded during runtime?

    @Kris392001 you'll probably need to 1. make a really big texture, or 2. make a custom generator to apply the textures to specific terrains, or 3. setup a series of masks to turn each texture on and off for each terrain.
    2. probably being the best option, though also the hardest.
     
  47. alejandronop

    alejandronop

    Joined:
    Jul 7, 2017
    Posts:
    11
    Hello, when I import saved data, decimals are lost
    before:
    upload_2018-11-19_3-13-2.png
    after:
    upload_2018-11-19_3-13-39.png

    In unity 2018.3
     
  48. Bodyclock

    Bodyclock

    Joined:
    May 8, 2018
    Posts:
    172
    Thanks for the reply. The texture in the example is already really big (8192) so I think the best solution is, as you say, a customer generator, a combination of the raw input generator and the texture generator. I'm an OK C# developer but am new to the Unity object model so there is a learning curve but I'll have a look and see what I can do. :)
     
  49. secondsight_

    secondsight_

    Joined:
    Mar 2, 2014
    Posts:
    163
    If it helps, here is a old shot of a multi terrain setup I have done. The background layer of the texture output is empty and has a opacity of 0. The colormaps are in the second layer.

     
    RadioactiveXP and malkere like this.
  50. Bodyclock

    Bodyclock

    Joined:
    May 8, 2018
    Posts:
    172
    Thanks, it's similar to a setup I had for a prototype with multiple raw inputs. But I'm really trying to avoid splitting up the colour map if I can. I'll give the custom generator a try and post back here if I have any success. Should say I'm happy to commission someone to write it if they have the necessary skills. :)