슬레이트 슬립 및 액티브 타이머

액티브 시스템 타이머를 통해 UI 업데이트 필요가 없을 때 슬레이트가 슬립 모드로 들어갈 수 있습니다.

Windows
MacOS
Linux

Slate (슬레이트)는 "중간 모드" UI 프레임워크, 즉 매 프레임마다 전체 UI 를 다시 그린다는 뜻입니다. 그래픽과 애니메이션이 풍성한 매우 역동적인 인터페이스에는 좋지만, 그로 인해 UI 에 변화가 없을 경우엔 프로세서가 불필요하게 낭비됩니다. 슬레이트의 Active Timer (액티브 타이머) 시스템을 사용하면 UI 업데이트가 필요없을 때 슬레이트가 Sleep (슬립) 상태로 들어가는 것이 가능합니다. 액티브 타이머 기능은 에디터 UI 작업에는 좋지만, 실시간 뷰포트가 있는 게임 UI 에는 좋지 않을 것입니다.

슬레이트 슬립 상태는 주어진 프레임 동안 다음 두 조건이 참일 경우 발생합니다:

  • 사용자 조작이 없을 때, 그리고

  • 액티브 타이머 실행이 필요치 않을 때 입니다.

사용자 조작은 마우스 이동, 클릭, 키 눌림을 말합니다.

다음 도표는 현재 슬레이트 어플리케이션의 틱이 매 프레임 어떻게 이루어지는지를 나타냅니다:

image00.png

이 도표는 슬레이트가 슬립 상태로 들어가면 에디터의 프로세서 시간이 어떻게 변하는지를 보여줍니다.

image01.png

액티브 타이머

액티브 타이머는 실행되면 슬레이트 틱/페인트 패스를 발동시키는 위젯으로 인해 등록되는 델리게이트 함수로, 그 발동은 사용자 동작이 없어도 일어납니다 (그래서 "액티브", 즉 능동적 속성의 타이머라는 것입니다). 액티브 타이머는 등록이 해제될 때까지 그 실행 주기에 설정된 빈도로 무한 반복 실행됩니다.

원래 Tick() 함수는 "패시브", 즉 수동 틱으로 여전히 존재합니다. 전처럼 슬레이트에서 호출은 되나, 슬레이트가 깨어있을 때만 가능합니다. 추후 일정 시점에서 이름을 PassiveTick() 으로 변경하고, Tick() 은 폐기시켜 이런 부분을 보다 명확히 할 것입니다.

액티브 타이머를 등록하려면:

  1. 다음 시그너처를 포함시켜 함수를 정의합니다:
    EActiveTimerReturnType Foo(double InCurrentTime, float InDeltaTime)

  2. FWidgetActiveTimerDelegate 에 바인딩합니다.

  3. 델리게이트와 타이머 실행 주기(0 은 매 프레임 주기)를 SWidget::RegisterActiveTimer() 에 전달합니다.

액티브 타이머 등록 해제에 사용할 수 있는 메서드는 세 가지 있습니다.

  • 델리게이트에서 EActiveTimerReturnType::Stop 을 반환합니다.

  • SWidget::RegisterActiveTimer() 에 의해 반환된 FActiveTimerHandle 을 SWidget::UnRegisterActiveTick() 에 전달합니다.

  • 액티브 타이머가 등록되어 있는 위젯을 소멸시킵니다.

현재 액티브 타이머는 이거 아니면 저거인 상황에 사용되므로, 하나의 액티브 타이머 실행이 필요한 경우 모든 슬레이트 틱이 일어납니다. 추가로 하나의 위젯이 동시에 등록할 수 있는 액티브 타이머의 수에는 제한이 없습니다. 이는 매우 유용할 수 있으나, 중복 등록의 위험성이 있기도 합니다. 그에 대한 방비를 위해서는 등록 상태 관리가 필요한데, 그 방법은 다음과 같습니다:

  • 위젯의 플래그를 통해 액티브 타이머 등록 여부를 기록합니다.

    • 예로 UE4 코드베이스의 bIsActiveTimerRegistered 를 살펴보세요.

  • RegisterActiveTimer() 에 의해 반환된 FActiveTimerHandle 로의 약 포인터를 저장하고, 그것이 유효하지 않을 때만 등록합니다.

    • 예로 UE4 코드베이스의 TWeakPtr ActiveTimerHandle 을 검색해 보세요.

    • 메모리 절약을 위해서는, 액티브 타이머를 명시적으로 등록 해제할 필요가 있을 때만 이 메서드를 사용하세요.

