[TIL] Unity 3D Cinemachine 3인칭 시점

Dreamer·2024년 10월 24일

1. 오늘 주제

오늘은 개인과제에 필요한 내용중에 3인칭 시점으로 캐릭터를 화면에 보여주는 것을 해보았다. 처음에서는 아무것도 안보고 이것저것 만져보다가 감이 잡히지 않아 정보를 찾아보니 생각보다 간단하게 3인칭 TPS 형식으로 Cinemachine을 적용할 수 있었다.. 그래서 오늘 한걸 기록해본다.

2. 적용해보기

  1. 우선은 Scene에 Free Look Virtual Camera를 추가해준다. 그리고 따라다닐 대상을 Follow에 Transform을 넣어주고, 고정해서 바라볼 Look At에 Transform을 넣어준다.

  2. 그리고 카메라가 돌아다닐 수 있는 영역 범위를 주기 위해 Orbits 에 Rig 값을 조정해준다.

  3. 이상태로 실행해보면 소스코드를 추가하지 않고도 카메라가 캐릭터를 따라다니는 걸 볼 수 있다.

3. 이동중에 마우스로 캐릭터 회전 시키기

위에서 한 방식만으로는 아직 제대로 움직이지 않는다. 여기에 캐릭터가 이동하는 동안에 화면을 움직이게 되면 캐릭터가 방향을 전환하는 기능을 넣어보자.
이번에는 스크립트가 필요하다.

  1. 우선은 PlayerInput.cs와 PlayerMovement.cs를 만들었다.
PlayerInput.cs

public class PlayerInput : MonoBehaviour
{
    private PlayerMovement movement;

    private void Awake()
    {
        movement = GetComponent<PlayerMovement>();
    }

    private void Start()
    {
        Cursor.lockState = CursorLockMode.Locked;
    }

    public void OnMove(InputAction.CallbackContext context)
    {
        if (context.phase == InputActionPhase.Performed)
        {
            movement.Move(context.ReadValue<Vector2>());
        }
        else if (context.phase == InputActionPhase.Canceled)
        {
            movement.Move(Vector2.zero);
        }
    }

    public void OnJump(InputAction.CallbackContext context)
    {
        if (context.phase == InputActionPhase.Started)
        {
            movement.Jump();
        }
    }

    public void OnRun(InputAction.CallbackContext context)
    {
        if (context.phase == InputActionPhase.Started)
        {
            movement.RunToggle();
        }
    }
}

PlayerInput.cs 에서 키를 입력하여 방향과 점프, 달리기 여부 버튼 등 이벤트로 받아주고 각각 조건에 맞게 component를 호출하여 실행해준다.

public class PlayerMovement : MonoBehaviour
{
	// ...
    private void Update()
    {
        if (direction != Vector3.zero)
        {
            look.Rotate();
        }
    }

    public void Move(Vector2 dir)
    {
        direction = dir.normalized;
    }
    
    // ...
}

이제 PlayerMovement.cs에서는 direction 이 Vector3.zero가 아닌경우 look.Rotate()를 하여 캐릭터가 이동중일 때만 화면을 돌리도록 해준다.

추가로 PlayerLook.cs 스크립트 파일을 아래와 같이 생성해주고,


public class PlayerLook : MonoBehaviour
{
    [Header("캐릭터 회전 속도")][Range(0, 3)]
    public float rotationSmoothTime = 0.1f;

    private Camera camera; 
    private float rotationVelocity = 0;

    public GameObject playerCameraRoot;

    private void Awake()
    {
        camera = Camera.main;
    }

    public void Rotate()
    {
    	// 대상이 될 카메라의 y축 각도
        float targetRotation = camera.transform.eulerAngles.y;
        // 현재 캐릭터의 y축 각도를 SmoothDampAngle로 대상 각도로 회전시켜준다.
        float rotation = Mathf.SmoothDampAngle(transform.eulerAngles.y, targetRotation, ref rotationVelocity, rotationSmoothTime);
        // 구해진 rotation을 Quaternion.Euler에 y축 각도로 넣어주고 transform.rotation에 적용
        transform.rotation = Quaternion.Euler(0, rotation, 0);
    }
}

이렇게 해주면 캐릭터가 이동중에 화면을 회전하면 캐릭터도 스무스하게 회전하게 된다.

힘들다 ㅠ

https://docs.unity3d.com/kr/Packages/com.unity.cinemachine@2.3/manual/index.html

profile
새로운 시작

0개의 댓글