UDN
Search public documentation:

PhysXDestructibleReferenceJP
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

PhysX Destructible リファレンス

ドキュメントの概要: PhysXDestructible クラスの説明。

ドキュメントの変更ログ: Bryan Galdrikian により 作成。

概要

PhysXDestructible は、UE3 の FracturedStaticMesh (フラクチャー静的メッシュ、FSM) の上位に構築された機能です。このドキュメントは読者が FSM に精通していることを前提として書かれています。FractureTool (フラクチャーツール) のページを参照し、FSM 機能について十分に理解してから進めてください。

PhysXDestructible が FracturedStaticMesh に優先して使用される場合

FracturedStaticMeshActor を使用すると、UE3 レベル内で小規模の破壊 (destruction) を効率よく生成することができます。ただし、破壊量の規模を拡大するとなると FracturedStaticMeshActor ではたちまちいくつかの制限事項に遭遇します。例えば、噴出されるすべてのフラクチャーピース (または集合体) は AActor で表されますが、これらが何百も排出されると AActor のオーバーヘッドが非常に大きくなる恐れがあります。

これに対して、!PhysXDestructibleActor は、何百あるいは何千もの剛体ピースからなる組織内で機能するように設計されていて、これを 2 つの方法で処理します。最初の方法では各断片を SkeletalMeshes 内のボーンとして表現し、これにより AActor のオーバーヘッドを大幅に削減します。2 番目の方法では断片化を階層的に実施し、断片化されていない大きなピースを 1 つの剛体と 1 つの SkeletalMesh のボーンとして表現します。

さらに、!PhysXDestructibles は破壊効果を強化するための特別な機能を備えています。例えば、!PhysXParticleSystem 用の 「クランブル (Crumble、粉砕) パーティクル システム」を割り当てることができます (PhysXParticleSystemReference を参照してください)。これは最も細かいフラクチャーレベルを表わし、一番小さなピースが破壊されると、それらのボリュームは PhysX の流体パーティクルシステムのセットに置き換えられます。メッシュデータ タイプを使用している場合は、これにより信憑性の高い粉砕効果を得ることができます。さらに、粉々に砕けるサウンドや、従来からのパーティクルエフェクト (煙やほこりなど) を割り当てることもできます。

PhysXDestructibleActors は静的または動的に扱うことができます。静的アクタの場合、その一部を「支持材 (サポート)」として 2 通りの方法で割り当てることができます。サポートチャンクの間にある (チャンクピースの) 隣接パスが途切れると、チャンクが緩みます。この特徴は FracturedStaticMeshActor を使って実装することもできますが、!PhysXDestructibleActor には、接触するアクタ同士の間に支持構造を作成できる追加機能があります。接触する PhysXDestructibleActors の連なり (サポートアイランド) が 1 つの支持構造を形成し、この特徴を利用して、例えば複数の PhysXDestructibleActors からなる高い柱を作成し、柱の中間を打ち抜くと、その上のアクタが自動的に崩れるようにすることができます。

最後に、!PhysXDestructibleActor は衝撃ダメージをサポートしています。衝撃ダメージの基準を指定することで、!PhysXDestructibleActor が相当量の打撃を受けた場合 (または衝突した場合) に断片化が発生します。

注意: 現在のところ、衝撃ダメージにバグが確認されており、うまく機能しない場合があります。出来るだけ早く対処する予定です。

PhysXDestructible はその存在を FracturedStaticMesh (分割されていない状態) として開始することにより、メッシュが分割されるまでより効率的な静的レンダリングの恩恵を受けることができます。

適切な FracturedStaticMesh 作成のためのガイドライン

要約: FractureTool を使い、少数のピース (5 ~ 20 ほど) を選択して静的メッシュを断片化します。

詳細: FractureTool は StaticMesh を適度の数のピースに断裂します。現在このツールでは、最高 150 ピースまで断裂できますが、この数は小さい値に (おそらく 1 ダースか、小さなオブジェクトの場合はそれ以下) にしておくように推奨されています。それは、!FracturedStaticMesh の各断片がそれぞれ 1 つの AActor になるためですが、この後に AActors がさらに作成されることはありません。これらの各 AActors (PhysXDestructibleParts) は、1 つまたは複数の SkeletalMesh により表現されます。

