비디오 게임에서 글 머리 기호는 어떻게 작동합니까?


64

C #에서 비디오 게임을 디자인 할 때이 질문에 부딪 쳤습니다.

Battlefield 또는 Call of Duty 와 같은 게임을 고려하면 수백 또는 수천 개의 총알이 동시에 날고 있습니다. 이벤트는 지속적으로 발생하며, 내가 아는 바로는 많은 처리 능력을 흡수합니까? 다양한 게임 개발자가 총알을 관리하는 방법 (2D 및 3D)과 가장 효율적인 방법이 무엇인지 알고 싶습니다.

비디오 게임에서 글 머리 기호는 어떻게 시뮬레이션됩니까? 라는 질문을 읽었습니다 . 그러나 프로그램 디자인 관점에서 총알이 어떻게 작동하는지는 다루지 않습니다.

몇 가지 아이디어가 있었지만 각각 단점이 있습니다.


내가 생각할 수있는 가장 효율적인 방법 (2D 게임) :

Bullet이라는 클래스를 만들어야했지만 사용자가 버튼을 길게 누르면 0.01 초마다 Bullet 개체가 만들어집니다. 이 글 머리 기호는 다음과 같습니다.

  • 1 속도

  • 2 촬영 위치의 시작 위치

  • 3 스프라이트 텍스처

  • 4 적중 효과

총알은 자체 클래스이므로 그리기, 이동 및 동작 리스너 자체를 관리 할 수 ​​있습니다.

프로세서에서 인스턴스화되고 파괴 된 수천 개의 오브젝트를 처리하는 것이 어렵지 않습니까 (적중 효과가 트리거 될 때)? RAM 공간?


3D 게임을위한 효율적인 방법-내가 생각한 또 다른 생각은 :

무기 클래스를 생성한다고 가정하겠습니다. 이 무기에는 다양한 기능이 있습니다.

  • 1 무기의 조준 위치를 감지하고 대상을보고 있는지 확인

  • 2 총기의 애니메이션을 트리거

  • 3 총이 가리키는 곳에서 체력을 빼는 것을 나타내는 doDamage () 메서드가 있습니다.

  • 4 버튼을 누를 때 불릿 애니메이션 클래스에 알립니다

그런 다음 BulletAnimation과 같은 정적 클래스를 생성하여 총을 트리거 한 총 위치, 총이 가리키는 위치 (총알 대상) 및 총알에 사용할 적절한 스프라이트 및 속도에 대한 알림을받을 수 있습니다. . 그런 다음이 클래스는 총에서 발사되는 총알을 시뮬레이트하기 위해 위치와 원하는 스프라이트를 모두 기반으로 스프라이트 (새 스레드에서 idk 일 수 있음)를 그립니다.


후자는 코딩하기가 훨씬 더 어려워 보이고 한 번에 수천 개의 총알에 대해 정적을 호출하기 위해 지속적으로 정적을 호출하는 데 많은 처리 능력이 필요하지 않습니까? 시작 및 종료 위치 모두에서 지속적인 업데이트를 얻는 것도 어렵습니다.

제 질문은 게임 제작자가 가장 효율적인 방법은 무엇입니까? 이 방법이 2D에서 3D 게임으로 변경됩니까?


16
오늘날에도 대부분의 게임은 총알의 비행을 시뮬레이션하지 않습니다. "충분히 빠른"것으로 간주되는 경우 간단한 히트 스캔이 대신 수행됩니다. 기본적으로 트리거를 누를 때 동시에 영향이 발생한다고 가정합니다. 어쨌든 "수백 또는 수천 개의 총알"은 실제로 많은 양이 아닙니다. 이는 오늘날의 머신보다 수천 배 적은 강력한 초기 콘솔 (다양한 총알 지옥 게임) 이후 게임에 있었던 것입니다. 당신은 단지 총알 당 가능한 적은 일을해야합니다. :)
Luaan

