고정 또는 가변 시간 단계를 언제 사용해야합니까?


256

게임 루프는 고정 또는 가변 시간 단계를 기반으로해야합니까? 항상 우월한가, 아니면 올바른 선택은 게임마다 다릅니 까?

가변 시간 단계

물리 업데이트는 "마지막 업데이트 이후의 경과 시간"인수로 전달되므로 프레임 속도에 따라 다릅니다. 이는로 계산을 의미 할 수 있습니다 position += distancePerSecond * timeElapsed.

장점 : 부드럽고 코딩하기 쉽다
단점 : 결정적이지 않고 매우 작은 단계에서 큰 단계로 예측할 수 없음

deWiTTERS 예 :

while( game_is_running ) {
    prev_frame_tick = curr_frame_tick;
    curr_frame_tick = GetTickCount();
    update( curr_frame_tick - prev_frame_tick );
    render();
}

고정 시간 단계

업데이트는 각 업데이트가 고정 된 기간 동안이라고 가정하므로 "시간 경과"를 허용하지 않을 수도 있습니다. 계산은 다음과 같이 수행 할 수 있습니다 position += distancePerUpdate. 이 예제에는 렌더링 중 보간이 포함됩니다.

장점 : 예측 가능하고 결정적 (네트워크 동기화가 더 쉬워 집니까?), 더 명확한 계산 코드
단점 : v- 동기화를 모니터링하기 위해 동기화되지 않음 (보간하지 않으면 불안감 그래픽 발생), 제한된 최대 프레임 속도 (보간하지 않는 한), 가변 시간 단계 가정 (예 : Pyglet 또는 Flixel )

deWiTTERS 예 :

while( game_is_running ) {
    while( GetTickCount() > next_game_tick ) {
        update();
        next_game_tick += SKIP_TICKS;
    }
    interpolation = float( GetTickCount() + SKIP_TICKS - next_game_tick )
                    / float( SKIP_TICKS );
    render( interpolation );
}

일부 자료


6
게임에는 다양한 시간 간격을 사용하고 물리에는 고정 단계를 사용하십시오
Daniel Little

7
고정 시간 단계를 사용하면 "모든 계산을 어디에서나 timeElapsed 변수와 혼동 할 필요가 없기 때문에"변수 시간 단계가 정확하게 코딩하기 쉽다고 말할 수는 없습니다. 그렇게 어렵지는 않지만 전문가로서 "코드를 더 쉽게"추가하지는 않을 것입니다.
pek

사실, 나는 당신이 가변 시간 단계를 보간 할 필요가없는 방법을 언급하고 있다고 생각합니다.
Nick Sonneveld

@pek 동의합니다. 가변 시간 단계에는 코딩 된 게임 루프가 더 간단하지만 "속도를 맞추기"위해 해당 가변성을 처리하는 엔터티를 더 코딩해야합니다. 고정 시간 단계는 게임 루프를 코딩하기가 더 복잡합니다 (시간 근사 분산을 정확하게 보상하고 추가 할 지연 시간 또는 수정을 유지하기 위해 건너 뛸 업데이트 수를 다시 계산해야하기 때문에). 항상 같은 시간 간격을 처리해야합니다. 전체적으로 어떤 접근법도 다른 것보다 명확하게 단순하지 않습니다.
Shivan Dragon

이 툴에서이 비주얼을 확인할 수 있습니다 : s3.amazonaws.com/picobots/assets/unity/jerky-motion/… 프레임 속도가 변할 때 어떻게 보일지에 대한 아이디어를 제공하지는 않지만
Buddy

답변:


134

질문과 관련된 두 가지 문제가 있습니다.

  • 물리 단계 속도를 프레임 속도와 연결해야합니까?
  • 물리가 일정한 델타로 스텝되어야합니까?

Glen fielder 's에서 당신의 시간 단계를 수정하세요. 그게 당신의 물리학 업데이트 속도가해야 의미 하지 프레임 속도에 묶여.

