How do I set the heights of a terrain using a smaller sized terrain?

I’m trying to scan a terrain that is 32x32 in size and use it as a template to modify the height data of a much larger terrain that is 500x500 .

The problem I’m having is that I can’t seem to figure out how to keep the height values identical.

The heightmap resolution of the larger heightmap is 513. For some reason the the heights in the smaller terrain produce much larger values when mapped directly to the larger terrain.

Can anyone provide any insight into why this is happening. All I want to do is map the heights directly without any scaling. What terrain settings are required for this?

for (int y = 0; y < terrainTile32.alphamapWidth; y++)
for (int x = 0; x < terrainTile32.alphamapHeight; x++)
newHeightData[x + xBase, y + xBase] = terrainTile32.GetHeight(x, y)

Did you check the height scaling property on the terrain object itself? Whatever value is in there will effectively act as a vertical scaling factor.

Thanks, for your help. I’m not seeing the vertical scaling factor. Is this the Terrain Height Property

Terrain Tile Settings
3069192--230771--Capture2.PNG

Main Terrain Settings
3069192--230770--Capture1.PNG

This is how much it’s modifying the underlying terrain when mapping the heights directly using SetHeights();
3069192--230772--Capture4.PNG

The scaling value I refer to is labelled “Terrain Height” in the editor, but is contained in TerrainData.heightmapScale

However, I see what is going on: the .GetHeight(x,y) function returns the local world-scale height of the terrain.

In contrast, the values in .GetHeights() / .SetHeights() are scaled from 0 to 1, and for display they are multiplied by Terrain Height by the terrain engine.

See: Unity - Scripting API: TerrainData.GetHeights

I think you want to divide the .GetHeight() value by the Terrain Height value and use that in your new data array.

This was the code I experimented with: drop it on an empty game object with a terrain somewhere in the scene too.

using UnityEngine;
using System.Collections;

public class ReportHeight : MonoBehaviour
{
    [Header( "Change these:")]
    public int x = 0;
    public int y = 0;

    void OnGUI()
    {
        Terrain t = FindObjectOfType<Terrain> ();

        TerrainData td = t.terrainData;

        Rect r = new Rect (0, 0, 200, 50);
        GUI.Label( r, "Height=" + td.heightmapScale);

        float z = td.GetHeight (x, y);
        r = new Rect (0, 50, 200, 50);
        GUI.Label( r, System.String.Format ("{0} x {1} == {2}",
                                         x, y, z));

        float[,] hts = td.GetHeights (0, 0, 513, 513);

        // CAREFUL: for fun, uncomment this to "poke" one terrain cell high
// THIS WILL MODIFY YOUR TERRAIN! USE CAUTION!!
//        hts [120, 120] = 1;
//        td.SetHeights (0, 0, hts);
    }
}

I’m not sure how to divide GetHeight (which is a float) by a Vector3, which is what heightmapScale returns. I tried using heightmapScale.y but that doesn’t work.

I noticed that dividing GetHeight by alphamapHeight works perfectly. That solves my problem ,but I’m not sure if it’s the right thing to do.

At this rate I can use mini terrains like tiles and blit them to my main terrain. .

Thanks again for you help.

Adding a display of .alphamapHeight, I see it is a direct reflection of “Control Texture Resolution,” which I don’t think has anything to do with the relationship you are trying to model. Keep in mind it might get legitimately changed in the future.

I recommend that you instead pick a handy constant (say 512?) and use that so that you know it won’t change… and if your code works, your code works… thunder ahead!!