StaticMesh を 1 つ のピースに「断片化」することも 可能 であり、それを実施した場合は、ダメージが発生すると FracturedStaticMesh 全体が 1 つまたは複数の SkeletalMesh に変換されます。しかし、!FracturedStaticMesh から開始するアプローチの背後には、ダメージを受けていない状態のメッシュを出来るだけ長く静的状態として保ち、この静的メッシュの強みである効率的なレンダリングを利用するという考えがあります。フラクチャーピースの数をあまり小さく (1 などに) することが推奨されていないのはそののためです。

_注意: この最適化は現在実装されておらず、!PhysXDestructible の断裂化を行うと、断片は すべて 個別の SkeletalMeshes になります。静的な最適化は近日中に実装される予定です。しかし、現在も上記のガイドラインに従って作業されることをお勧めします。これにより、後からコードドロップを追加してこの最適化を実装し、レベル内のフラクチャー性を向上させることできます。

PhysXDestructible の作成方法

マテリアル

StaticMesh を使って作業を開始しますが、最終的に SkeletalMeshes になることから、!PhysXDestructible と使用するすべてのマテリアルについて、マテリアル エディタで bUsedWithSkeletalMesh を選択する必要があります。

MaterialEditor.png

このチェックボックスが選択されていない場合、PIE (Play-In-Editor) でレベルを実行したときには変化は見られませんが、ゲーム内ではマテリアルが適用されません。

静的メッシュを断片化する際に、新たに作成される内部フェイスに適用するマテリアルを選択しなればなりません。この同一マテリアルは、!PhysXDestructible の生成に用いられる階層的分裂の結果として作成されるすべての内部フェイスに適用されます。この例では亀裂の入ったバレルのメッシュ (下図) を選択しました。 内部マテリアルは常に最後の FracturedStaticMesh 要素に含まれます。

Generic ブラウザでこの FracturedStaticMesh をダブルクリックして開きます。次に、Generic ブラウザで内部マテリアルを選択します (ここでは 'PinMat' が選択されています)。!StaticMesh エディタに戻り、[LODInfo[0]] ->[Elements[last index]] を開いて [Material] フィールド横のグリーンの矢印をクリックすると、そのフィールドに選択したマテリアルが挿入されます。

InteriorMaterial.png

メッシュのスライス

Generic ブラウザで FracturedStaticMesh を右クリックし、[Create New PhysX Destructible] (PhysX Destructible アクタを新規作成) を選択します。

SelectFSM.png

新しいアセットの保存先となるパッケージを選択して名前を入力すると、ダイアログが開いて PhysXFractureOptions が表示されます。これはスライスレベル (SlicingLevel?) の配列です。デフォルトではレベルが 1 つ設定されていますが、[!SlicingLevels] 配列名の横にあるグリーンの [+] ボタンをクリックして追加することができます。新しいレベルを追加するたびに、生成されるピースの数が幾何学的に増大するので注意が必要です。必要に応じて、[{}] ボタンを使って配列を消去して操作をやり直すことができます。

各レベル単位で、X、Y、Z 方向のスライス数と、線形/角度ノイズを選択できます。各軸に沿ったスライス面の数には、負の数でない任意の数値を指定できます。0 を選択した場合、その階層レベルに関しては当該軸方向のスライスが行われません。ノイズを選択しない場合、スライス面の法線の方向は軸と完全に平行になり、メッシュの境界ボックスを均等に分割します。!AngularNoise では、スライス面の法線がスライス軸から外れる距離を指定します (その範囲内で法線がランダムに選択されます)。!LinearNoise では、スライス面がスライス軸上でランダムに位置をずらす距離を指定します。このスケールは、各スライス面が境界ボックスの 1/N (N = 軸に沿ったスライスの数) を「ドメイン (範囲)」として取得するように設定します。直線移動が 1 の場合、スライス面を次のスライス面のドメインの真横に押し出します。