예를 들어, 디스플레이 프레임 속도가 50fps이고 시뮬레이션이 100fps에서 실행되도록 설계된 경우 물리 동기화를 유지하려면 디스플레이 업데이트마다 두 개의 물리 단계를 수행해야합니다.

Box2D에 대한 Erin Catto의 권장 사항에서도이를 옹호합니다.

따라서 시간 간격을 프레임 속도에 연결하지 마십시오 (실제로 정말로 필요한 경우가 아니면).

물리 단계 속도를 프레임 속도와 연결해야합니까? 아니.


고정 스텝 대 가변 스테핑에 대한 Erin의 생각 :

Box2D는 적분기라고하는 계산 알고리즘을 사용합니다. 적분기는 이산 시점에서 물리 방정식을 시뮬레이션합니다. ... 우리는 또한 시간이 많이 바뀌는 것을 좋아하지 않습니다. 가변 시간 단계는 가변 결과를 생성하므로 디버그하기가 어렵습니다.

고정 대 가변 스테핑에 대한 Glen의 생각 :

타임 스텝 수정 또는 폭발

... 자동차 시뮬레이션에서 쇼크 업소버에 대한 일련의 강성 스프링 구속 조건이있는 경우 dt의 작은 변화로 인해 실제로 시뮬레이션이 폭발 할 수 있습니다. ...

물리가 일정한 델타로 스텝되어야합니까? 예.


일정한 델타로 물리학을 강화하고 물리 업데이트 속도를 프레임 속도에 묶지 않는 방법은 여전히 ​​시간 누산기를 사용하는 것입니다. 내 게임에서 한 걸음 더 나아갑니다. 들어오는 시간에 스무딩 기능을 적용합니다. 그렇게하면 큰 FPS 스파이크가 물리를 너무 멀리 뛰어 넘지 않고 대신 한 두 프레임에 대해 더 빠르게 시뮬레이션됩니다.

고정 속도로 물리가 디스플레이와 동기화되지 않을 것이라고 언급했습니다. 목표 물리 속도가 목표 프레임 속도에 근접한 경우에 해당됩니다. 프레임 속도가 물리 속도보다 더 나쁩니다. 일반적으로 목표 FPS의 두 배인 물리 업데이트 속도를 감당할 수 있다면 목표로 삼는 것이 좋습니다.

큰 물리 업데이트 속도를 감당할 수없는 경우 프레임간에 그래픽의 위치를 ​​보간하여 그려진 그래픽이 실제로 움직이는 것보다 더 부드럽게 움직이는 것처럼 보이도록하십시오.


1
나는 기계를 업그레이드하기 전후에 The Floor is Jelly를 연주했으며 어리 석었습니다. 물리학은 실제로 게임 루프에서 호출되었으므로 (프레임 레이트에 묶여 있기 때문에) 같지 않았습니다. 타이머. 내 오래된 기계는 매우 나빴 기 때문에 지속적으로 슬로우 모션과 너무 빠른 모션을 전환했으며 게임 플레이에 큰 영향을 미쳤습니다. 이제는 매우 빠른 동작입니다. 어쨌든 게임은이 문제가 얼마나 문제가 될 수 있는지 보여주는 훌륭한 예입니다 (아직도 귀여운 게임입니다).
MasterMastic

55

실제로 3 가지 옵션이 있다고 생각하지만 옵션을 2로만 나열하고 있습니다.

옵션 1

아무것도하지 마세요. 특정 간격 (예 : 초당 60 회)으로 업데이트 및 렌더링을 시도하십시오. 뒤 떨어지면 걱정하지 마십시오. CPU가 게임을 따라갈 수없는 경우 게임이 느린 슬로우 모션으로 느려집니다. 이 옵션은 실시간 다중 사용자 게임에서는 전혀 작동하지 않지만 싱글 플레이어 게임에는 적합하며 많은 게임에서 성공적으로 사용되었습니다.

