x


Align GameObject to Terrain angle

I'm trying to enhance a simple clamp to terrain script I wrote to also rotate the object based on the angle of the terrain under it. There is probably easier ways to do what I am trying to do, but I'd also like to know why my code is simply not working.

function AlignToTerrainAngle(pos : Vector3, unitSize : float = 1.0) {
var frontSide : Vector3 = Vector3(pos.x + unitSize, 0, pos.z);
frontSide.y = terrain.SampleHeight(frontSide);

var backSide : Vector3 = Vector3(pos.x - unitSize, 0, pos.z);
backSide.y = terrain.SampleHeight(backSide);

var leftSide : Vector3 = Vector3(pos.x, 0, pos.z + unitSize);
leftSide.y = terrain.SampleHeight(leftSide);

var rightSide : Vector3 = Vector3(pos.x, 0, pos.z - unitSize);
rightSide.y = terrain.SampleHeight(rightSide);

// get pitch angle
var pitchAngle : float = Vector3.Angle(frontSide, backSide);

// get yaw angle
var yawAngle : float = Vector3.Angle(leftSide, rightSide);

Debug.Log("Pitch angle: " + pitchAngle + " Yaw angle: " + yawAngle);

var newRotation : Quaternion = Quaternion.identity;
newRotation += Quaternion.AngleAxis(pitchAngle, Vector3.right);
newRotation += Quaternion.AngleAxis(yawAngle, Vector3.forward);

// Rotate the model!
transform.rotation = Quaternion.Slerp(transform.rotation, newRotation, Time.deltaTime * 2.0);

}

I feel like I'm pretty close, but the angles are way too small (< 0.3), and assigning the new rotation Quaternion to the transform object seems to do nothing. Even hard coding larger angles resulted in no change.

more ▼

asked Aug 17 '10 at 07:31 PM

Ryan IRL gravatar image

Ryan IRL
3 2 2 5

(comments are locked)
10|3000 characters needed characters left

2 answers: sort voted first

The Slerp interpolation will only work if this function is called repeatedly (i.e., in Update()), since this variant of using a Lerp function (by giving it Time.deltaTime as interpolation parameter) is more like a "smooth follow", no longer a linear inerpolation. You might also want to increase the 2.0 scaling, to influence the speed at which the new rotaion angle is adapted.

Note that there is a method called Terrain.terrainData.GetInterpolatedNormal(x,y) which gives you the normal at a given position. However, since it is a method of the heightmap data, the values x and y are normalized between 0 and 1, so you would have to compute them by yourself, using your pos.x and pos.z and the actual terrain dimensions+location.

more ▼

answered Aug 17 '10 at 09:35 PM

Wolfram gravatar image

Wolfram
9k 8 20 52

(comments are locked)
10|3000 characters needed characters left

I know this is old, but it may help others as it helped me:

//make platform adjust terrain rotation
var rcHit : RaycastHit;

//Make raycast direction down
var theRay : Vector3 = transform.TransformDirection(Vector3.down);

if (Physics.Raycast(transform.position, theRay, rcHit))
{
    //this is for getting distance from object to the ground
    var GroundDis = rcHit.distance;

    //with this you rotate object to adjust with terrain
    transform.rotation = Quaternion.FromToRotation(Vector3.up, rcHit.normal);

    //finally, this is for putting object IN the ground
    transform.localPosition.y = (transform.localPosition.y - GroundDis)+1;
}
more ▼

answered Jun 22 '11 at 03:21 PM

BLF-Games gravatar image

BLF-Games
123 1 3 12

(comments are locked)
10|3000 characters needed characters left
Your answer
toggle preview:

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

Follow this question

By Email:

Once you sign in you will be able to subscribe for any updates here

By RSS:

Answers

Answers and Comments

Topics:

x2156
x1467
x438
x286
x79

asked: Aug 17 '10 at 07:31 PM

Seen: 3551 times

Last Updated: Jun 22 '11 at 03:21 PM