2D 플랫폼 게임에서 플레이어가 경사면에서 부드럽게 움직 이도록하는 방법은 무엇입니까?


18

2D 플랫폼 게임을위한 물리 엔진을 개발 중입니다. 충돌 감지에 분리 축 정리를 사용하고 있습니다. 지면은 오리엔테이션 바운딩 박스로 구성되며 플레이어는 축 정렬 바운딩 박스로 사용됩니다. (특히, SAT를 사용하여 OBB에 대한 스윕 충돌 감지를 수행하는 "실시간 충돌 감지"책의 알고리즘을 사용하고 있습니다). 동적 응답이 환경에 침투하지 않도록 충돌 응답에 상당히 작은 (0에 가까운) 복원 계수를 사용하고 있습니다.

엔진은 대부분 잘 작동합니다. 발생할 수있는 일부 경우에 대해 걱정하고 있습니다. 예를 들어, 다이어그램에서 A, B 및 C는지면입니다. 플레이어는 B를 따라 A를 향해 왼쪽으로 향하고 있습니다. 부정확 함으로 인해 플레이어 상자는 상자 B가 아래로 계속 올라갈 때 상자 B 약간 아래에있을 수 있습니다. 따라서 A에 도달하면 플레이어의 왼쪽 하단 모서리가 A의 오른쪽과 충돌 할 수 있습니다 (플레이어가 A의 상단 위로 부드럽게 이동하려는 의도이므로 바람직하지 않음). 플레이어가 상자 C의 맨 위에있을 때 B를 향해 왼쪽으로 이동하면 비슷한 문제가 발생할 수 있습니다 .B의 가장 극단적 인 지점은 플레이어의 왼쪽 하단 모서리가 위아래로 미끄러지는 대신 플레이어의 왼쪽과 충돌 할 수 있습니다 위의 B.

Box2D는 가장자리 모양에 대한 연결 정보를 저장 하여이 문제를 처리하는 것처럼 보이지만 실제로이 정보를 사용하여 문제를 해결하는 방법을 잘 모르겠습니다. 코드를 본 후 실제로 수행중인 작업을 파악하지 못합니다.

어떤 제안이라도 대단히 감사하겠습니다.


일반적인 물리 엔진은 효과와 떨어지는 상자에 적합하지만 답변 섹션에 나와있는 것처럼 문자 물리에는 적합하지 않습니다. 캐릭터에 "정적"물리학을 쓰면 100 % 제어 할 수 있고 나머지는 적절하게 시뮬레이션 된 다이나믹을 사용할 수 있습니다.
도미

답변:


14

플랫폼 및 물리

이러한 최첨단 사례는 많습니다. 좋은 재미있는 플랫 포머는 어떤 종류의 물리적으로 정확한 방식으로 행동하지 않으며, 마리오와 같은 수년간의 "완벽한"플랫 포머 이후에 플레이어가 기대하는 제어 및 행동은 Box2D 또는 다른 물리 엔진과 같은 일반적인 기술로는 구현하기가 매우 어렵습니다. 대부분의 훌륭한 플랫 포머는 플레이어 컨트롤러에서 일반적인 물리 또는 충돌 응답을 사용하지 않습니다.

선체 생성

특정 질문과 관련하여 가장 좋은 해결책은 상자를 사용자의 근거로 사용하지 않는 것입니다. 일련의 연결된 선분 (선체)을 사용하십시오. 이를 통해 충돌 감지 엔진은 실제로 걸을 수있는 표면에만 초점을 맞추고 AB와 BC 사이에 존재하는 "가짜"가장자리를 보지 않습니다. 이것이 실제로 Box2D가하는 일입니다. 모양은 바깥 쪽 표면을 생성하는 데 사용되며 서로 결합되어 선체를 형성합니다.

타일 ​​기반 게임 또는 바닥 역할을하는 다른 옆에 두 개의 AABB 객체가있는 상황에서도이 기능이 필요합니다. 충돌 엔진이 수직 모서리를 집어 들고 플레이어가이를 잡습니다. 도움이 될 수 있지만 문제를 해결하지 못하는 해킹이 있습니다. 해결책은 완전한 2D 상자가 아닌 표면을 나타내는 단일 선 세그먼트를 갖는 것입니다.

