Camera Controls in the Source SDK
Camera controls are spread across multiple source files in the Source SDK, but is largely centralized under the CInput (or CSDKInput) class. Most customizations to the camera control mechanisms can be accomplished either by editing methods in the CInput class directly, or by making your modifications to the CSDKInput stub provided. Keep in mind that if you modify the CInput class directly, it will make it harder to track updates to the Source SDK; on the flip side, if you decide to flesh out the CSDKInput class, you may need to extensively override or replace a large number of methods from the CInput class.
Before we get started, we should first review how the camera is represented to the rest of the engine. The camera position and direction are typically represented via a set of offset coordinates relative to the player. You can think of these offsets as a set of directions to tell how to position the camera starting from the player position:
- First, turn around the vertical axis by the offset vector's yaw component (this turns the camera left or right).
- Next, turn around the horizontal axis by the offset vector's pitch component (this points the camera up or down).
- Finally, move backwards along the direction you're now facing by the offset vector's distance component.
The camera offset is stored in the m_vecCameraOffset vector. You can access the pitch, yaw, and distance components by using a set of predefined enum values (PITCH, YAW, and DIST).
- game\client\iinput.h contains the abstract class that CInput implements.
- game\client\input.h contains the main CInput class.
- game\client\in_camera.cpp contains most of the third-person camera implementation.
- game\client\sdk\sdk_in_main.cpp contains the CSDKInput class, which can be used to override functionality in CInput.
- game\client\in_mouse.cpp has code to specifically update the ideal camera offset based on the mouse movement when in third-person mode.
How The Third-Person Camera Works
Essentially, the CInput class has full access to all keyboard and mouse input on the client. As such, it can use information about how the mouse moves in order to influence the camera position. Essentially, as the camera moves, the client updates the cam_idealpitch and cam_idealyaw ConVars to provide information about where the camera should be ideally positioned. Using this information, the CInput::CAM_Think method will update the actual camera offset in order to track the mouse movement. This tracking is done with a small lag to add a nice tracking effect instead of immediately snapping to the new position.
Additionally, the CInput::CAM_Think method does basic collision detection with the camera to ensure that it doesn't punch through a wall. The camera will automatically move closer to the player in the event that something lies between the player and the camera position.