Help with camera movement

Hi! I am trying to create my own camera system, it works well except when I move with character and rotate the camera at the same time.

I use fixedupdate() to make changes to character’s rb movement and rotation; and update() for camera position and lookat rotation.

float t1 = 0f;
    void FixedUpdate()
    {
        float vertical = Input.GetAxis("Vertical");
        float horizonatal = Input.GetAxis("Horizontal");

        if (Input.GetAxis("Jump") == 1 && (Time.time - t1) > 0.1f)
        {
            if (Physics.CheckSphere(transform.position + Vector3.down * half_plr_height, 0.1f, LayerMask.GetMask("Ground")))
            {
                Jump();
            }
        }
        if (vertical == 0f && horizonatal == 0)
        {
            return;
        }
       
        Vector3 forwardVector = (transform.position - camTransform.position).normalized;
        forwardVector.y = 0f;
        Vector3 rightVector = new Vector3(forwardVector.z, 0f, -forwardVector.x);

        Vector3 moveDir = moveSpeed * (forwardVector * vertical + rightVector * horizonatal);
        rb.velocity = moveDir + new Vector3(0f, rb.velocity.y, 0f);
        if (moveDir != Vector3.zero)
        {
            Quaternion rotAngle = Quaternion.LookRotation(-moveDir, Vector3.up);
            rb.rotation = Quaternion.RotateTowards(transform.rotation, rotAngle, characterRotateSpeed * Time.deltaTime);
        }
    }

    float angle1 = defoult_angle1;  // between 0 and 2pi
    float angle2 = defoult_angle2;  // between 0 and pi
    float cameraDistance = 4f;
    float cSens = cameraSensitivity * 100f;
    void Update()
    {
        if (Input.GetMouseButton(1))
        {
            float mX = Input.GetAxis("Mouse X");
            float mY = Input.GetAxis("Mouse Y");

            angle1 += -mX * cSens * Time.deltaTime;
            angle2 += mY * cSens * Time.deltaTime;
            angle2 = Mathf.Clamp(angle2, 0.52f, 2.62f);
        }

        Vector3 dir = new Vector3(Mathf.Sin(angle2) * Mathf.Cos(angle1), Mathf.Cos(angle2), Mathf.Sin(angle1) * Mathf.Sin(angle2));

        float clipDistance = 0f;
        bool clipping = false;
        float scroll = -Input.GetAxis("Mouse ScrollWheel");
        if (scroll != 0)
        {
            cameraDistance = Mathf.Clamp(cameraDistance + scroll * zoomSpeed * Time.deltaTime, 0f, maxZoom);
        }

        RaycastHit hit;
        Ray camRay = new Ray(transform.position, dir);
        if (Physics.Raycast(camRay, out hit, Mathf.Infinity, ~(1 << 3)))
        {
            if (hit.distance < cameraDistance)
            {
                clipping = true;
                clipDistance = hit.distance;
            }
         
        }

        if (!clipping)
        {
            cam.transform.position = transform.position + cameraDistance * dir;
        }
        else
        {
            cam.transform.position = transform.position + clipDistance * dir;
        }
        cam.transform.LookAt(transform.position);
    }

Dont use FixedUpdate except for physics adjustments. FixedUpdate runs according to the physics engine’s simulation. It’s not going to be in-sync with the rendering cycle and it may not catch all of the use input.
For most things, you should use Update instead, or if you are adjusting the camera’s position or rotation relative to the player you might want to put the camera code in LateUpdate so that the camera always updates after the player.

Editted because I misread your code. You might still try LateUpdate, though. Also, you probably want to move the input handling out of FixedUpdate.

1 Like

One other, idea- instead of directly setting the camera’s direction and position based on the players orientation, try storing these in a “target” transform instead. Then have the camera ease into that target with some tolerances. That way you can smooth-out your camera movement over time.

1 Like

Why not use Cinemachine?

2 Likes

That’s a good idea. SkilledNut, I assume you are trying to implement your own camera for educational reasons, but if you finally just want something that works, Cinemachine is probably one of the best official Unity add-ons ever made.

1 Like