42
총알은 일반적으로 pew-pew-pew기술을 통해 작동 합니다 :)
MonkeyZeus

5
수백 또는 수천 개의 총알이 동시에 날아 다니지 않습니다. 그렇게 빨리 발사하는 총은 없습니다. 강력한 Phalanx 조차도 초당 총알 총 75 개입니다. Wikipedia에 나열된 "유효 발사 범위"를 기준으로 총알이 최대 3 초 동안 비행하므로 Phalanx는 한 번에 225 개의 총알을 공중에 넣을 수 있습니다. M16은 약 12 ​​라운드 / 초로 최고를 기록하며 그 속도를 유지할 수 없습니다 (지속적인 발사의 최대 값은 0.25 라운드 / 초). 한 번에 많은 총을 발사하는 것은 아닙니다!
Cort Ammon

3
이것을 지적하기 위해 객체가 너무 단순 할 때 객체를 개별 클래스로 만드는 것은 결코 좋지 않습니다. 각 유형의 글 머리 기호에 대해 하나의 bulletField 인스턴스를 갖는 것이 훨씬 좋습니다. 코드 길이에 약간의 오버 헤드가 있으면 글 머리 기호 당 4 바이트 단어가 추가됩니다 (유형이 정수인 경우). 또한 하나의 객체로 쉽게 목록을 스캔 할 수 있습니다.
그레이트 덕

4
@Cort-게임 공간에 총기 하나만 있다고 가정합니다. OP는 수십 명의 플레이어가 자동 총을 동시에 발사 할 수있는 Battlefield 및 CoD와 같은 게임을 언급했습니다. 각 라운드가 실제로 물리적으로 공간에 포함되어 있다면 터무니없는 숫자가있는 것은 부당하지 않습니다.
Jesse Williams

답변:


78

나는 왜 당신이 그것들을 시뮬레이션하기가 어렵다고 생각하는지 알 수 있지만, 총알 (모든 발사체, 실제로)을 더 쉽게 만들기에 충분한 제약이 있습니다.

  1. 일반적으로 볼륨이있는 것이 아니라 단일 지점으로 시뮬레이션됩니다. 원에 대한 선과 같은 매우 단순한 표면에 대해서만 충돌을 수행하면되기 때문에 충돌 감지가 훨씬 쉬워집니다.

  2. 우리는 그들이 어떻게 움직 일지 알기 때문에 저장하거나 계산할 정보가 많지 않습니다. 귀하의 목록은 합리적으로 정확했습니다. 우리는 일반적으로 총알을 쏜 사람과 그 유형이 무엇인지 등 몇 가지 더 관련이 있습니다.

  3. 모든 발사체는 매우 유사하므로 동적으로 생성하는 모든 오버 헤드를 피하기 위해 미리 할당 할 수 있습니다. 1000 개의 발사체 배열을 할당 할 수 있으며 이제는 색인만으로 액세스 할 수 있으며 메모리에서 모두 순차적이므로 처리가 빠릅니다.

  4. 그들은 수명 / 범위가 고정되어 있으므로 오래된 글 머리 기호를 만료하고 메모리를 새 글 머리 기호로 매우 빠르게 재활용 할 수 있습니다.

  5. 그들이 무언가를 때리면, 나는 또한 그것들을 만료 시켜서 유한 한 수명을 갖습니다.

  6. 우리는 언제 만들어 졌는지 알기 때문에 새로운 것들이 필요하고 사전 할당 된 목록에 무료가 없다면 가장 오래된 것을 잡아 재활용 할 수 있으며 총알이 약간 일찍 만료되면 사람들은 알지 못합니다 .

  7. 스프라이트 (일반적으로) 또는 낮은 폴리 모델로 렌더링되며 화면에서 공간을 거의 차지하지 않으므로 렌더링 속도가 빠릅니다.

