Search Unity

Align Object to Terrain in Only One Axis

Discussion in 'Scripting' started by Ronald_McScotland, Mar 13, 2017.

  1. Ronald_McScotland

    Ronald_McScotland

    Joined:
    Jul 30, 2014
    Posts:
    173
    Hello, I've been experimenting with a wall system that automatically places wall modules along a line. Each module when placed Raycasts down to the terrain, and aligns itself with the terrain using the following code:

    Code (CSharp):
    1. if (Physics.Raycast (transform.position + (Vector3.up * 100f), Vector3.down, out hit, 200f, 1 << LayerMask.NameToLayer ("Ground"))){
    2.             transform.position = hit.point;
    3.             transform.rotation = Quaternion.LookRotation (hit.normal, transform.parent.forward);
    4. }
    The result is somewhat correct, in that it follows the terrain like so:


    However, the wall also leans out from hillsides:


    I've been unable to come up with a way to keep the wall following the angle of the terrain from laterally, without leaning out on its forward/backward axis. Any ideas?
     
  2. Ronald_McScotland

    Ronald_McScotland

    Joined:
    Jul 30, 2014
    Posts:
    173
    I managed to figure it out. In case anyone else has this problem, here's my solution:

    Code (CSharp):
    1.  
    2. (Physics.Raycast (transform.position + (Vector3.up * 100f), Vector3.down, out hit, 200f, 1 << LayerMask.NameToLayer ("Ground"))){
    3.             transform.position = hit.point;
    4.             Vector3 normal = hit.normal;
    5.             normal = transform.parent.InverseTransformDirection (normal);
    6.             normal.z = 0f;
    7.             normal = transform.parent.TransformDirection (normal);
    8.             transform.rotation = Quaternion.LookRotation (normal, transform.parent.forward);
    9. }
    10.  
    I use inverse transform direction to get the hit normal relative to the wall parent object. Then I eliminate the z component of that vector (since that's the axis I don't want any rotation on). Then convert the normal back to world space with transform direction, and align the wall segment to it using Quaternion.LookRotation.

    In my case I'm aligning with the parent transform's forward rather than up axis, because the wall segments were exported from blender and so have the z-axis representing up and down rather than forward and back, so in others cases it might be necessary to fiddle with which axes to align to.
     
    ScoutingNinja3D likes this.