- Home /
Why does my tree script not work
Hi , so I know another {one} about trees not using scripts because there not actual gameObjects....
So I ended up making a working cut the tree down script... but when I went to mass place the tree prefabs ... The script ended up nulling out that goes with the tag reverting back to default instead of " Tree ". So I looked threw the documentation and found terrainData and treeinstantce ... so I wrote a for loop and have a loading screen wait untill all the "Fake tree objects are created " meaning just the collider with a tree damage script " Java script "
The problem i'm having now is that .... ok it creates the number of trees for treeInstances so if I have 10 trees 10 fake tree objects with collider , if I have 20 ,... 20 fake tree objects suberb .... Ok there being made its loading , loading done.... HUH! the trees are all at 1 position on the corner of the terrain so I know I wrote the terrain positions array wrong and im not sure so much on how the positions are stored.... for the terrain data ...
Here is a snap shot of whats happening :
Here is my script: //Made by -=BloodyDuskTeam=- // //http://bloodyduskteam.ucoz.com/
//This script finds all the terrain's trees then creates the tree object for user interaction for each tree position
var treeFab : Transform;
var grabTerrain : Terrain;
var trees : TreeInstance[];
function Start () {
for (i=0; i <Terrain.activeTerrain.terrainData.treeInstances.Length; i++)
{
//var treeInstances : TreeInstance = new Terrain.activeTerrain.terrainData.TreeInstance();
Instantiate(treeFab, trees[i].position, Quaternion.identity);
}
}
I am trying, similarly to yourself, to make a survival game. However, I need to know further about the script treebehav.
Please show the function realTree to me, so that I may understand it.
Answer by RKSandswept · Jun 24, 2013 at 01:25 AM
Terrain positions are in the range of 0.0 to 1.0 across the terrain block.
So a line of 100 trees across your terrain block could be coded...
for(int i=0; i < 100; i++)
{
TreeInstance ti = new TreeInstance();
ti.prototypeIndex = 0;
ti.heightScale = 1.0f;
ti.widthScale = 1.0f;
ti.color = Color.white;
Vector3 v = new Vector3(i / 100.0f, 0.0f, i / 100.0f);
ti.position = v;
t.AddTreeInstance(ti);
}
Answer by bloodyduskteam · Mar 18, 2013 at 04:27 AM
Ok thanks to robertu is because is was storing the trees at a local position not, world coordinates .... So I wrote a algorithm if anyone is interested. here is the compiled script.
for (i=0; i <Terrain.activeTerrain.terrainData.treeInstances.Length; i++)
{
var terrain : TerrainData = Terrain.activeTerrain.terrainData;
var pos = Vector3.Scale(Terrain.activeTerrain.terrainData.treeInstances[i].position,terrain.size)+ Terrain.activeTerrain.transform.position;
Instantiate(treeFab, pos, Quaternion.identity);
}
Answer by robertbu · Mar 17, 2013 at 05:58 PM
I've not done much with Terrains, but based on a read in the script reference, you should be able to do something like:
for (int i=0; i < Terrain.activeTerrain.terrainData.treeInstances.Length; i++) {
var pos = Terrain.activeTerrain.terrainData.treeInstances[i].position;
Instantiate(treeFab, pos, Quaternion.identity);
}
This gets the positions directly from the treeInstances array. I'm assuming the positions are in world coordinates (since the reference did not say differently), but it is possible they are relative to the terrain.
Thanks robert , I thought this 1 was going to work as well yet i'm sill having problems with it storing the bunched up trees in the corner .. Though this one is scattering them about by 0.1 on vector3 away from each other . So still not sure here.....
If anyone could help me now i'm wondering if it has to do with my terrain map....
so whats its doing is grabbing the terrain object where it's Transform is at 0,0,0 then placing the trees at this position scattering them by .1,.1,.1 roughly away from each other so like you said sounds like a local coordnate but i'm not sure how to grab this information.
I looked around and found this calculation for world position:
Vector3 currentTreeWorldPosition = Vector3.Scale(currentTree.position, terrain.size) + Terrain.activeTerrain.transform.position;
I found it as part of the code here:
http://forum.unity3d.com/threads/110354-Finally-Removing-trees-AND-the-colliders
Thanks again Robert I did find this too actually 3 hrs ago and posted it I thought but it must of had an error so sorry about making you take the trouble . I'm new to these "anwser's" As I usually hunker down with the manual but this is one of unity's more undocumented syntax's.
$$anonymous$$y Question is if anyone or you has the time to figure out how to use removeat(i) with the trees ...
What I have is a script where the player cuts the "invisible" collide rs now and destroy the collide r all works fine. So what I try ed to do is setup a function inside the same script that creates the collide-rs. So my script looks like this for the tree creation is then sends a variable "realTree" the current tree index in the loop once the tree dies I want to call the tree creator scripts function and assign it the appropriate variable realTree to destroy but i'm getting errors.
here is function bieng called from a tree damage script on the "fake " trees .
Function call: grabTerrain.GetComponent(treeBe).killTree(realTree); //Real tree being the index passed from the fallowing SCRIPT:
//Like the example you showed me I tryed storing the trees in //a dynamic list still no feedback though .
var newTrees : List.<TreeInstance> = new List.<TreeInstance>(Terrain.activeTerrain.terrainData.treeInstances);
function Start (){
for (i=0; i <Terrain.activeTerrain.terrainData.treeInstances.Length; i++)
{
var terrain : TerrainData = Terrain.activeTerrain.terrainData;
var pos = Vector3.Scale(Terrain.activeTerrain.terrainData.treeInstances[i].position,terrain.size)+ Terrain.activeTerrain.transform.position;
var dist = Vector3.Distance(GameObject.Find("Player").transform.position, pos);
var fakeTree = Instantiate(treeFab, pos, Quaternion.identity);
fakeTree.GetComponent(treebehav).realTree = i;
print("Loading Trees" + i + "/" + Terrain.activeTerrain.terrainData.treeInstances.Length);
}
}
function killTree(treeId : int){
newTrees.RemoveAt(treeId);
Terrain.activeTerrain.terrainData.treeInstances = newTrees.ToArray();
}
Sorry I fixed this I was calling the function from a unknown instance... I just switched out grab terrain with GameObject.Find()
Works awesome, my guy is now a woodsman :) thanks again robert :)