# Moving Object Along Height of Collider Below

I’m trying to move a game object using WASD and have it maintain the height above the collider below it.

I have the movement working fine, and I’m doing a raycast to get the height off the object below the terrain, but I’m having a hard time figuring out how to use that information to hug the terrain (not a "T"errain, just the ground). I’ve read a bunch of tutorials but haven’t found a single complete solution and I can’t seem to put the pieces together in the right order.

The object just flies up higher and higher. It doesn’t hug the ground. I’m not using the height above ground yet. I figured I’d get this to work and then get it to hover.

I’m sure I’m missing something stupid. Any help is appreciated. This is to create a follow object for an RTS camera.

``````    void Update() {
Move();
}

private void Move() {
float x = Input.GetAxisRaw("Horizontal");
float z = Input.GetAxisRaw("Vertical");
float y = 0f;

if (x != 0 || z != 0) {
y = CalculateYPos();
Vector3 moveDir = new Vector3(x, y, z).normalized;
transform.position += moveDir * moveSpeed * Time.deltaTime;
}
}

private float CalculateYPos() {
float yPos = 0f;

RaycastHit hit;

if (Physics.Raycast(transform.position, transform.TransformDirection(Vector3.down), out hit, Mathf.Infinity)) {

float hitY = hit.point.y;
Debug.Log(\$"hitY={hitY}");

float distanceAboveY = hit.distance;
Debug.Log(\$"distanceAboveY={distanceAboveY}");

yPos = hitY + 1f;
Debug.Log(\$"yPos={yPos}");
}

return yPos;
}
``````

Hi,

Are you sure the ray is hitting the terrain, or collider below as you think, and not some part in the same GameObject?

Also, in line 13. What prevents moveDir from just keep adding hit.point.y + 1 to the transform.position?

Well, that would explain why moving just moves me up constantly, but I as I explained, I don’t know how to put the bits I have together into a working solution.

Edit: I realize you were referring to the .normalized thing. I did catch that but even if I don’t use .normalized, it acts the same.

I think what I should be doing is setting the y position after the movement but I can’t figure out how to do that.

You could separate setting the y position and adding the movement:

``````if (x != 0 || z != 0) {
y = CalculateYPos();
Vector3 moveDir = new Vector3(x, 0, z).normalized; // No y component
transform.position += moveDir * moveSpeed * Time.deltaTime; // Moving in the x-z plane only

adjustedPosition.y = y; // Override the y position
transform.position = adjustedPosition; // Update with y set correctly
// You could do this in fewer lines, but this makes it very clear what's happening
// Also note that using transform.position.y = y; would not work because transform.position is a Vector property, not a variable
}
``````

Ok, I have a working solution but I’m not sure it’s a “good” solution. I gave myself a hint in my edit above.

``````    private void Move() {
float x = Input.GetAxisRaw("Horizontal");
float z = Input.GetAxisRaw("Vertical");
float y = 0f;

if (x != 0 || z != 0) {
Vector3 moveDir = new Vector3(x, y, z).normalized;
transform.position += moveDir * moveSpeed * Time.deltaTime;
}

y = CalculateYPos();
transform.position = new Vector3(transform.position.x, y, transform.position.z);
}
``````

LOL! I’m happy to see I came to a reasonable conclusion. Thanks!

1 Like
``````    if (x != 0 || z != 0) {
Vector3 moveDir = new Vector3(x, 0, z).normalized; // No y component