• Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
This post has been wikified, any user with enough reputation can edit it.
avatar image
0
Question by nug700 · Nov 21, 2013 at 11:14 PM · c#terrainterrain-trees

Trees not being placed correctly by script on unity terrain.

I'm making a script to make a randomly generated terrain using the unity terrain engine. So far I've been able to set the heights and paint textures on the terrain. Now I want to place trees on it. For testing, I'm having the trees be place in a long diagonal line under the terrain.

 // This code is run for every point on the terrain heightmap x,y position
 float percent = UnityEngine.Random.value;
 if (percent >= 0.5f)
 {
     placedTrees++;
     //Vector3 treePos = new Vector3(x * (4000 / 256) + t.transform.position.x, 0.0f, y * (4000 / 256) + t.transform.position.z);
     Vector3 treePos = new Vector3(0 + placedTrees, 0, 0 + placedTrees);
     TreeInstance tree = new TreeInstance();
     tree.color          = baseTree.color;
     tree.heightScale    = baseTree.heightScale;
     tree.lightmapColor  = baseTree.lightmapColor;
     tree.position       = treePos;
     tree.prototypeIndex = baseTree.prototypeIndex;
     tree.widthScale     = baseTree.widthScale;
     treeList.Add(tree);
 }

 //run after the loop
 Debug.Log("trees placed: " + placedTrees);
 Debug.Log("tree array size: " + treeList.Count);
 t.terrainData.treeInstances = treeList.ToArray();

The two debug logs print the same result (usually around 2500), but yet only one tree appear in the scene. The full function can be found here.

Thanks in advance for any help.

Comment
Add comment · Show 1
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image panbake · Nov 23, 2013 at 01:02 AM 0
Share

What is the class TreeInstance? Normally you would need to instantiate a game object from a prefab with Instantiate ins$$anonymous$$d of using new. Something like

     GameObject treeGO = Instantiate(prefab, new Vector3(x,y,z), Quaternion.Identity) as GameObject;
     TreeInstance tree = treeGO.GetComponent<TreeInstance>();
 

This is if the class TreeInstance is a component that can be added to a game object. Alternatively you can generate a new game object and add the TreeInstance component.

2 Replies

· Add your reply
  • Sort: 
avatar image
5

Answer by kvoepel3 · Mar 12, 2015 at 03:42 AM

I realize this question is old, but it comes up in every single google search about Unity trees, so I'm going to answer it in hopes that someone who is a similarly frustrated Unity noob like myself (tackling run-time procedural terrain, which is probably not a great place to start) stumbles across it and gets what they need.

The problem with the trees is right here:

    Vector3 treePos = new Vector3(0 + placedTrees, 0, 0 + placedTrees);

There are two reasons why trees would show up where you don't want them, when you initialize the position in this way.

1) The Vector3 object that the TreeInstance expects contains a local terrain position, so all three elements of the vector should be floats between 1 and 0. Anything larger than 1 seems to be treated as 1, so since you're using an integer counter, all of your trees will effectively be given the position of <1, 0, 1> (which is smashed into one corner of the terrain, probably either high above or far beneath it, depending on your scale). The way to fix this is to divide each of these elements by the dimension of your terrain.

 Vector3 treePos = new Vector3(0.0f + placedTrees / t.terrainData.heightmapWidth, 0.0f, 0.0f + placedTrees / t.terrainData.heightmapHeight);

If you needed to divide the middle parameter, you'd need to do it by the value of the "Terrain Height" property in the editor. I'm currently too noobish to figure out how to get at that in a script. Since mine was 1000, I just hardcoded a 1000.0f in there, and viola, this code drew a line of trees across my Perlin terrain that looked like they belonged there.

My final code looked thusly:

 new Vector3(i/terData.heightmapWidth, terData.GetHeight((int)i, (int)i) / 1000f, i/terData.heightmapHeight);

2) For a 3D noob like me, thinking about 3 dimensional vectors can get confusing. It's very easy to understand that a Vector3 is x, y, z, but when thinking about height maps I'm only ever working with x and y. On a heightmap, x and y represent dimensions on the plane, but in the Vector3 used by TreeInstance/TerrainData, y represents the elevation, where x and z are on the plane. The OP probably didn't have this problem, but someone reading it might.

Happy run-time procedurally placed trees y'all.

Comment
Add comment · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image
0

Answer by oleg_v · Oct 05, 2020 at 12:15 AM

Small addition: vertical scale is in terrainData.heightmapScale.y

ps. Still can't get good info about terrain API via google :)

Comment
Add comment · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Welcome to Unity Answers

The best place to ask and answer questions about development with Unity.

To help users navigate the site we have posted a site navigation guide.

If you are a new user to Unity Answers, check out our FAQ for more information.

Make sure to check out our Knowledge Base for commonly asked Unity questions.

If you are a moderator, see our Moderator Guidelines page.

We are making improvements to UA, see the list of changes.



Follow this Question

Answers Answers and Comments

20 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

Distribute terrain in zones 3 Answers

How would you go about shaping terrain with scripting? (C#) 1 Answer

Flat Low Poly Terrain / Script a terrain 2 Answers

How to make a voxel terrain generate all around the start point 1 Answer

Instantiating a object in a certain position.. 1 Answer

  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges