Notice
Recent Posts
Recent Comments
Link
«   2025/04   »
1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30
Tags
more
Archives
Today
Total
관리 메뉴

Luna

[TIL Day 24] Unity 게임 개발 입문 본문

🎮 Unity_7 TIL WIL

[TIL Day 24] Unity 게임 개발 입문

fociend 2025. 2. 14. 10:16

이번 주차는 이 우주 컨셉이다 ..

오늘은 새로운 주차에 들어갔으니.. TIL 이미지도 바꾸고 글도 조금 가독성 있게 써보려 한다. 

 

오늘의 학습 키워드

- 유니티 강의 1주차 시작

- 강의 과제, 실습하기
공부한 내용 본인의 언어로 정리하기

[ FlappyPlane 프로젝트 시작 ]

 

언제나 그랬듯이 프로젝트는 설치와 세팅부터 ... 

화면 세팅 끝 .. ! 😎

BackGround 색은 원하는 색으로 바꿔주었다. (추후에 바뀔 예정인듯)

 

🔹 씬(Scene)이란?

씬(Scene)은 Unity에서 게임의 한 장면을 의미.

씬은 게임의 무대이며, 게임 요소를 배치하고 구성하는 기본 단위

 

🔹 Orthographic 카메라

원근이 없는 평면적인 뷰 제공

2D 게임에 필수

 

🔹 카메라 사이즈?

카메라 사이즈는 Orthographic 카메라에서 화면에 표시되는 세로 범위를 결정하는 값입니다.

중심에서 위나 아래로 보이는 월드 유닛의 길이

 

스프라이트 자료를 따로 다운로드 해서 들고왔다.

https://kenney.nl/assets/tappy-plane

이 자료는 사진에 보이는 것과 같이 하나의 이미지가 아니라 여러개의 이미지로 나누어서 쓸 거기 때문에

Sprite Mode를 Single이 아닌 Multiple로 바꿔주면 된다.

 

또 이 설정에 있는 Filter Mode를 Point로 바꾸어 주어서 이미지의 외곽선을 깔끔하게 만들어줍니다.

이미지는 Sprite Editer로 직접 슬라이스 해줍니다. 

 

자른 이미지의 이름 수정은

에디터 내부에서 가능

 

PPU(Pixels Per Unit) : 말 그대로 "1유닛 안에 픽셀이 몇 개 들어가는지" 정하는 값.

🔹 기본 개념

  • Unity 기본 PPU 값은 100
    → 즉, 100px짜리 이미지가 게임 월드에서 1 유닛 크기로 보임.
  • PPU 값을 올리면? → 픽셀이 더 촘촘해져서 스프라이트가 작아짐.
  • PPU 값을 내리면? → 픽셀이 넓게 퍼지면서 스프라이트가 커짐.

🔹 픽셀 아트 게임에서는?

픽셀 아트 게임 만들 때는 보통 1유닛을 16px이나 32px로 설정
그리고 Filter Mode를 Point (no filter)로 바꿔주면 흐릿해지는 거 없이 깔끔한 픽셀 느낌 살릴 수 있음!

쉽게 말하면, PPU는 "이 이미지가 게임에서 얼마나 크게 보일까?"를 정하는 중요한 값이라고 보면 됨 

 

애니메이터(Animator)란?

Unity에서 애니메이션 상태를 관리하고 전환하는 도구. 캐릭터나 오브젝트의 동작을 자연스럽게 구현할 때 사용됨.

 

🔹 애니메이션 상태 관리
Idle, Walk, Run 같은 다양한 상태를 정의하고, 각 상태에 맞는 애니메이션을 연결함.

 

🔹 조건에 따라 전환
속도, 입력 값, Trigger 등 특정 조건에 따라 애니메이션 상태를 변경할 수 있음.
예: 플레이어가 이동 속도를 증가시키면 Idle 상태에서 Run 상태로 전환됨.

🔹 부드러운 연결
상태 전환 간 자연스러운 애니메이션 블렌딩을 통해 게임 플레이를 더 몰입감 있게 만들 수 있음! 😆

 

스프라이트 렌더러의 소팅 오더란? (Order in Layer)

 

Unity에서 Sprite Renderer의 Sorting Order는 스프라이트의 렌더링 순서를 결정하는 값
값이 높을수록 다른 스프라이트보다 앞에 렌더링됨.

 

