🤍ref.

  1. Unity Learn John Lemon’s Haunted Jaunt: 3D Beginner

  2. Unity Documentation

✨Unity info
본 튜토리얼 문서의 유니티 버전은 2020.3v이나, 2021.3v으로 실습 후 게시글을 작성하였습니다.



🍋환경

1. 환경 광원 설정


image

Unity에서의 광원은 게임 오브젝트에 Light 컴포넌트를 추가한 것으로, Unity에서 새로운 Scene을 생성할 경우 기본값으로 방향 광원이 생성된다.

  • Light 컴포넌트: 광원의 컬러, 강도 및 유형 변경 가능
    • 그림자 및 라이트매핑을 위한 컨트롤 포함
  • 방향 광원: Directional 유형. 태양과 같이 거리가 매우 먼 광원 오브젝트를 모방
    • 어느 위치에나 배치 가능, 광원이 씬에 영향을 주는 각도(회전값) 변경 가능


image

  • Hierarchy view의 Directional Light 게임 오브젝트에서 광원의 색 변경 가능
    • Inspector view -> Color 프로퍼티 조정 (Color Picker 창이라고도 한다)
      • R, G, B, A 값을 조율해 광원 조정 (RGB(225, 240, 250))
  • Intensity: Scene의 defuse 환경광 밝기 설정 (0~8 사이 설정 가능, default값: 1)
  • Realtime Shadows: 실시간으로 그림자를 렌더링하는데 사용되는 컬러 지정
    • 그림자의 품질을 향상시키기 위해 Resolution 프로퍼티를 Very High Resolution으로 설정
    • BiasNormal Bias 프로퍼티를 0.01로 설정
    • Rotation: 광원을 회전해 집의 창문으로 빛이 들어오도록 설정(본 프로젝트에서는 (30, 20, 0)으로 설정함)


Bias? Normal Bias?

그림자는 일반적으로 씬이 최종 렌더링될 때 결정되는데, 광원이 비춘 사물의 표면이 그림자에 부분적으로 표시될 수 있다. 이때, 그림자에서 임의의 패턴 픽셀들이 나타나며 섀도우 애크니 효과가 발생한다.

image

섀도우 애크니 효과가 발생한 사물 (잘못된 그림자 결함)

섀도우 애크니를 방지하기 위해 섀도우 맵에 Bias 값을 거리에 추가한다(경계선의 픽셀이 통과해야하는 비교를 명확하게 함). 단, Bias값을 너무 높게 설정할 경우 그림자 주변 영역이 잘못 비춰져 그림자가 분리된다.

Normal Bias는 노멀값을 따라 게임 오브젝트를 일부 삽입할 수 있으나, 값이 너무 높게 설정될 경우 게임 오브젝트의 그림자가 좁게 표시된다.(광원 번짐 효과. 광원이 그림자 캐스트 영역까지 번짐)


image

Bias값을 너무 높게 설정했을 때의 사물 그림자


image

Normal Bias를 너무 높게 설정했을 때의 사물 그림자



2. 라이트매핑 효과 생성

전역 조명 라이트매핑: 실제 빛의 속성(Scene 내의 광원 반사)을 시뮬레이션하여 프로젝트 내에 저장된 에셋에 베이크함.

  • 직접 조명: 태양(Scene 방향 광원)과 같은 특정 광원으로부터의 조명
  • 간접 조명: 직접광이 표면에서 반사되어 발생하는 추가 조명

image

각각 조명x, 직접 조명, 간접 조명 포함


전역 조명 라이트매핑의 작업 시간을 줄이기 위해 근사치를 사용하여 유사한 효과를 생성할 수 있다.


image

  • Window ->Rendering -> Lighting을 클릭 후 New Lighting Setting을 선택하여 Inspector 창에 load

    • 팝업으로 Lighting 창이 따로 생성된다!
  • Realtime Global IlluminationBaked Global Illumination의 선택 해제

    • Realtime Global Illumination: 실시간 전역 조명. 가장 유연하며 사실적인 조명 옵션으로 직접 조명과 간접 조명 효과 제공 (간접 조명 일부 미리 계산)
    • Baked Global Illumination: 직접 조명과 간접 조명 효과를 모두 미리 계산


image

Environment 섹션

본 프로젝트에서는 하늘 머티리얼이 필요하지 않으므로 None으로 지정한다.

