I'm trying to make an object on the ground follow a flying object, for example a drone leading a human (for now i'm just using shapes - a cube and a capsule). My cube follows the capsule like i desire but i want the cube to follow the capsule on the ground only, rather than go up on the y-axis with the capsule. Right now, it follows the capsule everywhere, I want the capsule to lead while the cube follows along on the ground.
I have done some research on Google and Youtube but I have not seen any results. Please let me know how I can achieve this.
This is the code script attached to the cube(ground object)
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class follow_target : MonoBehaviour
{
public Transform mTarget;
float mSpeed = 10.0f;
const float EPSILON = 0.1f;
Vector3 mLookDirection;
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
mLookDirection = (mTarget.position - transform.position).normalized;
if((transform.position - mTarget.position).magnitude > EPSILON)
transform.Translate(mLookDirection * Time.deltaTime * mSpeed);
}
}
If the ground is planar, you can just set the y component to 0 (or whatever the ground y vector is).
If the ground changes in topology, you can do a raycast down from the capsule to get the hit point (vector3). You can use the hit point y component for the height. After that you will need to set the cubes rotation so that it is aligned to the ground. You could do that with a raycast as well, there are a number of examples of that online.
I hope that helps get you in the right direction.
Assuming a flat terrain at Y = 0
or make sure your objects stick to the ground so set them
private const float EPSILONSQR = EPSILON * EPSILON; void Update() { var difference = mTarget.position - transform.position; mLookDirection = difference.normalized; if(difference.sqrmagnitude > EPSILONSQR) { // In general be aware that Translate by default moves in the // objects own local space coordinates so you probably would rather // want to use Space.World transform.Translate(mLookDirection * Time.deltaTime * mSpeed, Space.World); var pos = transform.position; // reset the Y back to the ground pos.y = 0; transform.position = pos; } }or just map the direction down in the XZ plane (ignoring any differences in Y) as
private const float EPSILONSQR = EPSILON * EPSILON; void Update() { var difference = mTarget.position - transform.position; mLookDirection = difference.normalized; // simply ignore the difference in Y // up to you if you want to normalize the vector before or after doing that mLookDirection.y = 0; if(difference.sqrmagnitude > EPSILONSQR) { transform.Translate(mLookDirection * Time.deltaTime * mSpeed, Space.World); } }