🔹 기본 동작
같은 Sorting Layer에 있는 스프라이트들은 Sorting Order 값을 기준으로 렌더링 순서가 정해짐.
예: Sorting Order가 3이면 2인 스프라이트보다 앞에 그려짐.

🔹 Sorting Layer와의 관계
스프라이트는 먼저 Sorting Layer를 기준으로 그룹화된 다음, 그 안에서 Sorting Order 값으로 순서가 조정됨.

🔹 사용 예시
배경 스프라이트는 낮은 값을 줘서 뒤에 렌더링하고, 캐릭터나 전경 스프라이트는 높은 값을 줘서 앞에 나오게 하면 됨! 

 

Rigidbody 이용 할 때 체크 할 것! 

✅ Body Type이 Dynamic 인지

✅ Gravity Scale 1인지

 

리지드바디(Rigidbody)란?

Unity에서 Rigidbody는 오브젝트에 물리 엔진의 영향을 적용하는 컴포넌트
중력, 충돌, 힘과 같은 물리적인 동작을 처리할 때 사용됨.

🔹 중력 적용
Rigidbody가 추가된 오브젝트는 Unity의 물리 엔진에 의해 중력의 영향을 받음.
예:  공이 떨어지거나 캐릭터가 바닥으로 내려오는 동작.

🔹 힘과 속도
외부에서 힘(Force)을 가하거나 속도를 설정해서 오브젝트를 움직일 수 있음.
예:  폭발 효과로 오브젝트가 밀려나는 경우.

🔹 충돌 처리
Collider와 함께 사용하면 오브젝트 간의 충돌을 물리적으로 계산함.
예: 캐릭터가 벽에 부딪히거나 적과 충돌하는 동작.

🔹 Rigidbody의 주요 속성

  • Mass: 오브젝트의 무게를 설정
  • Drag: 공기 저항을 시뮬레이션해서 속도를 줄임.
  • Constraints: 특정 축의 움직임이나 회전을 제한 

📌 Unity 라이프사이클이란?

Unity에서 라이프사이클(Lifecycle)은 게임 오브젝트와 스크립트가 실행되는 순서를 정의

 

🔹 주요 단계

  • Awake: 스크립트가 활성화될 때 호출. 초기화 작업에 사용됨.
  • Start: 오브젝트가 활성화되고 첫 프레임 전에 한 번 호출됨.
  • Update: 매 프레임마다 호출. 주로 입력 처리와 게임 로직에 사용됨.
  • FixedUpdate: 물리 연산이 필요할 때 일정한 간격으로 호출됨.
  • LateUpdate: Update가 완료된 후 호출. 주로 카메라 추적 등에 사용됨.

🔹 중요성
각 단계가 명확히 구분되어 있어서, 적절한 함수에 코드를 배치하면 게임 로직을 더 효율적으로 만들 수 있음!

 

📌 GetComponent란?
Unity에서 GetComponent는 게임 오브젝트에 추가된 컴포넌트를 가져오는 메서드

컴포넌트를 통해 스크립트나 속성을 제어할 수 있음! 

 

📌 Input 클래스란?
Unity에서 Input 클래스는 사용자 입력(키보드, 마우스, 터치 등)을 처리하는 데 사용

🔹 주요 기능

  • 키보드 입력 처리: Input.GetKey, Input.GetKeyDown으로 특정 키 입력을 확인할 수 있음.
  • 마우스 입력 처리: Input.GetMouseButton으로 마우스 클릭을 확인할 수 있음.
  • 축 입력 처리: Input.GetAxis로 부드러운 이동을 구현할 수 있어. (예: Horizontal, Vertical)

📌 Time.deltaTime이란?
Time.deltaTime은 이전 프레임과 현재 프레임 사이의 시간을 반환

🔹 주요 역할
프레임 독립적인 움직임을 구현할 때 사용

예: speed * Time.deltaTime으로 일정한 속도로 이동할 수 있음! 

 

📌 충돌 처리 함수
Unity에서 충돌 처리는 ColliderRigidbody를 통해 구현

🔹 주요 함수

  • OnCollisionEnter: 충돌이 시작될 때 호출됨.
  • OnCollisionStay: 충돌이 계속되는 동안 매 프레임마다 호출됨.
  • OnCollisionExit: 충돌이 끝났을 때 호출됨.
  • OnTriggerEnter/Stay/Exit: Trigger Collider와의 상호작용을 처리하는 함수들