デフォルト設定では、各軸のスライス数は 1 であり、これにより元の各ピースからそれぞれ最大 2x2x2 = 8 個の新しいピースが生成されます。これが「最高値」である理由は、生成されたスライスがメッシュジオメトリと交差しない場合にはピースが生成されないためです。さらに、スライスによって形成されるボリュームが比較的かなり小さい場合も生成されません。

つまり、デフォルトでは FracturedStaticMesh の断片数に基づいてスライスが実行され、分裂階層内で次のレベルに含まれるピース数 (チャンク) の最大 8 倍のピースが生成されます。別のスライスレベルを追加すると、この数字が再度乗算されます。数百、数千あるいはそれ以上のチャンク数を簡単に生成できます。チャンク数が 1,000 を超えると、生成されるピース数の推定値を示す警告が表示されます。

スライス数 (X、Y および Z 方向のスライス数) vs. スライスレベル数に関する注意: 生成するピースの数を増やしたい場合は、通常は各軸に沿ったスライスの数を増やすよりも、別のスライスレベルを使用する方が良いでしょう。その方が断裂が出来るだけ階層状態で残り、生成される剛体の数を減らすことができるためです。スライス数の使い方のポイントは、非標準的な形状のメッシュの場合には、ピースがより一様な大きさになるように (立法体に近い形) 分割することです。これを最初の分割レベルで実行すると、以降のレベルでは単純に 1x1x1 の分割を行うだけで済みます。極端なケースとしては、ほうきの柄のような細長いオブジェクトが挙げられます。この場合には (ほうきの柄がローカルで Z 軸と平行に配置されているとすると)、X と Y 方向のスライス面を 0、Z には大きな数字 (数ダースでもおそらく可) を使用することをお勧めします。

SlicingOptions.png

スライス面を選択してから [OK] をクリックすると、スライスが開始されます。これには多少時間がかかる場合があります。!FracturedStaticMesh の各断片に対して SkeletalMesh が少なくとも 1 つ生成されます。(各 SkeletalMesh では最大 250 のチャンクが格納されます。スライスの結果生成されるチャンク数がこれより多くなると、使用する SkeletalMeshes の数も増えます。) スライスが終了すると、Generic ブラウザには多数の新しい PhysicsAssets と SkeletalMeshes が表示されますが、これらは無視してください。レベルでアクタの作成に使用するのは、新規作成された PhysXDestructible です。

Destructible のパラメータ

PhysXDestructible に保存できる Destructible (被破壊物) 関連のパラメータが多数存在します。!PhysXDestructible からアクタのインスタンスを作成すると、これらのパラメータがアクタ (PhysXDestructibleActor) にコピーされ、アクタ内部でインスタンス単位で変更することができます。!PhysXDestructible 「テンプレート」内でパラメータを変更するには、Generic ブラウザで PhysXDestructible をダブルクリックします。ウィンドウが開いて、上位レベルの 2 つの項目 (CookingScales、!DestructibleParameters) が表示されます。!CookingScales については後から説明します。まず Destructible 関連のパラメータに注目しましょう。

Generic ブラウザで PhysXDestructible を選択し、レベル編集ウィンドウで新しい PhysXDestructibleActor を作成する場所を右クリックします。

PhysXDestructibleProperties.png

DamageThreshold - チャンクを自由に解放するために受け取る必要があるダメージの量です。
bAccumulateDamage - これを選択すると、チャンクに適用されたダメージが累算されます。ダメージがダメージしきい値 (DamageThreshold?) を超えると、チャンクは自由に解放されます。選択を解除するとダメージは累算されず、チャンクを自由に解放するためには、1 回に受けるダメージがしきい値を超えなければなりません。
DamageCap - 適用されるダメージをこの量に制限します。0 (デフォルト) に設定した場合、適用されるダメージ量の制限はありません。
DamageToRadius - Destructible 内でダメージを距離に変換します。ダメージタイプが 'bFullDamage' の場合、この半径以内にあるすべてのチャンクにこの量が適用されます。その他の場合は、ダメージはその全量 (ダメージの中心点) から 0 (ダメージ半径) に向かって線形に低下します。ダメージに関して注意すべき点は次のとおりです。

  • チャンクがダメージを受けると、ダメージ量から DamageThreshold が減算され、残りはフラクチャー階層内にあるすべてのチャンクの「子」に適用されます。!DamageThreshold は、各階層レベルでチャンクを解放するのに必要な量です。ダメージタイプで線形フォールオフが使用されると、その作用によりダメージの開始点近くのメッシュは細かいピースに分割され、そこから離れるにつれて大きなピースに分割される傾向にあります。
  • ダメージから半径への変換は実際には次のように発生します。ダメージを DamageThreshold で割った結果に DamageToRadius を掛けて、さらにオブジェクトサイズ (オブジェクトの境界ボックスの中間幅) を掛けます。この演算によりダメージとサイズのいずれも調整されるので、!DamageThreshold とメッシュスケールが変化する可能性がありますが、ダメージのプロパゲーションへの変化はありません。

