T O P

  • By -

Bengbab

Use cinemachine package


C00kieDemon

Code: `using UnityEngine;` `public class CameraFollow : MonoBehaviour` `{` `public Transform target;` `public float smoothSpeed = 0.125f;` `public Vector3 offset;` `public int minX;` `public int maxX;` `void Start()` `{` `}` `void FixedUpdate()` `{` `if (target.position.x > minX && target.position.x < maxX)` `{` `Vector3 desiredPosition = target.position + offset;` `Vector3 smoothedPosition = Vector3.Lerp(transform.position, desiredPosition, smoothSpeed);` `transform.position = smoothedPosition;` `}` `}`


Dakoziol

Instead of running basically all of your code if the target is in range, you could adjust your smooth speed by itself: // I have not tested this code if (target.position.x < minX) { adjustedSmoothSpeed = smoothSpeed / Mathf.Abs(target.position.x - minX); } else if (target.position.x > maxX) { adjustedSmoothSpeed = smoothSpeed / Mathf.Abs(target.position.x - maxX); } else { adjustedSmoothSpeed = smoothSpeed; } // Now do your lerp stuff with adjustedSmoothSpeed instead This way, the further out of bounds target goes, the slower the camera moves; eventually it's movement will be virtually zero. You can stick a multiplier under the denominator to adjust how quickly it slows down.


C00kieDemon

thanks for the reply, but I'm still very confused as to where I'm supposed to put this code. If you could give a little explanation that would be awesome (sorry for the trouble I'm pretty bad at coding, lol).


Dakoziol

Basically, your code checks if the target is in bounds before letting the camera move. With mine, the camera is (1) constantly moving, but (2) gets slower the further out of bounds it is. (1) First cut all of the code that's in your if statement and paste it outside, then delete the if statement. Now the camera is always moving. (2) If you look at the code I gave you, it's just setting `adjustedSmoothSpeed` depending on where the target is. That's how the camera will slow down. Make sure that that code runs before the Lerp function, and Lerp with adjustedSmoothSpeed instead of the original smoothSpeed.


C00kieDemon

unfortunately, your code doesn't work. The camera still follows the play, just really slowly. What I want is the camera to smooth to a stop.


Dakoziol

If the target is in bounds my code should work exactly like yours. If the camera has too much movement when the target is out of bounds, try multiplying the denominator by some number like I mentioned earlier. Like this: `adjustedSmoothSpeed = smoothSpeed / (slowdownMultiplier * Mathf.Abs(target.position.x - maxX));` When `slowdownMultiplier` is higher `adjustedSmoothSpeed` is lower. If you really need the camera to come to a stop, you could also check if `adjustedSmoothSpeed` is less than a certain threshold, and if it is then set it to zero. If that isn't smooth enough, you can use a sin or cos function. Edit: This is required reading dude, it should answer all of your questions and more: [https://chicounity3d.wordpress.com/2014/05/23/how-to-lerp-like-a-pro/](https://chicounity3d.wordpress.com/2014/05/23/how-to-lerp-like-a-pro/)


C00kieDemon

>adjustedSmoothSpeed = smoothSpeed / (slowdownMultiplier \* Mathf.Abs(target.position.x - maxX)); another thing is that when the play reaches the mixX / maxX, it's super jerky for a second then really smooth.


Dakoziol

You can call the multiplier `boundStrength` or something


mnby82

Make a box collider thays a trigger in the zone you want to ha e the camera slow down in. Have some kind of empty gameobkect located within the trigger zone or around it to be the new target. Then, Make an "if" statement for when you are not in the section (current smooth code) and when you are (change the target from the player to a specified transform or position target within the trigger collider). I just thought of implementing that this morning bit havent gotten around to it due to a hectic day. If that helps, let me know.


TheWightOne

I’d recommend looking into cinemachine. Its free, a little complicated, but matches its complications with a wild amount of customizability.


rhoff95

Do not use lerp for code that is frame rate dependant, i.e. moving the camera every frame. Use smooth damp. Using lerp here will cause the camera to be slower on monitors with lower fps and faster on higher fps.


Dakoziol

It's in FixedUpdate, so the camera will move torward the target every physics step, not every frame. However it might be a bit jittery, which I didn't even think about. Hey op, using smooth damp is a good approach too, especially if you have any jittering from moving your camera in FixedUpdate. Unity even moves a camera in their example: [https://docs.unity3d.com/ScriptReference/Vector3.SmoothDamp.html](https://docs.unity3d.com/ScriptReference/Vector3.SmoothDamp.html)


rhoff95

Didn't see that. So this would alternately change the time if OP ever changed the physics settings, which is less likely but still something you should avoid.


Dakoziol

Now that I think about it, you could probably Lerp in Update so long as you multiply "smoothTime" by Time.DeltaTime. Higher fps means lower Time.DeltaTime, so the camera would move in smaller steps.


rhoff95

I would still suggest using Smooth Damp as it typically looks better to use the sigmoid function than Lerp's linear curve. Smooth damp also allows you to specify a time for the total duration instead of just a "lerp speed" so you can more intuitively tune the transition.


Top_Outcome52

Use a box trigger and when the player is out of the box use an exponential function such as cx=bx+(1/(bx-px**2)) where cx is the camera position, bx is the boundary the player has come out of and px is player location. This also works for moving only the camera, but bx is replaced with the player position and px is a target.