옵션 2

각 업데이트 사이의 델타 시간을 사용하여 객체의 움직임을 변경하십시오. 이론 상으로는, 특히 게임에서 가속 또는 감속하는 것이 없지만 일정한 속도로 움직이는 경우에 특히 좋습니다. 실제로 많은 개발자들이이를 잘못 구현하여 충돌 감지 및 물리가 일관되지 않을 수 있습니다. 일부 개발자는이 방법이 더 쉽다고 생각합니다. 이 옵션을 사용하려면 게임을 상당히 강화하고 (예를 들어 대부분의 사람들이 사용하는 표준 오일러 대신) Verlet 물리 통합기를 사용하고 충돌 감지에 광선을 사용하는 등의 주요 수학 및 알고리즘을 가져와야합니다. 단순한 피타고라스 거리 검사보다는. 나는 잠시 동안 Stack Overflow에서 이것에 대한 질문을하고 훌륭한 답변을 얻었습니다.

https://stackoverflow.com/questions/153507/calculate-the-position-of-an-accelerating-body-after-a-certain-time

옵션 3

Gaffer의 "시간 단계 수정"접근법을 사용하십시오. 옵션 1에서와 같이 고정 된 단계로 게임을 업데이트하되 경과 시간에 따라 렌더링 된 프레임 당 여러 번 그렇게함으로써 게임 논리는 실시간으로 유지하면서 불연속적인 단계를 유지합니다. 이런 식으로 Euler 통합 자 및 간단한 충돌 감지와 같은 게임 로직을 쉽게 구현할 수 있습니다. 델타 시간을 기반으로 그래픽 애니메이션을 보간하는 옵션도 있지만 이는 시각적 효과만을위한 것이며 핵심 게임 논리에 영향을 미치지 않습니다. 업데이트가 매우 집중적 인 경우 문제가 발생할 수 있습니다. 업데이트가 뒤쳐 질 경우 계속 업데이트하기 위해 점점 더 많은 업데이트가 필요하므로 게임의 응답 성이 떨어질 수 있습니다.

개인적으로, 나는 그것을 멀리 할 수있을 때 옵션 1을, 실시간으로 동기화해야 할 때 옵션 3을 좋아합니다. 나는 당신이하고있는 일을 알 때 옵션 2가 좋은 옵션이 될 수 있다고 생각합니다.


옵션 2와 관련하여 : 피타고라스를 적용 할 때 매우 무력한 경우를 제외하고는 레이 캐스트가 피타고라스 거리 검사보다 빠를 수 있다고 확신하지 못하지만, 광대역을 추가하지 않으면 레이 캐스트도 매우 비쌉니다.
Kaj

4
불평등 한 시간 간격으로 Verlet을 사용하면 목욕물로 아기를 버리게됩니다. Verlet이 안정된 이유는 후속 시간 단계에서 오류가 취소되기 때문입니다. 시간 간격이 같지 않으면 이런 일이 일어나지 않으며 물리학의 땅으로 돌아옵니다.
drxzcl

옵션 3-Joel Martinez의 XNA 접근 방식에 대한 설명처럼 들립니다.
topright

1
이것은 정말 좋은 대답입니다. 세 가지 옵션 모두 각자의 위치에 있으며 적절한시기를 이해하는 것이 중요합니다.
Adam Naylor

내가 작업 한 모든 MMO (EQ, Landmark / EQNext [cry], PS2 [briely] 및 ESO)는 항상 가변 프레임 시간을 사용했습니다. 나는 그 특정 결정에 대한 파티가 아니었고, 사실 후에 나타 났고 다른 사람들이 결정한 것을 사용했습니다.
Mark Storer

25

XNA Framework 가 고정 시간 단계를 구현 하는 방식이 정말 마음에 듭니다 . 주어진 드로우 콜이 너무 오래 걸리면 "캐치"될 때까지 update를 반복해서 호출합니다. Shawn Hargreaves는 여기에 설명합니다 :
http://blogs.msdn.com/b/shawnhar/archive/2007/11/23/game-timing-in-xna-game-studio-2-0.aspx