그 모든 것들을 고려할 때, 총알은 상대적으로 저렴한 경향이 있습니다. 우리의 예산이 총알에 의해 소비되고 렌더링 된 경우 일반적으로 한 번에 발사 할 수있는 샷 수를 제한하도록 재 설계합니다 (많은 오래된 아케이드 게임에서 볼 수 있음), 즉시 움직이는 빔 무기를 사용하십시오 예산 범위 내에서 발사 속도를 늦추십시오.


12
5)에 동의하지 않아야합니다 .5) 실제로 현대 게임에서 모든 것을 복잡하게 만듭니다. 초기 슈팅 게임에서는 이것이 허용되었습니다. 오늘날 COD조차도 플레이어가 나무 벽을 통해 쏠 수 있습니다. 6) 드문 문제이지만 경쟁 시스템에는 용납 할 수 없습니다.
SBoss

17
그런 다음 @SBoss는 다음과 같이 말합니다. "침투 할 수없는 물체에 부딪 치면 수명이 만료됩니다." 그리고 6 인 경우 캐릭터 당 최대 발사 속도를 제한하고 길이 배열을 유지함으로써 최악의 경우를 얻을 수 있습니다.num_characters * max_bullets_per_character
ratchet freak

14
@ SBoss 나는 # 6이 더 많은 것 같아요. 하향식 우주 게임. 느리게 움직이는 총알이 무언가를 치거나 사라지기 전에 화면에서 멀리 떨어진 곳으로 이동할 수 있습니다. 총알이 빠르게 움직이고 빠르게 세계의 경계에 도달하는 CoD 유형 게임에서는 문제가되지 않습니다.
BlueRaja-대니 Pflughoeft

1
대부분의 게임은 총알 (외부 탄도)을 전혀 모델링하지 않습니다. 대부분의 게임은 "히트 스캔"이라는 기술을 사용합니다.
Aron

45

글 머리 기호를 구현하는 가장 효율적인 방법 중 하나는 hitscan을 사용하는 것입니다 . 발사하는 것은 다소 간단합니다. 발사 할 때 총이 목표로하는 것을 확인하고 (가장 가까운 엔티티 / 물체 / 메시를 찾기 위해 광선을 사용하는 것) 확인한 다음 피해를 입히고 '히트'합니다. 실제, 빠르게 움직이는 보이지 않는 총알이 발사 된 것처럼 보이게하려면, 손상을 입기 전에 거리에 따라 약간의 지연을 추가하여 위조 할 수 있습니다.

이 접근법은 발사 된 발사체의 속도가 무한하다고 가정하고, 레이저 및 입자 빔 / 대포와 같은 무기 유형과 저격 소총의 형태에 일반적으로 사용됩니다 .

다음 접근 방식은 발사 된 총알을 발사체로 모델링하는 것인데, 발사체는 충돌의 대상이되는 자체 개체 / 물체, 그리고 방향과 속도를 변경하는 중력 및 / 또는 공기 저항으로 모델링됩니다. 여분의 물리 방정식으로 인해 히트 스캔 방식보다 복잡하고 실제 총알 오브젝트가 있기 때문에 리소스가 많이 사용되지만보다 현실적인 총알을 제공 할 수 있습니다.

게임에서 발사체 기반의 총알과 다른 오브젝트 간의 충돌을 관리하는 경우 오브젝트를 쿼드 또는 옥트리 로 정렬하여 충돌 감지를 크게 단순화 할 수 있습니다 . 옥트리는 주로 3D 게임에서 사용되며 쿼드 트리는 2D 또는 3D 게임에서 사용할 수 있습니다. 이 트리 중 하나를 사용하면 가능한 충돌 검사 수를 크게 줄일 수 있다는 장점이 있습니다. 예를 들어,이 트리 중 하나를 사용하지 않고 레벨에 20 개의 오브젝트가 활성화되어있는 경우 20과 모두 총알과 충돌하는지 확인해야합니다. 20 개의 오브젝트를 트리의 잎 (끝 노드)으로 나누면 많은 수의 엔티티가 총알과 동일한 리프에 존재하지만 검사 수를 줄일 수 있습니다.

