개발 TIL

내일배움캠프 17일차 TIL Unity 기초 배운내용 정리

yun-wj1126 2025. 2. 14. 22:10

PPU란 1Unity 유닛에 몇 개의 픽셀이 들어가는지를 결정하는 값이다

위와같이 작은 네모 한칸을 1 unity 유닛인데 기본적으로 PPU는 100으로 설정되어 있다.

텍스처 크기가 100 픽셀일 경우 Unity에서 1유닛으로 렌더링된다.

PPU가 크면 텍스처가 더 작게보이고 픽셀이 좀더 촘촘히 배치된다.

PPU가 작으면 텍스처가 더 크게보이고 픽셀이 더 넓게 배치된다.


배경이나 사물을 반복적으로 보이게 할때 복제하는 편한 단축키가 있다.

오브젝트를 선택 -> Ctrl + D를 통해 복제 -> 복제한 오브젝트를 선택한 후 V를 누른 상태로 모서리를 드래그 앤 드롭

이렇게 하면 쉽게 복사 붙여넣기를 할 수 있다.

 


transform.GetComponentInChildren<>();

InChildren을 사용시 내 오브젝트 뿐만 아니라 내 자식 오브젝트까지 검색해서 가져온다.

 


Mathf.Clamp는 주어진 값이 특정범위를 벗어나지 않도록 제한하는 함수이다.

사용이유

1. 값이 특정 범위를 벗어나지 않도록 하기 위해

2. 사용자 입력 제한

3. 게임 오브젝트의 위치 제한

4. 주로 체력, 속도, 입력값, 위치제한 등 에서 많이 사용됨

 


transform.rotation = Quaternion.Euler(0,0,lerpAngle)

 

4원소 쿼터니언의 오일러의 법칙을 사용할때

손가락을 이렇게 만든 다음 z축을 검지로 두고 축으로

회전시키면 어디 축으로 회전시킬 어떻게 회전될지 있다.

 

사용이유

1. Quaternion은 회전을 다룰 때 필수적인 데이터 타입이지만 사람이 이해하기 쉬운 Vector3 형태의 오일러 각도를 그대로 사용할 수 없어 Euler를 사용해서 직관적인 오일러 각도를 Quaternion으로 변환할 수 있어서 사용

2. 오브젝트 회전 적용

3. 부드러운 회전을 위해 (Lerp, Slerp 활용)

4. 깁발 현상 방지 : 오일러 각도를 직접 사용하면 특정 각도에서 축이 겹쳐버리는 "깁발현상"이 발생할 수 있는데 Quaternion을 사용하면 방지할 수 있다.

 


Time.deltaTime

실제 누적되는 시간을 사용할 때 사용함

성능이 다른 컴퓨터들은 성능를 맞춰줄 때 즉 실제로 이동하는 값을 맞춰줄때 사용

저프레임은 뚝뚝 끊어지고 고프레임은 부드럽게 이동하겠지만 결국 동일한 시간에 동일한 거리를 이동할 수 있다.

 

사용 이유

1. Time.deltaTime을 곱하면 프레임 속도와 상관없이 일정한 속도로 움직임 유지

2. 애니메이션이나 보간을 부드럽게 처리 가능

3. 물리 연산 시 Time.fixedDeltaTime 사용

프레임 속도가 달라도 동일한 속도로 동작하게 하려면 꼭 활용해야함


Collision과 Trigger

 

Collision

실제 물리 충돌이 발생하며 오브젝트가 밀려남

충돌 감지 시 오브젝트가 물리적으로 반응(예: 튕기거나 멈춤)

사용 목적: 벽에 부딪히는 캐릭터, 떨어지는 박스 등

사용 조건 :

 두 오브젝트 모두 collider가 있어야함

 최소한 하나는 Rigidbody가 있어야함

 isTrigger를 비활성화 해야함

 OnCollisionEnter(), OnCollisionStay(), OnCollisionExit() 를 사용하여 충돌 이벤트 처리

 

Trigger

충돌 감지만 하고, 물리적인 반응 없음

오브젝트가 서로 겹쳐도 반응하지 않고 이벤트만 발생.

사용 목적: 문을 자동으로 여는 센서, 아이템 줍기, 적의 감지 범위