2.0에서 Draw 동작이 변경되었습니다.

  • 현재 시간을 따라 잡기 위해 필요한만큼 업데이트를 호출하십시오.
  • 한 번 그리기
  • 다음 업데이트 시간이 될 때까지 기다리십시오

이것에 대한 나의 의견으로는 가장 큰 장점은 당신이 언급 한 것인데, 모든 시간 동안 변수를 포함 할 필요가 없기 때문에 모든 게임 코드 계산을 훨씬 간단하게 만듭니다.

참고 : xna는 가변 시간 단계도 지원하며 설정 일뿐입니다.


이것이 게임 루프를 수행하는 가장 일반적인 방법입니다. 그러나 모바일 장치로 작업 할 때 배터리 수명에는 좋지 않습니다.
knight666

1
@ knight666; 더 긴 시간 간격을 사용하면 반복 횟수를 줄이면 배터리 수명이 절약 될 것입니다.
falstro

이것은 여전히 ​​가변 업데이트입니다. 업데이트 델타는 프레임이 고정 값이 아닌 렌더링하는 데 걸리는 시간 (예 : 1/30 초)에 따라 변경됩니다.
데니스 먼지

1
@Dennis : 이해할 수 있듯이 Update 함수는 고정 델타로 호출됩니다.
RCIX

3
@ knight666 어-어떻게 알아? vsync가 켜져 있고 더듬 거리지 않는 경우이 방법은 동일해야합니다! 그리고 vsync 기능을 해제 한 경우 유휴 상태가되지 않아 CPU (및 배터리)가 필요 이상으로 자주 업데이트 됩니다.
앤드류 러셀

12

게임 업데이트와 물리 업데이트를 분리하는 또 다른 옵션이 있습니다. 물리 엔진을 게임 타임 스텝에 맞추려고하면 타임 스텝을 수정하거나 (통합에 더 많은 타임 스텝이 필요하고 더 많은 타임 스텝이 필요한 시간 단계가 필요하기 때문에 제어에서 탈피하는 문제) 문제를 일으킨다.

내가 많이 볼 수있는 해결책은 물리가 다른 스레드 (다른 코어)에서 고정 된 시간 간격으로 실행되도록하는 것입니다. 게임은 획득 할 수있는 가장 최근의 두 프레임을 보간하거나 보간합니다. 보간은 약간의 지연을 추가하고, 외삽은 약간의 불확실성을 추가하지만, 물리는 안정적이며 시간 단계를 통제에서 벗어나지 않습니다.

이것은 구현하기가 쉽지 않지만 미래의 증거가 될 수 있습니다.


8

개인적으로, 나는 가변 시간 단계의 변형을 사용합니다 (이것은 고정 및 가변의 하이브리드 유형이라고 생각합니다). 이 타이밍 시스템을 여러 가지 방법으로 스트레스 테스트했으며 많은 프로젝트에 사용하고 있습니다. 모든 것에 추천합니까? 아마 아닙니다.

내 게임 루프는 업데이트 할 프레임의 양을 계산 한 다음 (이 F라고 함) F 이산 논리 업데이트를 수행합니다. 모든 논리 업데이트는 일정한 시간 단위 (내 게임에서 종종 1/100 초)를 가정합니다. 모든 F 이산 논리 업데이트가 수행 될 때까지 각 업데이트가 순서대로 수행됩니다.

논리 단계에서 개별 업데이트가 필요한 이유는 무엇입니까? 연속 단계를 사용하려고하면 계산 된 속도와 이동 거리에 큰 값 F가 곱 해져 갑자기 물리 결함이 발생합니다.