📌 로컬 좌표와 월드 좌표
Unity에서 로컬 좌표(Local Position)와 월드 좌표(World Position)는 오브젝트의 위치를 측정하는 기준

🔹 로컬 좌표(Local Position)

  • 부모 오브젝트를 기준으로 한 오브젝트의 위치.
  • 오브젝트가 부모 오브젝트 내에서 얼마나 떨어져 있는지를 나타냄.
  • 부모 오브젝트의 위치나 회전이 바뀌면 로컬 좌표는 상대적인 위치를 유지하면서 반영됨.

🔹 월드 좌표(World Position)

  • 게임의 전체 월드에서의 위치.
  • 부모 오브젝트와 관계없이, Unity의 전역 좌표계(0, 0, 0)를 기준으로 계산됨.

📌 변수를 public으로 선언하는 것
Unity에서 변수를 public으로 선언하면, 해당 변수를 다른 스크립트에서 접근 가능하게 만들고, Inspector 창에 노출시켜서 쉽게 값을 설정할 수 있음.

 

📌 프리팹(Prefab)이란?
Unity에서 Prefab(프리팹)은 게임 오브젝트를 재사용 가능한 형태로 저장한 에셋
한 번 만든 프리팹을 여러 곳에서 사용할 수 있어서 개발 효율을 높일 수 있음! 

 

GameManager 스크립트를 만든 뒤 싱글톤으로 만들어줌

public class GameManager : MonoBehaviour
{
    static GameManager gameManager;
    public static GameManager Instance { get { return gameManager; } }

    private void Awake()
    {
        gameManager = this;
    }
}

싱글톤 기본 모습

또 밑의 예시 처럼 return만 필요할 경우 이렇게 간단하게 코드를 짤 수도 있다.

if (isDead) return;

 

📌 싱글톤 패턴이란?

  • 싱글톤 패턴(Singleton Pattern)은 클래스의 인스턴스를 하나만 생성하도록 보장하는 디자인 패턴
  • Unity에서는 static 키워드를 사용해 쉽게 구현할 수 있음.

🔹 유일한 인스턴스

  • 클래스의 인스턴스는 프로그램 전역에서 단 하나만 존재하도록 제한됨.
    예: 게임 매니저, 오디오 매니저 등.

🔹 전역 접근

  • 클래스의 static 변수나 속성을 통해 어디서든 동일한 인스턴스에 접근할 수 있음.
    일반적으로 public static Instance 속성을 통해 구현됨.

🔹 static의 역할

  • 클래스 내에서 static 변수를 사용해 인스턴스를 저장.
  • static은 클래스 단위로 메모리를 공유하므로, 인스턴스가 하나만 유지되도록 보장됨.

🔹 장점

  • 데이터와 객체를 일관되게 공유할 수 있음.
  • 메모리 낭비를 방지하고 관리가 쉬움.

🔹 단점

  • 전역 상태로 인해 코드 테스트와 유지보수가 어려울 수 있음.
  • 의존성이 강해지면 코드 확장성이 떨어질 수 있음. 😅

에러사항 

// 오늘은 코딩하다 오류점은 없고 몰랐던 부분과 해결을 위주로 적음

📌 GetComponent vs GetComponentInChildren의 차이점

Unity에서 게임 오브젝트의 컴포넌트를 찾을 때 자주 쓰는 두 가지 메서드

 

1. GetComponent<T>()

GetComponent는 현재 게임 오브젝트에서만 컴포넌트를 찾는 메서드임.

  • 예시: GetComponent<Rigidbody>()
    • 이건 현재 객체에서 Rigidbody 컴포넌트를 찾는 것
  • 특징:
    • 자식 오브젝트는 찾지 않음. 현재 오브젝트에서만 찾음.

2. GetComponentInChildren<T>()

GetComponentInChildren은 현재 게임 오브젝트랑 자식 오브젝트들에서 컴포넌트를 찾는 것

  • 특징:
    • 자식 객체도 찾음. 자식 중 첫 번째로 찾은 컴포넌트를 반환함.

📌 차이점 요약

  • GetComponent<T>(): 현재 게임 오브젝트에서만 컴포넌트를 찾음.
  • GetComponentInChildren<T>(): 현재 게임 오브젝트랑 자식 게임 오브젝트들에서 컴포넌트를 찾음.