사용 조건 :

 isTrigger를 활성화 해야함

 Rigidbody는 필수가 아님(하지만 필요하면 isKinematic으로 설정 가능

 OnTriggerEnter(), OnTriggerStay(), OnTriggerExit()을 사용하여 이벤트 처리

 

물리적으로 반응해야 한다면 collision 사용

충돌 감지만 하고 싶다면 Trigger 사용

예를 들어, 플레이어가 문을 통과할 때 트리거를 사용하여 자동 문이 열리게 만들고, 벽에 부딪힐 때는 콜리전을 사용하여 멈추게 하면 됨


로컬 좌표(Local Position)와 월드 좌표(World Position)의 차이점

 

1. 월드 좌표 (World Position)

씬(Scene) 내에서의 절대적인 위치

(0,0,0)이 씬의 중심(월드 원점)이며, 모든 오브젝트의 위치는 이 기준으로 설정됨

오브젝트가 씬 전체에서 어디에 있는지를 나타냄

transform.position을 사용하면 월드 좌표를 가져올 수 있음

부모-자식 관계와 무관하게 절대적인 위치를 나타냄

 

사용 예시

플레이어가 맵 내에서 정확히 어디에 있는지 확인할 때

적이 특정 위치(예: 목표 지점)로 이동해야 할 때

 

2. 로컬 좌표 (Local Position)

부모 오브젝트를 기준으로 한 상대적인 위치

부모 오브젝트의 위치가 바뀌면, 자식 오브젝트의 로컬 위치도 영향을 받음

 

오브젝트가 부모(Parent) 기준으로 어디에 있는지를 나타냄

transform.localPosition을 사용하면 로컬 좌표를 가져올 수 있음

부모가 이동하면, 자식 오브젝트도 함께 움직이지만, 로컬 좌표는 그대로 유지됨

 

사용 예시

캐릭터의 손(자식 오브젝트)에 무기가 붙어 있을 때

자동차(부모)가 움직여도, 바퀴(자식)는 상대적인 위치를 유지해야 할 때

 

 

 

오브젝트의 전역적인 위치를 다룰 때? → transform.position (월드 좌표)

부모를 기준으로 상대적인 위치를 다룰 때? → transform.localPosition (로컬 좌표)

 

예를 들어,

적이 플레이어에게 이동해야 한다면 transform.position을 사용해야 함

무기를 캐릭터의 손에 부착하려면 transform.localPosition을 사용해야 힘


((BoxCollider2D)collision)을 사용하는 이유는 충돌한 Collider를 BoxCollider2D 타입으로 변환(casting)하여, BoxCollider2D의 특정 기능이나 속성을 사용하기 위함

 

Collider2d 모든 콜라이더의 부모클래스라 값을 가져올수없어서 collision boxcollider 변환을 해서 사이즈를 가져온다. 왜냐하면 background라는 태그를 가진 애들은 boxcollider 달아놨기 때문에 boxcollider 변환해서 가로 사이즈를 가져온다.

 

여러가지 사용예시

충돌한 오브젝트가 100% BoxCollider2D일 때 → (BoxCollider2D)collision.collider

충돌한 오브젝트가 여러 종류의 Collider2D를 가질 가능성이 있을 때 → collision.collider as BoxCollider2D

Collider 외의 다른 컴포넌트도 확인해야 할 때 → collision.gameObject.GetComponent<BoxCollider2D>()

 


싱글톤 패턴을 초기화 하는것이 awake 때문에 플레이어에서 동시간때에 접근을하면 꼬일수도 있다

그렇기 때문에 Start 이용해서 접근하는게 좋다.

 


싱글톤 패턴

싱글톤 패턴은 클래스의 인스턴스를 단 하나만 생성하고, 어디서든 접근할 수 있도록 보장하는 디자인 패턴

Unity에서 게임 매니저, 오디오 컨트롤러, 데이터 관리 시스템전역적으로 하나만 존재해야 하는 객체를 만들 때 많이 사용

싱글톤 패턴을 사용하는 이유

1. 전역적으로 접근할 수 있도록 하기 위해

2. 하나의 인스턴스만 유지하여 메모리 낭비 방지

3. 객체 간 데이터 공유가 쉬워짐

4. 오브젝트의 중복 생성을 방지하여 버그를 예방

단점

1. 테스트가 어려움 : 전역 인스턴스를 사용하므로 의존성이 높아 유닛 테스트가 어렵다

2. 멀티스레딩 문제 : 멀티스레드 환경에서는 동기화를 추가해야 할 수도 있음

3. 클래스 간 결합도 증가 : 싱글톤을 여러 곳에서 직접 참조하면, 유지보수가 어려워질 수 있음

 

싱글톤을 사용하면 좋은 경우

게임에서 전역적으로 하나만 존재해야 하는 객체

데이터를 저장하고 공유하는 매니저 클래스

오디오 시스템, UI 매니저, 네트워크 매니저 등

 

하지만 무조건 싱글톤을 사용하면 코드의 결합도가 높아질 수 있기 때문에, 필요한 경우에만 사용하는 것이 좋음


Lerp

Lerp(Linear Interpolation, 선형 보간)은 두 값을 일정한 비율로 보간하여 부드럽게 변화시키는 함수
Unity에서는 위치, 회전, 색상 변화 등 다양한 애니메이션 효과를 만들 때 자주 사용

Lerp(a, b, t)는 a와 b 사이의 값을 t(0~1 사이의 값) 비율만큼 보간하는 함수야.

 

a: 시작 값

b: 끝 값

t: 보간 비율 (0 ~ 1)

 

float result = Mathf.Lerp(0, 100, 0.5f); 
// 0과 100 사이의 중간 값 (50)을 반환

 

t = 0이면 a 값을 반환
t = 1이면 b 값을 반환
t = 0.5이면 a와 b의 중간 값을 반환

 

장점

1. 부드러운 전환 : 갑작스러운 변화를 막고 자연스럽게 이동/변화

2. 간다한 구현 : 복잡한 수식 없이 두 값 사이를 쉽게 보간

3. 다양한 활용 가능 : 위치이동, 색상변화, UI 애니메이션 등

 

주의점

1. 완전히 목표 값에 도달하지 않음 : Lerp는 무한히 가까워지지만 완전히 도달하지 않음 → Mathf.Approximately()로 일정 거리 이하일 때 도착으로 처리

2. 속도가 점점 느려짐  : Lerp는 t가 작을수록 변화량이 적어짐 → SmoothDamp()를 사용하면 더 자연스러운 감속 가능

3. 고정된 속도로 이동하려면? : Vector3.MoveTowards()를 사용하면 일정한 속도로 이동 가능

 

사용 시기

오브젝트를 점진적으로 이동하거나 변화할 때

갑작스러운 변화 없이 부드러운 애니메이션이 필요할 때

색상, 위치, 크기 등을 자연스럽게 변화시킬 때

 

사용 방식

1. 오브젝트 위치 부드럽게 이동할때

2. 색상 변화

3. 부드러운 카메라 이동

 


newTrans.parent = this.transform;

 

newTrans 오브젝트의 부모(Parent)를 현재 오브젝트(this.transform)로 설정하는 코드

즉, newTrans가 현재 오브젝트의 자식(Child) 오브젝트가 되도록 만드는 역할

 

사용 이유

1. 계층 구조(Parent-Child) 설정 

2. 특정 오브젝트에 동적으로 생성된 오브젝트를 붙이기 : 예를 들어, 플레이어가 무기를 주웠을 때 무기가 플레이어의 손(자식)으로 설정됨

3. UI 오브젝트를 특정 부모 아래에 배치 : UI에서 버튼, 텍스트 등을 특정 패널의 자식으로 추가할 때 사용 가능

 

주의할 점

현재는 Transform.parent는 사용하지 않고 SetParent() 사용해야 함

Unity에서는 transform.parent 대신 SetParent() 사용을 권장

SetParent()는 worldPositionStays 옵션을 설정할 수 있어서, 부모를 바꿀 때 월드 좌표 유지 여부를 설정할 수 있음

newTrans.SetParent(this.transform, false); // 부모의 위치 기준으로 배치
newTrans.SetParent(this.transform, true);  // 원래 위치 유지

 

사용 시기

 

오브젝트를 동적으로 생성하고 특정 부모 아래에 추가할 때

부모 오브젝트와 같이 움직이는 자식을 만들 때

UI에서 버튼, 이미지 같은 요소를 특정 패널 안에 배치할 때

 

 

newTrans.parent = this.transform; → 부모-자식 관계 설정 (하지만 SetParent() 사용 추천)

부모를 설정하면 자식은 부모의 위치, 회전, 크기를 따라감.

게임 내 프리팹, UI 요소 배치, 장비 시스템 등에 활용 가능

 


프로젝트 생성시 라이브러리가 잘못 생성된 것이며 프로젝트 종료 후 프로젝트 폴더 내 라이브러리 삭제 후 프로젝트를 재실행하면 됨

실행하고 씬 다시 눌러서 들어가야함!