C++ ときどき ごはん、わりとてぃーぶれいく☆

Wonder Rabbit Projectのなかのひとのブログ。主にC++。

UE4/C++ Tick が来ない!そんなときのトラブルシュート備忘録

「Tick が来ない!」、たまによくあるのは私だけでしょうか。 UHogeFugaComponentTickComponent が来ない、 AHogeFugaActorTick が来ない、などなど。そんな場合の備忘録です。

疑い(1): bCanEverTickfalse

コンストラクター等で bCanEverTicktrue になっていない場合に Tick が来なくなる。 true にすれば良いし、そもそも通常はデフォルトで true なのでこのミスの可能性はわりと低い。低いけど根本的なところなので一応最初に疑って確認、必要なら修正。

// Actor の場合
PrimaryActorTick.bCanEverTick = true;

// Component の場合
PrimaryComponentTick.bCanEverTick = true;

疑い(2): bStartWithTickEnabledfalse

先の(1)と同様コンストラクター等で true になっていない事があれば開始時に自動的に Tick が発生しないので、とりあえず確認し、必要なら修正。これも通常デフォルトで true なのでコレジャナイ場合がほとんど。

// Actor
PrimaryComponentTick.bStartWithTickEnabled = true;

// Component の場合
PrimaryComponentTick.bStartWithTickEnabled = true;

疑い(3): bAllowTickOnDedicatedServerfalse // サーバーの場合のみ

疑い(1)、(2)と同レベルの段階の問題で、サーバー動作の場合はまた別のフラグが false だと Tick が来なくなる。もしサーバーの Tick が来ない時には一応疑う。

// Actor
PrimaryComponentTick.bAllowTickOnDedicatedServer= true;

// Component の場合
PrimaryComponentTick.bAllowTickOnDedicatedServer= true;

疑い(4): 実行中に SetActorTickEnabled( false ) あるいは SetComponentTickEnabled( false ) している

実行時の状況に応じた負荷制御等でプログラマーが明示的に SetActorTickEnabled( false ) を制御している Actor あるいは SetComponentTickEnabled( false ) を制御している Component の場合、本来意図した必要なタイミングでも false がセットされたままになっていると Tick が来ない。

この機能は Actor ないし Component 自身が Tick 内で false をセットするようなコードがある場合、当然自身の Tick は呼ばれなくなるので true に復帰するためには、どこか外部の何らかのトリガーによって true 引数で呼んであげて、かつ意図せず false が再セットされるような事が無いようにコード実装されていないと Tick が来ない怪が発生してしまう。

疑い(5): BeginPlay() override の実装で Super::BeginPlay() を呼んでいない

よくある Actor や Component の BeginPlayoverride での “うっかり” パターン。

// MyActor.h
protected:
  // よくある BeginPlay の override 宣言。ここまでは特に問題ない・w・
  void BeginPlay() override;
// MyActor.cpp ( Tick  来ないダメ版)
void MyActor::BeginPlay()
{
  // MyActor で必要な BeginPlay タイミングでの初期化とかなんとか実装して・・・
  hoge();
  
  // 実装して・・・
  fuga();
  
  // ”何か忘れていないだろうか・・・”
}

わざとらしくコメントを書いて置いたのでたいていの UE4/C++er は既に気づいたと思う。 Super::BeginPlay() を呼んでいない。

// MyActor.cpp ( Tick 来る良い版)
void MyActor::BeginPlay()
{
  // 実は Actor や Component の BeginPlay の中で Tick 関連のフラグや関数登録が実装されている。
  Super::BeginPlay();
  hoge();
  fuga();
}

↑今日はこのパターンにやられました(ノω・)テヘ

参考

  1. FTickFunction | Unreal Engine API Reference
  2. AActor::Tick | Unreal Engine API Reference
  3. UActorComponent::TickComponent | Unreal Engine API Reference
  4. Tick is never called, even though bCanEverTick is set to true. - UE4 AnswerHub
  5. Tick is never being called even though CanEverTick and StartWithTickEnables is true - UE4 AnswerHub

だそく

  1. Wizardry#4/ウィザードリィ#4 プレイ日記 Metal Page
    • 非常に重要な警告: このリンク先には重大なネタバレが含まれます。