ForceToDamage - この係数によりダメージに変換される衝撃力。これが機能するには、アクタ'の CollisionComponent で bNotifyRigidBodyCollision をオンにする必要があります。
CrumbleParticleSystem - これは PhysX のエミッタを含むパーティクル システムです (PhysXParticleSystemReference を参照してください)。!PhysX メッシュエミッタを使用して粉砕 (crumbling) をエミュレートできます。階層の最低 (最小) レベルに位置するチャンクが、ダメージによって DamageThreshold に達すると破壊されます。!CrumbleParticleSystem を選択した場合、そのチャンクのボリュームは「流体」メッシュパーティクルのグループに置換されます。これらはジオメトリとの衝突が可能で、小型の物体をエミュレートできます。
CrumbleParticleSize - CrumbleParticleSystem (上記参照) を使用する場合、破壊されたチャンクにはこの距離間隔でパーティクルが充填されます。
FractureSound - チャンクが自由に分割 (または粉砕) したときに再生する SoundCue。
DepthParameters - パレメータセットの配列で、チャンク階層の各レベルごとに 1 つのセットあります。この配列のサイズは調整できず、チャンク階層内のレベル数によって設定されます。Set [0] では PhysXDestructibleActor のパラメータ、Set [1] で上位レベルのチャンクのパラメータを指定します (1 つのチャンクがそれぞれ FracturedStaticMesh の断片を表します)。スライスレベルを 1 つ使用すると set [2] が作成され、このセットはその次に細かいチャンクレベルに適用されます。2 つのスライスレベルを使用すると set [3] が作成され、以下同様に続きます。各レベルのパラメータは次のとおりです。
  • bTakeImpactDamage* - ForceToDamage > 0 の場合、衝撃力はこのレベルにダメージを適用します。
  • bPlaySoundEffect* - FractureSound を設定した場合、このレベルのチャンクが自由に解放された (または粉砕した) ときに再生されます。
  • bPlayParticleEffect* - このレベルで分割されたチャンクは、!FracturedStaticMesh で設定した FragmentDestroyEffect を再生します (これは StaticMesh エディタの FSM 内で設定します。FractureTool のページを参照してください)。
  • bDoNotTimeOut* - これを設定した場合、このレベルのチャンクは config 変数 MaxDynamicChunkCount の値を超えない限り無限に存在し続けます (下記の LOD スケーリングを参照してください)。このパラメータを設定しない場合、config 変数 DebrisLifetime で指定した時間が経過した後に (これについても LOD スケーリングを参照のこと)、このチャンクは破壊されます。

LOD スケーリング

PhysXDestructible には 2 つのグローバル LOD パラメータがあります。これらはいずれも、!BaseEngine.ini とすべての派生 .ini ファイル内の [Engine.PhysXLODVerticalDestructible] にあります。

MaxDynamicChunkCount - PhysXDestructibles で遊離するチャンク、つまり剛体の最大数を設定します。この数は、レベル内のすべての PhysXDestructibles に対してのチャンクの合計数です。チャンクは FIFO に格納されるので、!MaxDynamicChunkCount の上限数を維持するために古いチャンクから破壊されることになります。
DebrisLifetime - 「残骸 (debris)」チャンクを保持する期間を設定します。この場合、"debris" とは、単に bDoNotTimeOut フィールド (Destructible パラメータを参照) がオンに設定されていないことを意味します。

