[Unity] Project. DayLight_9

Lingtea_luv·2025년 6월 29일

Project

목록 보기
35/38
post-thumbnail

Project. DayLight


아침까지 기능 구현 병합 작업과 빌드 세팅 수정한다고 잠을 못자서 6시 이후에 바로 뻗어버렸다. 병합 작업이 생각보다 오래걸렸는데, 코드 컨벤션 단계에서 병합 과정을 위한 논의가 필요했을 것 같다.

다른 사람이 구현한 기능과 연계되는 작업의 경우 메서드 호출, 로직 구현 방식을 전달하고 전달받은 사람은 호환성을 위해 추가로 코드를 작성하는 과정이 필요하다고 생각한다.

여튼 우여곡절 끝에 병합 과정과 빌드를 마쳤고, 다행히 기능 상의 문제는 크게 없이 빌드 테스트를 진행할 수 있었다.

Build Issue

List1

  1. 맵뚫 버그 → physics - Layer Collision Matrix 설정
    • 무기를 들었을 때
    • 공격하면서 이동
    • 퀵슬롯 바꾸면서 이동
    • 백점프 이동(뒤로 점프)
  2. 무한 점프
  3. 캐릭터 끼임 현상(점프 lock)
  4. 공격하면서 퀵슬롯을 빠르게 전환하면 모션 고정
  5. 좀비 시체 [F] 위치 조정 or 레이어 우선 순위 조정
  6. 총 생성 위치 조정
  7. 카메라 상하 이동시 플레이어를 중심으로 회전
  8. 플레이어 공격 선,후 딜레이 제거
  9. 루팅시간 3초 → 1초 수정
  10. 플레이어 앞 뒤로 미끄러지는 현상 수정
  11. 마우스 커서 평소에는 숨기고, 인벤토리 루팅 시에만 보이도록 수정
  12. 달리기 기능 추가
  13. 플레이어가 살짝 떠 있는 것 같은 현상

List2

  1. 몽둥이 위치 중앙으로 변경
  2. 점프, 사다리 튜토리얼 문구 출력
  3. 연기 색상 수정
  4. 투명벽 제거
  5. 웅크리기 collider 반영
  6. 수중 파라미터(지속 데미지) 반영
  7. 일부 건물 에셋 위치, 크기, 활성화 여부 수정
  8. 사다리 튜토리얼 이후 자경단 방향 카메라 컷씬 추가
  9. 이벤트 장소에서 팝업 문구 출력 “먼저 높은 곳에서 주변을 살펴보자”

작업 완료 기능

  1. 빌드 이슈 해결
  2. 투척 무기 궤적 구현
  3. 개별 루팅 아이템 구현
  4. Lootable 프리팹 생성
  5. 플레이어 사용 아이템 프로퍼티 연동
  6. 마우스 y값에 따른 시점 변동

작업 중 기능

  1. 남은 빌드 이슈 해결
  2. 몬스터 공격 로직 수정
  3. 사용 아이템 구현(포션, 음식, 음료)
  4. 근접 무기 플레이어 공격속도 반영
  5. 랜덤 아이템 루트 테이블 생성 기능 구현

공유 코드

이번에 공유하려는 것은 코드가 아닌 Cinemachine과 관련된 기능들이다. 백뷰 기준 마우스 입력 값에 따라 시점 변동을 구현하기 위해 Cinemachine을 사용했는데 꽤나 다양한 기능이 있어 소개하고 싶다.

Backview

먼저 백뷰를 구현하기 위해서는 매우 간단하다.

Player 하위에 VirtualCamera를 생성한 뒤 Follow와 Look At을 Player로 설정하고 Body를 Transposer, Aim을 Same As Follow Target으로 설정한다.

이후 스크립트 상에서 마우스 입력 값에 따라 Player가 좌우로 회전하도록 해주면, 마우스 입력 값에 따라 플레이어가 좌우로 회전하고 카메라는 뒤에서 플레이어를 비추는 백뷰 구현이 끝난다.

다만 이 경우 마우스 y 입력 값에 따른 위 아래 회전이 불가능하기 때문에 단순한 백뷰 시점을 구현할 때 사용하면 될 것이다.

Backview + Input(MouseY)

마우스 y 입력 값을 받기 위해서는 추가적인 작업이 필요한데 player 계층 구조는 그대로 두고 CinemachineVirtualCamera 컴포넌트의 Aim만 수정하면 된다.