히트 스캔 및 발사체와 같은 이러한 접근 방식은 2D 또는 3D 게임에서 자유롭게 사용할 수 있습니다. 무기의 정의와 제작자가 무기의 기능을 결정한 방법에 따라 다릅니다.


디자인 패턴, Hitscan 및 쿼드 / 옥트리에 대한 정보가 실제로 도움이됩니다. 또한 정보 주셔서 감사합니다!
Eric

8
히트 스캔을 고소하지는 않지만 발사체를 시뮬레이트하면 매우 빠르게 움직이므로 얇은 물체를 뒤틀 수 있습니다. 이 경우 게임의 모든 것이 가짜라는 것을 기억하십시오. 총알이 몇 센티미터에 불과하더라도 총알이 1 미터 길이 인 것처럼 충돌 감지를 수행 할 수 있습니다. 이 방법을 사용하면 대상에 충돌하지 않고 총알이 뒤틀리는 것에 대해 너무 걱정할 필요없이 총알 제거 및 비행 시뮬레이션 시간을 계속 할 수 있습니다. :).
Roy T.

2
총알의 물리학 (대포 포탄과 달리)이 중력 (총알 방울), 공기 저항과 같은 것을 존중하는 게임이 있습니까? (즉, 초점이 정밀 표적 촬영이나 그와 유사한 게임 인 특수 게임 이외의 게임 : FPS 등) 저는 게이머는 아니지만 그 정도의 충실도가 (때로는) 필요하다는 것에 놀랐습니다.
davidbak

3
@davidbak : 일반적인 게임 내 만남과 게임 장르에서 기대되는 사실성에 크게 의존합니다. 당신이 대부분 (만?) 가까운 쿼터 전투와 싸우고 있다면, 실제로 그 수준의 충실도가 필요하지 않습니다. 그러나 장거리 전투 옵션 (예 : 저격수 또는 RPG와 비슷한 설정의 궁수)이 존재하는 경우 현재 미사일에 영향을 미치는 중력이 예상됩니다. 로켓 발사기를 위쪽으로 향하게해도 로켓이 착지하여 어딘가에서 폭발 할 것으로 예상됩니다. 여전히 궤적은 실제 물리에서 계산되는 것이 아니라 대략적인 성능 (성능상의 이유)
hoffmale

1
Bad Company 2가 총알을 떨어 뜨린 이후 @davidbak Battlefield. 소총, 권총, 탱크 포탄, 로켓, 모든 것. Battlefield 3는 무료로 제공되며, (IIRC)를 확인할 수 있습니다. 물론 Battlefield 4에도이 기능이 있습니다. 이것을 볼 수있는 다른 게임은 "Sniper Elite"입니다. 2 또는 3이 최신 타이틀입니다. 물리는 그 게임에서 중요한 역할을합니다.
Apache

7

나는 결코 전문가는 아니지만, 당신의 질문에 대답하기 위해서는, 당신이 언급 한 것들이 많이 필요할 것입니다.

2D 예제의 경우 총알의 위치와 속도를 가질 수 있습니다. 글 머리 기호를 구현하는 방법에 따라 수명 또는 최대 거리가 필요할 수도 있습니다. 일반적으로 2 (x, y) 값이 포함됩니다. 그들이 부동이라면 16 바이트입니다. 글 머리 기호가 100 개이면 1600bytes 또는 약 1.5k입니다. 그것은 오늘날 기계에 아무것도 아닙니다.

다음으로 스프라이트에 대해 언급합니다. 각 글 머리 기호를 나타내는 단일 스프라이트 만 있으면됩니다. 그 크기는 그리는 비트 깊이와 화면에 표시되는 크기에 따라 다릅니다. 예를 들어, 채널당 풀 플로트 32 비트에서 256x256으로 압축되지 않은 경우에도 스프라이트의 경우 1MB입니다. (그리고 그것은 매우 클 것입니다!) 당신은 각 총알 위치에 같은 스프라이트를 그릴 것이지만, 스프라이트의 각 사본에 대해 추가 메모리를 사용하지는 않습니다. 적중 효과와 유사합니다.