이것을 제대로 구현하지 않으면 F = 현재 시간-마지막 프레임 시간 업데이트가 수행됩니다. 그러나 계산이 너무 늦어지면 (때로는 CPU 시간을 훔치는 다른 프로세스와 같이 제어 할 수없는 상황으로 인해) 끔찍한 건너 뛰기가 나타납니다. 유지하려는 안정적인 FPS는 곧 SPF가됩니다.

내 게임에서는 "매끄러운"(정렬) 속도 저하를 허용하여 두 드로우 사이에 가능한 로직 캐치 업의 양을 제한합니다. 클램핑하여이 작업을 수행합니다. F = min (F, MAX_FRAME_DELTA) 일반적으로 MAX_FRAME_DELTA = 2/100 * s 또는 3/100 * s입니다. 따라서 게임 로직보다 너무 늦을 때 프레임을 건너 뛰는 대신 프레임 손실을 크게 줄이고 프레임 속도를 늦추고 몇 프레임을 복구 한 후 다시 시도하십시오.

이를 통해 플레이어 컨트롤이 화면에 실제로 표시된 것과 더 가깝게 동기화되도록합니다.

최종 제품 의사 코드는 다음과 같습니다 (델타는 F가 앞에서 언급했습니다).

// Assume timers have 1/100 s resolution
const MAX_FRAME_DELTA = 2
// Calculate frame gap.
var delta = current time - last frame time
// Clamp.
delta = min(delta, MAX_FRAME_RATE)
// Update in discrete steps
for(i = 0; i < delta; i++)
{
    update single step()
}
// Caught up again, draw.
render()

이런 종류의 업데이트는 모든 것에 적합하지는 않지만 아케이드 스타일 게임의 경우 프레임을 놓치거나 플레이어 제어를 잃는 것보다 많은 일이 있기 때문에 게임 속도가 느려질 것입니다. 또한 프레임 손실로 인해 재현 할 수없는 글리치가 발생하는 다른 가변 시간 단계 접근 방식을 선호합니다.


마지막 요점에 강력히 동의하십시오. 거의 모든 게임에서 프레임 속도가 떨어지면 입력 속도가 느려집니다. 일부 게임 (예 : 멀티 플레이어)에서는 이것이 불가능하지만 가능하다면 여전히 더 좋습니다. : P 그것은 단순히 긴 프레임을 가지고 있고 게임 세계를 '정확한'상태로 '점프'하는 것보다 기분이 더 좋습니다.
Ipsquiggle

아케이드 머신과 같은 고정 하드웨어가 없다면, 아케이드 게임이 하드웨어를 유지할 수 없을 때 시뮬레이션 속도를 늦추면 느린 머신 속임수로 플레이 할 수 있습니다.

우리가 "속임수"에 관심이있는 경우에만 중요한 Joe. 대부분의 현대 게임은 실제로 플레이어 간의 경쟁이 아니라 재미있는 경험을 제공합니다.
Iain

1
우리는 아케이드 스타일의 게임에 대해 구체적으로 이야기하고 있습니다. 나는 엄청나게 많은 shmups를하고, 누군가 내가 순위표에 인공적인 둔화로 점수를 올리는 것을 발견했다면 나는 그들의 점수를 지우고 싶다.

답을 줄이려고하지는 않지만, 물리학을 따라 잡는 것이 렌더링보다 우선한다는 점을 제외하고는 렌더링이 물리 업데이트 속도와 직접 관련이없는 고정 된 단계로 해석합니다. 그것은 분명히 좋은 자질을 가지고 있습니다.
AaronLS

6

이 솔루션은 모든 것에 적용되는 것은 아니지만, 또 다른 수준의 가변 타임 스텝 (세계 각 객체에 대한 가변 타임 스텝)이 있습니다.

이것은 복잡해 보일 수 있지만 게임을 개별 이벤트 시뮬레이션으로 모델링하는 것으로 생각하십시오. 각 플레이어의 움직임은 동작이 시작될 때 시작하고 동작이 끝날 때 끝나는 이벤트로 표현 될 수 있습니다. 이벤트를 분리해야하는 상호 작용 (예 : 충돌)이있는 경우 이벤트가 취소되고 다른 이벤트가 이벤트 큐로 푸시됩니다 (아마도 이벤트 종료 시간별로 정렬 된 우선 순위 큐임).

