1
\$\begingroup\$

I want an object to follow another object just like the way it follows it when it's parented to it, but smoothly and only in the x and z axis.

Here's my code so far:

distanceX = player.position.x - transform.position.x;
distanceZ = player.position.z - transform.position.z;
transform.position = Vector3.Lerp(new Vector3(transform.position.x, transform.position.y, transform.position.z), new Vector3(transform.position.x + distanceX, transform.position.y, transform.position.z + distanceZ), Time.deltaTime);

Now the problem is that it goes way too close to the player and ignores the current distance.

If you got any questions please don't hesitate to ask.

Thank you for your time!

Edit:

I'm not looking to make the object go to the target's position, just to follow it and keep the distance, just like it does when it's parented to that object, but smoother movements.

Edit 2:

Looks like I have made a mistake when I said that I wanted to keep the same distance between the two objects. What I actually meant was that I want the offset to be the same. I apologize to anyone who I confused or wasted their time! P.S. I'm still looking forward to finding a fix for my issue.

\$\endgroup\$
7
  • \$\begingroup\$ Possible duplicate of Unity method to get a vector, which is x seconds behind another moving vector (A bit like TrailRenderer) \$\endgroup\$
    – Philipp
    Commented Apr 24, 2016 at 10:32
  • \$\begingroup\$ Nah, I'm looking for something else. \$\endgroup\$
    – Ssiro
    Commented Apr 24, 2016 at 10:38
  • \$\begingroup\$ What if the parent object moves toward the child? Should the child simply move away to maintain distance? \$\endgroup\$
    – Peethor
    Commented Apr 24, 2016 at 10:41
  • \$\begingroup\$ Yes, it should maintain the distance. \$\endgroup\$
    – Ssiro
    Commented Apr 24, 2016 at 10:42
  • \$\begingroup\$ "just like it does when it's parented" - when parented, what's maintained is not just the distance but also the offset (ie. the direction relative to the parent's orientation). Is the offset what you want to preserve (ie. a child to the left stays to the left), or do you just care about the amount of distance between them (ie. if the parent keeps moving left far enough, the child will start to trail behind it to the right)? Also, do you need any particular behaviour if the parent scales or rotates? \$\endgroup\$
    – DMGregory
    Commented Apr 24, 2016 at 13:45

4 Answers 4

3
\$\begingroup\$

This can be done with a very small modification to the script in the question Philipp linked:

public class BlendFollower : MonoBehaviour 
{    
    public Transform leader;
    public float followSharpness = 0.1f;

    Vector3 _followOffset;

    void Start()
    {
        // Cache the initial offset at time of load/spawn:
        _followOffset = transform.position - leader.position;
    }

    void LateUpdate () 
    {
        // Apply that offset to get a target position.
        Vector3 targetPosition = leader.position + _followOffset;

        // Keep our y position unchanged.
        targetPosition.y = transform.position.y;

        // Smooth follow.    
        transform.position += (targetPosition - transform.position) * followSharpness;
    }
}

Note that the rate of follow here is framerate-dependent, and using Time.deltaTime the way you have in your question won't correct for that (that particular use pattern only works for linear rates of motion, which is not what we have here)

If you have a very uneven framerate and want to improve consistency, the most robust solution is to move this to FixedUpdate and interpolate, but for purely visual effects this correction formula will suffice:

const float REFERENCE_FRAMERATE = 30f;

// Then, in LateUpdate()...
float timeRatio = Time.deltaTime * REFERENCE_FRAMERATE;
float adjustedSharpness = 1f - Mathf.Pow(1f - followSharpness, timeRatio);

transform.position += (targetPosition - transform.position) * adjustedSharpness;
\$\endgroup\$
2
\$\begingroup\$

Find the normal between the two then scale that normal by the distance wanted.

float distanceWanted = 3.0f;

Vector3 diff = transform.position - player.position;
diff.y = 0.0f; // ignore Y (as requested in question)
transform.position = player.position + diff.normalized * distanceWanted;

This will also keep the y of your following object to be exactly the same as player.position, you may want to add a vertical offset relative to the player:

transform.position = new Vector3(0.0f, verticalOffset, 0.0f) + player.position + diff.normalized * distanceWanted;
\$\endgroup\$
0
\$\begingroup\$

Try this:

calculate the angle between the player and the object on the X and Z axis
find the offset on the X and Z axis by using cosine and sine of the previous extabilished angle and multiplying them by the distance you want to keep
move the object to that offset
\$\endgroup\$
0
\$\begingroup\$

Set your object to the position of its parent, then translate it by the distance you desire by multiplying the orientation of the forward unit vector by the distance.

    transform.position + transform.forward * distance.
\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .