유니티(Unity)를 공부하며 물리 시스템과 이벤트 함수의 핵심 개념을 정리했다. 이번 학습은 물리 기반 힘 적용과 유니티의 이벤트 함수 동작 방식을 이해하는 데 초점을 맞췄으며, 실제 프로젝트에서 테스트하며 얻은 경험을 반영했다.
1. 물리 시스템: 연속적인 힘과 순간적인 힘
유니티의 물리 시스템에서 힘은 오브젝트의 움직임을 제어하는 핵심 요소다. 힘의 적용 방식은 연속적인 힘과 순간적인 힘으로 나뉜다.
연속적인 힘
- 정의: 자동차 엑셀처럼 지속적으로 가속을 추가하는 방식이다. 이미 움직이는 오브젝트에 적합하다.
- ForceMode:
- ForceMode.Force: 오브젝트의 질량을 고려해 힘을 적용한다.
- ForceMode.Acceleration: 질량을 무시하고 가속을 적용한다.
- 구현 경험: 차량 이동 로직을 구현하며 ForceMode.Force를 사용해 무게감 있는 가속을 테스트했다. 초기에는 가속이 너무 급격해 부자연스러웠으나, 힘의 크기를 조정해 부드럽게 만들었다.
- 배운 점: 연속적인 힘은 지속적인 움직임을 구현할 때 유용하며, 질량에 따라 동작이 달라진다는 점을 고려해야 한다.
순간적인 힘
- 정의: 뒤에서 미는 것처럼 순간적으로 속도를 부여하는 방식이다. 정지 상태에서 움직임을 시작할 때 적합하다.
- ForceMode:
- ForceMode.Impulse: 질량을 고려해 순간적인 힘을 적용한다.
- ForceMode.VelocityChange: 질량을 무시하고 속도를 즉시 변경한다.
- 구현 경험: 캐릭터 점프를 구현하며 ForceMode.Impulse를 사용했다. 점프 높이가 일정하지 않은 문제를 발견하고, Rigidbody의 질량과 힘의 크기를 조정해 해결했다.
- 배운 점: 순간적인 힘은 빠른 반응이 필요한 상황에서 효과적이며, Impulse와 VelocityChange의 차이를 이해하는 것이 중요하다.
물리 설정
- Project Settings > Physics: 중력, 마찰 등 물리 값을 조정할 수 있다. 예를 들어, 중력을 낮춰 점프의 느낌을 조정하며 테스트했다.
- 배운 점: 물리 설정은 게임의 전반적인 느낌에 큰 영향을 미친다. 디테일한 조정이 필수적이다.
2. 이벤트 함수
이벤트 함수는 별도의 호출 없이 자동으로 실행되며, 호출 시점이 정해져 있다. 유니티의 생명주기와 상호작용을 관리하는 데 핵심적인 역할을 한다.
Reset()
- 정의: 스크립트가 에디터에서 처음 연결되거나 Reset 명령 실행 시 호출된다.
- 구현 경험: 컴포넌트 초기 설정을 위해 Reset()을 사용했으나, 예상치 못한 호출로 변수가 초기화되는 문제를 겪었다. 호출 시점을 명확히 파악해 해결했다.
- 배운 점: Reset()은 에디터 작업에 유용하지만, 런타임에는 영향을 미치지 않으므로 주의해야 한다.
Awake(), OnEnable(), Start()
- 정의:
- Awake(): 오브젝트 생성 직후, 모든 스크립트 로드 시 호출된다. 초기화 작업에 사용된다.
- OnEnable(): 오브젝트 또는 스크립트 활성화 시 호출되며, Awake() 이후, Start() 이전에 실행된다.
- Start(): 첫 프레임의 Update() 직전에 호출되며, 다른 스크립트 초기화에 의존하는 작업에 적합하다.
- 순서: Awake() -> OnEnable() -> Start()
- 구현 경험: Awake()에서 참조를 설정하고, Start()에서 참조를 활용하는 패턴을 적용했다. 초기에는 OnEnable()의 호출 시점을 몰라 혼란스러웠으나, 문서를 참고해 명확히 이해했다.
- 배운 점: 초기화 순서를 정확히 파악하면 안정적인 스크립트 설계가 가능하다.
OnDisable()
- 정의: 오브젝트 또는 스크립트 비활성화 시 호출된다.
- 구현 경험: 오브젝트 풀링을 구현하며 OnDisable()에서 리소스 정리를 처리했다. 비활성화 시점이 명확해 코드가 간결해졌다.
- 배운 점: OnDisable()은 리소스 관리와 상태 초기화에 유용하다.
OnCollisionXXX vs OnTriggerXXX
- 정의:
- OnCollisionXXX: 물리적 충돌(충격, 마찰 등)을 처리하며, OnCollisionEnter, OnCollisionStay, OnCollisionExit 등이 있다.
- OnTriggerXXX: 물리 연산 없이 트리거 충돌을 감지하며, OnTriggerEnter, OnTriggerStay, OnTriggerExit 등이 있다.
- 구현 경험: 적과의 충돌을 OnCollisionEnter로 처리하며 데미지를 적용했다. OnCollisionStay가 예상보다 호출되지 않는 문제를 발견하고, Rigidbody의 Sleeping Mode를 Never Sleep으로 변경해 해결했다.
- 배운 점: Collision은 물리적 상호작용, Trigger는 논리적 이벤트 처리에 적합하다. Sleeping Mode 설정은 물리 안정성에 영향을 미친다.
OnMouseXXX
- 정의: Collider가 있는 오브젝트에서 마우스 입력(또는 터치)을 감지한다.
- OnMouseDown: 클릭 시 호출.
- OnMouseUp: 클릭 해제 시 호출.
- OnMouseDrag: 클릭 중 드래그 시 호출.
- 구현 경험: UI 버튼 대신 3D 오브젝트 클릭을 구현하며 OnMouseDown을 사용했다. 터치 입력이 제대로 감지되지 않는 문제를 해결하기 위해 Collider 크기를 조정했다.
- 배운 점: OnMouseXXX는 간단한 상호작용 구현에 유용하지만, 모바일 환경에서는 터치 처리에 주의해야 한다.
FixedUpdate()
- 정의: 고정된 시간 간격(기본 0.02초)으로 호출되며, 물리 연산에 적합하다. Edit > Project Settings > Time > Fixed Timestep에서 간격을 조정할 수 있다.
- 구현 경험: 캐릭터 이동을 Update()로 처리했으나, 프레임 드롭으로 불균일한 움직임이 발생했다. FixedUpdate()로 전환해 안정적인 물리 처리를 구현했다.
- 배운 점: FixedUpdate()는 기기 성능에 관계없이 일정한 물리 계산을 보장한다.
LateUpdate()
- 정의: Update() 이후 호출되며, 카메라 이동 등 후처리 작업에 사용된다.
- 구현 경험: 카메라가 캐릭터를 따라가도록 LateUpdate()에서 위치를 조정했다. Update()에서 처리했을 때 카메라가 끊기는 문제를 해결했다.
- 배운 점: LateUpdate()는 오브젝트 이동 후 보정 작업에 최적이다.
OnBecameVisible() / OnBecameInvisible()
- 정의: 오브젝트가 카메라에 보이거나 사라질 때 호출된다.
- 구현 경험: UI 요소의 렌더링 최적화를 위해 OnBecameInvisible()에서 리소스를 비활성화했다. Scene 뷰로 인해 OnBecameVisible()이 예기치 않게 호출되는 문제를 Scene 뷰 비활성화로 해결했다.
- 배운 점: Scene 뷰와 Game 뷰의 상호작용을 고려해야 정확한 테스트가 가능하다.
3. 개발 중 주요 이슈와 해결
- Sleeping Mode 문제: OnCollisionStay가 중단되는 문제를 Rigidbody의 Sleeping Mode 설정으로 해결했다. 물리 설정의 디테일한 조정이 중요함을 깨달았다.
- 이벤트 함수 혼란: Awake(), OnEnable(), Start()의 호출 순서를 혼동해 초기화 오류가 발생했다. 공식 문서와 테스트로 순서를 명확히 정리했다.
- 카메라 이동 끊김: Update()에서 카메라 이동을 처리했을 때 부자연스러운 움직임을 LateUpdate()로 전환해 해결했다.
4. 마무리
이번 학습을 통해 유니티의 물리 시스템과 이벤트 함수의 동작 방식을 깊이 이해할 수 있었다. 특히 힘의 적용 방식과 이벤트 함수의 호출 시점이 게임 로직 설계에 큰 영향을 미친다는 점을 체감했다.
'공부 > 유니티' 카테고리의 다른 글
괴혼 클론 코딩하기 (0) | 2023.09.15 |
---|---|
유니티 핵심 개념 정리 - Gizmo, Sprite, 스크립트 생명주기, 코루틴, 쓰레드 등 (0) | 2023.08.11 |
유니티 핵심 개념 정리 - URP, 컴포넌트, 입력 시스템, 물리 (0) | 2023.02.20 |
개발일지: 유니티로 플래피 버드 클론 게임 개발 (0) | 2022.12.30 |
개발일지: BangUlEe Dinogame - 공룡 게임 클론 개발 (0) | 2022.12.30 |