Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Camera and player collision issue.

Discussion in 'Scripting' started by Musty, Jun 18, 2014.

  1. Musty

    Musty

    Joined:
    Jul 1, 2013
    Posts:
    31
    hey guys ive got a 3rd person camera, but everytime I back into a wall the camera goes crazy and the player rotates like crazy, The camera has collision so it doesn't go through walls but when it goes too close to the player it goes crazy, It rotates the player like craz, and the camera shakes aswell i think.

    The code where the player is rotated happens here:

    Code (CSharp):
    1. void SnapAlignCharacterWithCamera()
    2.         {
    3.             if(MoveVector.x !=0 || MoveVector.z !=0)
    4.             {
    5.                 transform.rotation = Quaternion.Euler(transform.eulerAngles.x, Camera.mainCamera.transform.eulerAngles.y, transform.eulerAngles.z);
    6.             }


    The code for camera where it gets too close here:

    Code (CSharp):
    1. bool CheckIfOccluded (int count)
    2.         {
    3.             var isOccluded = false;
    4.  
    5.             var nearestDistance = CheckCameraPoints(TargetLookAt.position, desiredPosition);
    6.  
    7.             if(nearestDistance != -1)
    8.             {
    9.                 if(count < MaxOcclusionChecks)
    10.                 {
    11.                     isOccluded = true;
    12.                     Distance -= OcclusionDistanceStep;
    13.  
    14.                     if(Distance < 0.25f)
    15.                         Distance = 0.25f;
    16.                      
    17.                 }
    18.                 else
    19.                     Distance = nearestDistance - Camera.mainCamera.nearClipPlane;
    20.  
    21.                 desiredDistance = Distance;
    22.                 distanceSmooth = DistanceResumeSmooth;
    23.             }
    24.  
    25.  
    26.             return isOccluded;
    27.         }

    The video of what happens is here
    This is slow because of the frame rate, it happens really fast in unity.



    The full code here just incase, i didnt want to put a block of code here:
    http://pastebin.com/kEZQV2m7

    Thanks in advance any help would be appreciated.
     
  2. Rutenis

    Rutenis

    Joined:
    Aug 7, 2013
    Posts:
    297

    Have you tried setting the camera's collider to be triggered?
     
  3. Musty

    Musty

    Joined:
    Jul 1, 2013
    Posts:
    31
    sorry i dont understand what you mean?
     
  4. Rutenis

    Rutenis

    Joined:
    Aug 7, 2013
    Posts:
    297
    You said your camera has a collider attached to it, right? If you did, then open your camera in the inspector and set the Cameras Collider to be Trigger, check the little box next to the word "Is Trigger"
     
  5. Musty

    Musty

    Joined:
    Jul 1, 2013
    Posts:
    31
    Sorry no the camera doesn't have a collider, the collison is done through code, infact its doing a line cast and if its some thing thats not the player if zooms in
     
  6. Magiichan

    Magiichan

    Joined:
    Jan 5, 2014
    Posts:
    403
    Then why is the camera shaking?
     
  7. Musty

    Musty

    Joined:
    Jul 1, 2013
    Posts:
    31
    Whats happening is the camera is following an empty game object, the game object is inside the players head. The way the player rotates is it snaps to where the camera is facing when you move so whats happening is the camera gets too close to the player and it keeps rotation to face whre the camera is facing or thinks its facing. When I change the lookat game objects position it gets worse
     
  8. A.Killingbeck

    A.Killingbeck

    Joined:
    Feb 21, 2014
    Posts:
    483
    If you're trying to make the camera not clip through walls, the usual approach is to cast a ray from the player to the camera, if a hit collision occurs in that range, you would translate the camera to that hit point.
     
  9. Musty

    Musty

    Joined:
    Jul 1, 2013
    Posts:
    31
    Yea thats what in doing and it works only thing is it gets too close to the player
     
  10. A.Killingbeck

    A.Killingbeck

    Joined:
    Feb 21, 2014
    Posts:
    483
    That doesn't sound like what I suggested
     
  11. Musty

    Musty

    Joined:
    Jul 1, 2013
    Posts:
    31
    Sorry i worded it wrong, it doesnt have collision.

    This is the code for camera

    TP_Camera.cs

    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. public class TP_Camera : MonoBehaviour
    5. {
    6.     public static TP_Camera Instance;
    7.     public Transform TargetLookAt;
    8.     public float Distance = 8f;
    9.     public float DistanceMin = 4f;
    10.     public float DistanceMax = 16f;
    11.     public float DistanceSmooth = 0.05f;
    12.     public float DistanceResumeSmooth = 1f;
    13.     public float X_MouseSensivity = 5f;
    14.     public float Y_MouseSensivity = 5f;
    15.     public float MouseWheelSensivity = 5f;
    16.     public float X_Smooth = 0.05f;
    17.     public float Y_Smooth = 0.1f;
    18.     public float Y_MinLimit = -40f;
    19.     public float Y_MaxLimit = 80f;
    20.     public float OcclusionDistanceStep = 0.5f;
    21.     public int MaxOcclusionChecks = 10;
    22.  
    23.  
    24.     private float mouseX = 0f;
    25.     private float mouseY = 0f;
    26.     private float velX = 0f;
    27.     private float velY = 0f;
    28.     private float velZ = 0f;
    29.     private float velDistance = 0f;
    30.     private float startDistance = 0f;
    31.     private float  desiredDistance = 0f;
    32.     private Vector3 desiredPosition = Vector3.zero;
    33.     private Vector3 position = Vector3.zero;
    34.     private float distanceSmooth = 0f;
    35.     private float preOccludedDistance  = 0f;
    36.  
    37.     void Awake()
    38.     {
    39.         Instance = this;
    40.     }
    41.  
    42.     void Start()
    43.     {
    44.         Distance = Mathf.Clamp(Distance, DistanceMin, DistanceMax);
    45.         startDistance = Distance;
    46.         Reset();
    47.     }
    48.  
    49.     void LateUpdate()
    50.     {
    51.         if (TargetLookAt == null)
    52.             return;
    53.         HandlePlayerInput();
    54.  
    55.         var count = 0;
    56.         do
    57.         {
    58.             CalculateDesiredPosition();
    59.             count++;
    60.         }while (CheckIfOccluded(count));
    61.  
    62.  
    63.  
    64.         CheckCameraPoints(TargetLookAt.position, desiredPosition);
    65.  
    66.         UpdatePosition();
    67.     }
    68.  
    69.     void HandlePlayerInput()
    70.     {
    71.         var deadZone  = 0.01f;
    72.         if(Input.GetMouseButton(1))
    73.         {
    74.             mouseX += Input.GetAxis("Mouse X") * X_MouseSensivity;
    75.             mouseY -= Input.GetAxis("Mouse Y") * Y_MouseSensivity;
    76.         }
    77.  
    78.         mouseY = Helper.ClampAngle(mouseY, Y_MinLimit, Y_MaxLimit);
    79.  
    80.  
    81.         if (Input.GetAxis("Mouse ScrollWheel") < -deadZone || Input.GetAxis("Mouse ScrollWheel") > deadZone)
    82.         {
    83.             desiredDistance = Mathf.Clamp(Distance - Input.GetAxis("Mouse ScrollWheel") * MouseWheelSensivity, DistanceMin, DistanceMax);
    84.             preOccludedDistance = desiredDistance;
    85.             distanceSmooth = DistanceSmooth;
    86.         }
    87.     }
    88.  
    89.     void CalculateDesiredPosition()
    90.     {
    91.         resetDesiredDistance();
    92.         Distance = Mathf.SmoothDamp(Distance, desiredDistance, ref velDistance, distanceSmooth);
    93.  
    94.         desiredPosition = CalculatePosition(mouseY, mouseX, Distance);
    95.  
    96.  
    97.     }
    98.     Vector3 CalculatePosition(float rotationX, float rotationY, float distance)
    99.     {
    100.         Vector3 direction = new Vector3(0,0, -distance);
    101.         Quaternion rotation = Quaternion.Euler(rotationX, rotationY, 0);
    102.         return TargetLookAt.position + rotation * direction;
    103.     }
    104.  
    105.     bool CheckIfOccluded (int count)
    106.     {
    107.         var isOccluded = false;
    108.  
    109.         var nearestDistance = CheckCameraPoints(TargetLookAt.position, desiredPosition);
    110.  
    111.         if(nearestDistance != -1)
    112.         {
    113.             if(count < MaxOcclusionChecks)
    114.             {
    115.                 isOccluded = true;
    116.                 Distance -= OcclusionDistanceStep;
    117.  
    118.                 if(Distance < 0.25f)
    119.                     Distance = 0.25f;
    120.                    
    121.             }
    122.             else
    123.                 Distance = nearestDistance - Camera.mainCamera.nearClipPlane;
    124.  
    125.             desiredDistance = Distance;
    126.             distanceSmooth = DistanceResumeSmooth;
    127.         }
    128.  
    129.  
    130.         return isOccluded;
    131.     }
    132.  
    133.  
    134.     float CheckCameraPoints(Vector3 from, Vector3 to)
    135.     {
    136.         var nearestDistance = -1f;
    137.  
    138.         RaycastHit hitInfo;
    139.  
    140.         Helper.ClipPlanePoints clipPlanePoints = Helper.ClipPlaneAtNear(to);
    141.  
    142.         Debug.DrawLine(from, to + transform.forward * -camera.nearClipPlane, Color.red);
    143.         Debug.DrawLine(from, clipPlanePoints.UpperLeft);
    144.         Debug.DrawLine(from, clipPlanePoints.LowerLeft);
    145.         Debug.DrawLine(from, clipPlanePoints.UpperRight);
    146.         Debug.DrawLine(from, clipPlanePoints.LowerRight);
    147.  
    148.         Debug.DrawLine(clipPlanePoints.UpperLeft, clipPlanePoints.UpperRight);
    149.         Debug.DrawLine(clipPlanePoints.UpperRight, clipPlanePoints.LowerRight);
    150.         Debug.DrawLine(clipPlanePoints.LowerRight, clipPlanePoints.LowerLeft);
    151.         Debug.DrawLine(clipPlanePoints.LowerLeft, clipPlanePoints.UpperLeft);
    152.  
    153.         if(Physics.Linecast(from, clipPlanePoints.UpperLeft, out hitInfo)&& hitInfo.collider.tag != "Player")
    154.             nearestDistance = hitInfo.distance;
    155.  
    156.         if(Physics.Linecast(from, clipPlanePoints.LowerLeft, out hitInfo)&& hitInfo.collider.tag != "Player")
    157.             if(hitInfo.distance < nearestDistance || nearestDistance == -1)
    158.                 nearestDistance = hitInfo.distance;
    159.  
    160.         if(Physics.Linecast(from, clipPlanePoints.UpperRight, out hitInfo)&& hitInfo.collider.tag != "Player")
    161.             if(hitInfo.distance < nearestDistance || nearestDistance == -1)
    162.                 nearestDistance = hitInfo.distance;
    163.  
    164.         if(Physics.Linecast(from, clipPlanePoints.LowerRight, out hitInfo)&& hitInfo.collider.tag != "Player")
    165.             if(hitInfo.distance < nearestDistance || nearestDistance == -1)
    166.                 nearestDistance = hitInfo.distance;
    167.         if(Physics.Linecast(from, to + transform.forward * -camera.nearClipPlane, out hitInfo)&& hitInfo.collider.tag != "Player")
    168.             if(hitInfo.distance < nearestDistance || nearestDistance == -1)
    169.                 nearestDistance = hitInfo.distance;
    170.  
    171.         return nearestDistance;
    172.     }
    173.  
    174.     void resetDesiredDistance()
    175.     {
    176.         if(desiredDistance < preOccludedDistance)
    177.         {
    178.             var pos = CalculatePosition(mouseY, mouseX, preOccludedDistance);
    179.  
    180.             var nearestDisance = CheckCameraPoints(TargetLookAt.position, pos);
    181.  
    182.             if(nearestDisance  ==  -1  || nearestDisance > preOccludedDistance)
    183.             {
    184.                 desiredDistance = preOccludedDistance;
    185.             }
    186.         }
    187.     }
    188.  
    189.  
    190.  
    191.  
    192.  
    193.  
    194.     void UpdatePosition()
    195.     {
    196.         var posX = Mathf.SmoothDamp(position.x, desiredPosition.x, ref velX, X_Smooth);
    197.         var posY = Mathf.SmoothDamp(position.y, desiredPosition.y, ref velY, Y_Smooth);
    198.         var posZ = Mathf.SmoothDamp(position.z, desiredPosition.z, ref velZ, X_Smooth);
    199.         position = new Vector3(posX, posY, posZ);
    200.  
    201.         transform.position = position;
    202.  
    203.         transform.LookAt(TargetLookAt);
    204.     }
    205.  
    206.     public void Reset()
    207.     {
    208.         mouseX = 0;
    209.         mouseY = 10;
    210.         Distance = startDistance;
    211.         desiredDistance = Distance;
    212.         preOccludedDistance = Distance;
    213.        
    214.     }
    215.  
    216.     public static void UseExistingOrCreateNewMainCamera()
    217.     {
    218.         GameObject tempCamera;
    219.         GameObject targetLookAt;
    220.         TP_Camera myCamera;
    221.  
    222.         if(Camera.mainCamera != null)
    223.         {
    224.             tempCamera = Camera.mainCamera.gameObject;
    225.         }
    226.         else
    227.         {
    228.             tempCamera = new GameObject ("Main Camera");
    229.             tempCamera.AddComponent("Camera");
    230.             tempCamera.tag  = "MainCamera";
    231.         }
    232.         tempCamera.AddComponent("TP_Camera");
    233.         myCamera = tempCamera.GetComponent("TP_Camera") as TP_Camera;
    234.         targetLookAt = GameObject.Find("targetLookAt") as GameObject;
    235.         if (targetLookAt == null)
    236.         {
    237.             targetLookAt = new GameObject ("targetLookAt");
    238.             targetLookAt.transform.position = Vector3.zero;
    239.         }
    240.         myCamera.TargetLookAt = targetLookAt.transform;
    241.     }
    242. }
    243.  
    Helper.cs:

    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. public static class Helper
    5. {
    6.     public struct ClipPlanePoints
    7.     {
    8.         public Vector3 UpperLeft;
    9.         public Vector3 UpperRight;
    10.         public Vector3 LowerLeft;
    11.         public Vector3 LowerRight;
    12.     }
    13.  
    14.     public static float ClampAngle(float angle, float min, float max)
    15.     {
    16.         do
    17.         {
    18.             if(angle <  -360)
    19.                 angle +=  360;
    20.             if(angle > 360)
    21.                 angle  -=  360;
    22.  
    23.         } while (angle < -360 || angle > 360);
    24.  
    25.         return Mathf.Clamp(angle, min, max);
    26.     }
    27.  
    28.     public static ClipPlanePoints ClipPlaneAtNear(Vector3 pos)
    29.     {
    30.         var clipPlanePoints = new ClipPlanePoints();
    31.  
    32.         if(Camera.mainCamera ==null)
    33.             return clipPlanePoints;
    34.  
    35.         var transform = Camera.mainCamera.transform;
    36.         var halfFOV  = (Camera.mainCamera.fieldOfView /2) * Mathf.Deg2Rad;
    37.         var aspect = Camera.mainCamera.aspect;
    38.         var distance = Camera.mainCamera.nearClipPlane;
    39.         var height = distance * Mathf.Tan(halfFOV);
    40.         var width = height * aspect;
    41.  
    42.         clipPlanePoints.LowerRight = pos + transform.right * width;
    43.         clipPlanePoints.LowerRight -= transform.up * height;
    44.         clipPlanePoints.LowerRight += transform.forward * distance;
    45.  
    46.         clipPlanePoints.LowerLeft = pos - transform.right * width;
    47.         clipPlanePoints.LowerLeft -= transform.up * height;
    48.         clipPlanePoints.LowerLeft += transform.forward * distance;
    49.  
    50.         clipPlanePoints.UpperRight = pos + transform.right * width;
    51.         clipPlanePoints.UpperRight += transform.up * height;
    52.         clipPlanePoints.UpperRight += transform.forward * distance;
    53.  
    54.         clipPlanePoints.UpperLeft = pos - transform.right * width;
    55.         clipPlanePoints.UpperLeft += transform.up * height;
    56.         clipPlanePoints.UpperLeft += transform.forward * distance;
    57.  
    58.         return clipPlanePoints;
    59.     }
    60.  
    61. }
    62.