Subject says it all. I’m using the type of camera where it orbits and follows the player and zooming is achieved by creating distance between the camera and player. The problem is that the player’s movement is authoritative server based with client-side prediction. So I’m fairly sure the reason the camera is shaking while the player is in motion, is because the camera follows the player on the client, but then when the server sends the client data to check/correct its position, it causes the camera to move even the slightest based on the adjustment that’s needed to be made to the player’s position. Anyone else encounter this, or have some input they can give?
Can you smoothen your camera’s movement by lerping it? Something like below:
// in Update()
float smoother = 10f;
Vector3 targetPosition = ComputeTargetPositionBasedOnPlayerTransform();
camera.transform.position = Vector3.Lerp(camera.transform.position, targetPosition, smoother * Time.deltaTime);
// do the same for rotation, fov, etc.
Okay…so upon adding smoothing to my CameraController…I determined that it’s the player that’s being jittery. The camera is moving smoothly now, but if you pay close attention to the character model, you can see it jittering very slightly. Here’s my camera script…and I’m using a version of @GenaSG 's server-authoritative with client-side prediction movement method…found HERE.
using UnityEngine;
using System.Collections;
public class CameraController : MonoBehaviour
{
public Transform target; //Target to follow
// public float targetHeight = 1.7f; //Vertical offset adjustment
public float distance = 1.0f; //Default distance
public float offsetFromWall = 0.1f; // Bring camera away from any colliding objects
public float maxDistance = 20.0f; // Maximum zoom Distance
public float minDistance = 0.6f; // Minimum zoom Distance
public float xSpeed = 200.0f; // Orbit speed (Left/Right)
public float ySpeed = 200.0f; // Orbit speed (Up/Down)
public float yMinLimit = -80.0f; // Looking up limit
public float yMaxLimit = 80.0f; // Looking down limit
public float zoomRate = 40.0f; // Zoom Speed
public float rotationDampening = 3.0f; // Auto Rotation speed (higher = faster)
public float zoomDampening = 5.0f; // Auto Zoom speed (Higher = faster)
public LayerMask collisionLayers = -1; // What the camera will collide with
private float xDeg = 0.0f, yDeg = 0.0f, currentDistance, desiredDistance, correctedDistance;
void Start()
{
Vector3 angles = transform.eulerAngles;
xDeg = angles.x;
yDeg = angles.y;
currentDistance = distance;
desiredDistance = distance;
correctedDistance = distance;
}
void FixedUpdate()
{
if(target)
{
xDeg += Input.GetAxis ("Mouse X") * xSpeed * 0.02f;
yDeg -= Input.GetAxis ("Mouse Y") * ySpeed * 0.02f;
yDeg = Physics_Calculations.ClampAngle(yDeg, yMinLimit, yMaxLimit);
// Set camera rotation
Quaternion rotation = Quaternion.Euler(yDeg, xDeg, 0.0f);
// Calculate the desired distance
desiredDistance -= Input.GetAxis("Mouse ScrollWheel") * Time.deltaTime * zoomRate * Mathf.Abs(desiredDistance);
desiredDistance = Mathf.Clamp (desiredDistance, minDistance, maxDistance);
correctedDistance = desiredDistance;
// Calculate desired camera position
Vector3 position = target.position - (rotation * Vector3.forward * desiredDistance);
// Check for collision using the true target's desired registration point as set by user using height
RaycastHit collisionHit;
Vector3 trueTargetPosition = new Vector3(target.position.x, target.position.y, target.position.z);
// If there was a collision, correct the camera position and calculate the corrected distance
bool isCorrected = false;
if (Physics.Linecast(trueTargetPosition, position, out collisionHit, collisionLayers))
{
// Calculate the distance from the original estimated position to the collision location,
// subtracting out a safety "offset" distance from the object we hit. The offset will help
// keep the camera from being right on top of the surface we hit, which usually shows up as
// the surface geometry getting partially clipped by the camera's front clipping plane.
correctedDistance = Vector3.Distance(trueTargetPosition, collisionHit.point) - offsetFromWall;
isCorrected = true;
}
// For smoothing, lerp distance only if either distance wasn't corrected, or correctedDistance is more than currentDistance
currentDistance = !isCorrected || correctedDistance > currentDistance ? Mathf.Lerp(currentDistance, correctedDistance, Time.deltaTime * zoomDampening) : correctedDistance;
// Keep within limits
currentDistance = Mathf.Clamp(currentDistance, minDistance, maxDistance);
// Recalculate position based on the new currentDistance
position = target.position - (rotation * Vector3.forward * currentDistance);
//Finally Set rotation and position of camera
transform.rotation = rotation;
transform.position = Vector3.MoveTowards(transform.position, position, 0.5f);
}
}
public void SetTarget(Transform target)
{
this.target = target;
}
}
Yeah…I figured it out. It was the server authorization that was screwing things up. I made an error in that script which kept causing the player to try to be yanked back to its previous position from its new position every update…
hey ddrosen, i know this thread is veryyyyy old - but ive got exactly the same problem and need help. can you give more infos about how you solved this?
I doubt you’re having the same problem as I. This was a long time ago, but IIRC… My problem was that I wasn’t updating the player’s position on the server correctly. So every time the client moved their character, client-side-prediction would move it, but then the server sent a message with a different position (of the character on the server), which caused the client to try and correct the player’s position back to where it was before.