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\$
  • \$\begingroup\$ Possible duplicate of Unity method to get a vector, which is x seconds behind another moving vector (A bit like TrailRenderer) \$\endgroup\$ – Philipp Apr 24 '16 at 10:32
  • \$\begingroup\$ Nah, I'm looking for something else. \$\endgroup\$ – Ssiro Apr 24 '16 at 10:38
  • \$\begingroup\$ What if the parent object moves toward the child? Should the child simply move away to maintain distance? \$\endgroup\$ – Peethor Apr 24 '16 at 10:41
  • \$\begingroup\$ Yes, it should maintain the distance. \$\endgroup\$ – Ssiro Apr 24 '16 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 Apr 24 '16 at 13:45
2
\$\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\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.