스파르타코딩클럽_Unity개발과정

유니티 입문 강의 - The Stack

ybbro 2025. 5. 1. 15:22


1. Increment Snapping

강의 내용은 아니지만 오늘은 친구로부터 좋은 기능을 하나 배웠습니다!


씬 뷰에서 작업하다 이런 생각을 한번씩은 해보았을 것입니다.

 

드래그만으로
10의 간격으로 오브젝트를 배치할 수 없나?
90도씩 돌아가게끔 만들 수는 없나?
스케일을 1씩 키울 수 없나?

 

그런데 이게 가능했었습니다.


씬 뷰 상단탭 >> Increment Snapping

컨트롤 키를 누른 상태로 각 조작 방법별로 오브젝트를 잡고 드래그할 때 각 항목의 한번의 변화량
을 여기서 설정할 수 있습니다.


2. Mathf.PingPong(float t, float length)

이름 그대로 핑퐁. 탁구 랠리처럼 왔다갔다 하는 것을 표현할 때 씁니다.

자체적으로 증가하는 t 값이 필요 (그래프의 x축)
t의 값에 따라 0~length(y축 최대값)까지 왔다갔다 하는 값을 리턴

 

 

3. 중복 구문의 규칙을 만들고 개선

강의에서 다룬 해당 메서드에서는

x, z축 방향 이동하는 블럭에 대해 동일한 식을 2번씩 쓰는 것을 보고


이를 수식으로 만들어 통합하며
조각의 중심점의 연산 과정을 줄여 개선하였습니다.

    // stackBounds는 강의 내용에서는 Vector2를 사용했으나 수식화를 위해 Vector3로 변경. 기존 y값을 z값으로 옮겼습니다.

	bool PlaceBlock()
    {
        // 이번 블럭의 로컬 위치
        Vector3 lastPos = lastBlock.localPosition;

        // 어느 축 방향으로 움직이는지
        // xz평면, y축은 높이
        // x == 0, z == 2
        // 기본은 z축 방향 이동값
        int axisIndex = 2;
        // x축 방향 이동하면 값 변경
        if (isMovingX)
            axisIndex = 0;

        // 이번에 블록을 쌓을 때 오차의 양
        // lastPos[0] == lastPos.x, lastPos[2] == lastPos.z
        float delta = Mathf.Abs(prevBlockPosition[axisIndex] - lastPos[axisIndex]);
        // 오차가 음수인지 >> 떨어지는 조각 생성 방향
        bool isNegative = delta < 0;

        // 정확히 쌓기에 실패
        if (delta > errorMargin)
        {
            float stackBounds_orgin = stackBounds[axisIndex];
            // 오차만큼 다음에 생성될 블럭의 사이즈 조정
            stackBounds[axisIndex] -= delta;
            // 잘린 이후 해당 축의 사이즈가 0 이하가 되면 게임오버
            if (stackBounds[axisIndex] <= 0)
                return false;

            // 잘려서 쌓일 블럭의 새로운 중점
            float middle = (prevBlockPosition[axisIndex] + lastPos[axisIndex]) / 2f;
            // 쌓은 블럭의 스케일을 조정(플레이어는 여기서 잘렸다고 느낌)
            lastBlock.localScale = new Vector3(stackBounds.x, 1, stackBounds.z);

            // 스케일 변화에 맞춰 이번에 쌓은 블럭의 좌표 경신
            Vector3 tempPos = lastBlock.localPosition;
            tempPos[axisIndex] = middle;
            lastBlock.localPosition = lastPos = tempPos;

            // 잘린 부분처럼 보이는 조각 생성
            // 조각의 중심점
            Vector3 rubblePos = (isMovingX ? Vector3.right : Vector3.forward)
                              * (lastPos[axisIndex] + (isNegative ?  - stackBounds_orgin / 2  : + stackBounds_orgin / 2)) // 잘린 부분으로 이동해주기 위한 좌표
                              + Vector3.up * lastPos.y
                              + (isMovingX ? Vector3.forward : Vector3.right) * lastPos[Mathf.Abs(axisIndex-2)];

            Vector3 rubbleScale = isMovingX ? new Vector3(delta,1, stackBounds.z) : new Vector3(stackBounds.x, 1, delta);
            CreateRubble(rubblePos, rubbleScale);

            // 콤보 초기화
            comboCount = 0;
        }
        // 쌓기에 성공
        else
        {
            // 콤보 체크
            ComboCheck();
            // y축 좌표 +1(블록 두께는 1 고정)
            lastBlock.localPosition = prevBlockPosition + Vector3.up;
        }

        // 다음 블럭 움직임의 중심점
        secondaryPosition = lastBlock.localPosition[axisIndex];

        return true;
    }

 

 