일반적 용례

다음과 같은 일반적 용례에 대해 제안하는 액티브 타이머 구성은 다음과 같습니다:

  • 어떤 액션을 트리거시킬 때:

    • 항상 EActiveTimerReturnType::Stop 를 반환하는 액티브 타이머 주기를 0 으로 하여 등록합니다.

  • FCurveSequence 로 제어되지 않는 애니메이션 또는 보간 종류를 수행할 때:

    1. 관성 스크롤이 시작되면, 주기가 0 인 액티브 타이머를 등록하여 매 프레임 스크롤 업데이트를 합니다.

    2. 목적지에 도달하기 전까지 EActiveTimerReturnType::Continue 를 반환합니다.

    3. 목적지에 도달하면 EActiveTimerReturnType::Stop 를 반환하여 등록 해제합니다.

    이러한 관성 스크롤 예제는 SScrollBox 를 참고하세요.

  • 다양한 서브메뉴를 열거나 탭 도킹시 일정 딜레이 후 액션을 취하는 경우:

    • 딜레이를 0 초과 값으로 하여 등록합니다.

    액티브 타이머의 주기는 한 번 등록되면 변경할 수 없습니다. 실행 전 딜레이를 리셋시키려면, 액티브 타이머를 명시적으로 등록 해제한 다음 다시 등록해야 합니다.

  • 액션을 주기적으로 무한 시도할 경우:

    • 주기를 0 초과 값으로 등록하고 계속해서 EActiveTimerReturnType::Continue 를 반환합니다.

FCurveSequence 와 액티브 타이머

FCurveSequence 의 API 가 업데이트되어 위젯이 애니메이션 중일 때 액티브 틱을 등록하는 프로세스가 단순화되었습니다. 시퀀스를 재생하면 이제 애니메이션이 일어나는 위젯으로의 레퍼런스가 필요합니다. 시퀀스 재생 도중에는 전달된 위젯 대신 비어 있는 활성 틱이 자동 등록됩니다. 시퀀스의 루핑 여부는 이제 시퀀스 플레이시 지정됩니다. 하지만 그렇게 하면 액티브 틱이 무한 등록되므로, 사용시 주의를 요합니다. 루핑이 되든 말든, Pause(), JumpToStart(), 또는 JumpToEnd() 호출시 액티브 틱 등록은 해제됩니다.

슬레이트 슬립 모드 테스트

슬레이트 슬립 모드 관련 콘솔 변수는 둘 있습니다:

  • Slate.AllowSlateToSleep 는 슬레이트가 슬립 상태에 들어갈 수 있는지를 제어합니다. 현재 기본적으로 활성화되어 있습니다.

  • Slate.SleepBufferPostInput 은 사용자가 슬레이트 작업을 마지막으로 한 이후 얼마만큼 깨어있을지 기간을 정합니다. 이는 슬립 시스템의 영속적 기능이 아니므로, 디버깅에만 사용해야 합니다.

여기서의 목표는 슬립 모드가 불가능한 슬레이트와 구분되는 슬립 모드 가능 슬레이트를 만드는 것을 뿐이므로, 슬레이트가 실제로 슬립 모드인지 알기가 어렵습니다. 가장 좋은 모니터링 방법은 에디터 프레임 속도를 표시하는 것입니다 (에디터 세팅->기타->프레임 속도와 메모리 표시). 고정되면, 슬레이트가 슬립 모드인 것입니다.

새로운 언리얼 엔진 4 문서 사이트에 오신 것을 환영합니다!

문서 사이트에 대한 의견을 모을 수 있는 피드백 시스템을 포함해서 여러가지 새로운 기능을 준비하고 있습니다. 아래 Documentation Feedback 포럼(영문) 또는 언리얼 엔진 네이버 공식 카페(한글) 중 편하신 곳에 의견이나 문제점을 알려 주세요.

새 시스템이 준비되면 알려 드리겠습니다.

네이버 카페
공식 포럼