Environment Lighting 섹션에서 각각 Sky, Equator, Ground의 광원을 설정할 수 있다.

  • Sky: 씬 위에서 내려오는 환경 광원 제어 (RGB(170, 180, 200): 바닥과 침대, 테이블과 같은 오브젝트의 밝기 높임)
  • Equator: 지평선에서 씬 중앙으로 이동하는 광원 제어 (RGB((90, 110, 130): 벽과 소품의 밝기 높임)
  • Ground: 씬 아래에서 윗 방향으로 올라오는 광원 제어 (RGB(0, 0, 0): 실내의 전체적인 조명을 어둡게 함)



3. 내비게이션 메시 추가

유령이 Scene을 돌아다닐 수 있도록 NavMesh 빌트인 시스템을 활용할 수 있다.

  • NavMesh: 선택한 게임 오브젝트가 이동할 수 있는 영역 정의
    • 게임 오브젝트를 정적으로 지정하면 내비게이션 시스템이 해당 오브젝트가 이동하지 않는 것으로 추정

image

Level 게임 오브젝트를 선택한 후, Inspector 창에서 Static을 활성화할 수 있다. Static을 선택한 후, 대화창을 통해 자식 게임 오브젝트도 정적으로 표시할 수 있으며, 개별 자식 오브젝트를 직접 다루어 예외를 설정할 수도 있다.


  • 베이킹: 내비게이션 창에서 내비 메시 생성 (Window -> AI -> Navigation)

image

  • Agent Radius: NavMesh 위에서 움직일 대상의 반지름. 값이 커질수록 내비 메시의 빈 부분(돌아다닐 수 있는 영역)이 확장


image

내비 메시가 활성화된 영역. 아래 영역에서만 유령이 이동할 수 있다.



🍋카메라

ezgif com-gif-maker

캐릭터는 씬 내부를 돌아다니지만, 카메라가 캐릭터를 제대로 잡아주지 못한다 !


image

카메라를 조정해 카메라가 항상 캐릭터를 따라다니도록 설정할 수 있다. Scene을 카메라로 보기 위해 새로운 Scene을 생성할 경우 기본으로 Camera 컴포넌트가 생성된다. 카메라는 게임 오브젝트의 z축을 따르며, 다른 게임 오브젝트와 동일하게 작동한다.

카메라가 캐릭터를 따라가도록 하기 위해 별도의 스크립트를 작성하거나, 시네머신(Cinemachine)을 활용할 수 있다.


1. Cinemachine

  • Scene에서 하나 이상의 가상 카메라 생성, Cinemachine Brain 컴포넌트에서 관리

    • Cinemachine Brain: 모든 가상 카메라를 관리
      • Camera 컴포넌트가 포함된 게임 오브젝트(eg. Main Camera)에 연결하며 실제 카메라가 어떤 가상 카메라를 따를지 결정

시네머신(Cinemachine)을 사용한 가상 카메라 설정

  1. Project -> Assets -> Scenes에서 MainScene 더블 클릭
  2. Hierarchy view에서 카메라가 따라다닐 게임 오브젝트 (JohnLemon) 선택
  3. 커서를 Scene 창 위로 이동한 후 F키 누름 (게임 오브젝트에 focus 맞춤)
  4. 상단 메뉴 Cinemachine -> Create Virtual Camera 이동 => 새로운 카메라 오브젝트(CM vcam1) 생성 !

이후 Cinemachine Virtual Camera 컴포넌트 설정을 변경해 가상 카메라가 캐릭터를 트래킹하도록 한다.



1.1. 카메라 트래킹

image

카메라 오브젝트의 Inspector view. 카메라의 기본 위치(Position, Rotation) 및 캐릭터와의 거리(Camera Distance), 카메라 회전 정도(Aim)을 지정할 수 있다.

  • Cinemachine 컴포넌트의 Follow 프로퍼티를 트래킹하려는 게임 오브젝트로 지정
  • Aim: 가상 카메라가 회전하는 방식 설정
    • Aim 컴포넌트는 Do nothing으로 설정(카메라를 회전하지 않음)


ezgif com-gif-maker (2)

가상카메라가 설정된 후 Game view


2. 포스트 프로세싱 효과

게임 이미지를 렌더링하기 전, 필터 및 효과 적용

빈 오브젝트와 layer를 생성 후, Inspector viewAdd effect를 통해 다양한 효과를 만들 수 있다 !

ezgif com-gif-maker (3)

포스트 프로세싱을 적용한 후 Game view


🍋게임 엔딩 제작하기

1. UI 설정

캐릭터가 출구에 도달했을 때, 게임이 페이드아웃하고 종료되도록 UI 시스템을 사용한다.

image

Hierarchy view -> UI -> Image를 통해 UI 창을 새로 생성할 수 있다.

Scene 뷰의 2D 버튼을 클릭하면 새 게임 오브젝트를 제대로 확인할 수도 있다 !

일반적으로 UI 오브젝트를 새로 생성하면 EventSystem 게임 오브젝트가 함께 생성되나, 플레이어가 해당 UI와 서로 상호작용하지 않으므로 본 프로젝트에서는 제거한다.

  • EventSystem: 해당 게임 오브젝트와 연결된 컴포넌트가 함께 작동하여 UI 요소와 플레이어가 상호작용할 수 있도록 함


1.1. 캔버스 설정

image

  • Canvas: 해당 캔버스에 속하는 UI 요소가 렌더링되는 방식
    • Screen Space - Overlay: 캔버스가 화면을 채우고, 캔버스의 모든 UI 요소가 나머지 항목 위에 렌더링
    • Screen Space - Camera: 캔버스가 화면을 채우나, 특정 카메라로 랜더링됨. 카메라의 거리에 영향을 받음
    • World Space: 씬에 UI가 존재. 오브젝트의 앞이나 뒤에 렌더링 (캐릭터 위에 표시되는 이름 태그 등)
  • Canvas Scaler: 화면에서 UI 요소의 상대적 크기 조정. (해당 캔버스에서는 Image가 화면을 overlay하므로 제거)
  • Graphic Raycaster: UI 이벤트 감지 후 적절한 컴포넌트가 반응 (게임 내에서 플레이어는 UI와 상호작용하지 않으므로 제거)



1.2. Rect Transform

image

각각의 포인트(Anchor)가 모아진 모양. 앵커의 영역이 화면 전체이면 게임 진행 시 화면의 전체 모습이 UI로 비춰진다.


image

Image의 Inspector view

  • Rect Transform: Transform 컴포넌트의 2D 레이아웃 버전
    • Left, Top, Right, Bottom: 앵커를 기준으로 한 사각형 에지 포지션 (사각형 내부 padding)
    • Min: 사각형 왼쪽 하단 모서리의 앵커 포인트. (0,0) -> 사각형 왼쪽 하단 모서리의 앵커
    • Max: 사각형 오른쪽 상단 모서리의 앵커 포인트. (1,1) -> 상위 사각형 오른쪽 상단 모서리의 앵커

Min, Max를 각각 (0, 0), (1, 1)으로 설정하고, 에지 포지션을 모두 0으로 설정하면 이미지가 게임 화면을 전부 덮는다 !


image

Rect Transform 설정 및 Image Color를 RGB(0, 0, 0)으로 했을 때의 Scene view (2D)


image

Image의 자식 오브젝트로 새 이미지를 생성해 게임이 끝났을 때의 이미지 파일을 불러올 수 있다.


image

이미지와 Left padding 길이


image

image파일의 Rect Transform을 backgroud image 설정과 동일하게 적용.

Image Type 프로퍼티에서 Preserve Aspect를 활성화하면 이미지의 비율을 그대로 유지한 상태로 확대 가능


image

ExitImageBackground 게임 오브젝트에서 Canvas Group 컴포넌트를 사용하면 게임 진행 도중에는 이미지가 보이지 않도록 UI 기능을 조절할 수 있다.

  • Alpha: 그룹에 있는 UI 요소의 불투명도(0~1)



2. Game Ending 트리거

캐릭터가 GameEnding 영역에 진입했는지 여부를 알기 위해 새 게임 오브젝트를 생성한다. 만약 캐릭터가 해당 오브젝트에 닿았을 경우, Canvas Group의 Alpha 프로퍼티 값을 변경해 이미지를 Game view에 띄운다.

image

캐릭터와 오브젝트의 충돌 여부를 알기 위해 Box Collider 컴포넌트를 추가한다.

  • Is Trigger: 활성화 시 Collider를 트리거로 변경

트리거의 크기를 조절해 일정 영역에 닿으면 모두 게임을 끝낸 것으로 판정한다. Edit Collider 버튼을 누르면 Scene view에서 직접 Collider의 크기를 조절할 수 있다.


image

Scene view에서 Collider의 영역 조절



2.1. 게임 종료 스크립트

  • public float fadeDuration: 캐릭터가 트리거와 충돌 시 UI가 페이드되는 시간 설정
    • GameObject: 캐릭터가 트리거와 충돌할 때만 페이드가 발생하도록 게임 오브젝트에 대한 레퍼런스 선언

MonoBehaviour는 트리거 게임 오브젝트를 감지할 수 있도록 OnTriggerEnter 메서드를 제공한다! 해당 메서드를 통해 트리거와 충돌했을 경우의 이벤트를 작성할 수 있다.

  • if (other.gameObject == player): 게임 오브젝트가 player일 경우 이벤트 발생



  • bool m_IsPlayerAtExit: 플레이어가 게임을 종료했는지 여부를 알기 위해 bool 형식의 변수 선언
    • 플레이어가 트리거에 충돌했을 경우 m_IsPlayerAtExit = true를 반환하도록 한다.



  • EndLevel(): 캔버스 그룹을 페이드한 후 게임 종료
  • CanvasGroup exitBackgroundImageCanvasGroup: Canvas Group 컴포넌트에 대한 변수를 만들어 Inspector에 할당
    • 페이드가 끝나기 전에 게임이 종료되지 않도록 m_Timer변수 선언, Time.delta Time을 사용해 시간 경과 확인
    • m_TimerfadeDuration으로 나누어 페이드인(Alpha) 값 계산
  • m_Timer가 지정된 시간을 넘으면 페이드가 끝난 것으로 간주, 게임 종료(=>Application.Quit())
    • 플레이어가 게임 종료 이미지를 확인할 수 있도록 displayImageDuration을 추가해 1초의 시간을 더한다 !



2.2. 스크립트 변수 설정

image

GameEnding 오브젝트의 Inspector에 Game Ending 스크립트 삽입

  • Player: Player 변수로 JohnLemon 오브젝트 할당
  • ExitBackgroundImage: 게임 종료 이미지에 Exit Background Image Canvas Group 변수 할당


ezgif com-gif-maker (4)

🤓게임종료 !

Leave a comment