렌더링은 이벤트 큐에서 완전히 분리됩니다. 디스플레이 엔진은 필요에 따라 이벤트 시작 / 종료 시간 사이에 포인트를 보간하며,이 추정치에서 필요에 따라 정확하거나 느슨해 질 수 있습니다.

이 모델의 복잡한 구현을 보려면 공간 시뮬레이터 EXOFLIGHT를 참조하십시오 . 기존 고정 시간 분할 모델이 아닌 대부분의 비행 시뮬레이터와는 다른 실행 모델 (이벤트 기반 모델)을 사용합니다. 이 유형의 시뮬레이션의 기본 메인 루프는 의사 코드에서 다음과 같습니다.

while (game_is_running)
{
   world.draw_to_screen(); 
   world.get_player_input(); 
   world.consume_events_until(current_time + time_step); 
   current_time += time_step; 
}

우주 시뮬레이터에서 하나를 사용하는 주된 이유는 정확도 손실없이 임의의 시간 가속을 제공해야하기 때문입니다. EXOFLIGHT의 일부 임무는 완료하는 데 게임 년이 걸릴 수 있으며 32 배 가속 옵션도 충분하지 않습니다. 사용 가능한 시뮬레이션을 위해서는 1,000,000 배 이상의 가속이 필요합니다. 이는 타임 슬라이스 모델에서는 어렵습니다. 이벤트 기반 모델을 사용하면 1 초 = 7ms에서 1 초 = 1 년까지 임의의 시간 속도를 얻습니다.

시간 속도를 변경해도 시뮬레이션의 동작은 변경되지 않으며 이는 중요한 기능입니다. 원하는 속도로 시뮬레이터를 실행할 수있는 CPU 전원이 충분하지 않으면 이벤트가 누적되고 이벤트 큐가 지워질 때까지 UI 새로 고침이 제한 될 수 있습니다. 마찬가지로, 원하는만큼 시뮬레이션을 빨리 진행할 수 있으며 CPU를 낭비하거나 정확성을 희생하지 않아야합니다.

요약하자면 (런지-쿠타 통합을 사용하여) 길고 느긋한 궤도에서 한 대의 차량을 모델링하고 지상을 따라 동시에 튀는 다른 차량을 모델링 할 수 있습니다. 전 세계 타임 스텝이 없기 때문에 두 차량 모두 적절한 정확도로 시뮬레이션됩니다.

단점 : 복잡성 및이 모델을 지원하는 상용 물리 엔진 부족 :)


5

고정 시간 단계는 부동 소수점 정확도를 고려하고 업데이트 일관성을 유지하는 데 유용합니다.

간단한 코드이므로 테스트 해보고 게임에 적합한 지 확인하는 것이 좋습니다.

now = currentTime
frameTime = now - lastTimeStamp // time since last render()
while (frameTime > updateTime)
    update(timestep)
    frameTime -= updateTime     // update enough times to catch up
                                // possibly leaving a small remainder
                                // of time for the next frame

lastTimeStamp = now - frameTime // set last timestamp to now but
                                // subtract the remaining frame time
                                // to make sure the game will still
                                // catch up on those remaining few millseconds
render()

고정 시간 간격을 사용하는 주된 문제는 빠른 컴퓨터 사용자는 속도를 이용할 수 없다는 것입니다. 게임이 30fps로만 업데이트 될 때 100fps로 렌더링하는 것은 30fps로 렌더링하는 것과 같습니다.

