본 콘텐츠의 이미지 및 내용은 AI로 생성되었습니다.
본 콘텐츠의 이미지 및 내용을 무단으로 복제, 배포, 수정하여 사용할 경우 저작권법에 의해 법적 제재를 받을 수 있습니다.
이미지 로딩 중...
AI Generated
2026. 2. 2. · 3 Views
Flame 엔진 충돌 감지 완벽 가이드
Flutter의 Flame 게임 엔진에서 충돌 감지를 구현하는 방법을 알아봅니다. Hitbox 추가부터 CollisionCallbacks 사용, 디버깅까지 게임 개발에 필수적인 충돌 처리의 모든 것을 다룹니다.
목차
1. 충돌 감지 개념
김개발 씨가 첫 번째 게임을 만들고 있습니다. 플레이어 캐릭터가 적과 부딪히면 게임 오버가 되어야 하는데, 두 스프라이트가 겹쳐도 아무 일도 일어나지 않습니다.
"어떻게 해야 캐릭터끼리 부딪힌 걸 알 수 있지?"
**충돌 감지(Collision Detection)**는 게임에서 두 객체가 서로 접촉했는지 확인하는 기술입니다. 마치 자동차 범퍼에 달린 센서가 장애물과의 거리를 감지하는 것처럼, 게임 엔진도 객체들의 경계를 검사하여 충돌 여부를 판단합니다.
Flame 엔진에서는 HasCollisionDetection 믹스인과 Hitbox 컴포넌트를 조합하여 이 기능을 구현합니다.
다음 코드를 살펴봅시다.
// Flame 게임에서 충돌 감지 시스템 활성화
class MyGame extends FlameGame with HasCollisionDetection {
@override
Future<void> onLoad() async {
// 충돌 감지가 활성화된 게임에 컴포넌트 추가
await add(Player());
await add(Enemy());
}
}
// 충돌 감지 시스템은 매 프레임마다 모든 Hitbox를 검사합니다
// HasCollisionDetection이 없으면 충돌이 감지되지 않습니다
김개발 씨는 입사 전부터 꿈꿔왔던 모바일 게임 개발에 도전하고 있습니다. Flutter와 Flame 엔진을 사용해 간단한 슈팅 게임을 만드는 중이었죠.
플레이어가 총알을 발사하고, 적을 맞추면 점수가 올라가는 게임입니다. 문제는 총알이 적을 그냥 통과해버린다는 것이었습니다.
화면상으로는 분명히 총알과 적이 겹쳐 보이는데, 게임 로직에서는 아무 일도 일어나지 않았습니다. 선배 개발자 박시니어 씨가 김개발 씨의 코드를 살펴봅니다.
"아, 충돌 감지 시스템을 켜지 않았네요. Flame에서는 명시적으로 활성화해야 해요." 그렇다면 충돌 감지란 정확히 무엇일까요?
쉽게 비유하자면, 충돌 감지는 마치 교차로의 신호등 시스템과 같습니다. 신호등은 여러 방향에서 오는 차량들을 감시하고, 동시에 같은 지점을 통과하려 할 때 이를 감지하여 제어합니다.
마찬가지로 게임의 충돌 감지 시스템도 매 프레임마다 모든 객체의 위치를 확인하고, 겹치는 부분이 있는지 검사합니다. 충돌 감지가 없던 시절의 게임은 어땠을까요?
초창기 개발자들은 모든 객체 쌍의 좌표를 직접 비교해야 했습니다. 객체가 10개만 되어도 45번의 비교가 필요했고, 100개면 4,950번의 비교가 필요했습니다.
코드는 복잡해지고, 성능은 급격히 떨어졌습니다. 바로 이런 문제를 해결하기 위해 게임 엔진들은 최적화된 충돌 감지 시스템을 제공합니다.
Flame 엔진에서는 HasCollisionDetection 믹스인을 게임 클래스에 추가하는 것만으로 충돌 감지 시스템이 활성화됩니다. 이 시스템은 내부적으로 공간 분할 알고리즘을 사용하여 불필요한 비교를 줄이고, 성능을 최적화합니다.
위의 코드를 살펴보겠습니다. FlameGame 클래스에 with HasCollisionDetection을 추가한 것이 전부입니다.
이 한 줄이 게임 전체의 충돌 감지 시스템을 활성화합니다. 실제 게임에서는 플레이어와 적의 충돌, 총알과 적의 충돌, 플레이어와 아이템의 충돌 등 다양한 상호작용이 필요합니다.
HasCollisionDetection은 이 모든 것의 기반이 됩니다. 하지만 주의할 점이 있습니다.
HasCollisionDetection만 추가한다고 충돌이 감지되는 것은 아닙니다. 각 게임 객체에 Hitbox를 추가해야 합니다.
Hitbox는 다음 장에서 자세히 다루겠습니다. 다시 김개발 씨의 이야기로 돌아가 봅시다.
박시니어 씨의 설명을 들은 김개발 씨는 게임 클래스에 HasCollisionDetection을 추가했습니다. 이제 충돌 감지의 첫 걸음을 뗀 것입니다.
실전 팁
💡 - HasCollisionDetection은 반드시 FlameGame 클래스에 추가해야 합니다
- 충돌 감지 시스템은 기본적으로 비활성화되어 있으므로 명시적 선언이 필수입니다
2. Hitbox 추가하기
충돌 감지 시스템을 활성화한 김개발 씨. 하지만 여전히 충돌이 감지되지 않습니다.
박시니어 씨가 말합니다. "시스템만 켜면 끝이 아니에요.
각 객체에 '이 영역이 내 몸이야'라고 알려줘야 해요."
Hitbox는 게임 객체의 충돌 영역을 정의하는 컴포넌트입니다. 마치 사람이 헬멧과 보호대를 착용하듯, 게임 캐릭터에게 보이지 않는 충돌 영역을 입혀주는 것입니다.
Flame은 RectangleHitbox, CircleHitbox, PolygonHitbox 세 가지 기본 Hitbox를 제공합니다.
다음 코드를 살펴봅시다.
class Player extends SpriteComponent with CollisionCallbacks {
@override
Future<void> onLoad() async {
// 스프라이트 크기에 맞는 사각형 Hitbox 추가
add(RectangleHitbox());
}
}
class Bullet extends CircleComponent with CollisionCallbacks {
@override
Future<void> onLoad() async {
// 원형 객체에는 CircleHitbox가 적합
add(CircleHitbox());
}
}
// Hitbox 크기를 직접 지정할 수도 있습니다
// add(RectangleHitbox(size: Vector2(50, 100)));
김개발 씨는 HasCollisionDetection을 추가했지만, 여전히 총알이 적을 통과합니다. 뭔가 빠진 것 같았습니다.
박시니어 씨가 설명을 이어갑니다. "충돌 감지 시스템은 켜졌지만, 각 객체에게 '어디까지가 내 몸인지' 알려주지 않았어요.
그게 바로 Hitbox예요." Hitbox는 마치 권투 선수의 바디 프로텍터와 같습니다. 실제 선수의 몸은 복잡한 형태지만, 판정을 위해서는 단순화된 영역이 필요합니다.
게임에서도 마찬가지입니다. 복잡한 스프라이트 이미지 대신, 단순한 도형으로 충돌 영역을 정의합니다.
왜 스프라이트 이미지 그대로 충돌을 감지하지 않을까요? 픽셀 단위의 충돌 감지는 매우 무거운 연산입니다.
60fps 게임에서는 1초에 60번씩 모든 객체의 모든 픽셀을 비교해야 합니다. 반면 사각형이나 원의 충돌은 단순한 수학 공식으로 빠르게 계산할 수 있습니다.
Flame은 세 가지 기본 Hitbox를 제공합니다. RectangleHitbox는 가장 많이 사용되는 형태입니다.
사각형 영역으로 충돌을 감지하며, 대부분의 게임 캐릭터에 적합합니다. 인자 없이 사용하면 부모 컴포넌트의 크기를 그대로 따릅니다.
CircleHitbox는 원형 충돌 영역입니다. 공, 총알, 동전 같은 원형 객체에 적합합니다.
원의 충돌 감지는 두 점 사이의 거리만 계산하면 되므로 매우 빠릅니다. PolygonHitbox는 다각형 충돌 영역입니다.
삼각형, 오각형 등 복잡한 형태가 필요할 때 사용합니다. 세 가지 중 가장 연산이 무겁습니다.
위의 코드에서 Player 클래스를 보겠습니다. CollisionCallbacks 믹스인을 추가하고, onLoad에서 RectangleHitbox를 자식으로 추가합니다.
이것만으로 플레이어는 사각형 충돌 영역을 갖게 됩니다. Bullet 클래스는 원형이므로 CircleHitbox를 사용했습니다.
총알처럼 작고 둥근 객체는 원형 Hitbox가 더 자연스럽습니다. 실제 게임에서는 Hitbox 크기를 세밀하게 조정하는 경우가 많습니다.
캐릭터 스프라이트보다 Hitbox를 약간 작게 만들면 플레이어에게 여유를 주는 "관대한" 판정이 됩니다. 반대로 크게 만들면 "엄격한" 판정이 됩니다.
주의할 점은 CollisionCallbacks 믹스인도 반드시 추가해야 한다는 것입니다. 이 믹스인이 없으면 Hitbox가 있어도 충돌 이벤트를 받을 수 없습니다.
김개발 씨는 Player와 Enemy 클래스에 각각 Hitbox를 추가했습니다. 이제 충돌 영역은 정의되었습니다.
다음은 충돌했을 때 어떤 일이 일어날지 정의할 차례입니다.
실전 팁
💡 - 기본 Hitbox는 부모 컴포넌트 크기를 따르므로, 커스텀 크기가 필요하면 size 파라미터를 사용하세요
- 성능을 위해 가능한 단순한 형태의 Hitbox를 선택하세요 (Circle > Rectangle > Polygon)
3. CollisionCallbacks 사용
Hitbox까지 추가한 김개발 씨. 이제 충돌 자체는 감지되는 것 같은데, "충돌했을 때 뭘 해야 하는지"를 어디에 적어야 할지 모르겠습니다.
박시니어 씨가 웃으며 말합니다. "콜백 메서드를 오버라이드하면 돼요."
CollisionCallbacks는 충돌 이벤트를 처리하는 콜백 메서드들을 제공하는 믹스인입니다. onCollision은 충돌이 지속되는 동안 매 프레임 호출되고, onCollisionStart는 충돌이 시작될 때 한 번만 호출되며, onCollisionEnd는 충돌이 끝날 때 한 번 호출됩니다.
상황에 맞는 콜백을 선택하여 게임 로직을 구현합니다.
다음 코드를 살펴봅시다.
class Player extends SpriteComponent with CollisionCallbacks {
@override
void onCollisionStart(
Set<Vector2> intersectionPoints,
PositionComponent other,
) {
super.onCollisionStart(intersectionPoints, other);
// 충돌한 상대가 적인지 확인
if (other is Enemy) {
// 게임 오버 처리
gameOver();
} else if (other is PowerUp) {
// 파워업 획득
collectPowerUp(other);
}
}
}
김개발 씨는 Hitbox를 추가한 뒤 게임을 실행해 보았습니다. 하지만 여전히 아무 일도 일어나지 않습니다.
충돌은 감지되고 있을 텐데, 그 결과를 어떻게 처리해야 할까요? 박시니어 씨가 설명합니다.
"Hitbox는 '충돌 영역'이고, CollisionCallbacks는 '충돌했을 때 할 일'을 정의하는 거예요. 전화기와 전화 받는 사람의 관계라고 생각하면 돼요." 비유를 확장해 보겠습니다.
Hitbox는 전화기의 수신 안테나와 같습니다. 전화가 왔다는 신호를 감지합니다.
CollisionCallbacks는 전화를 받는 사람입니다. 신호를 받아서 실제로 응답합니다.
CollisionCallbacks 믹스인은 세 가지 핵심 콜백 메서드를 제공합니다. onCollisionStart는 두 객체가 처음 충돌하는 순간 딱 한 번 호출됩니다.
적과 부딪혀서 데미지를 받거나, 아이템을 획득하는 등 "한 번만 실행되어야 하는" 로직에 적합합니다. onCollision은 두 객체가 겹쳐 있는 동안 매 프레임 호출됩니다.
용암 위에 서 있으면 계속 데미지를 받는다거나, 치유 영역에 있으면 지속적으로 체력이 회복되는 등 "지속적인" 효과에 적합합니다. onCollisionEnd는 두 객체가 분리되는 순간 한 번 호출됩니다.
안전 지역을 벗어나면 경고 메시지를 표시하는 등의 로직에 사용됩니다. 위의 코드에서 Player 클래스는 onCollisionStart를 오버라이드합니다.
이 메서드는 두 가지 파라미터를 받습니다. intersectionPoints는 충돌 지점들의 좌표 집합입니다.
두 객체가 어느 지점에서 만났는지 알 수 있습니다. 총알이 적의 머리에 맞았는지, 몸통에 맞았는지 구분할 때 유용합니다.
other는 충돌한 상대 객체입니다. 타입을 확인하여 적인지, 아이템인지, 벽인지 구분하고 그에 맞는 처리를 합니다.
코드에서 is 키워드로 타입을 체크하는 부분에 주목하세요. other가 Enemy 타입이면 게임 오버를, PowerUp 타입이면 파워업 획득을 처리합니다.
이런 패턴은 게임 개발에서 매우 흔하게 사용됩니다. 주의할 점은 super 호출입니다.
콜백을 오버라이드할 때는 반드시 super 메서드를 먼저 호출해야 합니다. 그렇지 않으면 충돌 시스템이 제대로 작동하지 않을 수 있습니다.
김개발 씨는 onCollisionStart에서 적과의 충돌 처리 로직을 추가했습니다. 드디어 총알이 적에 맞으면 적이 사라지기 시작했습니다.
실전 팁
💡 - 한 번만 실행되어야 하는 로직은 onCollisionStart를, 지속적인 효과는 onCollision을 사용하세요
- super 호출을 잊지 마세요. 충돌 시스템의 내부 상태 관리에 필요합니다
4. 간단한 충돌 처리
이제 충돌 콜백까지 이해한 김개발 씨. 본격적으로 게임 로직을 구현하기 시작합니다.
총알이 적에게 맞으면 적이 사라지고, 플레이어가 적과 부딪히면 체력이 줄어야 합니다. 이 모든 것을 어떻게 조합할까요?
실제 게임에서는 여러 종류의 객체 간 충돌을 각각 다르게 처리해야 합니다. 타입 체크로 충돌 상대를 구분하고, removeFromParent로 객체를 제거하며, 게임 상태를 적절히 업데이트합니다.
충돌 처리는 양쪽 객체 중 한 곳에서만 하는 것이 일반적입니다.
다음 코드를 살펴봅시다.
class Bullet extends CircleComponent with CollisionCallbacks {
@override
void onCollisionStart(
Set<Vector2> intersectionPoints,
PositionComponent other,
) {
super.onCollisionStart(intersectionPoints, other);
if (other is Enemy) {
// 적 처치 시 점수 추가
gameRef.score += 100;
// 적 제거
other.removeFromParent();
// 총알도 제거
removeFromParent();
}
}
}
김개발 씨의 슈팅 게임이 점점 모양을 갖추고 있습니다. 이제 총알이 적에게 맞으면 둘 다 사라지고 점수가 올라가야 합니다.
어떻게 구현할까요? 박시니어 씨가 조언합니다.
"충돌 처리는 한 곳에서만 하세요. 양쪽에서 모두 처리하면 같은 일이 두 번 일어나거나, 예상치 못한 버그가 생길 수 있어요." 이 조언은 매우 중요합니다.
총알과 적이 충돌하면, onCollisionStart가 총알 측에서 한 번, 적 측에서 한 번, 총 두 번 호출됩니다. 만약 양쪽 모두에서 점수를 올리면 점수가 두 배로 오르는 버그가 생깁니다.
일반적으로 충돌 처리는 공격하는 측에서 담당합니다. 총알이 적을 맞추는 것이므로, 총알 클래스에서 처리하는 것이 자연스럽습니다.
위의 코드를 살펴보겠습니다. Bullet 클래스의 onCollisionStart에서 먼저 other가 Enemy인지 확인합니다.
총알은 벽이나 다른 총알과도 부딪힐 수 있으므로, 적과의 충돌만 특별히 처리해야 합니다. gameRef.score += 100은 게임의 점수를 올립니다.
gameRef는 Flame에서 현재 게임 인스턴스에 접근하는 방법입니다. 점수, 레벨, 게임 상태 등 전역적인 데이터는 보통 게임 클래스에 저장합니다.
**other.removeFromParent()**는 적을 게임에서 제거합니다. removeFromParent는 Flame 컴포넌트를 부모로부터 분리하여 더 이상 업데이트되거나 렌더링되지 않게 합니다.
**removeFromParent()**를 한 번 더 호출하여 총알 자신도 제거합니다. 총알은 적을 맞추면 사라져야 하니까요.
여기서 중요한 점이 있습니다. removeFromParent는 즉시 객체를 제거하지 않습니다.
현재 프레임이 끝난 후 안전하게 제거됩니다. 따라서 removeFromParent 호출 직후에도 객체의 속성에 접근할 수 있습니다.
만약 적 측에서도 충돌 처리가 필요하다면 어떻게 할까요? 예를 들어 적이 맞을 때 폭발 이펙트를 생성해야 한다면요?
그런 경우에는 적 클래스에 takeDamage 같은 메서드를 만들고, 총알에서 그 메서드를 호출하는 것이 좋습니다. 이렇게 하면 충돌 감지는 한 곳에서, 반응 로직은 각 객체가 담당하게 되어 깔끔한 구조가 됩니다.
김개발 씨는 이 패턴을 적용하여 총알-적 충돌, 플레이어-적 충돌, 플레이어-아이템 충돌을 각각 구현했습니다. 게임이 점점 완성되어 가고 있습니다.
실전 팁
💡 - 충돌 처리는 "공격하는 측" 또는 "능동적인 측" 한 곳에서만 구현하세요
- removeFromParent 후에도 같은 프레임 내에서는 객체에 접근할 수 있습니다
5. 경계 박스 충돌
김개발 씨의 게임에 새로운 문제가 생겼습니다. 플레이어나 적이 화면 밖으로 나가버립니다.
"화면 가장자리에 보이지 않는 벽을 만들어야 할 것 같은데..." 박시니어 씨가 말합니다. "ScreenHitbox를 사용해 보세요."
ScreenHitbox는 게임 화면의 경계를 Hitbox로 만들어주는 특별한 컴포넌트입니다. 이를 활용하면 객체가 화면 밖으로 나가는 것을 감지하거나, 화면 가장자리에서 반사되는 효과를 구현할 수 있습니다.
화면 밖으로 나간 총알을 자동으로 제거하여 메모리 누수를 방지하는 데에도 유용합니다.
다음 코드를 살펴봅시다.
class MyGame extends FlameGame with HasCollisionDetection {
@override
Future<void> onLoad() async {
// 화면 경계 Hitbox 추가
await add(ScreenHitbox());
await add(Player());
}
}
class Bullet extends CircleComponent with CollisionCallbacks {
@override
void onCollisionStart(
Set<Vector2> intersectionPoints,
PositionComponent other,
) {
super.onCollisionStart(intersectionPoints, other);
// 화면 밖으로 나가면 총알 제거
if (other is ScreenHitbox) {
removeFromParent();
}
}
}
슈팅 게임을 테스트하던 김개발 씨가 이상한 현상을 발견했습니다. 게임을 오래 플레이할수록 점점 느려지는 것이었습니다.
메모리 사용량을 확인해 보니, 화면 밖으로 나간 총알들이 계속 메모리에 남아있었습니다. "총알이 화면을 벗어나면 제거해야 해요.
안 그러면 보이지 않는 총알들이 계속 쌓여서 성능이 떨어져요." 박시니어 씨의 말에 김개발 씨는 고개를 끄덕였습니다. 화면 경계와의 충돌을 감지하는 가장 쉬운 방법은 ScreenHitbox를 사용하는 것입니다.
ScreenHitbox는 마치 게임 화면 테두리에 보이지 않는 벽을 세우는 것과 같습니다. 이 벽은 렌더링되지 않지만, 다른 Hitbox와 충돌을 일으킵니다.
객체가 이 벽에 닿으면 화면 경계에 도달했다는 것을 알 수 있습니다. 사용법은 간단합니다.
게임의 onLoad에서 **ScreenHitbox()**를 추가하면 됩니다. 이것만으로 화면 전체를 감싸는 Hitbox가 생성됩니다.
이제 총알 클래스에서 ScreenHitbox와의 충돌을 처리합니다. onCollisionStart에서 other가 ScreenHitbox인지 확인하고, 맞다면 removeFromParent로 총알을 제거합니다.
이 패턴은 매우 유용합니다. 화면 밖으로 나간 객체를 자동으로 정리하여 메모리 누수를 방지합니다.
수백 발의 총알을 발사해도 게임이 느려지지 않습니다. ScreenHitbox는 다른 용도로도 활용할 수 있습니다.
플레이어가 화면 밖으로 나가지 못하게 막고 싶다면, 플레이어의 onCollision에서 ScreenHitbox와의 충돌 시 이동을 제한하면 됩니다. 공이 벽에 튕기는 효과를 만들려면, 충돌 지점의 법선 벡터를 이용해 속도를 반전시키면 됩니다.
주의할 점이 있습니다. ScreenHitbox는 게임의 카메라 뷰포트가 아닌, 실제 게임 월드의 크기를 기준으로 합니다.
만약 카메라가 이동하는 게임이라면, ScreenHitbox 대신 직접 경계 컴포넌트를 만들어야 할 수 있습니다. 김개발 씨는 ScreenHitbox를 추가하고 총알의 자동 정리 로직을 구현했습니다.
이제 게임을 아무리 오래 플레이해도 성능이 일정하게 유지됩니다.
실전 팁
💡 - 화면을 벗어나는 객체는 반드시 제거하여 메모리 누수를 방지하세요
- ScreenHitbox는 카메라 이동이 없는 게임에서 가장 효과적입니다
6. 충돌 디버깅
김개발 씨가 고개를 갸우뚱합니다. 분명히 충돌해야 할 것 같은데 충돌이 안 됩니다.
"Hitbox가 제대로 달린 건지 눈으로 확인할 수 있으면 좋겠어요." 박시니어 씨가 미소를 지으며 말합니다. "디버그 모드를 켜면 돼요."
Flame은 개발 중 Hitbox를 시각적으로 확인할 수 있는 디버그 모드를 제공합니다. 컴포넌트의 debugMode를 true로 설정하면 Hitbox의 외곽선이 화면에 표시됩니다.
이를 통해 Hitbox의 크기와 위치가 의도한 대로 설정되었는지 확인할 수 있습니다.
다음 코드를 살펴봅시다.
class Player extends SpriteComponent with CollisionCallbacks {
// 디버그 모드 활성화
@override
bool get debugMode => true;
@override
Future<void> onLoad() async {
await super.onLoad();
// Hitbox가 화면에 빨간 선으로 표시됩니다
add(RectangleHitbox());
}
}
// 게임 전체에 디버그 모드 적용
class MyGame extends FlameGame with HasCollisionDetection {
@override
bool get debugMode => true; // 모든 컴포넌트에 적용
}
게임 개발에서 가장 답답한 순간 중 하나는 "왜 충돌이 안 되지?"입니다. 분명히 화면에서는 두 객체가 겹쳐 보이는데, 충돌 콜백은 호출되지 않습니다.
김개발 씨도 이 문제로 고민하고 있었습니다. 적 캐릭터의 특정 부분에만 총알이 맞고, 나머지 부분은 통과해버립니다.
박시니어 씨가 노트북을 가져와 코드를 한 줄 추가합니다. debugMode => true.
게임을 실행하자 스프라이트 위에 빨간색 사각형이 나타났습니다. "저게 실제 Hitbox예요.
보세요, 스프라이트보다 훨씬 작잖아요." debugMode는 Flame의 디버깅 기능입니다. 이를 활성화하면 Hitbox의 외곽선이 화면에 그려집니다.
보통 빨간색 선으로 표시되며, 충돌 영역의 실제 크기와 위치를 눈으로 확인할 수 있습니다. 사용 방법은 두 가지입니다.
첫 번째는 개별 컴포넌트에 적용하는 방법입니다. 특정 컴포넌트 클래스에서 debugMode getter를 오버라이드하여 true를 반환합니다.
이렇게 하면 해당 컴포넌트와 그 자식들만 디버그 모드가 적용됩니다. 두 번째는 게임 전체에 적용하는 방법입니다.
FlameGame 클래스에서 debugMode를 오버라이드하면, 게임의 모든 컴포넌트에 디버그 모드가 적용됩니다. 개발 초기에 유용합니다.
디버그 모드에서 확인할 수 있는 것들이 있습니다. Hitbox의 크기가 스프라이트와 맞는지 확인할 수 있습니다.
종종 Hitbox가 너무 작거나 커서 의도치 않은 동작이 발생합니다. Hitbox의 위치가 스프라이트의 중심에 맞는지도 확인할 수 있습니다.
앵커 포인트 설정에 따라 Hitbox가 엉뚱한 곳에 있을 수 있습니다. 여러 Hitbox가 겹치는 경우도 눈으로 확인할 수 있습니다.
복잡한 캐릭터는 여러 개의 Hitbox를 조합하기도 합니다. 실제로 김개발 씨의 문제는 스프라이트 크기와 Hitbox 크기가 맞지 않아서였습니다.
스프라이트를 로드할 때 크기를 지정했는데, Hitbox는 기본 크기를 사용하고 있었습니다. 문제를 해결한 후에는 debugMode를 false로 돌려놓거나, 릴리스 빌드에서 자동으로 비활성화되도록 설정해야 합니다.
디버그 그래픽은 약간의 성능 오버헤드가 있고, 무엇보다 사용자에게 보여줄 화면이 아닙니다. 김개발 씨는 디버그 모드 덕분에 문제를 빠르게 찾아 해결했습니다.
이제 충돌 문제가 생기면 가장 먼저 디버그 모드를 켜보는 습관이 생겼습니다.
실전 팁
💡 - 충돌 문제가 발생하면 가장 먼저 debugMode를 켜서 Hitbox를 확인하세요
- 릴리스 빌드 전에 반드시 debugMode를 false로 되돌리세요
이상으로 학습을 마칩니다. 위 내용을 직접 코드로 작성해보면서 익혀보세요!
댓글 (0)
함께 보면 좋은 카드 뉴스
AAA급 게임 프로젝트 완벽 가이드
Flutter와 Flame 엔진을 활용하여 AAA급 퀄리티의 모바일 게임을 개발하는 전체 과정을 다룹니다. 기획부터 앱 스토어 출시까지, 실무에서 필요한 모든 단계를 이북처럼 술술 읽히는 스타일로 설명합니다.
빌드와 배포 자동화 완벽 가이드
Flutter 앱 개발에서 GitHub Actions를 활용한 CI/CD 파이프라인 구축부터 앱 스토어 자동 배포까지, 초급 개발자도 쉽게 따라할 수 있는 빌드 자동화의 모든 것을 다룹니다.
게임 분석과 메트릭스 완벽 가이드
Flutter와 Flame으로 개발한 게임의 성공을 측정하고 개선하는 방법을 배웁니다. Firebase Analytics 연동부터 A/B 테스팅, 리텐션 분석까지 데이터 기반 게임 운영의 모든 것을 다룹니다.
게임 보안과 치팅 방지 완벽 가이드
Flutter와 Flame 게임 엔진에서 클라이언트 보안부터 서버 검증까지, 치터들로부터 게임을 보호하는 핵심 기법을 다룹니다. 초급 개발자도 쉽게 따라할 수 있는 실전 보안 코드와 함께 설명합니다.
애니메이션 시스템 커스터마이징 완벽 가이드
Flutter와 Flame 게임 엔진에서 고급 애니메이션 시스템을 구현하는 방법을 다룹니다. 스켈레탈 애니메이션부터 절차적 애니메이션까지, 게임 개발에 필요한 핵심 애니메이션 기법을 실무 예제와 함께 배워봅니다.