4. 포스트 프로세싱 (Post-Processing)

렌더링이 완료된 게임 화면에 추가 그래픽 효과를 적용하는 기술

렌더링 파이프라인의 마지막 단계에서 이루어지며,

화면의 전반적인 분위기를 변경 및 시각적인 품질을 개선

그러나,
추가적인 GPU 리소스를 요구하기에 과도한 사용은 성능 저하를 유발할 수 있음.
특히 모바일 환경에서는 최적화 중요

과도하게 사용할 경우 시각적 혼란 초래

여러 Volume 사용 시 우선순위를 설정해야 충돌하지 않음

<<주요 기능 >>

1) Bloom (블룸)

밝은 영역에서 빛이 번지는 효과 추가. 더 화려하고 빛나는 느낌

예) 판타지 게임의 마법 효과, 태양빛 등

 

2) Color Grading (색 보정)

화면 전체의 색상, 채도, 명도를 조정하여 특정 분위기 연출

예) 따뜻한 색조로 아늑한 느낌, 차가운 색조로 긴장감 있는 느낌 등

 

3) Depth of Field (초점 효과)

특정 영역에만 초점. 나머지 영역은 흐릿하게
예) 집중해서 보여줄 영역만 초점. 나머지는 흐릿하게

 

4) Motion Blur (모션 블러)

빠르게 움직이는 물체 주변에 잔상. 더 자연스럽고 역동적 연출

예) 레이싱 게임에서 차량의 속도감 강조

 

5) Ambient Occlusion (환경광 차폐)

표면 간의 좁은 공간에서 빛이 닿지 않는 어두운 영역을 추가하여 더 사실적인 그림자 표현

예) 벽과 바닥 모서리에 미세한 어두움

 

6) Vignette (비네트)

화면 가장자리를 어둡게 하여 중앙에 집중도를 높이는 효과

예) 긴장감 있는 장면에서 플레이어의 시선 유도

 

7) Chromatic Aberration (색수차)

렌즈의 왜곡 효과를 추가하여 화면 가장자리에 색 번짐 연출

예) 과장된 스릴, 혼란스러운 장면 등에서 나옴

 

8) Lens Distortion(렌즈 왜곡)

렌즈로 화면을 보듯이 굴곡 추가

<< 간단한 사용법 예시 >>

1) 패키지 설치

패키지 매니저 >> Unity Registry >> Post Processing 검색 >> Install


2) PostProcessVolume 컴포넌트

빈 오브젝트 생성 >> Add Component >> Post-Process Volume 추가

해당 과정은 예시입니다. 필요한 효과를 주기 위해서는 공부하여 여러 효과를 조합해야 합니다.


(1) isGlobal : 전체에 전처리를 하기 위해 체크

(2) Profile >> New 버튼 >> Bloom 생성

(3) Bloom의 드롭다운을 열기 >> intensity(강도) 체크로 활성화 >> 값 써주기


3) PostProcessVolume 오브젝트 레이어 설정

인스펙터 상단 Layer 드롭다운 >> Add Layer...
>> 포스트 프로세싱에 쓸 레이어 생성(위 이미지의 PostProcessing 레이어)
>> PostProcessVolume 오브젝트에 적용

 

 

4) Post-process Layer

강의에서는 카메라와 연관이 있으니 메인 카메라 오브젝트에 추가하였으나,

트리거 설정이 있는 것으로 보아선 어디 있어서 무방한 것으로 보입니다.


(1) Trigger: 해당 전처리기를 사용하여 처리할 트랜스폼 선택 (여기서는 메인 카메라)

(2) Layer : 드롭다운을 눌러 위에서 생성한 전처리 용도의 레이어

 

<< 적용 >>

Bloom 적용 전
Bloom 적용 후

 

빛 번짐 효과가 생기며 살짝 흐릿하고 화사한 느낌이 들게끔 바뀌었습니다.