Search Unity

(SOLVED) Camera Jitters from Authoritative Server

Discussion in 'Multiplayer' started by DRRosen3, Apr 7, 2016.

  1. DRRosen3

    DRRosen3

    Joined:
    Jan 30, 2014
    Posts:
    683
    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?
     
  2. zee_ola05

    zee_ola05

    Joined:
    Feb 2, 2014
    Posts:
    166
    Can you smoothen your camera's movement by lerping it? Something like below:

    Code (CSharp):
    1. // in Update()
    2. float smoother = 10f;
    3. Vector3 targetPosition = ComputeTargetPositionBasedOnPlayerTransform();
    4. camera.transform.position = Vector3.Lerp(camera.transform.position, targetPosition, smoother * Time.deltaTime);
    5.  
    6. // do the same for rotation, fov, etc.
     
  3. DRRosen3

    DRRosen3

    Joined:
    Jan 30, 2014
    Posts:
    683
    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.
    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. public class CameraController : MonoBehaviour
    5. {
    6.     public Transform target;                            //Target to follow
    7. //    public float targetHeight = 1.7f;                    //Vertical offset adjustment
    8.     public float distance = 1.0f;                        //Default distance
    9.     public float offsetFromWall = 0.1f;                // Bring camera away from any colliding objects
    10.     public float maxDistance = 20.0f;                    // Maximum zoom Distance
    11.     public float minDistance = 0.6f;                    // Minimum zoom Distance
    12.     public float xSpeed = 200.0f;                        // Orbit speed (Left/Right)
    13.     public float ySpeed = 200.0f;                        // Orbit speed (Up/Down)
    14.     public float yMinLimit = -80.0f;                    // Looking up limit
    15.     public float yMaxLimit = 80.0f;                    // Looking down limit
    16.     public float zoomRate = 40.0f;                        // Zoom Speed
    17.     public float rotationDampening = 3.0f;                // Auto Rotation speed (higher = faster)
    18.     public float zoomDampening = 5.0f;                    // Auto Zoom speed (Higher = faster)
    19.     public LayerMask collisionLayers = -1;                // What the camera will collide with
    20.    
    21.     private float xDeg = 0.0f, yDeg = 0.0f, currentDistance, desiredDistance, correctedDistance;
    22.  
    23.  
    24.     void Start()
    25.     {
    26.         Vector3 angles = transform.eulerAngles;
    27.         xDeg = angles.x;
    28.         yDeg = angles.y;
    29.         currentDistance = distance;
    30.         desiredDistance = distance;
    31.         correctedDistance = distance;
    32.     }
    33.  
    34.     void FixedUpdate()
    35.     {
    36.         if(target)
    37.         {
    38.             xDeg += Input.GetAxis ("Mouse X") * xSpeed * 0.02f;
    39.             yDeg -= Input.GetAxis ("Mouse Y") * ySpeed * 0.02f;
    40.  
    41.             yDeg = Physics_Calculations.ClampAngle(yDeg, yMinLimit, yMaxLimit);
    42.            
    43.             // Set camera rotation
    44.             Quaternion rotation = Quaternion.Euler(yDeg, xDeg, 0.0f);
    45.            
    46.             // Calculate the desired distance
    47.             desiredDistance -= Input.GetAxis("Mouse ScrollWheel") * Time.deltaTime * zoomRate * Mathf.Abs(desiredDistance);
    48.             desiredDistance = Mathf.Clamp (desiredDistance, minDistance, maxDistance);
    49.             correctedDistance = desiredDistance;
    50.            
    51.             // Calculate desired camera position
    52.             Vector3 position = target.position - (rotation * Vector3.forward * desiredDistance);
    53.            
    54.             // Check for collision using the true target's desired registration point as set by user using height
    55.             RaycastHit collisionHit;
    56.             Vector3 trueTargetPosition = new Vector3(target.position.x, target.position.y, target.position.z);
    57.            
    58.             // If there was a collision, correct the camera position and calculate the corrected distance
    59.             bool isCorrected = false;
    60.             if (Physics.Linecast(trueTargetPosition, position, out collisionHit, collisionLayers))
    61.             {
    62.                 // Calculate the distance from the original estimated position to the collision location,
    63.                 // subtracting out a safety "offset" distance from the object we hit.  The offset will help
    64.                 // keep the camera from being right on top of the surface we hit, which usually shows up as
    65.                 // the surface geometry getting partially clipped by the camera's front clipping plane.
    66.                 correctedDistance = Vector3.Distance(trueTargetPosition, collisionHit.point) - offsetFromWall;
    67.                 isCorrected = true;
    68.             }
    69.            
    70.             // For smoothing, lerp distance only if either distance wasn't corrected, or correctedDistance is more than currentDistance
    71.             currentDistance = !isCorrected || correctedDistance > currentDistance ? Mathf.Lerp(currentDistance, correctedDistance, Time.deltaTime * zoomDampening) : correctedDistance;
    72.             // Keep within limits
    73.             currentDistance = Mathf.Clamp(currentDistance, minDistance, maxDistance);
    74.            
    75.             // Recalculate position based on the new currentDistance
    76.             position = target.position - (rotation * Vector3.forward * currentDistance);
    77.            
    78.             //Finally Set rotation and position of camera
    79.             transform.rotation = rotation;
    80.             transform.position = Vector3.MoveTowards(transform.position, position, 0.5f);
    81.         }
    82.     }
    83.  
    84.     public void SetTarget(Transform target)
    85.     {
    86.         this.target = target;
    87.     }
    88. }
     
  4. DRRosen3

    DRRosen3

    Joined:
    Jan 30, 2014
    Posts:
    683
    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... :oops::rolleyes:
     
  5. Elharter

    Elharter

    Joined:
    Sep 20, 2015
    Posts:
    58
    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?
     
  6. DRRosen3

    DRRosen3

    Joined:
    Jan 30, 2014
    Posts:
    683
    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.