A Third-person camera is a type of camera placed behind the player, usually slightly shifted to the side, giving a visual representation of the game level and the player itself.
To make a Third-Person Shooter (TPS) camera in Unity, we will use a combination of regular player movement and a third-person view.
Step 1: Create The Player Controller
First, we will create a Player controller that will handle rotation and movement:
1. Create a new GameObject (GameObject -> Create Empty) and name it "Player".
2. Create a new Capsule (GameObject -> 3D Object -> Capsule) and move it inside the "Player" Object.
3. Remove the Capsule Collider component from the Capsule and change its position to (0, 1, 0).
4. Create a new GameObject and name it "CameraParent" and move it inside the "Player" Object, changing its position to (0, 1.64, 0).
5. Move the Main Camera inside the "CameraParent" Object and move it behind the Player (in this case, position it at (0.5, 0.6, -2.9)).
Create a new Script, call it 'SC_TPSController', and paste the code below inside it:
using UnityEngine;
[RequireComponent(typeof(CharacterController))]
public class SC_TPSController : MonoBehaviour
{
public float speed = 7.5f;
public float jumpSpeed = 8.0f;
public float gravity = 20.0f;
public Transform playerCameraParent;
public float lookSpeed = 2.0f;
public float lookXLimit = 60.0f;
CharacterController characterController;
Vector3 moveDirection = Vector3.zero;
Vector2 rotation = Vector2.zero;
[HideInInspector]
public bool canMove = true;
void Start()
{
characterController = GetComponent();
rotation.y = transform.eulerAngles.y;
}
void Update()
{
if (characterController.isGrounded)
{
Vector3 forward = transform.TransformDirection(Vector3.forward);
Vector3 right = transform.TransformDirection(Vector3.right);
float curSpeedX = canMove ? speed * Input.GetAxis("Vertical") : 0;
float curSpeedY = canMove ? speed * Input.GetAxis("Horizontal") : 0;
moveDirection = (forward * curSpeedX) + (right * curSpeedY);
if (Input.GetButton("Jump") && canMove)
{
moveDirection.y = jumpSpeed;
}
}
moveDirection.y -= gravity * Time.deltaTime;
characterController.Move(moveDirection * Time.deltaTime);
if (canMove)
{
rotation.y += Input.GetAxis("Mouse X") * lookSpeed;
rotation.x += -Input.GetAxis("Mouse Y") * lookSpeed;
rotation.x = Mathf.Clamp(rotation.x, -lookXLimit, lookXLimit);
playerCameraParent.localRotation = Quaternion.Euler(rotation.x, 0, 0);
transform.eulerAngles = new Vector2(0, rotation.y);
}
}
}
6. Attach the SC_TPSController script to the "Player" object (You will notice that it also added another component called Character Controller. Change its center value to (0, 1, 0)).
7. Assign the "CameraParent" Object to the "Player Camera Parent" variable.
Step 2: Add Camera Collision Detection
Camera collision detection will consist of a script that will check if there is anything between the Camera and the Player, and will automatically move the Camera closer, preventing it from clipping through the objects.
1. Create a new script, name it SC_CameraCollision, then paste the code below inside it:
using UnityEngine;
public class SC_CameraCollision : MonoBehaviour
{
public Transform referenceTransform;
public float collisionOffset = 0.3f;
public float cameraSpeed = 15f;
Vector3 defaultPos;
Vector3 directionNormalized;
Transform parentTransform;
float defaultDistance;
void Start()
{
defaultPos = transform.localPosition;
directionNormalized = defaultPos.normalized;
parentTransform = transform.parent;
defaultDistance = Vector3.Distance(defaultPos, Vector3.zero);
Cursor.lockState = CursorLockMode.Locked;
Cursor.visible = false;
}
void LateUpdate()
{
Vector3 currentPos = defaultPos;
RaycastHit hit;
Vector3 dirTmp = parentTransform.TransformPoint(defaultPos) - referenceTransform.position;
if (Physics.SphereCast(referenceTransform.position, collisionOffset, dirTmp, out hit, defaultDistance))
{
currentPos = (directionNormalized * (hit.distance - collisionOffset));
transform.localPosition = currentPos;
}
else
{
transform.localPosition = Vector3.Lerp(transform.localPosition, currentPos, Time.deltaTime * cameraSpeed);
}
}
}
2. Attach the SC_CameraCollision script to the Main Camera.
3. Assign the "CameraParent" Object to the "Reference Transform" variable.
4. Tweak the "Collision Offset" and "Camera Speed" values if the Camera is clipping through the walls.
The TPS Camera is now ready! Press Play to test it.