Well, can someone point me in the right direction?, lets point some facts first:
I have a player, with all the movement done in “FixedUpdate” (because of physics “MovePosition”, etc, jumping, you know…).
Then i have enemies patrolling, done with the navigation system. “navmesh agent”.
Also a “camera follow” script that follows the player object, done in the “LateUpdate”.
so im guessing you know what the problem is…
The player’s movement is done in the FixedUpdate and the camera’s movement which is done in the LateUpdate, which causes the player to look “jaggery” with a very “noisy” movement, But the enemies look fine, moving in the ground very smoothly.
I tried changing stuff all way around, putting the camera code in the FixedUpdate, so now the player’s movement looks very smooth, but all the enemies(done with navmesh) looks very, veeery jaggery and noisy.
So my guess is that they movement is done “internally” in the Update.
Now, how can i fix this? because there is plenty of reasons to move the player in the FixedUpdate, mainly if you use physics(like jumping, or just by moving it with “RigidBody.MovePosition”). And the navigation enemies are moved in the Update(i assume), what the heck can i do with the camera so they all look smooth and not jaggery? any approach ? help me pls
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class CameraFollow : MonoBehaviour {
public Transform positionTarget, lookTarget;
public float moveSpeed = 6f, lookSpeed = 5f;
Transform t;
Camera cam;
public static CameraFollow instance;
public bool DoShake = false;
public float ShakeMagnitude = 0.4f;
public float ShakeSpeed = 16f;
bool shakeTrigger;
Vector2 randomLocal;
bool isSoftShake;
// Use this for initialization
void Start () {
t = this.transform;
instance = this;
cam = Camera.main;
}
// Update is called once per frame
void FixedUpdate () {
if (positionTarget)
{
t.position = Vector3.Lerp(t.position, positionTarget.position, Time.deltaTime * moveSpeed);
}
if (lookTarget)
{
Quaternion tempRot = Quaternion.LookRotation((lookTarget.position) - t.position);
t.rotation = Quaternion.Slerp(t.rotation, tempRot, Time.deltaTime * lookSpeed);
}
if (DoShake)
{
if (!shakeTrigger)
{
shakeTrigger = true;
if (isSoftShake)
{
StartCoroutine(shakeRandomizerSoft(Random.Range(0.01f, 0.06f)));
}
else
{
StartCoroutine(shakeRandomizer(Random.Range(0.01f, 0.06f)));
}
}
Vector3 tempPosShake = new Vector3(randomLocal.x, randomLocal.y, 0f);
cam.transform.localPosition = Vector3.Lerp(cam.transform.localPosition, tempPosShake, Time.deltaTime * ShakeSpeed);
}
else
{
cam.transform.localPosition = Vector3.Lerp(cam.transform.localPosition, Vector3.zero, Time.deltaTime * (ShakeSpeed * 0.1f) );
}
}
IEnumerator shakeRandomizer(float randomTime)
{
randomLocal = new Vector2(
Random.Range(-ShakeMagnitude, ShakeMagnitude),
Random.Range(-ShakeMagnitude, ShakeMagnitude));
yield return new WaitForSeconds(randomTime);
shakeTrigger = false;
}
IEnumerator shakeRandomizerSoft(float randomTime)
{
randomLocal = new Vector2(
Random.Range(-ShakeMagnitude * 0.2f, ShakeMagnitude* 0.2f),
Random.Range(-ShakeMagnitude* 0.2f, ShakeMagnitude* 0.2f));
yield return new WaitForSeconds(randomTime);
shakeTrigger = false;
isSoftShake = false;
}
public static void EnableCameraShake()
{
instance.DoShake = true;
}
public static void DisableCameraShake()
{
instance.DoShake = false;
}
public void CallShake(bool isSoft, float time)
{
isSoftShake = isSoft;
DoShake = true;
StartCoroutine(shakeDelayDisabler(time));
}
IEnumerator shakeDelayDisabler(float timer)
{
yield return new WaitForSeconds(timer);
DoShake = false;
}
}
do not mind the “shake” part, thats working just fine. This script is placed in an “empty” gamesObject, which is the parent of the camera, so i can move the camera in the local position(that’s the shake thing). but what concerns my question is in the FixedUpdate :). Also, the move and look targets are just 2 spheres that i putted inside the character’s gameObject, so they move with the player and then the camera lerps to them.
Reproduced your setup and the player movement looks fine on my end, running the cam script in late update.
public class CameraFollow : MonoBehaviour
{
public static CameraFollow instance;
public Transform positionTarget, lookTarget;
public float moveSpeed = 6f, lookSpeed = 5f;
Transform t;
void Start () {
instance = this;
t = transform;
}
void LateUpdate () {
if (positionTarget)
{
t.position = Vector3.Lerp(t.position, positionTarget.position, Time.deltaTime * moveSpeed);
}
if (lookTarget)
{
Quaternion tempRot = Quaternion.LookRotation((lookTarget.position) - t.position);
t.rotation = Quaternion.Slerp(t.rotation, tempRot, Time.deltaTime * lookSpeed);
}
}
}
My guess is that your FPS is fairly low, making your Time.deltaTime value pretty high. Multiplied by your moveSpeed, you’re prob hitting around 1, near the high end of your interpolation.
Can you debug.log your time.deltatime in lateupdate, as well as lower your “moveSpeed” variable and see if that changes anything?