Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Edit terrain in real time?

Discussion in 'Editor & General Support' started by Warrior1424, Jul 28, 2011.

  1. Warrior1424

    Warrior1424

    Joined:
    Sep 30, 2010
    Posts:
    984
    Are there any commands to change the height of the terrain in certain areas in real time? I couldn't find any.
    Thanks!
     
  2. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,398
  3. flamy

    flamy

    Joined:
    Feb 7, 2011
    Posts:
    194
  4. Krysalgir

    Krysalgir

    Joined:
    Aug 30, 2010
    Posts:
    95
    Yep the TerrainData allows to set heightmap, trees, texture maps... as you like, I've made a custom editor tool to generate terrains.

    But I think RT is a bit ambitious, depending on the terrain size, as you set the whole terrain data (ie full arrays of float). If it's only the heightmap I may be OK though.
     
  5. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,398
    You don't have to set the entire terrain heightmap, just a small part. The terrain editing in the editor is real-time, and it's "just" editor scripts, so it would work at least as well in-game.

    --Eric
     
  6. davidsirmons

    davidsirmons

    Joined:
    Mar 16, 2014
    Posts:
    190
    Terrain deformation in real time is going to be a staple of a game I'm considering. It won't need texturing, object placement, etc. , just deformation up and down. The broadness of the deformation in the editor is great, and it's the area of effect that I'm trying to find a way to implement...

    Here's something I got from a tut about real time terrain deformation in Unity, and it requires the script to be put onto the terrain object, and for the terrain in the HIERARCHY tab to be dragged onto the "MyTerrain" slot in the script:

    using UnityEngine;
    using System.Collections;

    public class TerrainDeformation_realtime : MonoBehaviour
    {
    public Terrain myTerrain;
    int xResolution;
    int zResolution;
    float[,] heights;

    void Start()
    {
    xResolution = myTerrain.terrainData.heightmapWidth;
    zResolution = myTerrain.terrainData.heightmapHeight;
    heights = myTerrain.terrainData.GetHeights(0,0,xResolution,zResolution);
    }

    void Update()
    {
    if(Input.GetMouseButton(0))
    {
    RaycastHit hit;
    Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
    if(Physics.Raycast(ray, out hit))
    {
    raiseTerrain(hit.point);
    }
    }
    if(Input.GetMouseButton(1))
    {
    RaycastHit hit;
    Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
    if(Physics.Raycast(ray, out hit))
    {
    lowerTerrain(hit.point);
    }
    }
    }

    private void raiseTerrain(Vector3 point)
    {
    int terX =(int)((point.x / myTerrain.terrainData.size.x) * xResolution);
    int terZ =(int)((point.z / myTerrain.terrainData.size.z) * zResolution);
    float y = heights[terX,terZ];
    y += 0.001f;
    float[,] height = new float[1,1];
    height[0,0] = y;
    heights[terX,terZ] = y;
    myTerrain.terrainData.SetHeights(terX, terZ, height);
    }

    private void lowerTerrain(Vector3 point)
    {
    int terX =(int)((point.x / myTerrain.terrainData.size.x) * xResolution);
    int terZ =(int)((point.z / myTerrain.terrainData.size.z) * zResolution);
    float y = heights[terX,terZ];
    y -= 0.001f;
    float[,] height = new float[1,1];
    height[0,0] = y;
    heights[terX,terZ] = y;
    myTerrain.terrainData.SetHeights(terX, terZ, height);
    }
    }


    Now, I've changed the "GetMouseButtonDown" that was originally there to instead say: "GetMouseButton" in order to make the deformation continuous. Still, it only raises up these jagged spikes from the terrain, and I can't see anything in this script which allows me to soften the area of effect. Even better, I'd like to be able to create craggy mountain ranges with a sweep of the player's hand. Not sure how to approach this, and ultimately hope to have such an effect with marching cubes terrain or some other large scale procedural method. If anyone can offer useable insight in how I can soften the effect, please let me know.
     
  7. NeverConvex

    NeverConvex

    Joined:
    Jun 26, 2013
    Posts:
    88
    I haven't played around with real-time terrain deformation before, but I think you should be able to alter the size of the area affected --- e.g., so that it's not just a single point being raised up to form a spike --- by altering the dimensions of height, which right now is just large enough (as a [1,1] 2-D array) to contain a single point, but could in principle be made larger to simultaneously raise/lower a larger piece of terrain simultaneously. Once height is larger than [1,1], you could, I think, alter the rigidity of the effect by changing values for more than just a single point in heights; e.g., after incrementing y and setting the target point to the incremented value in heights, make two nested for loops that proportionally increase points nearby the target point, in heights, based on their distance from the target point.
     
  8. goat

    goat

    Joined:
    Aug 24, 2009
    Posts:
    5,182
    Probably if you want to learn the API to do this you should download Terrain ToolKit 1.0.2 for working examples.
     
    doodaddy likes this.
  9. davidsirmons

    davidsirmons

    Joined:
    Mar 16, 2014
    Posts:
    190
    Well, thanks for the effort guys. I'm not a scripter/programmer. None of that would be of any use.
    So unless anyone can give actual line by line insight, there's not much I would be able to do.
     
  10. goat

    goat

    Joined:
    Aug 24, 2009
    Posts:
    5,182
    You're right go to the Learn section of Unity first and then download Terrain Toolkit 1.0.2 for as close to a line by line insight as you'll get without someone standing over your shoulder.
     
  11. davidsirmons

    davidsirmons

    Joined:
    Mar 16, 2014
    Posts:
    190
    NeverConvex, Thanks for trying. I'll open it up and hope to God the numbers and letters make sense.

    Goat, I hope the next time you need a 3d model or code (you have yet to say which one is your skill) I hope someone points you to 3ds max or C# (whichever one you DON'T have any familiarity with) and tells you 'good luck'.
     
  12. goat

    goat

    Joined:
    Aug 24, 2009
    Posts:
    5,182
    You've got to be kidding?

    I can't afford 3DS Max so that's a non-issue. I taught myself Blender well enough with my time and my effort thanks to some good tutorials from others, just as I directed you to in the Unity Learn section. I taught myself C# but then I am a C programmer.

    I hope you don't act like that to people that give you advice that actually would help you face to face.

    Some people really.
     
    Last edited: May 26, 2014
    doodaddy likes this.
  13. davidsirmons

    davidsirmons

    Joined:
    Mar 16, 2014
    Posts:
    190
    Aptitude.

    Mine is art. Not programming.

    You haven't helped. And if someone just stood behind me and said what you said, I'd tell them the same as I told you.

    I've farted around with the scripts I've been able to scrape up from the quagmire of code/pseudo-code in these forums, and been able to actually get some small things to work on my own. So my half-ass coding is equal to your half-ass 3d art. But if you want high quality 3d art, you ain't cutting it. If I want high-end programming, I ain't cutting it. See? That's my dilemma, and telling me to involve myself in something that's forever been beyond my aptitude is no help.
     
  14. NeverConvex

    NeverConvex

    Joined:
    Jun 26, 2013
    Posts:
    88
    I played around a little bit with the script you provided, and as a first pass wrote up this change to raiseTerrain:

    Code (csharp):
    1.     private void raiseTerrain(Vector3 point)
    2.     {
    3.         int terX =(int)((point.x / myTerrain.terrainData.size.x) * xResolution);
    4.         int terZ =(int)((point.z / myTerrain.terrainData.size.z) * zResolution);
    5.         float[,] height = myTerrain.terrainData.GetHeights(terX - 4,terZ - 4,9,9);  //new float[1,1];
    6.  
    7.         for(int tempY = 0; tempY < 9; tempY++)
    8.             for(int tempX = 0; tempX < 9; tempX++)
    9.             {
    10.                 float dist_to_target = Mathf.Abs((float)tempY - 4f) + Mathf.Abs ((float)tempX - 4f);
    11.                 float maxDist = 8f;
    12.                 float proportion = dist_to_target / maxDist;
    13.  
    14.                 height[tempX,tempY] += 0.01f * (1f - proportion);
    15.                 heights[terX - 4 + tempX,terZ - 4 + tempY] += 0.01f * (1f - proportion);
    16.             }
    17.  
    18.         myTerrain.terrainData.SetHeights(terX - 4, terZ - 4, height);
    19.     }
    If you use it near the edges of the terrain, it throws an error, since I didn't add any checks to make sure you don't try to modify points off of the terrain. On the interior of the terrain you can play with variations on this and see how it alters the effect of the raiseTerrain function, though; I'd experiment with different alterations until you figure out one that provides the effect you want.
     
    Last edited: May 26, 2014
    twobob likes this.
  15. davidsirmons

    davidsirmons

    Joined:
    Mar 16, 2014
    Posts:
    190
    There it is! Direct and helpful. In like fashion, if I hear someone struggling for some resolution to 3d modeling/texturing/animation problems, I use my 20+ years of experience to offer meaningful guidance. And thank you for this!
     
  16. NeverConvex

    NeverConvex

    Joined:
    Jun 26, 2013
    Posts:
    88
    I wouldn't assume my code is all that helpful until you've tested it. :p I threw it together very quickly and only experimented with it a little bit myself. It should serve as a starting point for what I proposed above, though, and for investigating similar variations, hopefully.

    EDIT: Oh, I think I noticed a pretty important problem with the code I copy/pasted; the line

    Code (csharp):
    1. height[tempX,tempY] += 0.001f * proportion;
    should be

    Code (csharp):
    1. height[tempX,tempY] += 0.001f * (1f - proportion);
    The former version will apply no change at the targeted point, and maximum change in a ring around it; the latter will do the opposite---maximum change at the targeted point, no change after you leave a certain distance from the target, which is more along the lines of what I think you'd want.

    EDIT2: Oooh, and this line shouldn't be commented out:

    Code (csharp):
    1. heights[terX - 4 + tempX,terZ - 4 + tempY] += 0.001f * (1f - proportion);
    EDIT3: It may just be the camera angle I'm sitting at, but it looks best to me with 0.001f changed to 0.01f. For some reason, the maximum size of the hills created seems to vary with the value set for that constant, so 0.01f results in hills, while 0.0001f makes barely noticeable rolls, and 0.1f makes crazy mountain crags. Not sure why the maximum height depends on that constant, though; would've thought you could just hold down the mouse longer and get a higher mountain, hmm.

    EDIT4: Ahhh, there was another mistake; was grabbing the wrong part of the heightmap. Works as I imagined it would, now.
     
    Last edited: May 26, 2014
  17. goat

    goat

    Joined:
    Aug 24, 2009
    Posts:
    5,182
    You'd say it too my face huh? And that explains you must resort to forums to ask for help.

    That isn't high end programming anymore than my learning Blender is high end art. In fact it's much easier which explains how you think your 'programming' is something better than my 'art' when it's not even relevant to the topic at hand. See?

    And you are in the gossip section of the Unity forums asking for programming help.

    Enough said.

    Ignore list for you.
     
    Last edited: May 26, 2014
  18. NeverConvex

    NeverConvex

    Joined:
    Jun 26, 2013
    Posts:
    88
    Found a number of errors in the original code I posted (edited the original post and my last reply to reflect this); seems to work how I anticipated it would, now. Here's a side-by-side comparison of the two (see attached --- new function is on the left, old one is on the right). It would be relatively easy to modify this so that it works on the boundaries, so that it generates a plateau or a ring rather than a hill, to make wider/softer hills, etc.
     

    Attached Files:

    Last edited: May 26, 2014
  19. Propagant

    Propagant

    Joined:
    Nov 18, 2013
    Posts:
    32
    Where can I change size of ring that can raise a terrain?