title: 3rd Person Camera Clipping Walls in Unity
body: <p>In Unity I am creating a 3rd person game with the camera following the player, while also being able to rotate on its own. Right now when I rotate the camera and there's a wall, the camera seems to go through the wall.</p>
  <p>I have tried adding a sphere collider and a rigidbody to the camera, but that did not help. I also created an empty GameObject with a sphere collider as the parent and making the camera a child. I also tried creating an empty child with a sphere collider.</p>
  <p>I have attached a video of the situation along with my code for  the camera script. The shadow in the photo is actually the wall that my camera is going through. <a href="https://imgur.com/a/WpqJMn9" rel="nofollow noreferrer">Video of wall clipping.</a> Any suggestions of how to fix this? Thanks!</p>
  <pre><code>public class OrbitCamera : MonoBehaviour
  {
  [SerializeField] private Transform target;
  public float rotSpeed = 1.5f;
  private float vertRotY;
  private float horiRotX;
  private Vector3 offSet;
  
  // Start is called before the first frame update
  void Start()
  {
      vertRotY = transform.eulerAngles.y;
      offSet = target.position - transform.position;
  }
  
  void FixedUpdate()
  {
      RaycastHit hit;
      
  
      if (Physics.Raycast(transform.position, Vector3.forward, out hit, 100f))
      {
  
      }
  }
  
  private void OnTriggerEnter(Collider other)
  {
      if (other.tag == &quot;Wall&quot;)
      {
          print(&quot;touching wall&quot;);
      }
  }
  
  // Update is called once per frame
  void LateUpdate()
  {
      float horiInput = Input.GetAxisRaw(&quot;Horizontal&quot;);
      float vertInput = Input.GetAxisRaw(&quot;Vertical&quot;);
      if (horiInput != 0)
      {
          vertRotY += horiInput * rotSpeed;
          
      }
      else
      {
          vertRotY += Input.GetAxis(&quot;Mouse X&quot;) * rotSpeed * 3;
  
      }
  
      if (vertInput == 0)
      {
          horiRotX += Input.GetAxis(&quot;Mouse Y&quot;) * rotSpeed * 3;
          horiRotX = Mathf.Clamp(horiRotX, -45f, 20f);
      }
  
      Quaternion rotation = Quaternion.Euler(-horiRotX, vertRotY, 0);
      transform.position = target.position - (rotation * offSet);
      
      //transform.Rotate(rotation.eulerAngles);
      transform.LookAt(target);
      //transform.RotateAround(target.transform.position, Vector3.up, vertRotY);
      //transform.RotateAround(target.transform.position, Vector3.left, rotSpeed * 3);
  }
  </code></pre>
  <p>}</p>
  <p>Here is my player movement script:</p>
  <pre><code>public class RelativeMovement : MonoBehaviour {
  [SerializeField] private Transform target;
  
  public float moveSpeed = 6.0f;
  public float rotSpeed = 15.0f;
  public float jumpSpeed = 15.0f;
  public float gravity = -9.8f;
  public float terminalVelocity = -20.0f;
  public float minFall = -1.5f;
  
  private float _vertSpeed;
  private ControllerColliderHit _contact;
  
  private CharacterController _charController;
  private Animator _animator;
  
  
  //Physics force
  public float pushForce = 3.0f;
  
  // Use this for initialization
  void Start() {
      _vertSpeed = minFall;
  
      _charController = GetComponent&lt;CharacterController&gt;();
      _animator = GetComponent&lt;Animator&gt;();
  }
  
  // Update is called once per frame
  void Update() {
  
      
  
      // start with zero and add movement components progressively
      Vector3 movement = Vector3.zero;
  
      // x z movement transformed relative to target
      float horInput = Input.GetAxis(&quot;Horizontal&quot;);
      float vertInput = Input.GetAxis(&quot;Vertical&quot;);
      if (horInput != 0 || vertInput != 0) {
          movement.x = horInput * moveSpeed;
          movement.z = vertInput * moveSpeed;
          movement = Vector3.ClampMagnitude(movement, moveSpeed);
  
          Quaternion tmp = target.rotation;
          target.eulerAngles = new Vector3(0, target.eulerAngles.y, 0);
          movement = target.TransformDirection(movement);
          target.rotation = tmp;
  
          // face movement direction
          //transform.rotation = Quaternion.LookRotation(movement);
          Quaternion direction = Quaternion.LookRotation(movement);
          transform.rotation = Quaternion.Slerp(transform.rotation, direction, rotSpeed * Time.deltaTime);
  
          _animator.SetBool(&quot;isRunning&quot;, true);
          
         
      }
      else
      {
          _animator.SetBool(&quot;isRunning&quot;, false);
      }
      //_animator.SetFloat(&quot;Speed&quot;, movement.sqrMagnitude);
  
  
      // raycast down to address steep slopes and dropoff edge
      bool hitGround = false;
      RaycastHit hit;
      if (_vertSpeed &lt; 0 &amp;&amp; Physics.Raycast(transform.position, Vector3.down, out hit)) {
          float check = (_charController.height + _charController.radius) / 1.9f;
          hitGround = hit.distance &lt;= check;  // to be sure check slightly beyond bottom of capsule
      }
  
      // y movement: possibly jump impulse up, always accel down
      // could _charController.isGrounded instead, but then cannot workaround dropoff edge
      if (hitGround) {
          if (Input.GetButtonDown(&quot;Jump&quot;)) {
              _vertSpeed = jumpSpeed;
          } else {
              _vertSpeed = minFall;
              _animator.SetBool(&quot;isJumping&quot;, false);
          }
      } else {
          _vertSpeed += gravity * 5 * Time.deltaTime;
          if (_vertSpeed &lt; terminalVelocity) {
              _vertSpeed = terminalVelocity;
          }
          if (_contact != null ) {    // not right at level start
              _animator.SetBool(&quot;isJumping&quot;, true);
          }
  
          // workaround for standing on dropoff edge
          if (_charController.isGrounded) {
              if (Vector3.Dot(movement, _contact.normal) &lt; 0) {
                  movement = _contact.normal * moveSpeed;
              } else {
                  movement += _contact.normal * moveSpeed;
              }
          }
      }
      movement.y = _vertSpeed;
  
      movement *= Time.deltaTime;
      _charController.Move(movement);
  }
  
  // store collision to use in Update
  void OnControllerColliderHit(ControllerColliderHit hit) {
      _contact = hit;
  
       //Physics method portion
  
      Rigidbody body = hit.collider.attachedRigidbody;
      if(body != null &amp;&amp; !body.isKinematic){
          body.velocity = hit.moveDirection * pushForce;
      }
  }
  </code></pre>
  <p>}
  `</p>