Home > Software engineering >  how can make smooth camera in Unity?
how can make smooth camera in Unity?

Time:12-14

I want the camera to look softly at my character in Unity. But my camera lags.

Code:

public GameObejct cam;

void Update() { cam.transform.LookAt(transform.position); }

Premise:

This script is in CharacterObject, and i enter the MainCamera to public GameObject cam variable.

Result:

The MainCamera is looking CharcaterObject, but it has short stop lag. GameView has little shaking.

CodePudding user response:

maybe It seems that the update is not able to run it continuously, so take it out as a function and run it, and if it doesn't work, try debug.log.

CodePudding user response:

First off, I am pretty sure you mean cam.transform.LookAt(transform); and not cam.transform.LookAt(transform.position); since the Transform.LookAt() doesn't allow Vector3 as the first parameter.

Moving on. Try moving the camera positioning in FixedUpdate() instead of Update(). This is to ensure that it's not dependent on the current FPS (meaning the FPS in that frame "tick" which, say, if you would have some hogging app in the back that would use 98% of your resources would freeze the game, then do a snap-back when resync-ing the "ticks").

Next, you need to learn about Interpolation. Check out Lerp and Slerp mostly, but if you find any other info, don't be shy about checking it out. If you don't care about to much "blah blah", focus on Lerp as this is the most common. Interpolation has many uses, one being predicting movement.

History lesson, feel free to skip

  1. While not a factor now, back when 33k modems were about and even before 1Mbps speeds, lag was more than an issue (and trust me on this, any feeling of "lag" you might have now is nothing compared to what was back then) so one method of smoothing gameplay was interpolating movement, meaning predicting movement of other players, then correcting it and smoothing it to make it seamless in order to reduce the perception of lag.
  2. Another other use is predicting projectile movement client side to reduce bandwidth usage and only updating it with "real" data once something changes on the server. For example a non-seeking rocket will always have a linear path, but if a player jumps out all of a sudden, the server can update it for you so you can see the player being hit by it, otherwise, the flying and wall hit can be simulated client-side to reduce the traffic (of the server updating you with the rocket position every single frame explosion) History lesson ended

Let's apply it here:

  cam.transform.position = Vector3.Lerp(cam.transform.position, formerCamPosition, 0.15*Time.fixedDeltaTime);
  cam.transform.LookAt(transform);

In this case, formerCamPosition should be the location in the previous frame, like one that is at an offset from the character. This can be updated in FixedUpdate() just before the Lerp() (you can "force" usage of transform and use the target there if you are 100% sure the camera offset won't change, but normally this is unreliable if you have position correction when near walls and the camera needs to clip to walls as to not go "outside" of the map). The reason to use fixedDeltaTime is to make sure you use the FPS in the game, even if they are based on fixed ticks.

If you prefer "real" ticks, you can keep using Update(), but change the smoothing to use Time.deltaTime. It's not written in stone to use FixedUpdate(). Some prefer to use LateUpdate() (with Time.deltaTime). See which is best for your game. Also note, if the smoothing "doesn't feel right", you can always replace 0.15 by a public variable which you can tweak in the Inspector for the best value. If you want to use the Time.(fixed)deltaTime, I recommend setting that smoothness to 1.0, not to delete it from the code as to allow you more control.

  • Related