Unity의 3인칭 카메라

3인칭 카메라는 플레이어 뒤에 배치되는 카메라 유형으로, 일반적으로 약간 옆으로 이동하여 게임 레벨과 플레이어 자체를 시각적으로 표현합니다.

Unity에서 3인칭 슈터(TPS) 카메라를 만들기 위해 일반 플레이어 움직임과 3인칭 시점의 조합을 사용합니다.

Sharp Coder 비디오 플레이어

1단계: 플레이어 컨트롤러 생성

먼저 회전과 이동을 처리하는 플레이어 컨트롤러를 만듭니다.

  • 새 게임 개체를 만들고(Game Object -> Create Blank) 이름을 지정합니다. "Player"
  • 새 캡슐(게임 개체 -> 3D 개체 -> 캡슐)을 만들고 "Player" 개체 내부로 옮깁니다.
  • Capsule에서 Capsule Collider 구성 요소를 제거하고 위치를 (0, 1, 0)으로 변경합니다.
  • 새 GameObject를 생성하고 이름을 "CameraParent"로 지정한 다음 "Player" Object 내부로 이동하고 위치를 (0, 1.64, 0)으로 변경합니다.
  • 메인 카메라를 "CameraParent" 개체 내부로 이동하고 플레이어 뒤로 이동합니다. (제 경우에는 이 위치로 이동했습니다: (0.5, 0.6, -2.9))

Unity의 3인칭 카메라

  • 새 스크립트를 만들고 SC_TPSController라고 부르고 그 안에 아래 코드를 붙여넣습니다.

SC_TPSController.cs

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<CharacterController>();
        rotation.y = transform.eulerAngles.y;
    }

    void Update()
    {
        if (characterController.isGrounded)
        {
            // We are grounded, so recalculate move direction based on axes
            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;
            }
        }

        // Apply gravity. Gravity is multiplied by deltaTime twice (once here, and once below
        // when the moveDirection is multiplied by deltaTime). This is because gravity should be applied
        // as an acceleration (ms^-2)
        moveDirection.y -= gravity * Time.deltaTime;

        // Move the controller
        characterController.Move(moveDirection * Time.deltaTime);

        // Player and Camera rotation
        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);
        }
    }
}
  • SC_TPSController 스크립트를 "Player" 개체에 연결합니다. (Character Controller라는 또 다른 구성 요소도 추가되었음을 알 수 있습니다. 중심 값을 (0, 1, 0)으로 변경합니다.)
  • "CameraParent" 개체를 "Player Camera Parent" 변수에 할당

2단계: 카메라 충돌 감지 추가

Camera 충돌 감지는 카메라와 플레이어 사이에 아무것도 없는지 확인하고 자동으로 카메라를 더 가까이 이동하여 카메라가 개체를 통과하는 것을 방지하는 스크립트로 구성됩니다.

  • 새 스크립트를 만들고 이름을 SC_CameraCollision으로 지정한 다음 그 안에 아래 코드를 붙여넣습니다.

SC_CameraCollision.cs

using UnityEngine;

public class SC_CameraCollision : MonoBehaviour
{
    public Transform referenceTransform;
    public float collisionOffset = 0.3f; //To prevent Camera from clipping through Objects
    public float cameraSpeed = 15f; //How fast the Camera should snap into position if there are no obstacles

    Vector3 defaultPos;
    Vector3 directionNormalized;
    Transform parentTransform;
    float defaultDistance;

    // Start is called before the first frame update
    void Start()
    {
        defaultPos = transform.localPosition;
        directionNormalized = defaultPos.normalized;
        parentTransform = transform.parent;
        defaultDistance = Vector3.Distance(defaultPos, Vector3.zero);

        //Lock cursor
        Cursor.lockState = CursorLockMode.Locked;
        Cursor.visible = false;
    }

    // LateUpdate is called after Update
    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);
        }
    }
}

이제 TPS 카메라가 준비되었습니다. 재생을 눌러 테스트해 보세요.

원천
TPSCamera.unitypackage172.07 KB