Search Unity

Camera Controller Script

Discussion in 'AR/VR (XR) Discussion' started by LadyLegend, May 24, 2020.

  1. LadyLegend

    LadyLegend

    Joined:
    Oct 6, 2017
    Posts:
    50
    The blocking layer works to a certain point but the it still goes through the wall I tried every setting but it doesn't work properly. I also tried widening my player controller capsule and it worked but then its too big to walk up to things like a table to grab things off of it. Does anyone have any idea that could help me? I think maybe the script is resetting after a certain number but I don't know how I should change the script.

    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. namespace RootMotion {
    5.  
    6.     /// <summary>
    7.     /// 3rd person camera controller.
    8.     /// </summary>
    9.     public class CameraController : MonoBehaviour {
    10.  
    11.         // When to update the camera?
    12.         [System.Serializable]
    13.         public enum UpdateMode {
    14.             Update,
    15.             FixedUpdate,
    16.             LateUpdate,
    17.             FixedLateUpdate
    18.         }
    19.  
    20.         public Transform target; // The target Transform to follow
    21.         public Transform rotationSpace; // If assigned, will use this Transform's rotation as the rotation space instead of the world space. Useful with spherical planets.
    22.         public UpdateMode updateMode = UpdateMode.LateUpdate; // When to update the camera?
    23.         public bool lockCursor = true; // If true, the mouse will be locked to screen center and hidden
    24.  
    25.         [Header("Position")]
    26.         public bool smoothFollow; // If > 0, camera will smoothly interpolate towards the target
    27.         public Vector3 offset = new Vector3(0, 1.5f, 0.5f); // The offset from target relative to camera rotation
    28.         public float followSpeed = 10f; // Smooth follow speed
    29.  
    30.         [Header("Rotation")]
    31.         public float rotationSensitivity = 3.5f; // The sensitivity of rotation
    32.         public float yMinLimit = -20; // Min vertical angle
    33.         public float yMaxLimit = 80; // Max vertical angle
    34.         public bool rotateAlways = true; // Always rotate to mouse?
    35.         public bool rotateOnLeftButton; // Rotate to mouse when left button is pressed?
    36.         public bool rotateOnRightButton; // Rotate to mouse when right button is pressed?
    37.         public bool rotateOnMiddleButton; // Rotate to mouse when middle button is pressed?
    38.  
    39.         [Header("Distance")]
    40.         public float distance = 10.0f; // The current distance to target
    41.         public float minDistance = 4; // The minimum distance to target
    42.         public float maxDistance = 10; // The maximum distance to target
    43.         public float zoomSpeed = 10f; // The speed of interpolating the distance
    44.         public float zoomSensitivity = 1f; // The sensitivity of mouse zoom
    45.  
    46.         [Header("Blocking")]
    47.         public LayerMask blockingLayers;
    48.         public float blockingRadius = 1f;
    49.         public float blockingSmoothTime = 0.1f;
    50.         [Range(0f, 1f)] public float blockedOffset = 0.5f;
    51.  
    52.         public float x { get; private set; } // The current x rotation of the camera
    53.         public float y { get; private set; } // The current y rotation of the camera
    54.         public float distanceTarget { get; private set; } // Get/set distance
    55.  
    56.         private Vector3 targetDistance, position;
    57.         private Quaternion rotation = Quaternion.identity;
    58.         private Vector3 smoothPosition;
    59.         private Camera cam;
    60.         private bool fixedFrame;
    61.         private float fixedDeltaTime;
    62.         private Quaternion r = Quaternion.identity;
    63.         private Vector3 lastUp;
    64.         private float blockedDistance = 10f, blockedDistanceV;
    65.  
    66.         public void SetAngles(Quaternion rotation)
    67.         {
    68.             Vector3 euler = rotation.eulerAngles;
    69.             this.x = euler.y;
    70.             this.y = euler.x;
    71.         }
    72.  
    73.         public void SetAngles(float yaw, float pitch)
    74.         {
    75.             this.x = yaw;
    76.             this.y = pitch;
    77.         }
    78.  
    79.         // Initiate, set the params to the current transformation of the camera relative to the target
    80.         protected virtual void Awake () {
    81.             Vector3 angles = transform.eulerAngles;
    82.             x = angles.y;
    83.             y = angles.x;
    84.            
    85.             distanceTarget = distance;
    86.             smoothPosition = transform.position;
    87.  
    88.             cam = GetComponent<Camera>();
    89.  
    90.             lastUp = rotationSpace != null? rotationSpace.up: Vector3.up;
    91.         }
    92.  
    93.         protected virtual void Update() {
    94.             if (updateMode == UpdateMode.Update) UpdateTransform();
    95.         }
    96.  
    97.         protected virtual void FixedUpdate() {
    98.             fixedFrame = true;
    99.             fixedDeltaTime += Time.deltaTime;
    100.             if (updateMode == UpdateMode.FixedUpdate) UpdateTransform();
    101.         }
    102.  
    103.         protected virtual void LateUpdate() {
    104.             UpdateInput();
    105.  
    106.             if (updateMode == UpdateMode.LateUpdate) UpdateTransform();
    107.  
    108.             if (updateMode == UpdateMode.FixedLateUpdate && fixedFrame) {
    109.                 UpdateTransform(fixedDeltaTime);
    110.                 fixedDeltaTime = 0f;
    111.                 fixedFrame = false;
    112.             }
    113.         }
    114.  
    115.         // Read the user input
    116.         public void UpdateInput() {
    117.             if (!cam.enabled) return;
    118.  
    119.             // Cursors
    120.             Cursor.lockState = lockCursor? CursorLockMode.Locked: CursorLockMode.None;
    121.             Cursor.visible = lockCursor? false: true;
    122.  
    123.             // Should we rotate the camera?
    124.             bool rotate = rotateAlways || (rotateOnLeftButton && Input.GetMouseButton(0)) || (rotateOnRightButton && Input.GetMouseButton(1)) || (rotateOnMiddleButton && Input.GetMouseButton(2));
    125.  
    126.             // delta rotation
    127.             if (rotate) {
    128.                 x += Input.GetAxis("Mouse X") * rotationSensitivity;
    129.                 y = ClampAngle(y - Input.GetAxis("Mouse Y") * rotationSensitivity, yMinLimit, yMaxLimit);
    130.             }
    131.  
    132.             // Distance
    133.             distanceTarget = Mathf.Clamp(distanceTarget + zoomAdd, minDistance, maxDistance);
    134.         }
    135.  
    136.         // Update the camera transform
    137.         public void UpdateTransform() {
    138.             UpdateTransform(Time.deltaTime);
    139.         }
    140.  
    141.         public void UpdateTransform(float deltaTime) {
    142.             if (!cam.enabled) return;
    143.            
    144.             // Rotation
    145.             rotation = Quaternion.AngleAxis(x, Vector3.up) * Quaternion.AngleAxis(y, Vector3.right);
    146.  
    147.             if (rotationSpace != null) {
    148.                 r = Quaternion.FromToRotation(lastUp, rotationSpace.up) * r;
    149.                 rotation = r * rotation;
    150.  
    151.                 lastUp = rotationSpace.up;
    152.  
    153.             }
    154.  
    155.             if (target != null) {
    156.                 // Distance
    157.                 distance += (distanceTarget - distance) * zoomSpeed * deltaTime;
    158.  
    159.                 // Smooth follow
    160.                 if (!smoothFollow) smoothPosition = target.position;
    161.                 else smoothPosition = Vector3.Lerp(smoothPosition, target.position, deltaTime * followSpeed);
    162.  
    163.                 // Position
    164.                 Vector3 t = smoothPosition + rotation * offset;
    165.                 Vector3 f = rotation * -Vector3.forward;
    166.  
    167.                 if (blockingLayers != -1) {
    168.                     RaycastHit hit;
    169.                     if (Physics.SphereCast (t, blockingRadius, f, out hit, distanceTarget - blockingRadius, blockingLayers)) {
    170.                         //distance = hit.distance;
    171.                         blockedDistance = Mathf.SmoothDamp(blockedDistance, hit.distance + blockingRadius * (1f - blockedOffset), ref blockedDistanceV, blockingSmoothTime);
    172.                     } else blockedDistance = distanceTarget;
    173.  
    174.                     distance = Mathf.Min(distance, blockedDistance);
    175.                 }
    176.  
    177.                 position = t + f * distance;
    178.  
    179.                 // Translating the camera
    180.                 transform.position = position;
    181.             }
    182.  
    183.             transform.rotation = rotation;
    184.         }
    185.  
    186.         // Zoom input
    187.         private float zoomAdd {
    188.             get {
    189.                 float scrollAxis = Input.GetAxis("Mouse ScrollWheel");
    190.                 if (scrollAxis > 0) return -zoomSensitivity;
    191.                 if (scrollAxis < 0) return zoomSensitivity;
    192.                 return 0;
    193.             }
    194.         }
    195.  
    196.         // Clamping Euler angles
    197.         private float ClampAngle (float angle, float min, float max) {
    198.             if (angle < -360) angle += 360;
    199.             if (angle > 360) angle -= 360;
    200.             return Mathf.Clamp (angle, min, max);
    201.         }
    202.        
    203.     }
    204. }
     
    Last edited: May 24, 2020
  2. arfish

    arfish

    Joined:
    Jan 28, 2017
    Posts:
    782
    Hi,

    Perhaps it´s just the Clipping Planes settings for the camera having a to high Near value?
    Have you searched for "unity clipping through walls"?
     
    Last edited: May 28, 2020
  3. LadyLegend

    LadyLegend

    Joined:
    Oct 6, 2017
    Posts:
    50
    I just realized this isn't an oculus script but root motion final IK script I apologize I ask the creator about it yesterday. Nothing yet but the clipping planes have no effect. In playmode you can see the clipping plane and the camera position. the clipping panel never reaches the wall and the camera gets block all the way up until I am up against the wall. I tries putting the clipping near all the way down and up no effect on it :(
     
  4. arfish

    arfish

    Joined:
    Jan 28, 2017
    Posts:
    782
    So its not clipping in Editor, only in builds?
    Perhaps you could use a ray to log the distance from the camera to the wall, to see if they differ.
     
  5. LadyLegend

    LadyLegend

    Joined:
    Oct 6, 2017
    Posts:
    50
    It's going through walls in both play mode and when I build. I was thinking about doing the raycast but then I cant use this script which in turns effect another script and it's a domino effect. I'd have to make new scripts for more than this camera. Alas I'll just wait to hear from the creator if nothing then yup I will to the raycast but it seem he uses raycastimg in the script already it just taps out when I'm up against the wall. I hope it's just his script and nothing else so when I do make my own third person camera it wont just do the same thing.
     
  6. arfish

    arfish

    Joined:
    Jan 28, 2017
    Posts:
    782
    Ok, if the part of the player containing the camera actually is going through walls, I guess that what needs to be addressed.
     
  7. LadyLegend

    LadyLegend

    Joined:
    Oct 6, 2017
    Posts:
    50
    The camera gets blocked up to this point. See below the clipping plane is still in front of my guy.

    Screen Shot 2020-05-28 at 4.12.42 PM.png The parent game object that I selected never moves from the center of the room. See below the gizmo is in the center of the room and my guy is up against the wall. Below the game object is the camera you see behind him. The camera somehow slipped through the wall :( Screen Shot 2020-05-28 at 4.14.12 PM.png

    The part of the code that has a raycast in it is this part

    Code (CSharp):
    1.  if (target != null) {
    2.                 // Distance
    3.                 distance += (distanceTarget - distance) * zoomSpeed * deltaTime;
    4.                 // Smooth follow
    5.                 if (!smoothFollow) smoothPosition = target.position;
    6.                 else smoothPosition = Vector3.Lerp(smoothPosition, target.position, deltaTime * followSpeed);
    7.                 // Position
    8.                 Vector3 t = smoothPosition + rotation * offset;
    9.                 Vector3 f = rotation * -Vector3.forward;
    10.                 if (blockingLayers != -1) {
    11.                     RaycastHit hit;
    12.                     if (Physics.SphereCast (t, blockingRadius, f, out hit, distanceTarget - blockingRadius, blockingLayers)) {
    13.                         //distance = hit.distance;
    14.                         blockedDistance = Mathf.SmoothDamp(blockedDistance, hit.distance + blockingRadius * (1f - blockedOffset), ref blockedDistanceV, blockingSmoothTime);
    15.                     } else blockedDistance = distanceTarget;
    16.                     distance = Mathf.Min(distance, blockedDistance);
    17.                 }
    18.                 position = t + f * distance;
    19.                 // Translating the camera
    20.                 transform.position = position;
    21.             }
    22.             transform.rotation = rotation;
    23.         }
    24.  
    For some reason it gives out but why and where? And If I do a recast would it do the same thing? wouldn't my raycast script be pretty much the same? Do I need thicker walls? I can
     
    Last edited: May 28, 2020
  8. arfish

    arfish

    Joined:
    Jan 28, 2017
    Posts:
    782
    Ohh, you have a third person camera, looking at the player from outside.
    If the walls are single sided, they should be transparent for the camera when looking through them from behind.

    Another solution I think may be to move the camera not just relative to the player, but also make it avoid the walls. Perhaps by moving it closer to the player, or looking at the player from the side.
     
  9. LadyLegend

    LadyLegend

    Joined:
    Oct 6, 2017
    Posts:
    50
    What do you mean by single sided? Like there's no room on the other side?

    The other solution I think will make controlling the character feel weird like if your viewing the player from the side you would have to press forward/up if your back is facing the wall to move away from the wall when naturally you'd press right or left to move away from the wall because of the view. Even if I could somehow change the directional input which seems like it'll involve more than just altering the code to stop the camera at that breaking point what ever it is and that's what I can't figure out. Where in the code is that breaking point.
     
  10. arfish

    arfish

    Joined:
    Jan 28, 2017
    Posts:
    782
    Yeah, the most natural behaviour for the camera is probably to stop when the camera hits the wall, and let the player move closer to it. The camera usually floats above, so it shouldn't hit the player.

    Other option is to hide any obstacles like the walls between the camera and the player, or make the walls invisible colliders thicker when the player is facing from them so the player cant back up to far, pushing the camera though the wall.
     
  11. LadyLegend

    LadyLegend

    Joined:
    Oct 6, 2017
    Posts:
    50
    I dont think I can make the invisible collider larger because I made the model in blender and generated a mesh in unity but even if I could make it bigger you think that can stop making the camera break through it? I think I did try that but I cant remember at this point because I left the problem where it is and continued working on other things. The creator said it was just a demo and that there are better scripts out there but I'm using another one of his scripts that require that particular camera controller and I tried other camera controlls and the character becomes jittery and that's a whole other bag smh. so I'm waiting on a response on that I hope he understands and looks over his code felt like he doesn't want to review it. Understandably so it's not what his asset is about but here's hoping!