Aim을 POV로 바꾸게 되면 카메라가 항상 Look At을 바라보지 않고, 마우스의 입력값을 통해 카메라의 회전을 제어할 수 있게 된다.
다만 위에서 이미 마우스 x 입력값에 따른 수평 회전 처리를 스크립트로 하고 있기 때문에 Horizontal Axis의 Input Axis Name을 비워 마우스 x 입력값을 적용시키지 않고, Vertical Axis 즉 수직 회전 처리를 마우스 y 입력값에 따라 추가로 처리하도록 구성한다.

수직 회전의 경우 카메라가 너무 많이 돌아가면 플레이어가 시야에서 벗어나기 때문에 Value Range를 적당한 값으로 설정할 필요가 있다.

다만 이 경우 단점이 있는데 카메라가 플레이어를 기준으로 위아래로 회전하는 것이 아닌 카메라 자체가 위 아래로 회전하기 때문에 플레이어가 시야에서 멀어진다는 단점이 있다.

Backview + Input(MouseY) + Look At Player

그렇다면 플레이어를 항상 바라보지만, 수직 회전 처리를 하기 위해서는 어떻게 해야할까?
이를 구현하기 위해 시네머신 컴포넌트를 1시간 가까이 만졌지만, 정작 시네머신이 아닌 스크립트 상에서 회전 처리를 할 필요가 있었다.

위를 보면 시네머신이 아예 빠져있는 것을 볼 수 있은데 단순히 마우스 입력값에 따른 카메라의 회전 처리를 스크립트로 처리하면 플레이어를 중앙에 고정된 상태로 시점 구현이 가능하다.

public class PlayerCameraController : MonoBehaviour
{
    [Header("References")]
    [SerializeField] private Transform _player;
	[SerializeField] private Transform _cameraRig;
    [SerializeField] private float _minPitch;
    [SerializeField] private float _maxPitch;

    [Header("Mouse Config")]
    [SerializeField][Range(0, 1)] private float _mouseSensitivityX;
    [SerializeField][Range(0, 1)] private float _mouseSensitivityY;
    
    public float OffsetX { get; private set; }
    public float OffsetY { get; private set; }
    
    private void Update()
    {
        OffsetX += Input.GetAxis("Mouse X") * _mouseSensitivityX;
        _player.rotation = Quaternion.Euler(0f, OffsetX, 0f);
        
        OffsetY += Input.GetAxis("Mouse Y") * _mouseSensitivityY;
        OffsetY = Mathf.Clamp(OffsetY, _minPitch, _maxPitch); 
        _cameraRig.rotation = Quaternion.Euler(OffsetY, 0f, 0f);
    }
}       

수평 회전 처리는 마우스 x 입력 값에 따라 플레이어를 회전시키고, 수직 회전 처리는 마우스 y 입력 값에 따라 플레이어 하위에 위치한 CameraRig를 회전시키는 것이다. 이렇게 하면 다음과 같은 시점 구현이 완료된다.

물론 이렇게 시네머신을 사용하지 않고 구현이 가능하지만, 시네머신의 기능인 Cinemachine collider를 사용하지않아 벽과의 충돌로 인한 위치 보정을 적용하기위해서는 스크립트를 작성하거나 시네머신을 추가할 필요가 있다.

Backview + Input(MouseY) + Look At Player + Camera Collision Offset

결국 우리가 원했던 최종 기능은 이렇게 4가지가 종합된 것이었기에 시네머신을 추가하여 기능 구현을 마무리했다.

스크립트는 위에서 작성한대로 두고, 시네머신을 추가하여 Follow, Look At으로 Player로 설정한 뒤 Add Extension으로 Cinemachine collider를 추가하면 벽과의 충돌을 감지하고 위치가 보정되도록 구현하는 것이 가능하다.

Collide Against를 Tag : Wall로 설정하고 Ignore Tag에 Player를 넣는 처리를 통해 구현을 마무리하면 끝이다.

결국 벽과의 충돌 보정 기능 구현을 먼저하려고 Cinemachine을 추가했다가 여기에 너무 매몰되어 기본적인 기능 구현에 시간이 걸린 케이스라서, 기능 구현 우선 순위를 제대로 정하고 작업에 들어갈 필요성을 느꼈다.

profile
뚠뚠뚠뚠

0개의 댓글