I am have an issue with a camera set up of mine thats designed to prevent the camera from penetrating blocks, in C#. It does this by raycasting to the four points of the near clipping plane of the camera. If one of these raycasts hit, it moves the camera inward. I have managed to trace the problem down to the incorrect assignment of a float.
public Vector3 cameraOffset = new Vector3();
public GameObject viewCamera;
public float clipSize = .4f;
public float sensitivity = 15F;
public float minimum = -60F;
public float maximum = 60F;
float rotationY = 0F;
void FixedUpdate ()
{
rotationY += Input.GetAxis("Mouse Y") * sensitivity;
rotationY = Mathf.Clamp(rotationY, minimum, maximum);
transform.localEulerAngles = new Vector3(-rotationY, transform.localEulerAngles.y, 0);
Vector3 realDir = transform.TransformDirection(cameraOffset);
Vector3 hClipOffset = transform.TransformDirection(new Vector3(clipSize, 0f, 0f)); // Setup Raycasts
Vector3 vClipOffset = transform.TransformDirection(new Vector3(0f, clipSize/2f, 0f));
RaycastHit urHit; // Raycast info holders
RaycastHit ulHit;
RaycastHit lrHit;
RaycastHit llHit;
float modifyDist = 1f;
Vector3 urDir = realDir + vClipOffset + hClipOffset; // Specify the directions to the four corners of the cameras near clipping plane
Vector3 ulDir = realDir + vClipOffset - hClipOffset;
Vector3 lrDir = realDir - vClipOffset + hClipOffset;
Vector3 llDir = realDir - vClipOffset - hClipOffset;
if (Physics.Raycast(transform.position, urDir, out urHit, urDir.magnitude)) { // check if it clips upper right edge
float a = urHit.distance / urDir.magnitude; //prevent penetration by pushing camera in
if (a < modifyDist) modifyDist = a;// always use the closest collision
}
if (Physics.Raycast(transform.position, ulDir, out ulHit, ulDir.magnitude)) { // check if it clips upper left edge
float a = ulHit.distance / ulDir.magnitude; //prevent penetration by pushing camera in
if (a < modifyDist) modifyDist = a;// always use the closest collision
}
if (Physics.Raycast(transform.position, lrDir, out lrHit, lrDir.magnitude)) { // check if it clips lower right edge
float a = lrHit.distance / lrDir.magnitude; //prevent penetration by pushing camera in
if (a < modifyDist) modifyDist = a;// always use the closest collision
}
if (Physics.Raycast(transform.position, llDir, out llHit, llDir.magnitude)) { // check if it clips lower left edge
float a = llHit.distance / llDir.magnitude; //prevent penetration by pushing camera in
if (a < modifyDist) modifyDist = a;// always use the closest collision
}
Debug.DrawRay(transform.position, urDir, Color.green); // ur debug draw rays
Debug.DrawRay(transform.position, ulDir, Color.red); // ul
Debug.DrawRay(transform.position, lrDir, Color.cyan); // lr
Debug.DrawRay(transform.position, llDir, Color.yellow); // ll
viewCamera.transform.localPosition = cameraOffset * modifyDist; // modify the normal vector
viewCamera.transform.LookAt(transform.position); // always look at this transform
}
Using Debug code not shown here, i have traced the problem to this section of code.
float a = llHit.distance / llDir.magnitude;
if (a < modifyDist) modifyDist = a;
The value modifyDist seems to get assigned to 0 (modifyDist is a float), even thought the value of a is not zero. This is the only code in the script, so the problem must occur here.
The issue only happens on the two left side raycasts, with the right side working properly. The only difference between the two sides is the hClipOffset beings subtracted instead of added.
The small section of code right above returns valid numbers, but the assignation fails, for example this was debug logged directly after the if statement:
llHit.distance = 7.5116
llDir.magnitude = 10.15666
a = .73263
modifyDist = 0
I have no idea why modifyDist is being set equal to zero, or why it is only happening on the left side. Any help will be appreciated.
ok, but what is your question?
– SissoWhy is modifyDist registering as 0?
– aevalareOk, if it is zero, is because something assigned it. What is the exactly value of "a" (100 or 0.0000001) when this happens? What is the type of modifyDist?
– SissomodifyDist is a private float and until i started debugging it never left the scope of this method (this is all in a fixed update in a script, and is the only code in it). I have debugged logged "a" right before the assignment happens, and a decimal like .75321 is typical.
– aevalareSo here's one problem: if (Physics.Raycast(transform.position, ulDir, out ulHit, ulDir.magnitude)) { // check if it clips upper left edge float a = urHit.distance / ulDir.magnitude; //prevent penetration by pushing camera in if (a < modifyDist) modifyDist = a;// always use the closest collision } This is inconsistent, you are setting a to a combination of things from ur and ul.
– whydoidoit