0
\$\begingroup\$

I have asked this question on other community but still get no response after a month, so I decided to ask it here.

I am trying to put player position to the middle of camera when it is reaching near the edge of the camera. It works correctly with the following code:

transform.position = playerPosition;

where playerPosition is the current position of the player.

But, when I try it with Vector3.Lerp or Vector3.MoveTowards, it won't reach the player's x position.

Here is how it looks when using Lerp or MoveTowards

https://www.youtube.com/watch?v=E50RpycrUxI

And here is when not using Lerp or MoveTowards

https://www.youtube.com/watch?v=ng_A4AfDQFE

The script:

 public GameObject player;
 private Vector3 playerPosition;
 private Vector3 pos;
 public float offsetSmoothness;
 void Update () {
     // player's position relative to camera
     pos = Camera.main.WorldToViewportPoint(player.transform.position);
     playerPosition = new Vector3(player.transform.position.x,
                                    transform.position.y,
                                    transform.position.z);
     // if player reach the edge of the camera do the following
     if (pos.x < 0.1 || pos.x > 0.9)
     {
          transform.position = Vector3.Lerp (transform.position,
                                                playerPosition,
                                                offsetSmoothness * Time.deltaTime);
          // transform.position = playerPosition;
     }
 }

Why Vector3.Lerp is not positioning the player to the center of the camera when this condition is used to execute it: if (pos.x < 0.1 || pos.x > 0.9) ?

And how to make it working as expected, which is making the Vector.Lerp position the player to the center of camera when the player close to the edge of the camera?

\$\endgroup\$
4
  • \$\begingroup\$ How much is offsetSmoothness? \$\endgroup\$
    – Bálint
    Commented Feb 7, 2018 at 23:29
  • \$\begingroup\$ @Bálint offsetSmoothness is dynamic variable. It has no effect other than making the camera movement slower or faster. I set it to 10 on the Inspector panel. \$\endgroup\$
    – Ari
    Commented Feb 8, 2018 at 2:28
  • \$\begingroup\$ Lerp accepts values between 0 and 1 and the less it is, the smoother the result will be. You should probably look up what it actually does. \$\endgroup\$
    – Bálint
    Commented Feb 8, 2018 at 5:53
  • \$\begingroup\$ @Bálint I have no problem with smoothness. I want to center the player inside the camera once it is reaching the edge of the camera. \$\endgroup\$
    – Ari
    Commented Feb 8, 2018 at 10:21

2 Answers 2

2
\$\begingroup\$

This is because you are only calling Vector3.Lerp or MoveTowards while pos.x < 0.1 || pos.x > 0.9. This means that once the camera moves a little bit pos.x < 0.1 || pos.x > 0.9 won't be true anymore so the camera won't keep moving. To fix this you could create a co-routine that runs until the player is in the middle of the camera:

public GameObject player;
public float speed;
private bool isMovingCamera;

void Update () {
    // player's position relative to camera
    Vector3 pos = Camera.main.WorldToViewportPoint(player.transform.position);
    Vector3 playerPosition = new Vector3(player.transform.position.x,
                                    transform.position.y,
                                    transform.position.z);
    // if player reach the edge of the camera do the following
    if ((pos.x < 0.1 || pos.x > 0.9) && !isMovingCamera)
    {
        StartCoroutine(CenterCameraOnPlayer());
    }
}

IEnumerator CenterCameraOnPlayer() {
    isMovingCamera = true;

    do {
        Vector3 camPos = transform.position;
        Vector3 playerPos = player.transform.position;


        float step = speed * Time.deltaTime;
        // Move camera towards player at speed units per second.
        transform.position = Vector3.MoveTowards(camPos, playerPos, step);
        yield return null;
    } while(Vector3.Distance(camPos, playerPos) > 0.1f);

    isMovingCamera = false;
}

You might have to tweak some numbers (like 0.1f in the while condition) to make it feel right. This is also untested, but the general idea should work.

\$\endgroup\$
0
\$\begingroup\$

You're misunderstanding Lerp, or Linear Interpolation. You're not supposed to set the third parameter or t to speed * time, you're supposed to give it a value between 0-1 for which it will interpolate.

So:

Lerp(A, B, 1) will return B,

Lerp(A, B, 0) will return A,

Lerp(A, B, 0.5) will return the middle point between A and B.

With that in mind, what you need is to have a function that makes t go from 0-1 within X seconds.

\$\endgroup\$
3
  • \$\begingroup\$ There are actually two common patterns for using lerp, and they can involve time in the third parameter. See a deeper write-up in this answer. \$\endgroup\$
    – DMGregory
    Commented Mar 11, 2018 at 19:32
  • \$\begingroup\$ It is just the way to use what is exist. \$\endgroup\$
    – Ari
    Commented Mar 11, 2018 at 22:28
  • \$\begingroup\$ @DMGregory thanks for the link, interesting read. Although it is a valid way to use it, i feel like many people use Lerp like that [using time for t] without knowing what linear interpolation really is, so i just wanted to clear that up. \$\endgroup\$ Commented Mar 12, 2018 at 21:50

You must log in to answer this question.

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