- Home /
Height Sampling...
Ok, so I have a script that creates a circle around the object its attached to, samples the height points, then determines if the ground is flat enough to place the object permanently. The script works perfect on the the flat ground (say 0 feet) by changing green. Then when the object hits too steep of a grade it turns red.
The problem is that: if i have a raised area that is completely flat (a plateau) the object will become red signifying that the grade is too steep...but its flat.
Heres my script:
function Update() { isLevel(); }
///////////////////////////////////////////////////////////////////////////////////////////
function isLevel () {
var sampleHeights = new Array();
//Array used to store the heights of the sampled points on the circle. var theta : float = 0; //Increments the radius of the sweep. var maximumHeight : float; var minimumHeight : float;
objectCenter = self.renderer.bounds.center; objectRadius = self.renderer.bounds.extents.x;
//Adds the center height to the array
sampleHeights.Add(myTerrain.SampleHeight(objectCenter));
//Samples points in a cricle around the object
while(theta < 6.28) //6.28 default number
{
theta += Mathf.PI/6; //Amount of points you wish to sample
var pos : Vector3 = objectCenter + Vector3(objectRadius*Mathf.Cos(theta),objectRadius*Mathf.Sin(theta)); //Calculates the points being sampled
sampleHeights.Add(myTerrain.SampleHeight(pos));
}
//Used to find the minimum and maximum heights.
maximumHeight = sampleHeights[0];
for(var i = 0; i < sampleHeights.length; i++)
{
//Goes through all the sample points and finds the min and max values.
minimumHeight = Mathf.Min(minimumHeight,sampleHeights[i]);
maximumHeight = Mathf.Max(maximumHeight,sampleHeights[i]);
}
//returns maximum height minus the minimum height and compares it to the grade tollerance
if(maximumHeight - minimumHeight > gradeTollerance)
greenOrRed = false;
else
greenOrRed = true;
footprint();
}
Answer by Jesse Anders · Jan 27, 2011 at 07:02 AM
I'm going to guess the problem is that you haven't initialized minimumHeight. You need to add this line:
minimumHeight = sampleHeights[0];
Also, instead of 6.28, you can just use Math.PI * 2.
hmmmm, first. Totally didnt see that i was not adding a $$anonymous$$ height and $$anonymous$$athf.Pi is definitely a much better route, so thank you for that :). I made those tweaks then decided to see what was actually getting stored in the array. It seems that the array is storing all the same points...
EX: 11.65765 11.65765 11.65765 11.65765 11.65765 11.65765
thats samepleHeights [0 through 5]. So i don't know if 1 point is being added multiple times, or if the sampling circle isnt large enough. Those are my only two thoughts :/
Thanks again for the help btw :)
Didn't you say the area you were sampling was flat? If so, the values should in fact all be the same (within numerical limits at least).
I was saying that it works when the terrain is flat at a height of 0, but if the terrain is flat at a height of say 10 (such as a pla$$anonymous$$u) where there is no grade around, it doesnt work...I want the script just to detect when the immediate area around the object is flat so i can place it. It shouldnt matter whether its a flat spot 10 units in the air or 0.
Thanks again Jesse :)
Hmm...also, i just noticed that when it gets to the top of the pla$$anonymous$$u and im moving it around it stops sampling. So it is only sampling at a height of 0 or on a continually rising slope...
Answer by Aaron 5 · Jan 27, 2011 at 08:58 PM
Ok, so i just realized that the points i am finding are just y values. As we all know, y=mx+b, I am trying to find the slope (m) which is m = (Y2 -Y1) (X2 -X1). Terrain.SampleHeight is just giving me the y values so its not calculating slope at all, just a maximum height. This is why i cant place on a plateau.
My new question is: How do i get both the x and y coordinates of the sampling points. Terrain.GetPosition does not seem to like Vector3...
The best overload for the method 'UnityEngine.Terrain.GetPosition()' is not compatible with the argument list '(UnityEngine.Vector3)'.
I would also like to avoid making 6 offset raycasts to detect points...
heres the updated code...
function isLevel () {
var sampleHeights = new Array(); //Array used to store the heights of the sampled points on the circle.
var theta : float = 0; //Increments the radius of the sweep.
var maximumHeight : float;
var minimumHeight : float;
objectCenter = self.renderer.bounds.center;
objectRadius = self.renderer.bounds.extents.x;
//Adds the center height to the array
sampleHeights.Add(myTerrain.SampleHeight(objectCenter));
//Samples points in a cricle around the object
while(theta < Mathf.PI * 2) //6.28 default number
{
theta += Mathf.PI/6; //Amount of points you wish to sample
var pos : Vector3 = objectCenter + Vector3(objectRadius*Mathf.Cos(theta),objectRadius*Mathf.Sin(theta)); //Calculates the points being sampled
sampleHeights.Add(myTerrain.SampleHeight(pos));
}
//Used to find the minimum and maximum heights.
maximumHeight = sampleHeights[0];
minimumHeight = sampleHeights[0];
for(var i = 0; i < sampleHeights.length; i++)
{
//Goes through all the sample points and finds the min and max values.
minimumHeight = Mathf.Min(minimumHeight,sampleHeights[i]);
maximumHeight = Mathf.Max(maximumHeight,sampleHeights[i]);
}
print (sampleHeights[0] + " " + sampleHeights[1]+ " " + sampleHeights[2]);
//returns maximum height minus the minimum height and compares it to the grade tollerance
if(maximumHeight - minimumHeight > gradeTollerance)
{
greenOrRed = false;
}
else
{
greenOrRed = true;
}
footprint();
}