[SOLVED] Third person camera collision with Raycasting (problems with distance smoothing)

I’m working on my third person camera code and have run into some issues regarding wall detection and adjustment.

I have a functional Raycast solution that tracks wall collisions and adjusts the camera relative to the player, except the camera code I have is built off code that has built in distance smoothing in its calculations, and it’s making my raycast “bounce” off colliders, messing up the raycast check.

    void WallDetection()
    {
        float wallBuffer = 2f;

        if (Physics.Raycast(TargetLookAt.position, -transform.TransformDirection(Vector3.forward), out hitInfo, Distance, walls))
        {
            Distance = hitInfo.distance - wallBuffer;
        }
    }

This is the distance calculation and smoothing code the camera is using:

void CalculateDesiredPosition()
    {
        // Evaluate distance
        Distance = Mathf.SmoothDamp(Distance, desiredDistance, ref velDistance, DistanceSmooth);
  
        // Calculate desired position
        desiredPosition = CalculatePosition(mouseY, mouseX, Distance);
    }

    Vector3 CalculatePosition(float rotationX, float rotationY, float distance)
    {
        Vector3 direction = new Vector3(0, 0, -distance);
        Quaternion rotation = Quaternion.Euler(rotationX, rotationY, 0f);
        return TargetLookAt.position + rotation * direction;
    }

    void UpdatePosition()
    {
  
        var posX = Mathf.SmoothDamp(position.x, desiredPosition.x, ref velX, X_Smooth);
        var posY = Mathf.SmoothDamp(position.y, desiredPosition.y, ref velY, Y_Smooth);
        var posZ = Mathf.SmoothDamp(position.z, desiredPosition.z, ref velZ, X_Smooth);
        position = new Vector3(posX, posY, posZ);
  
        transform.position = position;
  
        transform.LookAt(TargetLookAt);
    }

>>The issue in question<<

I’m a novice coder so I’m probably missing something obvious.
I want to know how to either make it perform the same task without the smoothing issue, or preferably modify the Raycast code so that it takes the smoothing in mind when calculating collisions.

Any help is appreciated

Hi @cyberspacecat

Not working on 3rd person game camera right now, but I happened to stumble on this exact same issue.

Here’s how I went around it (don’t really remember why it exactly happened):

// Eses
// Direction to camera from target (transform = camera pos)
var dir = (transform.position - targetPoint).normalized;

// If camera is not at it's ideal position
if (!Mathf.Approximately(cameraDistNow, cameraDist))
{
    // The spot where it should be is direction x defined distance
    var cameraSpot = dir * cameraDist;

    // Start moving towards this spot (changes each frame, as player tumbles view)
    transform.position = Vector3.MoveTowards(transform.position, cameraSpot, Time.deltaTime * dollySpeed);

    // Where we are now
    cameraDistNow = Vector3.Distance(transform.position, targetPoint);
}

I’m not sure if its directly usable by you, didn’t check your code properly, but I hope it helps!

I didn’t have any luck with your code, unfortunately, although after some trial and error with different Mathf methods I managed to get it working with a simple Lerp (I feel like a dork for overthinking this).

Lightly modified my Raycast code and removed the wall buffer from the wall distance calculation because it didn’t actually clip with this method and the raycast overlapped itself and spun the camera around wildly trying to correct itself.

        if (Physics.Raycast(TargetLookAt.position, -transform.TransformDirection(Vector3.forward), out hitInfo, desiredDistance, walls))
        {
            Distance = hitInfo.distance;
        }
        else
        {
            Distance = desiredDistance; //And putting it back towards the default camera distance should it not hit a wall
        }

Then the lerp like this. Camera itself doesn’t feel less smooth as a result so the SmoothDamp was probably overkill for my purposes.

    void CalculateDesiredPosition()
    {
        // Evaluate distance
        Distance = Mathf.Lerp(Distance, desiredDistance, DistanceSmooth * Time.deltaTime);

        // Calculate desired position
        desiredPosition = CalculatePosition(mouseY, mouseX, Distance);
    }

I’ll mark this as solved, but if someone has a more elegant solution I’m sure anyone coming across this, as well as myself, will appreciate it.