이렇게 두 가지 메서드는 상황에 맞게 사용하면 됨.

자식 객체까지 찾고 싶으면 GetComponentInChildren, 현재 객체에서만 찾고 싶으면 GetComponent를 쓰면 됨.

 

✔️ GetMouseButtonDown(int button)에서 int button 숫자값 종류

0. 왼쪽 클릭

1. 오른쪽 클릭

2. 휠

3. 뒤로가기

4. 앞으로 가기

 

📌 Mathf.Clamp()

Mathf.Clamp()는 Unity에서 숫자를 특정 범위 내로 제한하고 싶을 때 쓰는 함수

이 함수는 값이 최소값이나 최대값을 넘지 않도록 자동으로 조절해줌. 그래서 값이 범위를 벗어나지 않게끔 딱 맞게 조정해 줌.

 

사용법:

float Mathf.Clamp(float value, float min, float max);
  • value: 제한할 값
  • min: 허용되는 최소값
  • max: 허용되는 최대값

동작 방식:

  • 만약 valuemin보다 작으면, min을 반환
  • 만약 valuemax보다 크면, max를 반환
  • 만약 valueminmax 사이에 있으면, value 그대로 반환

예시:

float result = Mathf.Clamp(10f, 0f, 5f);
// result는 5f. (10은 5보다 크니까 최대값인 5로 제한!)

result = Mathf.Clamp(3f, 0f, 5f);
// result는 3f. (3은 범위 안에 있으니까 그대로 3이 반환!)

result = Mathf.Clamp(-2f, 0f, 5f);
// result는 0f. (-2는 0보다 작아서 최소값인 0으로 제한)

 

결론:

Mathf.Clamp()는 값을 정해진 범위로 안전하게 제한하고 싶을 때 정말 유용하게 쓸 수 있는 함수

 

📌 Quaternion.Euler()

Quaternion.Euler()는 Unity에서 회전을 다룰 때 사용하는 함수

이 함수는 오일러 각을 이용해서 Quaternion 회전값을 만드는 데 사용됨.

오일러 각은 x, y, z 축에 대한 회전 각도를 의미하고, 이 값을 기반으로 Quaternion 회전값을 계산해서 객체를 회전시킬 수 있음.

 

사용법:

Quaternion Quaternion.Euler(float x, float y, float z);
  • x: x축 회전 각도 (degree 단위)
  • y: y축 회전 각도 (degree 단위)
  • z: z축 회전 각도 (degree 단위)

동작 방식:

Quaternion.Euler()는 x, y, z 축에 대한 오일러 각을 입력받아, 그에 맞는 Quaternion 회전값을 반환

Quaternion은 회전값을 다루기 위한 수학적 표현이라, 여러 번 회전이 겹쳐지거나 복잡한 회전 동작을 처리할 때 유용

예시:

// x축으로 90도 회전
transform.rotation = Quaternion.Euler(90f, 0f, 0f);

// y축으로 45도 회전
transform.rotation = Quaternion.Euler(0f, 45f, 0f);

// z축으로 180도 회전
transform.rotation = Quaternion.Euler(0f, 0f, 180f);

요약:

  • Quaternion.Euler()는 오일러 각을 사용해서 회전값을 계산하고, 그 값을 Quaternion으로 변환해줌.
  • 이 함수는 주로 회전을 쉽게 다룰 수 있게 해주고, transform.rotation에 적용할 수 있음.

Quaternion을 사용할 때는 오일러 각을 직접 쓰는 것보다 가독성이나 회전의 안정성을 고려해서 사용하는 게 좋음.

 

📌  SetInteger()

SetInteger()는 Unity에서 Animator 컴포넌트의 파라미터를 설정할 때 사용하는 메서드

이 메서드는 애니메이션 상태를 전환하거나 특정 애니메이션을 제어하는 데 유용하게 쓰임.

SetInteger()는 이름 그대로 정수형 파라미터 값을 설정할 때 사용됨.

 

사용법:

animator.SetInteger(string parameterName, int value);
  • parameterName: 설정하려는 애니메이터의 파라미터 이름. 애니메이터 컨트롤러에서 설정한 파라미터의 이름을 넣어줌.
  • value: 파라미터로 설정할 정수 값. 이 값에 따라 애니메이션의 상태가 바뀌거나 다른 동작이 실행될 수 있음.