最大チャンク数の上限を超えたためにチャンクを除去する場合、またはタイムアウト時間を経過した場合は、!CrumbleParticleSystem を用いてチャンクを完全に粉砕します。!CrumbleParticleSystem が設定されていない場合、チャンクは単純に消去されます。

PhysXDestructibleActor の作成

PhysXDestructibleActor を作成するには、Generic ブラウザで PhysXDestructible を選択し、レベルエディタ内でアクタを配置したい場所を右クリックして [Add PhysXDestructibleActor] (PhysXDestructibleActor を追加) を選択します (次図を参照)。

CreatePhysXDestructibleActor.png

レベル内にアクタを配置したら、インスタンスの DestructibleParameters を変更したり、アクタのスケーリングや動的アクタへの変更を行えるようになります。Destructible アクタの「支持材 (サポートチャンク)」に作用するパラメータもあります。後述の「支持材 (サポートチャンク)」のセクションを参照してください。

PhysXDestructibleActor プロパティを開きます。

PhysXDestructibleActorProperties.png

注意すべき点がいくつかあります。

  1. DestructibleParameters の設定は PhysXDestructible からコピーされていますが、このアクタインスタンス用に変更することができます。
  2. PhysXDestructibleActor を動的アクタにするには、その Physics プロパティを PHYS_RigidBody に変更します。
  3. 動的 でない PhysXDestructibleActor は、サポートアイランド (支持構造) の一部となることができます。この詳細は、後続の「支持材 (サポートチャンク)」のセクションで説明します。サポートチャンクに関するフィールドが 4 つあります。
    • SupportDepth* - 階層内のこの深度で、支持計算を実行します。深度 = 0 (デフォルト) は、!FracturedStaticMesh の断片の深度、すなわち最大サイズのピースで支持計算が行われることを意味します。
    • PerFrameProcessBudget* - フレームあたりの支持計算を、繰り返して実行できる回数 (支持グラフのステップ数)。サポートアイランドが非常に大きい場合を除き、通常これは問題になりません。ProcessBudget の値を超えると、未処理のチャンクは自動的に遊離します。
    • bSupportChunksInSupportFragment* - これを設定した場合、!SupportDepth のチャンクは、!FracturedStaticMesh のサポートチャンクの子である場合のみ「サポートチャンク」であると見なされます (FractureTool を参照)。
    • bSupportChunksTouchWorld* - これをオンにした場合、!SupportDepth のチャンクはワールドジオメトリに接触した場合のみ「サポートチャンク」であると見なされます。

クランブルパーティクルシステムの作成

クランブルパーティクルシステムは、!PhysX のエミッタとメッシュエミッタを通常使用してクランブル (粉砕) をエミュレートします。粉砕は「体積充填」法により実行されるため、数百、ときには数千もの流体パーティクルが生成される場合があります。このような場合には、インスタンス化したメッシュのレンダリングをパーティクルに使用することをお勧めします。これを実現するには、パーティクルに適用するマテリアルを開いて、bUsedWithInstancedMeshParticles をオンにします。

MeshHWInstancing.png

このメッシュパーティクルに適用するマテリアルを使って PhysX メッシュエミッタを作成します。PhysXParticleSystemReference を参照してください。

次に、!PhysXDestructible の「テンプレート」か、または PhysXDestructibleActor インスタンスの DestructibleParameters を開きます。Generic ブラウザでパーティクル システムを選択し、!CrumbleParticleSystem 横のグリーンの矢印をクリックしてフィールドを設定します。

これまで実行してきた内容を確認するために、破壊可能なバレルを設置したレベルを実行し、バレルを左クリックしてダメージを適用すると、次図のような状況が発生します。

BarrelDestroyed.png

支持材 (サポート チャンク)

前述のように、静的アクタの PhysXDestructibleActor には「サポート チャンク」を設けることができます。サポート チャンクの計算は次のように行われます。サポート チャンクに接触したチャンクは支持され、支持されたチャンクに接触したチャンクも支持されます。この方法で、アクタ全体が支持されている状態から開始し、十分に (チャンクが支持されているチャンクとの接触を失うまで) 破壊されると、アクタの一部は支持されなくなり、支えを失ったチャンクは動的になります。

