매우 간단한 3D 레이싱 게임에서 충돌은 어떻게 처리됩니까?


9

간단한 3D 자동차 경주 게임 (특히 Outrun 2 / Motoracer와 같은 게임)에서 충돌이 어떻게 발생하는지 궁금했습니다.

복잡한 환경 (오픈 월드)이있는 고전적인 자동차 경주 게임에서는 비행기 충돌 (트랙, 건물 다른 건물)에 대한 기본 상자 (자동차 용)로 수행됩니다. 모든 것은 일부 경계 상자를 사용하여 최적화됩니다 (많은 게임에서 충돌이 수행되는 방식입니다).

Outrun 2 / Motoracer와 같은 게임에서 게임 플레이는 너무 간단하여 개발자가 필요하지 않을 수 있으며 모든 것이 단순화되었습니다. 그것을 연주하지 않는 사람들을 위해, 여기에 너무 구체적인 것이 있습니다 :

  • 자동차 / 자전거는 항상 도로에 붙어 있습니다.
  • 도로는 항상 같은 크기이며 매우 간단한 형태입니다.
  • 유일한 가능성은 그 길을 따라 가거나 길을 떠날 수 없거나 다른 것과 충돌하는 것입니다 (다른 자동차 / 자전거는 제외하지만 우리는 신경 쓰지 않습니다).
  • 도로와 충돌하면 매우 기본적인 아케이드 충돌이 발생합니다 (자동차는 단순히 도로에서 밀려납니다)

충돌이 발생했다고 생각하는 방법은 다음과 같습니다.

전체 트랙은 거대한 3D 베 지어 곡선으로 간주 될 수 있습니다. 이 곡선에서 도로 다각형을 생성 할 수있었습니다 (곡선에서 생성 된 앞, 왼쪽 및 위쪽 벡터 사용). 이 방법을 사용하여 다른 요소 (집, 나무 등)도 배치하고 정렬 할 수 있습니다.

그런 다음 충돌을 처리하고 자동차를 그립니다.

1) 현재 자동차 3D 위치에서 3D 곡선에서 가장 가까운 위치를 찾습니다. 즉, 3D 자동차 위치를 베 지어 곡선 위치로 변환합니다. 도로의 모든 3D 위치는 3D 곡선 ( t) + 측면 변위 ( d)를 따라 변위로 간주 될 수 있습니다 . 명확하지 않은 경우 아래 이미지를 확인하십시오 (2D 예이지만 3D에 쉽게 적용됨).

여기에 이미지 설명을 입력하십시오

t = 0 차량이 트랙 섹션의 시작 부분에있을 때, t = 1 차량이 끝났을 때. d = -1 또는 1 대의 차량이 선로의 경계에있을 때, d = 0의 차량이 도로 중앙에있을 때

2)를 사용하여 도로에 자동차를 정렬 t하고 d(매우 간단한 : 모두에 대해 t그리고 d값 i가 3 차원 위치 + 업 / 전면 / 좌측 벡터를 얻을 수있다). 차는 이제 길에 붙어

3) d자동차의 측면 변위 를 확인하십시오 . 값이 너무 크 (d > 1)거나 낮은 (d < -1)차에 도달하지 못한 경우 자동차를 올바른 위치에 놓기 위해 클립으로 고정하십시오.

이것은 또한 3d 컬링을 매우 간단하게 만듭니다 . 현재 자동차 t위치 에서로 트랙을 그립니다 t + some_big_enough_value_to_avoid_visible_clipping.

아니면 내가 완전히 틀렸을 수도 있습니다. 자동차 (경계 상자)와 트랙을 나타내는 매우 간단한 다각형 세트 (건물 등 제외)를 확인하는 것이 훨씬 빠르고 간단했을 것입니다. 3d 월드 (및 결과로 생성 된 colision 모델)는 일부 타사 툴 (게임을 실행할 때 더 이상 3d 곡선이 아니라 단지 많은 다각형)을 사용하여 이전에 생성되었을 것입니다.

답변:


16

나는 당신이 묘사 한 것과 비슷한 몇 가지 상업용 게임에서 일했습니다.

각각의 게임에서, 트랙의 측면을 따라 보이지 않는 "벽"을 생성하는 다각형이 실제로 있었고, 그 벽에 대한 전통적인 충돌 테스트를했습니다. 이는 도로 측면, 보이지 않는 벽 내부에 충돌 할 수있는 추가적인 위험이있을 수 있으며 스플라인 접근 방식으로 할 수있는 것보다 더 빠르게 도로 폭을 변경할 수 있음을 의미했습니다.

