Search Unity

(Solved)Raycast for camera collision (move closer to player when wall detected)

Discussion in 'Scripting' started by tijanikun, Aug 21, 2019.

  1. tijanikun

    tijanikun

    Joined:
    Aug 10, 2017
    Posts:
    129
    Hello,
    Im facing a problem with my code, how it works at this moment:

    Im using a raycast from player to camera, when a wall hit the raycast, i change the distance of the camera by -0.2f, if no wall is detected i change the distance by +0.2f (check scripts
    Code (CSharp):
    1.  RaycastHit CameraRaycast;
    2.             Ray CameraRay = new Ray(transform.position, CameraSensivity.transform.position - transform.position);
    3.             Debug.DrawRay(transform.position, CameraSensivity.transform.position - transform.position);
    4.             if (Physics.Raycast(CameraRay, out CameraRaycast, RayFloat1))
    5.             {
    6.                 if (CameraRaycast.collider.tag != "Player" && CameraRaycast.collider.tag != "Head")
    7.                 {
    8.                     CameraSensivity.GetComponent<ThirdPersonCamera>().distance -= 0.2f;
    9.                     RayFloat1 -= 0.2f;
    10.                 }
    11.             }
    12.             else
    13.             {
    14.                 if (!Physics.Raycast(CameraRay, out CameraRaycast, RayFloat1 + 0.2f))
    15.                 {
    16.                  
    17.                         CameraSensivity.GetComponent<ThirdPersonCamera>().distance += 0.2f;
    18.                         RayFloat1 += 0.2f;
    19.                    
    20.                 }
    21.             }
    22.         }
    It works quite well but there is a weird loop ( -0.2f > +0.2f > -0.2f > +0.2f > .....) that make the camera shaking when i hit the wall in some direction (check screenshot), it's very unpleasant

    These angle are working: upload_2019-8-21_18-35-56.png
    upload_2019-8-21_18-34-15.png
    And this one is shaking:
    upload_2019-8-21_18-36-21.png
    upload_2019-8-21_18-34-24.png

    Im working on it since hours, i really need your help please
     

    Attached Files:

  2. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    38,745
    This is most like hysteresis: the camera moves closer, sees the player, then moves back, then can't see the player, lather rinse repeat.

    You can handle it a couple of ways.

    The most straightforward way is to check a second time from the new position before accepting the new distance. This means, if I can see the player, recheck from the place you intend to pull back to, and if you CANNOT see him from that further back place, stay where you're at for now.

    Another way is to apply a low-pass filter to the distance output so that it tweens more slowly and doesn't jerk back and forth. This may change the smoothness of the dollying in either pleasant or unpleasant ways.

    ANOTHER option if you're feeling brave is to install Unity's Cinemachine because I am pretty sure they have routines to handle this type of thing, but I haven't checked specifically and have not used that API much at all.
     
    tijanikun likes this.
  3. tijanikun

    tijanikun

    Joined:
    Aug 10, 2017
    Posts:
    129
    You 2nd solution is quite good, i smoothed the value so it's not unpleasant
    (I made a new float and smoothed the value)
    distance3 = Mathf.SmoothDamp(distance3, distance, ref yVelocity, 0.1f);

    Code (CSharp):
    1.  
    2.             RaycastHit CameraRaycast;
    3.             Ray CameraRay = new Ray(transform.position, CameraSensivity.transform.position - transform.position);
    4.             Debug.DrawRay(transform.position, CameraSensivity.transform.position - transform.position);
    5.             if (Physics.Raycast(CameraRay, out CameraRaycast, RayFloat1))
    6.             {
    7.                 if (CameraRaycast.collider.tag != "Player" && CameraRaycast.collider.tag != "Head")
    8.                 {
    9.                     CameraSensivity.GetComponent<ThirdPersonCamera>().distance -= 0.2f;
    10.                     RayFloat1 -= 0.2f;
    11.                 }
    12.             }
    13.             else
    14.             {
    15.                 if (!Physics.Raycast(CameraRay, out CameraRaycast, RayFloat1 + 0.2f))
    16.                 {
    17.                  
    18.                         RayFloat1 += 0.2f;
    19.                     if (!Physics.Raycast(CameraRay, out CameraRaycast, RayFloat1 + 0.2f))
    20.                     {
    21.                         CameraSensivity.GetComponent<ThirdPersonCamera>().distance += 0.2f;
    22.                     }
    23.                     else
    24.                     {
    25.                         RayFloat1 -= 0.2f;
    26.                     }
    27.  
    28.                 }
    29.             }
    Is it what you are explaining me?

    Code (CSharp):
    1.  if (Physics.Raycast(CameraRay, out CameraRaycast, RayFloat1))
    2.             {
    3.                 if (CameraRaycast.collider.tag != "Player" && CameraRaycast.collider.tag != "Head")
    4.                 {
    5.                     CameraSensivity.GetComponent<ThirdPersonCamera>().distance -= 0.2f;
    6.                     RayFloat1 -= 0.2f;
    7.                 }
    8.             }
    9.             else
    10.             {
    11.                 if (!Physics.Raycast(CameraRay, out CameraRaycast, RayFloat1 + 0.2f))
    12.                 {
    13.  
    14.                     CameraSensivity.GetComponent<ThirdPersonCamera>().distance += Mathf.SmoothDamp(CameraSensivity.GetComponent<ThirdPersonCamera>().distance, CameraSensivity.GetComponent<ThirdPersonCamera>().distance + 0.2f, ref yVelocity, 0.1f);
    15.                         RayFloat1 += 0.2f;
    16.                    
    17.                 }
    18.             }
    I also tried that, it doesn't shake but most of time the camera stay behind wall

    Anyway the actual solution is good enought, as always this forum is sweet, thank you Kurt
     
    Kurt-Dekker likes this.
  4. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    38,745
    You're welcome! Camera behavior is one of the trickiest things to "get right." I'm happy it worked out for you!