즉, 하나 이상의 고정 된 시간 간격을 사용할 수 있습니다. 60fps를 사용하여 사소한 오브젝트 (예 : UI 또는 애니메이션 스프라이트)를 업데이트하고 30fps를 사용하여 사소하지 않은 시스템 (예 : 물리 및)을 업데이트 할 수 있으며, 사용하지 않는 오브젝트, 리소스 삭제 등 장면 관리 뒤에서 수행 할 느린 타이머도 사용할 수 있습니다.


2
게임이 신중하게 만들어진 경우 render 메소드는 보간을 수행하여 30fps 업데이트를 실제로 30fps에서 렌더링하는 것과 동일하지 않게 할 수 있습니다.
Ricket

3

이미 언급 한 것 외에도 게임에서 원하는 느낌이들 수도 있습니다. 항상 일정한 프레임 속도를 보장 할 수 없다면 어딘가 속도가 느려지고 고정 및 가변 시간 단계가 매우 다르게 보일 것입니다. 고정은 게임이 한동안 슬로우 모션으로 진행되는 효과를 가져 오며 때로는 의도 한 효과가 될 수 있습니다 (이카가와 같은 구식 스타일의 슈팅 게임을 보면 보스를 때린 후 폭발이 느려지는 곳). 시간 간격이 가변적이면 사물이 올바른 속도로 움직일 수 있지만 위치 등이 갑자기 바뀌면 플레이어가 정확하게 행동하기가 어려울 수 있습니다.

고정 시간 단계는 네트워크를 통해 작업을 더 쉽게 할 수 있다는 것을 알 수 없습니다. 하나의 컴퓨터에서 시작하고 느리게하기 위해 모두 약간 동기화되지 않았지만 다른 머신은 더 동기화되지 않습니다.

나는 항상 개인적으로 변수 접근 방식을 선호했지만 그 기사에는 몇 가지 흥미로운 점이 있습니다. 그래도 여전히 고정 단계를 매우 일반적으로 발견했습니다. 특히 사람들이 PC에서 얻을 수있는 매우 높은 속도와 비교할 때 프레임 속도가 일정한 60fps라고 생각하는 콘솔에서 특히 그렇습니다.


5
원래 게시물의 게임에서 Gaffer 링크를 반드시 읽으십시오. 나는 이것이 그 자체로 나쁜 대답이라고 생각하지 않기 때문에 나는 그것을 투표하지 않을 것이지만, 나는 당신의 주장에 동의하지 않습니다 .
falstro

정해진 시간 간격으로 인해 게임이 느려지는 것은 의도적 인 것이 아니라고 생각합니다 . 왜냐하면 그것은 통제력이 없기 때문입니다. 통제력 결여는 정의상 우연히 항복하므로 의도적 일 수 없습니다. 그것은 당신이 염두에두고있을 수 있지만, 내가 계속하고 싶은 한입니다. 네트워킹의 고정 타임 스텝에 대해서는 동일한 타임 스텝없이 두 개의 다른 머신에 물리 엔진을 동기화시키는 것이 불가능하기 때문에 확실한 장점이 있습니다. 동기화하는 유일한 옵션은 모든 엔터티 변환을 전송하는 것이므로 대역폭이 너무 무거울 수 있습니다.
Kaj

0

Gaffer의 "시간 단계 수정"접근법을 사용하십시오. 옵션 1에서와 같이 고정 된 단계로 게임을 업데이트하되 경과 시간에 따라 렌더링 된 프레임 당 여러 번 그렇게함으로써 게임 논리는 실시간으로 유지하면서 불연속적인 단계를 유지합니다. 이런 식으로 Euler 통합 자 및 간단한 충돌 감지와 같은 게임 로직을 쉽게 구현할 수 있습니다. 델타 시간을 기반으로 그래픽 애니메이션을 보간하는 옵션도 있지만 이는 시각적 효과만을위한 것이며 핵심 게임 논리에 영향을 미치지 않습니다. 업데이트가 매우 집중적 인 경우 문제가 발생할 수 있습니다. 업데이트가 뒤쳐 질 경우 계속 업데이트하기 위해 점점 더 많은 업데이트가 필요하므로 게임의 응답 성이 떨어질 수 있습니다.

