1
\$\begingroup\$

I'm making a terrain generator for a game and I need it to smooth down to a float, I've tried a bunch of different things with lerping but I can't figure it out.

i need to stop this from happening by smoothing the height down to 1 once it gets to the edges

I need to stop this from happening by smoothing the height down to 1 once it gets to the edges.

public LevelManager level;

public float noise;
public float oceanNoise;
public float mountainNoise;



public Transform water;
public Transform land;

public void Start()
{
    level = FindObjectOfType<LevelManager>();
    


}
public void Update()
{
    float landNoise = noise + oceanNoise;
    noise = SimplexNoise.Noise(transform.position.x * level.deatalscale, transform.position.z * level.deatalscale);
    oceanNoise = SimplexNoise.Noise(transform.position.x * level.oceanDetailScale, transform.position.z * level.oceanDetailScale);
    mountainNoise= SimplexNoise.Noise(transform.position.x * level.mountainDetailScale, transform.position.z * level.mountainDetailScale);
    

    if (noise > level.thresh)
    {
        land.gameObject.SetActive(true);
        water.gameObject.SetActive(false);

    }
    else
    {
        land.gameObject.SetActive(false);
        water.gameObject.SetActive(true);

    }

    if (oceanNoise < level.oceanHhresh)
    {
        land.gameObject.SetActive(false);
        water.gameObject.SetActive(true);

    }

    if (oceanNoise < level.oceanHhresh)
    {
        land.gameObject.SetActive(false);
        water.gameObject.SetActive(true);

    }
    land.transform.localScale = new Vector3(level.planeScale, Mathf.Lerp(noise*level.height,1,noise) * level.height + level.addHeight, level.planeScale);





    if (level.landpos.Contains(transform.position))
    {
        Destroy(gameObject);
    }
}

This script goes on the terrain chunk and it uses its position to find value in noise, the level manager just holds a few settings.

Any help is appreciated, thanks in advance.

\$\endgroup\$
2
\$\begingroup\$

I don't recommend using code like this for terrain generation, for several reasons:

  1. You don't want to be re-processing your terrain in every Update. If your terrain parameters can change on the fly, call a Regenerate() function to do this work only when such a change occurs.

  2. You don't want a separate object for every cell of your world. I know it looks like Minecraft and similar games are made of millions of separate cube objects, but they are not. They build chunk meshes that represent the visible outer surface of whole regions of the map at a time, so they don't have millions of mesh instances to render, or millions of scripts running every frame.

  3. You don't want two noise functions battling over the same outcome. Right now your noise parameter determines the height of the land, but the oceanNoise parameter determines whether the land even exists. So in many cases the land will just stop abruptly, not because noise dropped down below the water level, but because the otherwise-invisible oceanNoise overruled it.

For a single cell, it looks like you want something like this:

void Regenerate() {
    float noise = SimplexNoise.Noise(transform.position.x * level.detailScale,
                                     transform.position.z * level.detailScale);

    bool isLand = noise > level.thresh;

    land.gameObject.SetActive(isLand);
    water.gameObject.SetActive(!isLand);

    if(isLand) {
        var scale = Vector3.one * level.planeScale;

        float surplus = (noise - level.thresh) / (MAX_NOISE_VALUE - level.thresh);
        scale.y = level.scaleToMatchOceanLevel + surplus * level.landScale;
        land.transform.localScale = scale;
    }
}

This way you'll get ocean where the land sinks low enough to hit the water level, and land elsewhere. Because the ocean occurs only where the land is low, you'll naturally get a falloff from land to water, instead of sudden cliffs.

\$\endgroup\$
2
  • \$\begingroup\$ the update function is just for temporary testing. the terrain generator loads each tile in as the player objects move. I need them to be individual objects because I need to edit values on each one. this is more of a sandbox board game, I understand that games like Minecraft use generated meshes, not actual cubes. this answer work. also a brief explanation of why I was adding several layers of noise. I wanted to make it so i could add different terrain features like lakes and mountains. thank you for the awesome help! 1/2 \$\endgroup\$
    – Indiepixel
    Sep 14 '20 at 4:07
  • \$\begingroup\$ (I'm really sorry for the messy code, im dyslexic and it messes with things sometimes) this works wonderfully, i will figure out how to implement other features on my own. thank you once again. \$\endgroup\$
    – Indiepixel
    Sep 14 '20 at 4:08

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.