Hey guys, some developers and I are creating a game for the iPhone and poly count is something that needs to be taken into consideration. Instead of using the Terrain editor to create terrain, we used a third party application and imported it into Unity. We’re wanting to create a random generation of trees throughout this terrain mesh. I created some tree textures that use an alpha map that can be placed on planes. I’m wanting the planes to billboard to the camera and I found the “LookAtCameraYonly” script in the wiki to make this possible. Does anyone know if there’s a way or if there’s a script that will randomly place these billboards throughout the imported terrain mesh?
This is definitely something than can be accomplished with some basic scripting.
Why not take a look at Object.Instantiate, which you can use to create the trees… how to place them is up to you! You’ll probably want to generate random positions within the x and z horizontal bounds of your “terrain” surface, instantiate the trees well above the ground, then drop them down to the surface by subtracting the distance (which you can obtain by casting a ray downwards). That will assure that they are properly placed on a hilly or vertically irregular terrain.
You can read up on instantiating objects in the documentation right here:
And learn a bit more about instantiating prefabs during runtime right here:
And I’m going to move this to the scripting forum, so other developers might chime in. There are certainly other approaches to this-- some easier, some more powerful.
Okay I’m really lost. I’m not a programmer by any means and I’m having trouble getting this whole raycaster thing to work. Can anyone help me with this?
Okay I managed to take one tree, place it above the terrain, cast a ray downward, then basically move down until it hits the terrain and that’s where it stops. Where I’m lost is when it comes to instantiating multiple trees into a random pattern and pulling them down to the terrain. If anyone has done anything similar to this, I would be really happy if you could help me out!
I’m new to all this, but can’t you just simply call Random function in a loop of how many trees you want to create and do the same code as you did with one tree for placement?
You could probably use Random.Range(min : int, max : int) function once for X and once for Y coordinates?
So something like this ( not verified code ) should work:
for (i = 0; i < numberOfTrees, i++)
{
x = Random.Range( minX, maxX);
y = Random.Range( minY, maxY);
// call your own tree creating function with position
CreateTree(x, y);
}
Of course you can get much fancier than this and exclude some regions like water etc., but this is just to illustrate the point.
Also you might want to save each successful position in some array, so you can check that no 2 trees are placed very close to each other etc and adjust position accordingly.
I managed to generate the trees randomly but it generates them at world center. How would I only generate the trees within the bounds of the terrain mesh?
Here is the code I used to generate random coordinates for the trees:
var prefab : GameObject;
var gridX = 5;
var gridY = 5;
var spacing = 2.0;
function Start () {
for (var count = 0; count < 100; count++) {
var x = Random.value * 100;
var y = Random.value * 100;
var pos = Vector3(x, 10, y) * spacing;
Instantiate(prefab, pos, Quaternion.identity);
}
}
I guess I’m just confused as to where I even get the dimensions of my terrain mesh. I can’t pass any min/max values in if I’m not sure where to find them haha. I’m really sorry I’m really new to all this. I’m more of a designer rather than a coder. I really appreciate your help though!
Okay guys I finally figured it out! So if anyone wants to benefit from this, here is the code to align the trees to the terrain and randomly distribute them throughout the terrain:
var prefab : GameObject;
var gridX = 5;
var gridY = 5;
var spacing = 2.0;
function Start () {
for (var count = 0; count < 100; count++) {
var position = Vector3
(Random.Range(-118.8479, 112.2937), 0, Random.Range(10.1025, -10.04498));
var hit : RaycastHit;
if (Physics.Raycast (position, -Vector3.up, hit)) {
distanceToGround = hit.distance;
position.y = position.y - distanceToGround;
}
Instantiate(prefab, position, Quaternion.FromToRotation(Vector3.forward, Vector3.up));
}
}
Now is there a way to use the script outside of runtime so that it creates the trees inside the editor? I want to be able to go back and edit where some trees are showing up…
Also, I tried to make all the instantiated objects billboard but it doesn’t seem to be working. The billboard code works correctly but not when applied with the instantiate code. Here is the billboard code:
// CameraFacingBillboard.cs
using UnityEngine;
using System.Collections;
public class CameraFacingBillboard : MonoBehaviour
{
public Camera m_Camera;
public void Update()
{
transform.LookAt(transform.position + Vector3.up,
m_Camera.transform.rotation * Vector3.right);
}
}
If anyone has experience with this, it would really help me out! Thanks!
I’m no programmer as well(!), but as you haven’t got any solution from the real guys, I think you are stuck with me :lol:
I’ve had a similar problem once.
And it may be my solution is nowhere near the right one, but it works.
As the object you instantiate is a prefab, you need to make the public variable (the camera) which I’m sure you have provided in the inspector, a prefab as well. You can’t use objects which alone exist in the scene, if you are going to instantiate the objects via scripting. I have no clue why it is that way, or whatever else I have misunderstood to think it is that way []
So try that. Make the main camera you use into a prefab, and drag that prefab into the public camera variable of that script, and I’m pretty sure you’ll have it working…
I hope so anyways.
Remember to check your tree prefab in the project view, to make sure it has the camera prefab as camera after you have made the camera into a prefab.
In your script you have a public variable of the class Camera. This one needs to be set either in the inspector (by draging the camera into it) or by code. And since you don’t set it by code, I just assumed you set it by dragging. But if you don’t do either of the two, the script will not work at all. The object (your billboards) needs to know what to look at.
If you haven’t dragged the main camera into the slot in the script, yoyu may want to try just that, before doing anything else I have told you