그러나 우리는 충돌 터널링 / 글리치로부터 보호하기 위해 충돌이 어떻게 작동 할 것이라고 생각하는지 섹션에 나열한 내용을 수행했으며이 시스템은 AI 로직 경주에도 많이 사용되었습니다. 또한 HUD에 "1 / 2nd / 3rd / etc"표시기를 표시 할 수 있도록 어떤 자동차가 리드에 있는지 확인하는 데에도 사용했습니다. 때때로이 데이터는 큰 충돌 후 자동차를 다시 생성하는 데에도 사용되었습니다.

충돌이 어떻게 작동한다고 생각하는지 놓친 부분 은 스플라인으로 작업 할 때 일반적으로 스플라인 리브를 제공한다는 것입니다. 리브는 트랙이 스플라인에서 각 방향으로 옆으로 얼마나 멀리 연장되는지를 나타내는 데이터 비트입니다. 따라서 길이가 100 미터 인 스플라인의 경우 리브가 50 개가되어 길이에 따라 2 미터마다 트랙 너비가 제공됩니다. 이를 통해 트랙의 범위에 따라 너비를 변경할 수 있습니다. 내가 작업 한 게임에서이 리브는 "트랙 표면"과 "드라이브 가능 영역"을 구분했습니다. 따라서 스플라인의 중간에서 얼마나 멀리 떨어진 활주로가 있는지를 알려주는 도로 폭 세트와 모래 / 잔디 / 그 밖의 거리가 얼마나 멀리 있는지를 나타내는 또 다른 폭이 있습니다. 이를 통해 플레이어는 트랙에서 합리적인 거리를 주행 할 수 있지만 실제 도로 표면의 위치를 ​​AI에 알 수 있습니다.

제가 작업 한 많은 게임들도 다른 데이터를 갈비뼈에 저장했습니다. 한 게임은 트랙 조명 정보를 리브에 구워서 영역이 그림자에 있는지 여부를 쉽게 계산할 수 있습니다 (그런 다음 자동차 렌더링에 사용되어 렌즈 플레어를 그릴 지 여부 및 기타 효과를 결정하는 데 사용됨). 스플라인의 일부를 볼 수있는 시네마틱 카메라 배치에 대한 정보가 추가되었으므로 재생 중에 가시 거리 계산을 수행 할 필요가 없었습니다. 또 다른 하나는 스플라인에 몇 개의 레인이 있었는지, 어느 방향으로 갔는지, 그리고 각 레인이 위치한 수평 변위에 대한 정보를 포함했습니다. 이를 통해 도로 차선 내에서 올바르게 운전할 수있는 교통 차량을 포함시킬 수있었습니다. 갈비뼈는 노면에 필요한 다양한 종류의 데이터를 저장하는 데 환상적입니다.

리브는 일반적으로 스플라인과 연결된 배열에 저장됩니다. 속도 때문에 일반적인 구현에는 립 간격이 균등하게 적용되므로 스플라인을 따라 객체의 거리를 알고 나면 스플라인을 따라 거리를 립 사이의 거리로 나누어 배열에서 가장 가까운 립 인덱스를 계산할 수 있습니다. 그렇지 않으면 리브 배열을 통해 이진 검색을 수행하여 올바른 도로 너비 데이터를 찾을 수 있습니다.

컬링 설명은 스플라인 접근 방식을 사용하는 방법에 대한 기본적인 설명을 제공하지만 실제로 제안하는 것보다 약간 더 복잡합니다.이 방법으로 컬링에 스플라인을 사용하면 긴 머리핀 회전이 종종 반대쪽을 그리지 않습니다. 트랙의 거리에 의해 측정 될 때 , 크로우가 날 때 측정 할 때 단지 몇 미터 거리에 있더라도 턴의 반대쪽이 매우 멀리있을 수 있기 때문에. 또한 월드 지오메트리를 볼 수있는 거리는 일반적으로 트랙 메시를 볼 수있는 거리와 다르므로이 시스템에도 실제로 맞지 않습니다. 내 경험에 따르면 대부분의 경우 모델을 그릴 지 여부를 결정하기 위해 추적 추적 논리에 의존하지 않는 것이 좋습니다. 훨씬 안정적이며 표준 카메라 절두체 테스트를 사용하는 글리치가 줄어 듭니다.



0

저는 OpenGL 레이서에서 원래 트랙의 경계를 정의하기 위해 두 개의 원을 사용하여 시작했지만 너무 번거로 웠습니다. glReadPixel을 사용하여 픽셀 색상을 읽습니다. 플레이어 자동차가 녹색 (잔디 색) 픽셀 위에 있으면 움직임이 더 제한됩니다. 성능에는 거의 영향이 없습니다.


이것은 2D 게임 (원, 픽셀 색상별로 충돌)을 설명하는 것처럼 들립니다. 그렇습니까? 그렇다면 그 대답은 주제가 아닙니다.
Kromster

투시 투영에서 게임을 언급하고 있습니다. glReadpixel은 2D ortho 또는 3D Perspective 모드에서 적용될 수 있습니다.
ztech79
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.