UDN
Search public documentation:

ActorTickingJP
English Translation
中国翻译
한국어

Interested in the Unreal Engine?
Visit the Unreal Technology site.

Looking for jobs and company info?
Check out the Epic games site.

Questions about support via UDN?
Contact the UDN Staff

UE3 ホーム > エンジン プログラミング > アクタのティック
UE3 ホーム > UnrealScript > アクタのティック
UE3 ホーム > ゲームプレイ プログラミング > アクタのティック

アクタのティック


概要


アクタは、1 フレームにつき 1 回ずつ、フレームの間の経過時間を引数としてティックされます。ティックの順序は、アクタがワールド中のアクタ リスト (全レベルのアクタ リストをまとめたもの) に出現する順序になります。アクタのティックは、非同期動作の前、非同期動作の間、そして、非同期動作の後の 3 つの局面で行われます。アクタがどのグループの中でティックされるかは、TickGroup メンバーによって制御されます。非同期動作 (物理的動作など) の前に状態を更新する必要があるアクタは、TG_PreAsyncWork グループに割り当てる必要があります。そうしないと、誤動作や、1 フレームでのずれなど、問題を引き起こします。物理的動作のようなスレッドと並列にティックしてよいアクタは、TG_DuringAsyncWork グループに割り当てます。このグループ内のアクタが、剛体物理データを操作するような関数を呼び出すと、その呼び出しは無視され、エラーが記録されます。このような呼び出しは、メモリ リークや無効なシーン状態などを招く危険があるので、必ず修正するようにしてください。SpawnActor() 、MoveActor() 、SetLocation() 、SetCollision() などについても、同じことが言えます。このような関数は、実行は継続されますが、物理スレッドには影響を与えません。また、エラーも記録されます。物理状態の更新に依存するアクタは、グループを TG_PostAsyncWork に設定します。このグループのアクタ (ビークル、ラグドールなど) の正確なワールド状態は、物理シミュレーションの結果によって決まります。この段階なら、物理動作の関数や、移動、スポーン、衝突などの Unreal 関数を呼び出しても安全です。

以下は、各ティック グループにアクタを入れた場合の長所・短所の一覧です。:

TG_PreAsyncGroup


+ 任意の Unreal 関数や Novodex 物理関数を安全に呼び出すことができます

+ 物理シミュレーション用の位置や回転などを更新します

- 直前のフレームの物理シミュレーション結果について動作します

- 並列処理は行われません

TG_DuringAsyncGroup


+ 物理シミュレーションと並列に動作します

- シーン データに書き込み (読み込みは OK) を行うような特定の Unreal 関数、および、任意の Novodex 物理関数を呼び出すのは危険です

TG_PostAsyncGroup


+ 任意の Unreal 関数や Novodex 物理関数を安全に呼び出すことができます

+ 現在フレームの物理シミュレーション データ上で動作します

- 並列処理は行われません

したがって、アクタを特定のリストに入れるかどうかの一般的な法則は、次のようになります。:

  1. 衝突状態を変更したり、衝突可能なアクタをスポーンしたり、Novodex データに書き込みを行ったりするアクタは、TG_PreAsyncWork に入れる必要があります。通常ここに入れられるアクタとしては、Pawn、武器、および、剛体クラスの一部があります。
  2. 衝突状態を変更したり、衝突するアクタをスポーンしたり (衝突しないアクタならよい)、Novodex データを変更するアクタは、TG_DuringAsyncWork グループに配置する必要があります。ここでは、アクタのティックにかかる時間が物理シミュレーションにかかる時間を隠してくれる、つまり、ここで 2ms ティックすると、2ms のシミュレーション時間が自由になるので、最適の場所です。このグループに入れるアクタの候補としては、パーティクル システム、オーディオ、AI 処理などがあります。
  3. アクタ自体の Unreal データを更新する前に、Novodex からデータを取得する必要があるアクタは、TG_PostAsyncWork に入れる必要があります。ビークルやラグドールは、たいていこのグループに入れられます。

アクタのスポーン


スポーンされたアクタ (および、そのコンポネントすべて) は、設定されたティック グループに関わらず、スポーンされたグループの中でティックされます。新たにスポーンされたアクタが、正しいティック グループでティックされるのは、次のフレームからです。ただし、非同期動作の間にスポーンされたアクタのティックは例外で、TG_PostAsyncWork まで延期されます。

コンポネントのティック


アクタと同様、コンポネンも別々のティック グループに配置することができます。これまでは、アクタのコンポネントはすべて、アクタのティックの際にティックされていました。これは現在でも同様ですが、アクタと異なるグループに入れる必要のあるコンポネントは、ティックされる際の管理を行うリストに追加されます。コンポネントのティック グループへの割り当ては、アクタの割り当てと同じ基準で行う必要があります。

ティック コードのフロー


ゲーム スレッド 物理スレッド
ワールドのアクタ リストを走査して、TG_PreAsyncWork の中のアクタをティックし、それ以外のアクタは遅延する アイドル
ティックされた各アクタのコンポネント リストを走査して、TG_PreAsyncWork の中のコンポネントをティックし、それ以外のアクタは遅延する アイドル
物理スレッドを開始するように通知する シミュレーションを開始する
TG_DuringAsyncWork リストの各アクタをティックする 物理系をシミュレートする
アクタの各コンポネンをティックする (必要があれば遅延する) 物理系をシミュレートする
TG_DuringAsycnWork がコンポネントをティックするまで、各コンポネントを遅延する 物理系をシミュレートする
物理動作が完了するまでブロック シミュレーション結果を返す
TG_PostAsyncWork リストの各アクタをティックする アイドル
アクタの各コンポネンをティックする アイドル
TG_PostAsycnWork がコンポネントをティックするまで、各コンポネントを遅延する アイドル
レンダリングおよび繰り返し アイドル

詳細なコードのフロー (および、ティック後)


コードのフロー (フレームごと)

Object ticking
   Pre-physics
      controller (input)
      pawn (script)
      Components
         SkeletalMeshComponent: update animations, skeleton controls, then compute the matrices
   Physics, async
      pawn physics
   Post-physics
   Camera tick
   Viewport tick

   "server travelling"
   "client travelling"
   streaming

Render
   Calculate VP matrix (ask camera in script, returns cached value)
   Controller.PreRender
      UTPawn.PreRender (pretty good thing for licencees to use as well)
   Render everything

Audio

Callgraph computation

なぜティックは重要なのか?

ティックやレンダリング順序について理解することは、フレームのずれの発生を防ぎ、呼び出し順への依存関係を回避するために不可欠です。たとえばカメラは、ティックが済んでから更新されるので、カメラに関係のある処理 (プレーヤーの所持品やレーザー点など)は、すべて、PreRender に行われる必要があります。しかし、 アニメーション がカメラ位置に依存しているような場合には、フレームのずれが 発生します 。なぜなら、アニメーションは物理系の前処理の間に発生し、ポーン動作は物理動作の間に発生し、カメラはポーンの位置に依存するので、アニメーションの依存関係がループになるからです。この問題を回避するためには、このうちのどれかを、1 フレーム中に複数回重複して計算しなくてはならないかもしれません。たとえば、アニメーション ティックとカメラ ティックを物理動作の後に移動すれば、アニメーションは正しくカメラ位置を更新できるはずです (ただし、特にそのようにコーディングしない限り、カメラは1フレームにつき 2 回更新されることになります)。

-- Main.JordanWeitz(jordan@zombie.com)-2005年12月12日