☑️

【UE5】TickableObjectを自分で実装するときはGetStatID関数を実装しないとハングしてエディターが落ちたので対処する

2024/11/01に公開

概要

TickableWorldSubsystemを継承して実装して使おうとすると、ソリューションから起動した時(エディターから起動は未検証)にハングしたので短いですが備忘録として記事を書いておきます。

今回はTickabeWorldSubsystemを実装しながら説明します。

環境

UE5.4.4

原因

最初はこういう感じのクラスを実装して使おうとしてました。

ExampleTickableObject.h
#pragma once

#include "CoreMinimal.h"
#include "Subsystems/WorldSubsystem.h"
#include "UExampleTickableObject.generated.h"

UCLASS(Blueprintable)
class UExampleTickableObject : public UTickableWorldSubsystem
{
    GENERATED_BODY()
public:
    virtual void Tick(float DeltaTime) override;
};

ExampleTickableObject.cpp
#include "GameClearTimeWorldSubsystem.h"

void UExampleTickableObject::Tick(float DeltaTime)
{
    //諸々の更新処理
}

これで実際にランタイムで動作させようとした所、下記のようなクラスの所でエラーが発生しました。

void FDebug::ProcessFatalError(void* ProgramCounter)
{
    // This is not perfect because another thread might crash and be handled before this assert
    // but this static variable will report the crash as an assert. Given complexity of a thread
    // aware solution, this should be good enough. If crash reports are obviously wrong we can
    // look into fixing this.
    bHasAsserted = true;
    
    GError->SetErrorProgramCounter(ProgramCounter);
    GError->Logf(TEXT("%s"), GErrorHist);
}

そのまま続行するとハングしてしまい、エディターが落ちてしまいました。
原因はGetStatId()関数をoverrideしてないとベースクラスであるUTickableWorldSubsystemPURE_VIRTUALで実装していてエラー(例外?)処理がされてしまい落ちてしまうみたいでした。
なので、この関数を実装すれば解決しました。

対処法

UE5 How to make Tickable Objects

こちらの記事を参考にしながら実装した所、下記のような実装で解決しました。

ExampleTickableObject.cpp
StatId UExampleTickableObject::GetStatId() const
{
    RETURN_QUICK_DECLARE_CYCLE_STAT(UExampleTickableObject, STATGROUP_Tickables);
}

このGetStatIDStatとはなにかというと、Tick対象のオブジェクトにつける一意のIDみたいで識別のために必要みたいです。
参考させていただいた記事ではRETURN_QUICK_DECLARE_CYCLE_STATというマクロを使うと簡単にStatIDが作れるみたいです。
第一引数にクラス名、第二引数にSTATGROUP_Tickablesという統計に使うグループ名を入れると簡単にStatIDというのを作ってくれるみたいでした。

参考

How do I implement Pure Virtual Methods?

Discussion