0

What I'm trying to do
I'm trying to spawn a tree only on flat ground but GetSteepness() isn't working and GetInterpolatedNormal() also doesn't seem to be working

The Problem
the trees always seem to spawn on places I don't want them to like on really steep hills they do also spawn on flat ground but i would rather them not spawn on hills at all

I would also like to eventually
use this method whenever it gets solved to place grass only on flat grounds but I don't know how to spawn grass and I don't think instantiate will be good for performance I would be using billboard grass for performance reasons

What I've tried
GetInterpolatedNormal system doesn't work FYI I've tried playing around with Value.x/y/z and switching the Steepness.x/y/z > Value.x/y/z to Steepness.x/y/z < Value.x/y/z

void PopulateTrees(TerrainData terrainData) {
var ray = new Ray(new Vector3(Random.Range(-100, 100), 1000 f, Random.Range(-100, 100)), -this.transform.up);
RaycastHit hit;
if (Physics.Raycast(ray, out hit)) {
    Vector3 terrainSize = Terrain.activeTerrain.terrainData.size;
    Steepness = Terrain.activeTerrain.terrainData.GetInterpolatedNormal(hit.point.x / terrainSize.x, hit.point.y / terrainSize.z);
    if (Steepness.x < Value.x && Steepness.y < Value.y && Steepness.z < Value.z) {
        Instantiate(PineTree, new Vector3(hit.point.x, hit.point.y - .1 f, hit.point.z), transform.rotation = new Quaternion(0, Random.Range(-1000, 1000), 0, 100));
    }
}

}

GetSteepness() method I don't know what system will be more performant this way seemed to only put trees in weird areas

void PopulateTrees(TerrainData terrainData) {
    var ray = new Ray(new Vector3(Random.Range(-100, 100), 1000 f, Random.Range(-100, 100)), -this.transform.up);
    RaycastHit hit;
    if (Physics.Raycast(ray, out hit)) {
        Steepness = terrainData.GetSteepness(hit.point.x, hit.point.z);
        if (Steepness > Value) {
            Instantiate(PineTree, new Vector3(hit.point.x, hit.point.y - .1f, hit.point.z), transform.rotation = new Quaternion(0, Random.Range(-1000, 1000), 0, 100));
        }
    }
}

This is a photo of the problem

  • Why `hit.point.y / terrainSize.z`? – shingo Dec 17 '21 at 06:34
  • 2
    `GetInterpolatedNormal` returns a normal. A normal on a flat ground points to the sky. – shingo Dec 17 '21 at 06:35
  • please show how do you tried with `GetSteepness`. Take into account that it gets the gradient of the terrain at point (x,y) where the x and y values are normalized coordinates in the range 0..1. and where probably world's z is your terrain's y. – rustyBucketBay Dec 17 '21 at 07:49
  • I would give a look to [this](https://answers.unity.com/questions/452204/terraindatagetsteepness-usage.html) and try it that way – rustyBucketBay Dec 17 '21 at 07:50

1 Answers1

0

Try this:

void PopulateTrees(TerrainData terrainData) {
    var ray = new Ray(new Vector3(Random.Range(-100, 100), 1000 f, Random.Range(-100, 100)), -this.transform.up);
    RaycastHit hit;
    if (Physics.Raycast(ray, out hit)) {
        Steepness = terrainData.GetSteepness(hit.point.x / terrainData.size.x, hit.point.z / terrainData.size.z);
        if (Steepness > Value) {
            Instantiate(PineTree, new Vector3(hit.point.x, hit.point.y - .1f, hit.point.z), transform.rotation = new Quaternion(0, Random.Range(-1000, 1000), 0, 100));
        }
    }
}

GetSteepness() should return a value in the range of 0...90

Zserbinator
  • 365
  • 2
  • 10