Making the camera follow the mouse but stay near the player?

I have my player running around well and the camera works, but I don’t want my camera attached square on the player. I’m making an isometricish dungeon crawler and wanted the camera to more or less follow the player and for the player to face the mouse pointer, but for the camera to drift to wherever the mouse is currently.

In other words, the camera follows the mouse, but there is a ‘boundary’ around the player so if he starts moving it’ll tag along. This will probably conflict with my current camera, as it relies on the player facing where the camera is pointing on a Vector3.

My current movement file:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
  
[DisallowMultipleComponent]
[RequireComponent(typeof(Animator))]
[RequireComponent(typeof(Rigidbody))]
[RequireComponent(typeof(CapsuleCollider))]
public class Movement : MonoBehaviour
{
    Animator anim;
  
    private Camera mainCamera;
  
    bool isWalking = false;
  
    const float WALK_SPEED = .25f;
  
    void Start ()
    {
        mainCamera = FindObjectOfType<Camera>();
    }
  
    void Awake()
    {
        anim = GetComponent<Animator>();
    }
  
    void Update()
    {
        Turning();
        Walking();
        Move();
        Jump();
  
        //Player look
        Ray cameraRay = mainCamera.ScreenPointToRay(Input.mousePosition);
        Plane groundPlane = new Plane(Vector3.up, Vector3.zero);
        float rayLength;
  
        if (groundPlane.Raycast(cameraRay, out rayLength))
        {
            Vector3 pointToLook = cameraRay.GetPoint(rayLength);
            Debug.DrawLine(cameraRay.origin, pointToLook, Color.blue);
  
            transform.LookAt(new Vector3(pointToLook.x, transform.position.y, pointToLook.z));
        }
    }
  
    void Turning()
    {
        anim.SetFloat("Turn", Input.GetAxis("Horizontal"));
    }
  
    void Walking()
    {
        if (Input.GetKeyDown(KeyCode.LeftShift)) {
            isWalking = !isWalking;
            anim.SetBool("Walk", isWalking);
        }
    }
  
    void Move()
    {
        if (anim.GetBool("Walk"))
        {
            anim.SetFloat("MoveZ", Mathf.Clamp(Input.GetAxis("MoveZ"), -WALK_SPEED, WALK_SPEED));
            anim.SetFloat("MoveX", Mathf.Clamp(Input.GetAxis("MoveX"), -WALK_SPEED, WALK_SPEED));
        }
        else
        {
            anim.SetFloat("MoveZ", Input.GetAxis("MoveZ"));
            anim.SetFloat("MoveX", Input.GetAxis("MoveX"));
        }
    }
  
    void Jump()
    {
        if (Input.GetKeyDown(KeyCode.Space))
            anim.SetTrigger("Jump");
    }
}

My current camera file:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
  
public class SmoothCamera : MonoBehaviour
{
  
    public Transform lookAt;
  
    private bool smooth = true;
    private float smoothSpeed = 0.125f;
    private Vector3 offset = new Vector3(0, 10, -10);
  
    private void LateUpdate()
    {
        Vector3 desiredPosition = lookAt.transform.position + offset;
        if (smooth)
        {
            transform.position = Vector3.Lerp(transform.position, desiredPosition, smoothSpeed);
        }
        else {
            transform.position = desiredPosition;
        }
    }
}

I’m still (obviously) pretty new so excuse me if this is a dumb question.

So it looks to me like all you need to do is find a different offset value - how about raycasting from the camera to the mouse point (using Camera.ScreenPointToRay(Input.mousePosition)) and then changing offset by some portion of the distance between the lookAt.position and the raycast position?

So something like

private Vector3 defaultOffset;
private Camera camera;
private Vector3 offsetForOffset;
private float maxDistance;
private float scaleFactor;

void Start()
{
    defaultOffset = new Vector3(0,10,-10);
    scaleFactor = 0.5f; //This is to make the camera not go all the way to the mouse cursor position, tweak it until it feels right.
    maxDistance = 3.0f; //This limits how far the camera can go from the player, tweak it until it feels right.
}

void LateUpdate()
{
    RaycastHit hit;
    Ray ray = camera.ScreenPointToRay(Input.mousePosition);
    
    if (Physics.Raycast(ray, out hit)) {
        offsetForOffset = (hit.point - lookAt.position) * scaleFactor;
    }
    else
        offsetForOffset = Vector3.zero; // This makes it so that if the camera raycast doesn't hit, we go to directly over the player.
    if(offsetForOffset.magnitude > maxDistance)
    {
        offsetForOffset.Normalize(); // Make the vector3 have a magnitude of 1
        offsetForOffset = offsetForOffset * maxDistance;
    }
    offset = defaultOffset + offsetForOffset;
    
    Vector3 desiredPosition = lookAt.transform.position + offset;

    if (smooth)
    {
        transform.position = Vector3.Lerp(transform.position, desiredPosition, smoothSpeed);
    }
}

Lemme know how that works for you?

Did anyone solve this? if not to fix this (you’ll need to change a lot more then just this, but this fixes the mouse/camera issue)

for:

desiredPosition = lookAt.transform.position + offset;

change it to:

desiredPosition = new Vector3(offsetForoffset.x+offset+lookAt.position.x, offsetForoffset.y+offset+lookAt.position.y, offsetForoffset.z+offset+lookAt.position.z);

this will make your mouse move the camera around the player and will also make sure the camera follows your LookAt target.