개인적으로, 나는 그것을 멀리 할 수있을 때 옵션 1을, 실시간으로 동기화해야 할 때 옵션 3을 좋아합니다. 나는 당신이하고있는 일을 알 때 옵션 2가 좋은 옵션 일 수 있다고 생각합니다. 그러나 나는 그것을 멀리 할만 큼 충분히 내 한계를 알고 있습니다.


당신이 대답을 훔치려면 적어도 그 사람을 신용!
PrimRock

0

60fps로 동기화 된 고정 시간 간격이 거울에 부드러운 애니메이션을 제공한다는 것을 알았습니다. 이는 VR 애플리케이션에서 특히 중요합니다. 다른 어떤 것도 물리적으로 구역질이 나고 있습니다.

가변 시간 단계는 VR에 적합하지 않습니다. 다양한 타임 스텝을 사용하는 Unity VR 예제를 살펴보십시오. 불쾌합니다.

VR 모드에서 3D 게임이 매끄럽다면 VR 이외의 모드에서 탁월합니다.

이 두 가지 비교 (Cardboard VR 앱)

(가변 시간 단계)

(고정 된 시간 간격)

일정한 시간 간격 / 프레임 속도를 달성하려면 게임을 멀티 스레딩해야합니다. 물리, UI 및 렌더링은 전용 스레드로 분리해야합니다. 그것들을 동기화하는 것은 끔찍한 PITA이지만 결과는 원하는 거울 부드러운 렌더링 (VR의 경우)입니다.

모바일 게임은 esp입니다. 임베디드 CPU 및 GPU의 성능이 제한적이므로 문제가됩니다. CPU에서 최대한 많은 작업을 오프로드하려면 GLSL (속어)을 조금만 사용하십시오. GPU에 매개 변수를 전달하면 버스 리소스가 소비됩니다.

개발하는 동안 항상 프레임 속도를 표시하십시오. 실제 게임은 60fps로 고정 된 상태로 유지하는 것입니다. 대부분의 화면과 대부분의 안구에 대한 기본 동기화 속도입니다.

사용중인 프레임 워크는 동기화 요청을 알리거나 타이머를 사용할 수 있어야합니다. 이것을 달성하기 위해 잠자기 / 대기 지연을 삽입하지 마십시오 – 약간의 변화가 눈에 even니다.


0

가변 시간 단계는 렌더링주기, 이벤트 처리, 네트워크 작업 등 가능한 한 자주 실행해야하는 절차를위한 것입니다.

고정 시간 단계는 예측 가능하고 안정적인 무언가가 필요할 때를위한 것입니다. 여기에는 물리 및 충돌 감지가 포함되지만 이에 국한되지는 않습니다.

실제적으로 물리 및 충돌 감지는 자체 시간 단계에서 다른 모든 것과 분리되어야합니다. 작은 고정 시간 단계에서 이와 같은 절차를 수행하는 이유는 절차를 정확하게 유지하기 위함입니다. 임펄스 크기는 시간에 따라 크게 달라지며 간격이 너무 커지면 시뮬레이션이 불안정 해지고 미친 물건이 튀어 오르는 공 단계처럼지면을 통해 튀어 나오거나 게임 세계에서 튀어 오르는 것처럼 바람직하지 않습니다.

다른 모든 것은 가변 시간 단계에서 실행할 수 있습니다 (전문적으로 말하면 고정 된 시간 단계로 렌더링을 잠그는 것이 좋습니다). 게임 엔진이 응답하려면 네트워크 메시지 및 사용자 입력과 같은 항목을 가능한 빨리 처리해야합니다. 즉, 폴링 간격이 가능한 짧아야합니다. 이것은 일반적으로 변수를 의미합니다.

다른 모든 것은 비동기식으로 처리 할 수있어 타이밍이 문제가됩니다.

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