StatVisualizer?

  • In-Game에서 발생한 event들을 수집하고, 이를 시각화하여(via UnrealEd) 살펴볼 수 있는 기능.
  • 플레이어들의 주요 동선이나 KillEvent 등 다양한 이벤트를 수집할 수 있으며, 게임별 유니크 이벤트를 위한 확장 기능 또한 충실하게 되어 있는 편이다.

UDN Links

Related code files

  • GameplayEventsWriter.uc / GameplayEvents.cpp
    • 메인 클래스
    • 추후 이를 sub-classing하여 해당 게임에 맞는 이벤트 로깅을 시도할 수 있다.
  • GameStats.uci
    • GameStats 로깅을 위한 UnrealScript Include File이다.
    • 각 이벤트들의 EventID
    • 각종 상황을 편하게 기록하기 위한 macro 들이 정의되어 있다.
      • `RecordKillEvent(KillType,Killer,DamageType,Dead) 등과 같은

Pre-Setting for using GameStatVisualizer

1. 우선 DefaultGame.ini에 다음 내용을 추가하여야 한다.
// 게임 클래스의 설정 내용에 아래 설정 추가.
 
// UDN에 보면 GameplayEventsWriterClassName이 "UTGameplayEventsWriter"로 되어 있는데, 이 클래스가 현재 없다.
GameplayEventsWriterClassName="Engine.GameplayEventsWriter"
bLogGameplayEvent=true
2. 그 뒤 DefaultEditor.ini에 GameStatsBrowser를 위한 설정을 해야 한다.
// 기본적으로 GameStatsBrowser 설정이 되어 있다.
// 여기에서 다음 부분들을 바꾸어 주어야 한다.
RemoteConnectionIp="XXX.XXX.XXX.XXX" // <<- 이 녀석을 실제 머신의 ip로 지정한다.
 
// 아래 두 설정 중 바꾸어주어야 하는 부분은 Data Source 부분이다.
// Data Source의 값을 실제 머신의 Host name으로 지정해 주어야 한다.
ConnectionString="~~~~~~~~~~~~~~~"
RemoteConnectionStringOverride="~~~~~~~~~~~~~~~"

3. 마지막으로, Match가 시작되기 전 GameStatsWriter 인스턴스를 생성해야 한다.

// Gameplay statistics 변수들
var config string GameplayEventsWriterClassName;    // 사용될 클래스명
var config bool bLogGameplayEvents;    // 이벤트 로깅을 할 것인가?
var transient GameplayEventsWriter GameplayEventsWriter;    // 통계수집 클래스 인스턴스
 
// 원하는 GameInfo subclass에서 PostBeginPlay() 함수에 다음과 같이 인스턴스 생성 코드를 삽입한다.
function PostBeginPlay()
{
    local class<GameplayEventsWriter> GameplayEventsWriterClass;
 
    if ( bLogGamePlayEvents && GameplayEventsWriterClassName != "" )
    {
        GameplayEventsWriterClass = class<GameplayEventsWriter>(FindObject(GameplayEventsWriterClassName, class'Class'));
        if ( GameplayEventsWriterClass != None )
        {
            GameplayEventsWriter = new(self) GameplayEventsWriterClass;
            if ( GameplayEventsWriter != None )
            {
                // Do something...
            }
            else
            {
                // Do something...
            }
        }
    }
}

How to write GameplayEvents

  • 이제 사전설정이 끝났으므로 실제 기록을 해보자.
  • 위 Pre-Setting 3번 과정에서 GameplayEventsWriter의 인스턴스를 생성하였다.
  • 이제 본격적인 기록을 위해 StartLogging 함수를 호출하여야 한다.
  • 보통 매치가 시작되고 끝날 때까지 기록을 하므로 다음 코드 블럭과 같이 시작/끝을 하는 게 보통이다.
function StartMatch()
{
    if ( GameplayEventsWriter != None && !GameplayEventsWriter.IsSessionInProgress() && !class'WorldInfo'.static.IsMenuLevel() )
    {
        // Parameter는 HeartBeating 주기이다. 단위는 초 단위.
        // 특정 주기로 반복해서 기록해야 하는 이벤트를 위한 "Poll" timer를 HeartBeatDelta 주기로 생성시킨다.
        // 예를 들어, 플레이어들의 location 정보 수집 등에 사용될 수 있겠다.
        GameplayEventsWriter.StartLogging(0.5f);
    }
    ...
}
 
// EndLogging은 게임이 종료되는 곳에 넣어주면 된다.
// ex) function EndGame
  • 이제 게임이 진행되는 동안 GameplayEvents 기록이 되므로, 각 상황에 맞게 보고 싶은 곳에서 이벤트 로깅 함수를 호출해주면 된다.
    • KillEvent 등의 이벤트 말이다.

How to visualize GameplayEvents

  • GameStats가 정상적으로 생성되면, XXXGame\Stats 폴더가 생성된다.
    • “MapName”-“Platform”-“Version”의 naming rule이 사용된다.
    • 즉, 00_AITest_Big-PC-427742 처럼 폴더가 생성된다.
  • 해당 폴더안에는 Stats file이 날짜별로 저장되며, file extension은 “gamestats”이다.
    • ex) 00_AITest_Big-PC-04-17.24.33.gamestats
  • 자, 이제 GameStats 파일이 제대로 생성된 것을 확인하였으니, UnrealEd에서 확인해 보자.
  • 그러기 위해서는 UnreadEd를 실행시킬 때 ”-gamestats” commandline을 붙여서 실행해야 한다.
    • XXGame.exe editor -gamestats
    • Editor 실행 후 평소엔 보이지 않던, GameStats 탭이 보일 것이다.
    • 5418250216_6e232cc2b5_z.jpg
  • 하지만, 생성했었던 Stats 파일이 아직 보이지 않을 것이다. 하지만 당황하지 말자.
  • Stats 파일은 해당 Map이 에디터에 로드가 되어 있어야 보인다.
  • 00_AITest_Big 맵을 로드하니까, 다음과 같이 Stats 파일이 보인다.
    • 5418250204_498bf81892_b.jpg

TODO & 활용도

  • GameplayEventsWriter를 sub-classing하여 추후 의미있는 이벤트 로깅을 할 수 있도록 해야 한다.
  • 각종 상황에 맞게 이벤트 로깅을 실제 수행하여 HeatMap 의 기능이 정말 원활한지 보아야 한다.
  • 이것을 통해 특정 레벨의 커버리지를 정확하게 측정하는데 도움이 될 것이다.