さらに、レベル内で接触する 2 つ以上の PhysXDestructibleActors に支持構造を延長することができます。接触する PhysXDestructibleActors の各アイランドが支持構造を形成し、静的な Destructibles アクタをつないで、つまり「タイル化 」し、1 つの大きな destructible アクタのような振る舞いをさせることができます。

動的 Destructibles アクタは支持計算の対象から外れます。これらはサポートアイランドの一部ではありません。

サンプルとして、ここで破壊可能な壁面を作成してみましょう。!EffectsDemo_Resources.Ephyra_lpwallow3 は手ごろな壁面ですが、小さ過ぎるので、これをスケーリングのサンプルとしても活用することにします。

スケーリングとクッキング

前のセクションで紹介した壁面サンプルを使い、前述の手順に従って EffectsDemo_Resources.Ephyra_lpwallow3 から PhysXDestructible を作成します。FractureTool を使用してこれを 12 の断片に分割し、2 番目のスライスレベルにより多数のピースにスライスすることにします。この壁面を使えるようにするにはスケーリングが必要で、そのため、チャンクの衝突モデルにもスケーリングが必要です。さらに、これらの (凸面) 衝突モデルをレベル内であらかじめクックしておきたいので、クック時のスケールを指定する必要もあります。!PhysXDestructible をダブルクリックし、[!CookingScales] の横にあるグリーンの [+] ボタンをクリックして CookingScales 配列を追加します。次に、クックに適用するスケールを追加します。この例では、(10,10,10) つまり 10 倍 の均一スケールを選択することにします。ただし、スケーリングなしのインスタンスを使用しない場合は (1,1,1) のスケールを削除し、レベルファイルのサイズを節約するようにします。

CookingScale.png

Generic ブラウザで PhysXDestructible を選択し、前述と同様にレベル内に PhysXDestructibleActor を作成します。アクタを作成したらアクタ プロパティ シートを開き、[!DrawScale3D] を (10,10,10) に変更します。

ScalingADestructible.png

これで、スケーリングした Destructible アクタを使用できるようになりました。

支持構造のサンプル

この壁面を使った支持構造のサンプルを完成させるために、レベルを実行し、コンソールで APEXVIS SUPPORT と入力します。destructible アクタが支持を受けている場合は、支持グラフが描かれます。

Support.png

上図の壁面は地面と接触していて (デフォルトにより bSupportChunksTouchWorld が設定されていたため)、そのため最下位のチャンクがサポートチャンクになります。エディタに壁面をコピーし、これをコピー元の壁の上方で隣接する位置に移動すると、支持グラフは 2 番目の壁面まで伸張します。

Support2.png

2 番目の壁面はワールド ジオメトリと接触していないので (および、この例ではデフォルトで bSupportChunksInSupportFragment が False に設定されているので)、それ自体はサポートチャンクではありませんが、支持されている PhysXDestructibleActor と接触することでこれも支持を得て、2 つの壁がサポートアイランドを形成していることが分かります。

次に、下方の壁面を射撃します。

PartiallyDestroyedWalls.png

これと上方の壁面との支持が遮断されるまで射撃を続けてください。

DestroyedWalls.png

確認されているい問題

  1. 衝撃ダメージ機能が動作しない場合があります。これはインテグレーションのバグか、または PhysX SDK のバグが原因です。
  2. 最初のダメージで FracturedStaticMesh が除外され、!SkeletalMeshes に置換されます。実装が予定されているより効率的なアプローチでは、断片を非表示にして、必要な場合のみ SkeletalMeshes に置換し、出来るだけ静的メッシュによって描写されるようにします。
  3. スライス後のメッシュが細かすぎると、エラーが発生し、小さな破片が空中に「漂って」いるように見える場合があります。
  4. FracturedStaticMeshes と PhysXDestructibles に変更を加えても、レベル内の PhysXDestructibleActor インスタンスにプロパゲートされません。