0.01 초마다 발사하는 것을 언급합니다. 그것은 당신의 무기에서 초당 100 개의 총알입니다. 미래의 무기조차도 꽤 많습니다! 이 위키 백과 기사 에 따르면 :

방아쇠를 당기면 라운드 발사 속도는 순환 속도입니다. 일반적인 순환 발사 속도는 돌격 소총의 경우 600-900 RPM, 경우에 따라 1,000-1,100 RPM, 기관단총과 기관총의 경우 900-1,200 RPM, 기관총의 경우 600-1,200 RPM입니다. 공격 헬리콥터 및 기타 전투 차량에 장착 된 M134 미니건은 초당 100 발 (6,000RPM) 이상의 발사 속도를 달성 할 수 있습니다.

그래서 그것은 헬리콥터의 속도입니다!

Battlefield / Call of Duty / etc 등에서 언급 한 것과 같은 큰 세계의 경우, 모든 총알 위치를 계산할 수 있지만 조치가 멀리 떨어져있는 경우 모든 총알 위치를 그릴 수는 없습니다. 또는 가까이 갈 때까지 시뮬레이션하지 않을 수 있습니다. (나는 큰 일을하지 않았 으므로이 부분에 대해 조금 추측하고 있음을 인정해야합니다.)


6

프로세서에서 인스턴스화되고 파괴 된 수천 개의 오브젝트를 처리하는 것이 어렵지 않습니까 (적중 효과가 트리거 될 때)? RAM 공간?

컴퓨터가 얼마나 빠른지 과소 평가하고 있다고 생각합니다. 이것은 이었다 때로는 80 년대와 90 년대의 시스템 문제. 이것이 원래 스페이스 인베이더가 현재 총알이 맞을 때까지 다른 총알을 발사하지 못하게하는 이유입니다. 화면에 스프라이트가 너무 많으면 일부 게임에서 "느려짐"이 발생했습니다.

하지만 요즘? 텍스처링 및 조명을 수행하는 데 필요한 픽셀 당 수천 개의 작업에 충분한 처리 성능 이 있습니다. 수천 개의 움직이는 물체에는 문제가 없습니다. 이를 통해 모든 프래그먼트가 다른 프래그먼트와 충돌 처리하고 탄도 곡선을 따르는 파괴 가능한 지형 (예 : 적색 진영)을 수행 할 수 있습니다.

알고리즘 적으로 약간주의해야합니다. 수천 개의 객체가있을 때 모든 다른 객체에 대해 모든 객체를 검사하는 순진한 접근 방식을 수행 할 수 없습니다. 글 머리 기호는 일반적으로 다른 글 머리 기호와의 충돌을 확인하지 않습니다.

작은 일화 : 네트워크로 연결된 Doom (90 년대 원본)의 첫 번째 버전은 총알이 발사 될 때마다 네트워크를 통해 하나의 패킷을 보냈습니다. 한 명 이상의 플레이어가 기관총을 얻었을 때 네트워크가 쉽게 압도 될 수 있습니다. 90 년대는 네트워크를 사용할 수 없게되었을 때 네트워크 관리자에게 문제를 일으켜 대학이나 직장 네트워크에서 불법으로 Doom을 플레이하는 사람들로 가득했습니다.


이 상황에서 전기 톱이 어떻게 작동했는지 궁금합니다.
reas0n

1
IIRC는 첫 번째 네트워크 운명의 실제 문제는 브로드 캐스트 패킷을 대신 사용하여 각 패킷을 모든 반대 플레이어에게 별도로 보낼 필요가 없다는 것입니다. 전송 된 패킷 수는 줄었지만 안타깝게도 게임을하지 않는 컴퓨터를 포함하여 네트워크의 모든 컴퓨터에 상당한 CPU 부하가 발생했습니다.
supercat

