Camera

개발조하·2023년 11월 30일
0

Unity

목록 보기
11/30
post-thumbnail

1. Camera 컴포넌트 속성

  • Culling Mask
    : 카메라가 렌더링할 Layer 선택
    ㄴ 'Monster' 레이어를 사용하고 있는 Cube1만 렌더링되지 않는 것!

2. Camera 활용

ㄴ CameraController.cs 사용하기

2.1 QuaterView로 player 따라가기

1) Main Camera를 Player 산하로 넣는다?
❌ Player가 회전할 때 Camera의 앵글도 함께 바뀌어 어지러움 유발 문제 발생..!

💡 Main Camera를 Player의 산하로 넣지 말고 개별 object로 사용
CameraController.cs로 Player를 계속 촬영하되, Camera의 회전값은 Player를 따라가는 것이 아니라 world좌표를 기준으로 Player와 일정 거리를 유지한 상태로 함께 움직이도록 설정함!

public class CameraController : MonoBehaviour
{
    [SerializeField] Define.CameraMode _mode = Define.CameraMode.QuarterView;
    [SerializeField] Vector3 _delta;
    [SerializeField] GameObject _player;

    void Update()
    {
        //카메라의 위치 설정
        transform.position = _player.transform.position + _delta; 
    }
}

ㄴ 즉, 카메라의 위치 = player 위치 + 떨어져 있는 Vector3값
ㄴ enum으로 정리하는 Define 스크립트 별도 생성 후 사용

public class Define //컴포넌트로 사용 X
{
    public enum CameraMode
    {
        QuarterView,
    }
}

2.2 player 주시하기_LookAt()

⚠️ player가 덜덜 떨리면서 이동하게 됨
-> 현재 playercontroller와 CameraController 모두 Update()에서 실행되고 있는데, 두 스크립트 중에 누가 먼저 연산될지는 랜덤이다. 만약 cameraController가 먼저 연산되면 우리 설계보다 _delta가 조금 더 멀리 가있을 것이고, PlayerController가 먼저 연산되면 우리가 원하는 거리가 유지될 것. 이처럼 1/2확률로 연산 순서가 정해지고 카메라 위치가 결정되기 때문에 player가 덜덜 떨면서 이동하는 것처럼 보여진다..

💡 무조건, PlayerController의 연산이 먼저 진행되도록 설정!
유니티의 Life Cycle을 살펴보면, LateUpdate()가 Update()보다 늦게 실행되는 것을 알 수 있다.
ㄴ 즉, PlayerController의 Update()가 실행 된 후, CameraController가 LateUpdate()로 실행되게 만들면 된다.

public class CameraController : MonoBehaviour
{
    //필드 변수 초기화
    [SerializeField] Define.CameraMode _mode = Define.CameraMode.QuarterView;
    [SerializeField] Vector3 _delta = new Vector3(0.0f, 6.0f, -5.0f);
    [SerializeField] GameObject _player = null;

    void LateUpdate()
    {
        if(_mode == Define.CameraMode.QuarterView)
        {
            //카메라의 위치 설정
            transform.position = _player.transform.position + _delta;
            //player 주시
            transform.LookAt(_player.transform);
        }
    }

    //나중에 QuaterView의 값을 받아올지도 모르니까 만들어 둠
    public void SetQuaterView(Vector3 delta)
    {
        _mode = Define.CameraMode.QuarterView;
        _delta = delta;
    }
}

2.3 클릭한 위치로 player 이동시키기

  • InputManager.cs에 MouseAction 이벤트 생성
    ㄴ Define.cs에 enum MouseEvent 만듦

  • PlayerController.cs에 클릭 시 기능 추가
    ㄴ 목적지 변수 _destinationPos & 이동상태 확인용 플래그 _moveToDest 필드 추가
    ㄴ MouseAction에 OnMouseClicked() 구독 신청

  • OnMouseClicked() 생성 ㄴ Click되면, 클릭 위치를 _destinationPos로 설정
    ㄴ _moveToDest = true;로 이동 상태로 변경

  • player 실제 이동 구현 코드

⚠️ 현재 코드로 실행을 해보면 목적지에 도착했을 때 캐릭터가 좌우로 와리가리하다 넘어져버리는 문제 발생 ?!!!
💡 Math.Clamp(값, 최소값, 최대값)을 사용하여 값(_speed * Time.deltaTime)이 최소값보다 작아지면 최소값으로 덮어쓰기되고, 최대값(dir.magnitude)보다 커지면 최대값으로 덮어쓰기되도록 한다.

2.4 클릭한 방향으로 player 자연스럽게 회전

  • Quaternion.Slerp(현재 위치, 바라볼 뱡향, 두 회전값의 블렌딩 비율)을 사용하여 부드러운 회전 구현
    ㄴTime.deltaTime에 곱하는 상수를 높일수록 회전 속도가 빨라짐

2.5 카메라가 벽에 가려질 경우, 다시 player쪽으로 이동

카메라에서 player를 향해 발사한 Raycast가 벽과 충돌했다면, 충돌 지점(hit.point)과 플레이어 사이의 거리를 계산한다. 이 거리에 0.8f를 곱해 카메라를 플레이어에 더 가깝게 이동시킨다.
-> 이로써 카메라가 벽에 완전히 가려지는 것을 방지할 수 있다!

2.6 쿼터뷰로 설정한 카메라 다른 씬에서도 사용하기

-> 만든 Camera를 Prefab화하면 다른 씬에서도 활용할 수 있다.

📄 참고자료
[인프런]c#과 유니티로 만드는 MMORPG_Camera
Unity_Life Cycle

profile
Unity 개발자 취준생의 개발로그, Slow and steady wins the race !

0개의 댓글