동작 방식:

  • SetInteger()는 애니메이터의 파라미터 중 정수형 파라미터를 설정하는 데 사용됨.
  • 예를 들어, 애니메이터에서 캐릭터의 상태에 따라 다른 애니메이션을 재생하고자 할 때 이 메서드를 사용해서 파라미터 값을 변경할 수 있다.
  • 애니메이터에 설정된 Transition(전환)에 따라 값이 바뀔 때 애니메이션이 변경될 수 있음.

예시:

// "State"라는 이름의 정수형 파라미터를 1로 설정
animator.SetInteger("State", 1);

// "State"라는 이름의 정수형 파라미터를 2로 설정
animator.SetInteger("State", 2);

애니메이터에서 사용 예시:

  1. 애니메이터에 State라는 정수형 파라미터를 만들고, 각 숫자에 따라 다른 애니메이션 상태를 설정.
  2. 코드에서 SetInteger()를 사용해 State 값을 변경하고, 애니메이터가 그에 맞게 애니메이션을 전환.

요약:

SetInteger()는 정수형 파라미터를 설정하는 메서드로, 주로 애니메이션 상태를 변경하는 데 사용됨.

애니메이터 컨트롤러에서 파라미터에 따라 애니메이션을 전환할 때 유용하게 쓸 수 있다. 😊

 

📌 GameObject.FindObject(s)OfType<T>()

GameObject.FindObjectOfType<T>()는 Unity에서 특정 타입을 가진 첫 번째 게임 오브젝트를 찾는 데 사용되는 메서드.

주로 씬에 있는 특정 종류의 컴포넌트를 찾고자 할 때 사용됨. 만약 그 타입에 맞는 객체가 없다면 null을 반환.

 

사용법:

T GameObject.FindObjectOfType<T>();
  • T: 찾고자 하는 타입. 예를 들어, Player, Enemy, Rigidbody 같은 컴포넌트나 클래스 타입을 넣을 수 있음.

이 함수는 씬에 있는 첫 번째 해당 타입의 객체를 찾아 반환함.

그래서 여러 개의 같은 타입이 있다면 첫 번째 객체만 찾을 수 있음. 만약 그 타입이 씬에 없다면 null을 반환함.

 

주의사항:

  • GameObject.FindObjectOfType<T>()는 씬에서 단 하나만 찾을 수 있음. 만약 여러 개의 객체가 필요하다면 FindObjectsOfType<T>()를 사용해야 함.
  • 이 메서드는 성능상 문제가 있을 수 있어서 최소한으로 사용하는 게 좋음. 여러 번 호출하면 게임 성능에 영향을 줄 수 있음.

FindObjectsOfType<T>()와의 차이점:

  • GameObject.FindObjectOfType<T>(): 첫 번째로 발견된 타입 하나만 반환.
  • GameObject.FindObjectsOfType<T>(): 씬에 있는 모든 타입 객체들을 배열로 반환.

예시 (FindObjectsOfType<T>):

Enemy[] enemies = GameObject.FindObjectsOfType<Enemy>();
  • 씬에서 모든 Enemy 객체들을 배열로 반환. FindObjectOfType는 하나만 반환되지만, FindObjectsOfType는 여러 개를 반환할 수 있음.

요약:

GameObject.FindObjectOfType<T>()는 씬에서 첫 번째로 발견되는 특정 타입의 게임 오브젝트를 찾는 메서드

여러 개가 필요하다면 FindObjectsOfType<T>()를 사용하는 게 좋음. 성능에 민감하니까 꼭 필요한 경우에만 사용하는 게 좋음! 😊

 

⚠️ 유니티에서 Create Empty 생성 할 때 Transform 리셋 하기 ⚠️

 

오늘의 회고

오늘은 새로운 조에서 새로운 분들과 만났다. (이미 알고 계신 분도 한 분 계셨지만)

그래서 뭔가 새롭고 새로시작하는 느낌이라 좋다.

유니티 1주차 첫 프로젝트를 하루만에 완강했다! 

사실 3번째 프로젝트까지 다 해버리고 싶었지만 당연하게도 시간 부족. 

모르는 함수들 찾아보다보니 시간이 많이 흘렀다. 그래도 첫 프로젝트 완강해서 뿌듯함. 


내일 공부할 것

내일은 주말입니다 ^---^ 🌟💖