다각형을 서로 자르고 클립 포인트를 가장자리 목록에 결합하여 일반적인 경우 선체를 생성 할 수 있습니다.

경 사진 표면

예제에 경사가 포함되어 있고 복원 및 기타 물리적 특성에 대해 언급하고 있기 때문에 곧 알아 차릴 몇 가지 다른 문제를 지적 할 것이며, 이는 일반적인 충돌 감지 및 응답이 플랫 포머에 적합하지 않은 이유를 추가로 설명합니다. 먼저, 각이 진 플랫폼에 서서 점프 한 다음 착륙하십시오. 착륙 할 때 캐릭터가 약간 미끄러질 수 있습니다. 문제는 생성하는 접촉 법선이 일반적으로 각진 표면에서 지적된다는 것입니다. 그런 다음 충돌을 해결할 때 플레이어가 해당 방향으로 밀립니다. 캐릭터가 똑바로 쓰러졌지만 착륙 할 때 위로 밀리고 오른쪽으로 조금 밀려 미끄러 져 나옵니다. 상대 속도를 고려하면 해킹 될 수 있습니다.

고치기 어려운 두 번째 문제는 경사로를 빠르게 내려 가려고 할 때 발생하는 문제입니다. 플레이어는 경사로 아래로 "홉"이동합니다. 이것은 오늘날 대부분의 AAA 게임에서도 볼 수 있습니다. 어리석은 것처럼 보일뿐만 아니라 게임에서 플레이어가지면에 발을 딛고 점프해야하는 경우 플레이어는 경사로의 작은 부분에서만 경사로에 닿기 때문에 경사로를 내리고 반쯤 아래로 점프하기가 어렵습니다. 그것을 내려가는 시간. 보다 간단한 수정 방법은 플레이어가 움직일 때 광선 캐스트를 단순히 수행하고 플레이어가 점프하지 않고 이전에 지상에 있었던 경우 플레이어 위치를 가장 가까운 표면 (아래로 플레이어와 매우 가까운 경우)에 맞추는 것입니다.

플레이어가 마치 일반 강체 인 것처럼 속도, 마찰 및 회복을 모델링하려고하면 경사로를 달릴 때 플레이어가 공중으로 발사되는 것을 발견 할 수도 있습니다. 넘어 지거나 점프하지 않는 한 플레이어의 움직임은 수평 움직임으로 제한되어야합니다. 물론, 오래된 황금 시대 플랫 포머를 플레이하는 경우 플레이어의 수평 속도가 수평 표면과 경사 표면 사이에서 일정하다는 것을 알 수 있습니다. 경사면을 오르 내릴 때도 고려해야합니다.

결국에는 다른 여러 모퉁이가 발생할 것입니다. 좋은 플랫 포머를 만들려는 경우 일반적인 물리학 및 충돌 응답 알고리즘에 의존하기보다는 물리학에서 분리 된 플랫 포머 플레이어 컨트롤러를 구현하고 원하는 움직임 및 제어 동작을 하드 코딩하는 것이 가장 좋습니다.


답장을 보내 주셔서 감사합니다. 접지를 나타내는 상자를 줄로 줄이는 것을 고려했지만 실제로 문제 자체를 해결할 것이라고는 생각하지 않습니다. 예를 들어, 그라운드 박스가 이제 선이고 플레이어가 C 라인에 서서 B쪽으로 왼쪽으로 이동하는 경우 부정확 함으로 인해 플레이어 박스가 C 라인보다 약간 아래에있을 수 있습니다. 그런 다음 플레이어 박스의 왼쪽 가장자리 여전히 라인 B와 충돌하여 바람직하지 않은 충돌을 일으킬 수 있습니다.
Nick Kovac

이런 일이 발생하지 않도록하는 다른 메커니즘이 없다면 Box2D가 문제를 해결하는 상자 대신 선을 사용한다는 것이 아니라 Box2D가 체인 모양을 사용하여 선 세그먼트 사이의 연결 정보를 사용하여 충돌이 발생하지 않도록하는 것입니다. 현재 주요 문제는 정확히 어떻게하는지에 대한 세부 사항을 이해하지 못한다는 것입니다.
Nick Kovac

