경일 메타버스 20220720 16주차 3일 수업내용. 유니티 & C# - 좀비 서바이버 : 라이팅, 3D 모델, 애니메이터, 시네머신, 인터페이스, 파티클 시스템, 스크립터블 오브젝트, 특성, 리플렉션
라이트 연산은 굉장히 비싼 연산이다. 그래서 웬만하면 라이팅 정보를 저장해 놓는다. 즉, 미리 연산한다. => 라이트맵(Light Map)
글로벌 일루미네이션(GI; Global Illumination) : 간접광 계산
유니티에서 제공하는 라이트 종류
점(Point) : 구형 조명
스팟(Spot) : 원뿔형 조명
직사광(Directional) : 태양광
레이어를 여러 개 사용해서 동시에 여러 상태를 한꺼번에 표현할 수 있었음.
위에서부터 아래로 차례대로 오버라이딩
오버라이딩을 하기 위한 아바타 마스크
자연스러운 애니메이션을 위해 블렌드 트리를 사용할 수 있다.
휴머노이드 릭(Humanoid Rig)
리깅(Rigging) : 3D 모델의 골격과 움직임을 정의하는 조인트(관절) 계층 구조를 만드는 것
사람 형태의 모델은 휴머노이드 릭을 사용한다.
자연스러운 카메라 연출을 위한 패키지
브레인 카메라(Brain Camera)와 가상 카메라(Virtual Camera)로 나뉨
브레인 카메라(Brain Camera) : 모니터로 화면을 송출하는 역할
가상 카메라(Virtual Camera) : 카메라 연출에 필요한 데이터를 저장
객체 지향 프로그램에서 메시지를 정의할 수 있는 도구
인터페이스는 여러 개를 구현할 수 있다.
인터페이스를 상속한다면 반드시 해당 인터페이스에 정의된 메시지를 재정의해야 한다.
인터페이스를 활용해 코드 간(객체 간) 결합도를 낮출 수 있다. => 느슨한 커플링(Loose Coupling)
여러 데이터를 저장할 수 있는 데이터 컨테이너
유니티 에디터 상에서 데이터를 수정할 수 있음.
프로그램에서 데이터 사본은 딱 하나만 생성됨. 즉, 각 인스턴스마다 데이터를 들고 있지 않음.
ScriptableObject를 상속하면 스크립터블 오브젝트를 생성할 수 있다.
리플렉션(Reflection)은 동적으로 타입에 대한 정보를 제공하는 시스템으로 GUI 툴을 만들 때 유용함
특성(Attributte)은 C# 언어의 구성 요소 중 하나로 클래스, 메소드, 필드 등의 요소에 대한 메타데이터(추가 정보)를 제공하는 특수한 클래스
라이팅은 어려우니, 나중에 쓸 일이 있으면 그 때 유니티 튜토리얼을 해보거나 매뉴얼을 보면서 다시 배우자.
참고 : Lost Crypt - New 2D Sample Project for Unity! (Overview)
오브젝트가 빛을 받았을 때 어떻게 보일지 미리 그려둔 텍스처
라이팅(빛을 쬐는 효과)은 연산 비용이 비싸기에, 라이트맵을 미리 구워둠으로써 실시간 연산량을 줄인다.
글로벌 일루미네이션(Global Illumination)
물체의 표면에 직접 들어오는 빛뿐만 아니라 다른 물체의 표면에서 반사되어 들어온 간접광까지 표현, GI
매우 높은 처리량을 요구하여 최신 PC 성능으로도 완전한 실시간 GI는 사용하기 힘들다.
사용하더라도 여러 제약과 대안을 함께 사용.
실시간 글로벌 일루미네이션
빛의 세기와 방향 등이 달라졌을 때 그 변화를 간접광에 실시간으로 반영
라이트맵을 여러 방향에 대해 생성해, 여러가지 경우에 대한 빛의 예상 반사 방향과 광원의 예상 이동 경로 등 정보를 미리 계산해 저장한다.
미리 계산했기에 게임 도중 빛의 방향이 달라져도 간접광을 적은 비용으로 추측할 수 있으며, 광원의 변화를 실시간으로 간접광에 반영할 수 있다.
이처럼 미리 계산은 하기에, 미리 계산된 실시간 GI(Precomputed realtime GI)라고도 부른다.
베이크된 글로벌 일루미네이션
고정된 빛에 의한 간접광들을 라이트맵으로 구워 게임 오브젝트 위에 입힌다.
반영된 간접광 효과는 게임 도중에 실시간으로 변하지 않는다.
실시간 글로벌 일루미네이션보다 표현의 질과 런타임 성능이 더 좋다.
빛이 게임 도중에 달라져도 간접광에 반영되지 않는다.
⇒ 이질감
점(Point) : 구형 조명
스팟(Spot) : 원뿔형 조명
직사광(Directional) : 태양광
3D파일 파일 포맷 : .fbx 등등
Rigidbody → Angular Drag : 각 항력. 회전에 대한 마찰력.
유한 상태 머신은 하나의 상태만 현재 상태가 될 수 있다.
여러 개의 유한 상태 머신을 병렬로 실행
⇒ 여러 상태를 현재 상태로 중첩되게 할 수 있다.
⇒ 애니메이터 레이어를 여러 개 사용하여 여러 애니메이션 상태를 오브젝트 하나에 중첩한다.
각 레이어에서 애니메이션이 위에서 아래 순서로 덮어쓰기(Override) 되어 재생된다.
레이어를 나누는 이유는 더 적은 애니메이션 클립으로 다양한 경우에 대응하기 위함이다.
휴머노이드 릭(Humanoid Rig)
리깅(Rigging) :
3D 모델의 골격과 움직임을 정의하는 조인트 계층 구조를 만드는 것
같은 타입(ex. 휴머노이드)으로 리깅된 3D 모델은 체형이 달라도 애니메이션 클립이 호환된다.
⇒ 리타게팅(Retargetting)
mixamo.com :
휴머노이드 릭의 애니메이션 다운로드 사이트
아바타 마스크
//ex
Vector3 offset1 = transform.forward * MoveSpeed * Time.fixedDeltaTime * _input.MoveDirection;
// Vector 연산 3번
// Vector3 * float => Vector3
// Vector3 * float * float => Vector3 * float => Vector3
// Vector3 * float * float * float => Vector3 * float * float => Vector3 * float => Vector3
Vector3 offset2 = MoveSpeed * Time.fixedDeltaTime * _input.MoveDirection * transform.forward;
// 최적화 : Vector 연산 1번
// float * float * float * Vector3 => float * float * Vector3 => float * Vector3 => Vector3
https://docs.unity3d.com/kr/current/Manual/com.unity.cinemachine.html
카메라의 움직임을 손쉽게 제어하는 유니티 공식 패키지
여기서 다루는 내용은 극히 일부이다. 연출을 더 적극 활용하려면 추가로 공부하자.
시네머신이 제공하는 카메라
브레인 카메라(Brain Camera)
가상 카메라(Virtual Camera)
씬에 여러 개 존재
설정을 저장하고 브레인 카메라가 이 중 하나를 골라 현재 활성화된 카메라로 이용
브레인 카메라가 그 위치로 이동해 설정을 모두 자신의 설정으로 사용한다.
추적의 세기 조절 - 에임(Aim)
데드존(Dead Zone) :
목표가 화면의 데드존에 있는 동안 카메라는 움직이지 않는다.
소프트존(Soft Zone) :
목표가 화면의 소프트존에 있다면 목표가 화면의 조준점(Aim)에 오도록 카메라가 부드럽게 움직인다.
목표는 소프트존을 벗어나지 않는다.
하드 리밋(Hard Limits) :
목표가 화면의 소프트존을 벗어나 하드 리밋에 도달하려 한다면 목표가 화면의 조준점(Aim)에 오도록 카메라가 빠르게(격하게) 움직인다.
따라서 목표는 소프트존을 벗어나지 않는다.
설정
외부와 통신하는 공개 통로이자, 통로의 규격
메시지를 정의하는데 사용된다.
C#의 클래스는 다중 상속을 지원하지 않는다
⇒ 인터페이스에 대해서는 예외이다.
인터페이스는 한번에 여러 개 구현할 수 있다.
인터페이스의 메소드는 선언만 존재하고, 구현은 상속 받는 클래스에 맡긴다.
이때, 구현은 public으로 해야한다.
public interface IFlyable
{
void Fly();
}
public interface IWalkable
{
void Fly();
}
public class Bird : IFlyable, IWalkable
{
public void Fly()
{
// fly
}
public void Walk()
{
// walk
}
}
https://docs.unity3d.com/kr/current/Manual/ParticleSystems.html
파티클이라고 부르는 매우 작은 이미지나 메시를 시뮬레이션하고 렌더링하여 시각 효과를 생성한다.
시스템의 각 파티클은 효과의 개별 그래픽 요소를 구현하고,
시스템은 모든 파티클을 종합적으로 시뮬레이션하여 완성된 효과를 구현한다.
파티클 시스템은 불, 연기, 액체 등과 같은 동적 오브젝트를 구현할 때 유용하다.
https://docs.unity3d.com/kr/current/Manual/class-ScriptableObject.html
Unity 2019 버전부터 나온 클래스
클래스 인스턴스와는 별도로 대량의 데이터를 저장하는 데 사용할 수 있는 데이터 컨테이너
값의 사본이 생성되는 것을 방지하여 프로젝트의 메모리 사용을 줄이는 것
⇒ 프로젝트의 공용 데이터
연결된 MonoBehaviour 스크립트에 변경되지 않는 데이터를 저장하는 프리팹
이 있는 프로젝트의 경우 유용
ScriptableObject를 이용하여 데이터를 저장한 후 모든 프리팹의 레퍼런스를 통해 접근 가능
⇒ 메모리에 데이터 사본을 하나만 저장한다
게임 오브젝트에 연결할 수 없으며 대신 프로젝트의 에셋으로 저장해야 한다
에디터 세션 동안 데이터 저장 및 보관
데이터를 프로젝트의 에셋으로 저장하여 런타임 시 사용
여러 오브젝트가 공유하여 사용할 데이터를 에셋 형태로 분리
데이터를 유니티 인스펙터 창에서 편집 가능한 형태로 관리
https://docs.microsoft.com/ko-kr/dotnet/csharp/programming-guide/concepts/attributes/
C#에서 제공하는 확장 기능, 특수 클래스
코드적으로 추가적인 정보(메타데이터)를 표현할 수 있다.
변수, 함수, 클래스 위에 특성 이름을 적어주면 된다
[CreateAssetMenu(menuName = "Scriptable/GunData", fileName = "Gun Data")]
public class GunData { }
https://docs.microsoft.com/ko-kr/dotnet/csharp/programming-guide/concepts/reflection
동적으로 어셈블리나 모듈, 타입에 대한 정보를 제공하는 시스템
프로그래밍 레벨에서 어떤 타입의 멤버에 관한 정보를 가져오거나,
메소드를 가져오거나 하는 등의 동작을 할 수 있다.
GUI를 만들 때 유용하다.