Unity Cinemachine Camera

김김김김·2024년 2월 28일

Cinemachine이란?

오늘은 Unity에서 제공하는 기능 중 하나인 Cinemachine Camera를 사용해보았다.
Cinemachine은 장면 구성 및 상호 작용을 기반으로 최고의 장면을 만들어 실시간으로 카메라 동작을 조정, 반복, 실험 및 생성할 수 있는 역동적이고 스마트하며 코드가 없는 카메라용 도구 모음이다.
Cinemachine은 Window -> Pakage Manager로 설치를 진행할 수 있다.


프로젝트에서의 Cinemachine

현재 포더킹 모작 프로젝트를 진행 중이다.
포더킹 게임에서의 카메라의 움직임이 다양하게 존재하지만 필자는 포더킹 모작 프로젝트에서 필요한 요소만 채택하기로 했다.
포더킹에도 다양한 모드가 존재하지만 프로젝트에서 사용되는 모드는 포더킹의 힐데브란트의 저장소이다.

1. 처음 스테이지 진입 시
2. 플레이어와 적군의 차례일 때
3. 전투 승리 후 다음 스테이지 진입 시

시네머신(Cinemachine)을 제작할 때 이 3가지 상황을 제작하기로 하였다.

1. 스테이지 진입 시

2. 전투 상황 시

3. 전투 종료 후 다음 스테이지 진입 시

이렇게 3가지 시네머신 카메라를 제작하였다.

이슈 발생

카메라의 이동과 시점을 결정하는 부분에서 Cinemachine Dolly Track with Cart라는 기능을 활용했다. Dolly Cart는 지정된 경로에서 카메라가 속도에 맞춰 이동하는 기능이다.
카메라를 사용 중 LookAt이라는 기능을 활용하여 카메라의 이동은 Track을 따라 움직이고 시점은 LookAt으로 오브젝트를 중점적으로 맞춰주는 역할을 수행한다.
하지만 여기서 문제점이 발생했다. 포더킹 모작 프로젝트를 진행하던 중 Managers 오브젝트와 스크립트를 통해서 게임이 실행되었을 때 오브젝트를 불러오는 방식으로 인스펙터창에서의 조작이 불가능하다는 것을 느꼈다. 하지만 유니티에서 코드로 조작해서 되지 않는 것은 없다.

스크립트

스크립트를 보여주기전 간단하게 설명하자면 LookAt 즉, 포커싱을 누구로 할 것인가에 대한 고민을 하던 중 게임이 심심하지 않게 느끼려면 카메라가 지정된 타켓을 카메라의 중심에 실시간으로 반응하면 되지 않을까? 라는 생각에 스크립트를 작성하였다.

  1. 스테이지 진입 시
using Cinemachine;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class StartVCam : MonoBehaviour
{
    CinemachineVirtualCamera VCam;
    CinemachineDollyCart cart;
    StageManager stageManager;
    Vector3 lastPosition;

    private void OnEnable() => OnLookAt();

    public void OnLookAt()
    {
        VCam = GetComponent<CinemachineVirtualCamera>();
        stageManager = Managers.Stage;
        VCam.m_LookAt = stageManager.target.transform;
        cart = GetComponentInParent<CinemachineDollyCart>();
        lastPosition = cart.transform.position;
    }

    public void Update()
    {
        Vector3 currentPos = cart.transform.position;

        if (lastPosition == currentPos)
        {
            GameObject go = transform.root.gameObject;
            
            gameObject.SetActive(false);
            Managers.Stage.turnVCam = Managers.Spawn.CameraByID((PrefabID)4);
            
        }
        lastPosition = currentPos;
    }
}

이 스크립트가 작동되는 원리로는 OnLookAt()은 position의 위치 값을 받아 처음 스테이지 진입했을 때의 카메라가 도착지점에 도착했다는 것을 확인하는 용도이며, 카메라의 LookAt을 게임 실행 후 생성된 오브젝트의 위치값을 받아오는 것으로 작성이 되었다.


  1. 턴 진행 시
using Cinemachine;
using UnityEngine;

public class TurnCamera : MonoBehaviour
{
    CinemachineVirtualCamera turnVCam;
    CinemachineDollyCart cart;
    Transform lookAtObject;

    void Start()
    {
        turnVCam = GetComponent<CinemachineVirtualCamera>();
        cart = GetComponentInParent<CinemachineDollyCart>();
        turnVCam.m_LookAt = Managers.Stage.target.transform;

    }

    private void Update()
    {
        if (turnVCam != null)
        {
            if (Managers.Stage.isPlayerTurn.Value)
            {
                cart.m_Speed = -3f;
            }
            else
            {
                //turnVCam.m_LookAt = lookAtObject;
                cart.m_Speed = 3f;
            }
        }
    }
}

턴 진행 전 Managers.Stage.target.transform은 스테이지 진입하여 플레이어 차례일 때는 몬스터를 클릭하였을 때의 타켓을 지정하고 반대로의 경우는 플레이어를 타켓으로 하여 추적하는 오브젝트이다. 따라서 target 오브젝트의 위치값을 카메라의 중심에 담는 기능을 수행하는 것이다.
다음으로 if문을 통해서 turnValue값을 통해 플레이어턴과 몬스터턴을 구분하여 구현했다.

마치며

시네머신 카메라를 통해서 상황에 맞는 상호작용을 수월하게 진행할 수 있어서 다루기 좋았다.

0개의 댓글