Camera controller: follow behind main character + offset

I use the attached c# script to control the camera.

Mouse scroll (pulley/roller/wheel): Zooming in and out of the main character

Up Arrow (or W key) and Down Arrow (or X key): Raise and Lower the camera

Right arrow (or D key) and Left arrow (or A key): Rotate the camera around the main character

I try to get the camera to follow the back of the main character, and add it the offset that player defined by using mouse and arrows.

This line correctly moves the camera according to the input from the mouse and arrows:

transform.position = target.position + offset * currentZoom; 

This line correctly moves the camera so that it will follow the back of the main character:

transform.position = target.position - target.forward + Vector3.up;

But each of them works correctly only if the other is canceled. If I try to merge them into one line, like:

transform.position = target.position - target.forward + Vector3.up + offset * currentZoom;

then the camera doesn’t move properly:

  1. Using the left and right arrows moves the camera around the main
    character in ellipse/oval shape instead of in a circle

  2. When the character moves, the offsset set by the right and left
    arrows isn’t saved but the camera returns to being exactly behind
    the back of the main character

What do I need to do to combine the two lines so that camera does move properly?

using UnityEngine;

public class CameraController : MonoBehaviour
{
    public Transform target;
    public Vector3 offset = new Vector3(10f, 6f, 0f); 
    public float RotationX = .5f;
    public float rightLeftSpeed = 5f;

    public float currentZoom = .13f;
    public float minZoom = .1f;
    public float maxZoom = 1f;
    public float speedZoom = .1f;

    public float currentHeight = 6f;
    public float minHeight = 0f;
    public float maxHeight = 10f;
    public float speedHeight = 1f;

    void Update()
    {
        currentZoom -= Input.GetAxis("Mouse ScrollWheel") * speedZoom;
        currentZoom = Mathf.Clamp(currentZoom, minZoom, maxZoom);

        currentHeight += Input.GetAxis("Vertical") * speedHeight * Time.deltaTime;
        currentHeight = Mathf.Clamp(currentHeight, minHeight, maxHeight);
        offset.y = currentHeight;

        offset = Quaternion.AngleAxis(-Input.GetAxis("Horizontal") * rightLeftSpeed, Vector3.up) * offset;
    }

    void LateUpdate()
    {

        transform.position = target.position + offset * currentZoom;
        transform.position = target.position - target.forward + Vector3.up;
        transform.LookAt(target.position + Vector3.up * RotationX);
    }
}

I would seperate the axis’s. I would make the camera a child of an empty and have the camera’s transform do the zoom. If you use vector3.forward in local space will keep it moving forward and back on the same axis. Then have the empty parents transform orient around the player. When you isolate the child objects world space to inherit the parents rotation, it will correctly orient around the player and zoom in and out.