Physics.Raycast Hit Distance

Hi, I am just getting started with Unity Engine and i am having a little problem with the HitResult.distance value outputed from physics.raycast. Here is a video i recorded about how the problem looks like:

As you can see in the video, i am controlling a camera with a raycast from the cube to the camera and i am using 3 raycast only for better result (c# code in last 15 seconds).

The distance given by the raycast function in output is varying with a noticed value like in a frame it is 1.9 and in the next 2.3 and in the next it is 1.9.

i tried using an average between the previous given distance and the current distance to reduce the difference but it didn’t work .


using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class CameraScript : MonoBehaviour
{

public Transform Target = null;
public LayerMask CameraEvitableLayer;
public float Distance = 3f;
public Vector3 Offset = Vector3.zero;
public float MaxSpeed = 70f;
public Vector3 currentVel = Vector3.zero;
public float smoothTime = 0.1f;
private float MouseScroll = 0f;
private Transform ThisTransform = null;
private Vector3 DesiredPosition = Vector3.zero;
private float PrevCameraHitDistance = -1f;

void Awake()
{
    ThisTransform = GetComponent<Transform>();
}

// Update is called once per frame
void LateUpdate()
{
    MouseScroll = Input.GetAxis("Mouse ScrollWheel");
    Distance += MouseScroll;
    DesiredPosition = Target.position + Offset - Distance * Target.forward;
    CameraHit(ref DesiredPosition, ref PrevCameraHitDistance);
    ThisTransform.position = Vector3.SmoothDamp(ThisTransform.position, DesiredPosition, ref currentVel, smoothTime, MaxSpeed);
    ThisTransform.LookAt(Target);
    
}

// Manages Camera Positining in Environnment Hit Case.
private bool CameraHit(ref Vector3 DesiredPosition, ref float PrevDistance)
{
    RaycastHit HitRight;
    if(Physics.Raycast(Target.position + Offset, ThisTransform.forward * -1, out HitRight, Distance,CameraEvitableLayer))
    {
        DesiredPosition = Target.position + Offset - (HitRight.distance - 0.2f) * Target.forward;
        Debug.Log("Hit Distane For camera: " + HitRight.distance + ".");
        return true;
    }
    return false;
}

}


Thanks.

could you show us the script

You are doing three raycasts all with the same out parameter (HitResult). You are then bouncing around between the results of these different raycasts (whichever one happens to hit first depending on your position and rotation, and even a possible race condition).

Try reworking your code so that you are using different out parameters for each raycast.

Your code doesn’t make much sense. Of course it’s possible to do 3 raycasts like that, however only one will actually take affect which is the first one that hits something. However that means you don’t know which ray actually has detected the hit. If you look at a steep angle onto a surface the difference can be huge. The point that you actually use in the end hasn’t been checked by no raycast since you do one to the left, one to the right and one above. For such a max distance check you usually want to execute all 3 raycasts and just use the one with the smallest distance. In that case you have to execute all 3 raycasts unconditionally and have to use 3 different hit structures. Currently you only check one raycast and only use the others only if one fails.

Why the distance average? When you move through the scene the result will be complete garbage as you mix the current distance with the old one. So when you first look at an object 300 units away and then on a object 20 units away you would use the average of those two. Over time (given that you run that every frame) the average distance would asymptotically get closer to the actual distance.

I would recommend you just use a single spherecast instead of your strange 3 ray setup.