First Person Camera clipping, but not in the usual way.

I’ve been working on a first person game in the vein of a Looking Glass game, and one of the major aspects of those games is their really natural feeling lean, specifically in the first Thief.

My setup for the player controller is pretty typical,

  • Character Controller
  • A game object in very center of that
  • A camera up from the center

Then this code is on the Character Controller

    public Transform _Pivot;

    public float speed = 100f;
    public float maxAngle = 20f;

    float curAngle = 0f;

    // Use this for initialization
    void Awake()
    {
        if (_Pivot == null && transform.parent != null) _Pivot = transform.parent;
    }

    // Update is called once per frame
    void Update()
    {

        if (Input.GetKey(KeyCode.Q))
            curAngle = Mathf.MoveTowardsAngle(curAngle, maxAngle, speed * Time.deltaTime);
        else if (Input.GetKey(KeyCode.E))
            curAngle = Mathf.MoveTowardsAngle(curAngle, -maxAngle, speed * Time.deltaTime);
        else
            curAngle = Mathf.MoveTowardsAngle(curAngle, 0f, speed * Time.deltaTime);

My problem is that every time I lean the character near a wall the camera clips right through. In Thief what happens is the camera bumps against as if it were a physical object, and so I tried adding a collider to the camera and it didn’t do anything.

How can I make it so that the wall stops the camera?

Sounds like you need to separate the camera from the character controller and control its movement independently. It can optionally still be a child of the controller, but I would personally remove it from the controller’s hierarchy.

You can create a controller for the camera that tries to keep it in the best possible spot. (this can also handle head-bobbing, jerking when getting hit by an enemy, tasks like that). Usually this will be exactly where it currently lives, so I’d recommend creating a “dummy” child on the controller at the camera’s normal position, then using that as a target for your camera controller to “seek” to.

This camera controller could have its own collider (orchestrated to keep it from conflicting with the char controller’s collider) you can use to check collisions. Or you could achieve something very similar with some raycasting instead to check for obstacles like these troublesome walls.

Once you know you’re colliding, you can take action in the same frame to correct any clipping. This would be done by finding the best place for the camera to be in the current situation, which will probably be somewhere between it’s default target position and a position some distance away from the nearest point of collision you’ve detected.

Best,