はじめに
UnrealEngineでGameInstanceSubsystemを使用し、毎フレームTickを実行したくなり以下のクラスを作成したときにTickが二回実行されていた
class HOGE_API Hoge : public UGameInstanceSubsystem, public FTickableGameObject
バージョン
UE5.3.0
なぜ二回実行されるのか
UObject継承クラスは、ClassDefaultObjectが暗黙に作成されてしまいます。
自分が作成したGameInstanceSubsystemクラスにもCDOは作成されてしまいます。
このCDOによってTickが余分に呼び出されてしまいます。
FTickableGameObjectの実装
FTickableObjectBaseを継承していて、このクラスで
/**
* Virtual that can be overloaded by the inheriting class. It is
* used to determine whether an object is ready to be ticked. This is
* required for example for all UObject derived classes as they might be
* loaded async and therefore won't be ready immediately.
*
* @return true if object is ready to be ticked, false otherwise.
*/
virtual bool IsTickable() const { return true; }
とTickを実行できる関数が定義されています。
対策
IsTickableがtrueを返すのが問題なので独自にオーバーライドします。
FTickableGameObjectの継承先で
bool bIsTickable = false;
bool UHogeGameInstanceSubsystem::IsTickable() const
{
return bIsTickable;
}
と関数をオーバーライドします。
このままだと自分が作成したGameInstanceSubsystemでもTickが実行されないので、Initailize関数でbIsTickableをtrueにします。
void UHogeGameInstanceSubsystem::Initialize(FSubsystemCollectionBase& Collection)
{
Super::Initialize(Collection);
bIsTickable = true;
}
CDOからはInitalize関数が実行されないので、これでCDOのTickは実行されなくなりました。