* 해당 글은 유니티 게임 개발 수업 후 정리한 글입니다
https://bootcamp.likelion.net/school/kdt-ugm-5th
유니티 게임 개발 5기 : 멋사 부트캠프
개발부터 출시까지! 나만의 게임을 세상에 선보이는 유니티 부트캠프
bootcamp.likelion.net
* Update()
일반적인 작업용
이동 작업을 transform으로 직접 조작할 경우 여기서 처리하나,
이 방식은 프레임 스킵이 발생하면 그만큼 렌더링이 지연되어 지연되고,
지연된 만큼 한 번에 이동되기 때문에 순간이동처럼 보일 수 있다
또, transform으로 이동하는 경우, 물리 엔진을 거치지 않아 충돌 감지가 발생하지 않는다
[🤔 그럼 여기서 물리엔진 계산하면 되잖아]
물리 엔진은 고정된 시간 간격(Fixed Timestep)으로 계산된다
대부분 Update 속도가 훨씬 빠르며,
프레임마다 속도를 갱신하지만, 물리 엔진이 아직 계산을 반영하기 전 상태에서 덮어쓰게 되므로
이로 인해 이동 타이밍과 충돌 판정 타이밍이 엇갈리면서, 불안정한 움직임, 충돌 처리 누락, 끊김 등이 발생할 수 있다
* FixedUpdate()
물리 연산 작업용
Rigidbody를 이용한 물리 기반 작업은 여기서 처리하지 않으면 연산 타이밍이 꼬일 수 있다
[❓ Why]
물리 엔진은 고정된 시간 간격으로 계산하기 때문이다
* 최종적인 결론
입력은 Update에서
물리 엔진을 이용한 이동은 FixedUpdate에서
float input;
void Update()
{
// 입력은 Update에서
input = Input.GetAxisRaw("Horizontal");
}
void FixedUpdate()
{
// 이동은 FixedUpdate에서
rb.velocity = new Vector2(input * speed, rb.velocity.y);
}
* 타일맵(Tilemap)
이미지를 작은 타일로 나눠 격자 형태로 배치해서, 큰 배경이나 맵을 효율적으로 구성하는 방식
큰 배경 이미지를 통째로 가져가면 메모리 부담이 크지만,
작은 이미지를 반복해서 배치하면 동일한 리소스를 재사용하게 되므로 빌드 용량이 훨씬 가벼워진다
그 결과, 컴파일과 빌드 시간도 줄일 수 있다
* 타일 팔레트(Tile Palette)
타일맵 작업을 위해, 타일 이미지를 마치 물감을 팔레트에 올려두듯 정리해 놓는 도구
필요한 타일을 여기서 선택해서 씬에 배치할 수 있도록 도와준다
Window > 2D > Tile Palette
* Tilemap Collider 2D
타일맵마다 개별적인 Collider를 자동 생성해주는 컨포넌트
타일 하나마다 Collider가 생성되므로 경계선이 많아지고, 그로 인해 물리 연산이 비효율적이다
* Composite Collider 2D
여러 개의 Collider를 하나의 커다란 콜라이더로 합쳐주는 최적화 도구
성능 향상과 충돌 경계 단순화를 위해 자주 사용되며, Tilemap Collider 2D와 함께 쓰인다
[Edge Radius]
Collider 외곽선의 가장자리를 부드럽게 둥글리는 정도를 나타낸다
값이 클수록 둥글게 처리되어, 이동 가능한 영역이 그만큼 줄어든다
* Rigidbody 2D(Static 설정)
정적인 지형용으로 적절한 설정이며, 물리 시뮬레이션 전에 Collider를 미리 생성해두는 방식
즉, 런타임 중에 계산하지 않고, 씬 실행 시점에 이미 계산돼 있어서 성능에 유리하다
Composite Collider를 쓰려면 반드시 Rigidbody 2D가 필요하며, 이때는 Static 설정을 쓰는 게 일반적이다
* 지금 공부하고 있는 방식은 상하좌우 이동만 가능한 2D 캐릭터 조작 게임으로, 중력이나 회전이 필요하지 않음
[따라서]
물리 엔진에서 중력을 0으로, Freeze Rotation의 Z축을 체크하여 안정적인 이동 구현 가능
[만약 중력과 회전이 있다면]
중력에 의해 콜라이더의 둥근 곡면을 따라 미끄러지거나, 충돌 시 회전이 발생해 구르는 듯한 동작이 나타난다
둥근 곡면이 없더라도 충돌 시 물리 회전이 적용되어 기울어지거나 옆으로 눕는다
* 유니티의 UI 이벤트 시스템 인터페이스
UI 오브젝트나 Collider가 붙은 GameObject에서만 이벤트가 발생하며,
반드시 EventSystem과 Raycaster 구성 필요
[정리]
UI 오브젝트인 경우
- EventSystem
- Canvas + GraphicRaycaster
Collider가 붙은 GameObject(2D 기준)
- EventSystem
- Physics2DRaycaster
(1) IPointerDownHandler
마우스 버튼 또는 터치가 눌렸을 때 호출됨
void OnPointerDown(PointerEventData eventData)
(2) IDragHandler
마우스 또는 터치를 누르고 움직일 때(= 드래그) 호출됨
void OnDrag(PointerEventData eventData)
(3) IPointerUpHandler
마우스 버튼 또는 터치가 떼어졌을 때 호출됨
void OnPointerUp(PointerEventData eventData)
* 조이스틱 방향 벡터 코드
// direction1(방향 + 거리 포함) → 정규화 안된 상태
var dragDirection = _currPosition - _startPosition;
https://shine94.tistory.com/462
[Unity] 수학과 Unity 관점에서 벡터와 스칼라 정리
* 수학에서의 백터와 스칼라 (1) 스칼라(Scalar) 크기만 갖는 값 (예) 5m, 섭씨 20도, 256바이트, 4000 칼로리 (2) 벡터(Vector) 크기 + 방향을 갖는 값 (예) 30m/초 동쪽, 약 5마일 북쪽, 힘, 가속도 [정리하자면
shine94.tistory.com
* magnitude
벡터의 길이(방향은 무시됨)
* normalized
방향만 유지하고 길이를 1로 만든 벡터
* 조이스틱 드래그 방향 처리 코드
public void OnPointerDown(PointerEventData eventData)
{
_startPosition = eventData.position;
}
public void OnDrag(PointerEventData eventData)
{
_currPosition = eventData.position;
var dragDirection = _currPosition - _startPosition;
// distance : 거리
// +75f, -75f : X/Y축 조이스틱 입력의 최대값(조이스틱 범위 제한)
var maxDistance = Mathf.Min(dragDirection.magnitude, 75f);
// _startPosition : 조이스틱 원래 위치
// dragDirection.normalized * maxDistance : 드래그 방향값 * 최대 거리 75f
handlerUI.transform.position = _startPosition + dragDirection.normalized * maxDistance;
}
public void OnPointerUp(PointerEventData eventData)
{
// 드래그 종료 시 조이스틱 핸들 위치 초기화
handlerUI.transform.position = Vector2.zero;
}
* 조이스틱 UI 구성 및 설정 경로
Canvas > Joystick(빈 오브젝트) > Background(조이스틱 배경) > Handle(방향 표시 이미지)
ㄴ Joystick(빈 오브젝트)의 Image 컴포넌트는 투명도 0으로 설정해야 함
* ForceMode2D
(1) Force
지속적으로 작용하는 힘(Continuous Force)
FixedUpdate마다 누적 적용되어 속도를 점점 증가시키는 가속도
(예) 바람, 물살처럼 꾸준히 밀어내는 힘
rigidbody2D.AddForce(Vector2.right * 10f, ForceMode2D.Force);
이 경우, FixedUpdate마다 10만큼의 가속도가 누적되어 점점 빨라진다
(2) Impulse
순간적인 충격(Instantaneous Impulse)
한 순간에 속도를 즉시 변화시키는 힘
점프, 충돌, 폭발처럼 짧고 강한 충격을 줄 때 사용
rigidbody2D.AddForce(Vector2.up * 10f, ForceMode2D.Impulse);
이 경우, 한 번만 힘이 적용되며 질량에 따라 속도 변화량이 결정된다
FixedUpdate 마다 반복 적용되지 않고, 딱 한 번 즉시 작용된다
* 애니메이션 블렌딩 시 실수했던 점
처음에 2D Simple Directional을 선택했는데, 이 블렌드 타입은 방향 값이 180도 이상인 경우를 처리할 수 없다
수업에서 사용했던 방향 값(예: -1, 0, 1)처럼 양방향 입력이 필요한 경우에는 2D Freeform Directional을 선택해야 했다
* AudioSound
동시에 여러 개의 사운드를 재생할 수 없기 때문에, 효과음을 겹쳐 재생하려면 각각 AudioSound가 필요하다
ㄴ 소리를 중첩시킬 때, 애니메이션의 이벤트와 연결하여 트리거로 활용하기도 한다
* Time.timeScale(영상 재생 시 배속 조절과 유사한 개념)
유니티의 시간의 흐름 속도를 조절할 수 있는 속성이다
기본 값은 1f이며, 이는 정상적인 시간 흐름이다
값을 0f으로 설정하면 시간이 완전히 정지되며, 애니메이션, 이동, 물리 처리 등 모두 멈춘다
'게임프로그래밍 > Unity_C#' 카테고리의 다른 글
[멋쟁이사자처럼부트캠프] 유니티 게임 개발 5기(2025.06.16-2025.06.19) (0) | 2025.06.27 |
---|---|
[멋쟁이사자처럼부트캠프] 유니티 게임 개발 5기(2025.06.09-2025.06.13) (0) | 2025.06.27 |
[멋쟁이사자처럼부트캠프] 유니티 게임 개발 5기(2025.06.04-2025.06.05) (0) | 2025.06.05 |
[멋쟁이사자처럼부트캠프] 유니티 게임 개발 5기(2025.05.29-2025.05.30) (0) | 2025.06.04 |
[멋쟁이사자처럼부트캠프] 유니티 게임 개발 5기(2025.05.26-2025.05.28) (0) | 2025.05.28 |