일반적인 물리 엔진에서 아이디어를 가져 와서 플랫폼 게임에 적용 할 때 발생하는 문제에 대해 다른 좋은 점을 제기했습니다. 나는 당신이 논의 한 아이디어를 구현하는 비슷한 엔진을 보았습니다. 나를위한 주요 문제점은 수치 오류와 관련된 까다로운 가장자리 사례입니다.
Nick Kovac

@Kovsa : 다시 말하지만, 충돌의 일부가되어서는 안되는 가장자리를 제거하면 특정 오류가 사라집니다. 가장자리를 묶어 중단없는 모양을 만듭니다. 레벨을 설계 할 때 표면에 작은 틈새가 없도록 정점을 함께 스냅하는 것이 좋습니다. 실제로 3D 메쉬 편집기에서 레벨을 디자인하는 방법과 다르지 않습니다.
Sean Middleditch

흠 ... 나는 그렇게 생각하지 않습니다. 다이어그램에서 가장자리를 묶어 중단없는 모양을 만들면 상자 A, B 및 C의 상단과 같은 세 개의 선 세그먼트로 구성된 모양이 나타납니다. 단일 모양이지만 여전히 라인 A, B, C에 대해 별도로 충돌 감지를 수행해야합니까? 상자와이 결합 된 모양 사이의 충돌을 감지 할 수있는 알고리즘을 의미하지 않는 한? 일련의 모서리가 오목 할 수 있기 때문에 SAT가 아니라고 가정합니다.
Nick Kovac

5

충돌 응답을 위해 상자가 둥근 모서리 (수치 오류와 비슷한 반경) 인 것처럼 상자를 처리하면 두 가지 문제를 모두 해결할 수 있다고 생각합니다. 이렇게하면 A와 B, B와 C 사이의 미팅 코너의 효과적인 결합 표면이 더 매끄럽게됩니다.

따라서 왼쪽으로 이동하는 PLAYER가 A의 모서리에 닿으면 충돌 법선이 순전히 오른쪽이 아니라 대각선이되어 왼쪽 및 위쪽 동작을 계속할 수 있습니다.


그러나 플랫 포머 물리에 대해 알고있는 것을 검토 할 때보다 일반적인 해결책은 플레이어 를보다 둥근 모양으로 만들고 지형을 그대로 두는 것입니다. 특히, 플레이어 모양을 캡슐 (2D) / 스피어 (3D)로 펼치면 충돌 법선이 자연스럽게됩니다. 좋습니다. 거의 수직이되어 잡기 문제가 발생하지 않습니다.

OBB 전용 충돌 알고리즘을 사용하고 있지만 OBB-OBB 충돌을 찾은 후에도 OBB 내에 완전히있는 모양에 대해 추가 테스트를 수행 할 수 있어야합니다.


흠, 흥미로운 아이디어 ... 어떻게 구현하겠습니까? 비록 상자를 사용하는 단순함에 다소 반대입니다. 더 많은 통찰력을 얻기 위해 포럼에 비슷한 질문을 게시했습니다.
Nick Kovac

구현 세부 정보가 없습니다. 죄송합니다. 이러한 물리 엔진 코드 전문가는 아닙니다. 그러나 퍼지 요소를 기반으로하지 않는 솔루션에 대해 더 나은 아이디어를 얻었습니다. 내 편집을 참조하십시오.
Kevin Reid

1
둥근 모양을 사용하는 것은 효과가 있지만 수학적으로 더 복잡하고 플랫 포머에게는 차선책으로 나타날 수 있습니다. 플레이어는 난간 위에 서있는 캐릭터를 픽셀 단위로 완벽하게 제어 할 수 있어야합니다.
Sean Middleditch 2016 년

원장 : D' oh! 좋아, 내가 생각했던 것만 큼 간단하지는 않다.
Kevin Reid

예, 캡슐 방식은 2D 플랫 포머가 아닌 3D 게임에 더 적합한 것으로 보입니다. 픽셀 퍼펙트 컨트롤을 갖는 것은 저에게있어 우선 순위입니다 (구식 2D 플랫 포머와 마찬가지로). 그러나 상자를 사용할 수있는 솔루션이 있어야합니다!
Nick Kovac 23.35에
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.