1

나는 전문가와는 거리가 멀지 만 여가 시간에 멀티 플레이어 2D 슈팅 게임을하고 있습니다.

내 방법

클라이언트와 서버간에 다양한 글 머리 기호 클래스가 있습니다 (오프라인을 재생할 때도 서버 인스턴스는 별도의 프로세스에서 시작되고 '메인'게임에 의해 연결됨).

클라이언트는 모든 틱 (초당 60 초)으로 플레이어의 마우스 포인터와 화면 중앙 (캐릭터가있는 곳) 사이에서 베어링을 작동시키고 서버로 전송되는 정보의 일부입니다. 플레이어가 그 순간에 발사하고 있다면 (무기가 적재되고 준비되었다고 가정 할 때), 단순히 약간의 좌표와 기본 피해 (사격 한 무기의 통계에서 비롯됨)와 함께 서버 측 탄환 인스턴스가 생성됩니다 그것). 불릿 인스턴스는 일부 수학 함수를 사용하여 클라이언트에서 수집 한 베어링에서 X 및 Y 속도를 계산합니다.

이후의 모든 진드기마다 총알이 해당 좌표로 이동하고 기본 피해를 사전 정의 된 양만큼 줄입니다. 이 값이 1 이하로 떨어지거나 월드의 솔리드 오브젝트에 부딪히면 총알 인스턴스가 삭제되고 2D에서 테스트 포인트 충돌이 매우 저렴 해 지므로 빠른 발사 무기조차도 성능에 무시할만한 영향을 미칩니다.

클라이언트의 경우, 글 머리 기호 정보는 실제로 네트워크를 통해 수신되지 않으며 (테스트에서 낭비로 판명 됨) 대신 틱당 업데이트의 일부로 각 문자에는 'fired'부울이 있으며, true이면 클라이언트가 로컬을 생성합니다 총알 객체는 서버와 거의 똑같이 작동하지만 스프라이트가 있다는 점만 다릅니다.

이것은 당신이 보는 글 머리 기호가 서버에서 정확하게 그것을 나타내는 것은 아니지만, 플레이어에게 차이가 있다면 거의 눈에 띄지 않으며 네트워크 이점은 불일치보다 중요합니다.

다른 방법에 대한 참고 사항

내 게임을 포함한 일부 게임은 실제 물체 인 것처럼 각 진드기를 각 진드기로 이동시키는 반면, 다른 게임은 촬영 방향으로 벡터를 만들거나, 예를 들어 카운터- 파업 게임. 총알 발사의 애니메이션과 같이 위장하기 위해 약간의 클라이언트 쪽 트릭이 있지만 모든 의도와 목적에 따라 각 총알은 레이저 입니다.

복잡한 히트 박스가있을 수있는 3D 모델의 경우 간단한 경계 상자 FIRST에 대해 충돌을 테스트하는 것이 표준이며, 성공하면 더 '상세한'충돌 감지로 넘어갑니다.


0

이를 충돌 감지라고합니다. 8 비트 컴퓨터는 하드웨어에서 플레이어 미사일 그래픽을 사용하여이 작업을 수행했습니다. 현대 게임 엔진은 물리 엔진과 선형 대수를 사용합니다. 무기의 현재 방향은 3D 벡터로 표시됩니다. 그것은 불의 방향으로 무한한 선을 제공합니다. 모든 움직이는 물체는 하나 이상의 경계 구체를 가지고 있는데, 이것은 선과의 충돌을 감지하는 가장 간단한 물체입니다. 두 가지가 교차하면 맞지 않습니다. 그렇지 않으면 맞지 않습니다. 그러나 풍경이 방해가 될 수 있으므로 (계층 경계 볼륨을 사용하여) 확인해야합니다. 교차점이있는 가장 가까운 개체는 적중 한 개체입니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.