UDN
Search public documentation:

PhysicalMaterialSystemJP
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 では、物理マテリアルをマテリアルまたは MaterialInstanceConstantJP (マテリアル インスタンス定数) に添付できます。マテリアルに追加のプロパティを持たせるだけとは反対に、添付によって、物理マテリアル システムを複数のマテリアル上で再使用できます。

次に簡単な例を挙げます。

ゲーム中の砂利道に適用した gravelRoad (砂利道) マテリアルがあります。砂利道マテリアルは、gravel (砂利) と呼ばれる物理マテリアルを持ちます。

砂利の物理マテリアルで、足音を立てている PawnType に基づいて再生される様々な足音サウンドをセットしました。

PawnTypeOne が歩くとき、SoundCue A からの音が再生されます。

PawnTypeTwo が歩くとき、SoundCue B からの音が再生されます。

** 同じマテリアルにある2つの物理マテリアルは、単独のマテリアルでサポートされています。衝突が起こると、ラインチェックコードはトライアングルヒットを検出して、ヒット位置でテクスチャUVを取得し、ヒットピクセルが白か黒かを決定するため、マスクテクスチャ内をルックアップします。それに対応している物理マテリアルはリターンされます。

プログラマのための詳しい説明

詳しい説明:

PhysicalMaterial.uc を参照してください。

具体的には:
var(PhysicalProperties) export editinline PhysicalMaterialPropertyBase PhysicalMaterialProperty;

PhysicalMaterialPropertyBase.uc に読みたいと思われるようなコメントがあります!

状況に合った足音サウンドを得て、他のうまくできた物理マテリアル ベースの効果のためのフレームワークを置くために、クラスを作ります。

class MyGamePhysicalMaterialProperty extends PhysicalMaterialPropertyBase
collapsecategories
editinlinenew
hidecategories(Object);

var(FootSteps) editinline MyGamePhysicalMaterialFootSteps MyGamePhysicalMaterialFootSteps;

次のクラス MyGamePhysicalMaterialFootSteps では、以下のようになっています。

var() SoundCue ProtagonistFootSteps;

var() SoundCue NPCTypeOneFootSteps;

var() SoundCue NPCTypeTwoFootSteps;

などなど。

それでは、ポーンがステップを踏むとき(AnimNotify_Footstep またはその他の方法によって)、イベントを適切なポーンに送る eventPlayFootStepSound を呼び出すことができます。そうするとそのイベントが今度は適切なポーンに送られます。これで、ポーンは、タイプと物理マテリアルに基づいて何のサウンドを再生するかを決定できます。

例えば、NPC 鬼が、砂利道を歩いています。鬼が足を踏み eventPlayFootStepSound が呼び出されると、トレースダウンし、物理マテリアルを見つけて、ポーン タイプに基づいて SoundCue を得て、それを再生します。

注:現在、物理マテリアルを得るためには、トレース ダウンする必要があります。直接、C++ でトレースする方が効率的なのと、大部分のライセンス保持者がゲームに望む機能であるため、 eventPlayFootStepSound で物理マテリアルを渡せるように更新する予定です。状況に合った足音サウンドはすばらしいものです。

明らかに、 PhysicalMaterialシステムとプロパティのフレームワークとでは、上記のように、状況に合ったあらゆる種類の機能が実行できます(例えば、impact sounds, hit effects, decals, footstepsなど)。

物理マテリアルの階層

プログラミング スタッフが、上記の特定のゲーム クラスを作成すると、コンテンツ チームが、物理マテリアルの階層を作成し始めることができ、ゲーム設計者が要求する効果をマテリアルに配置し始めることができます。

コンテンツ クリエータのための詳細な説明

PhysicalMaterial (物理マテリアル)は、var(Parent)PhysicalMaterial Parent ペアレントを持ちます。このため、物理マテリアルの階層を作成することが可能で、したがって(私たちの例の場合では) FootStep (足音サウンド)の階層を作成することが可能です。

以下のようになります。

Default
^
|
Clay
^
|
Wet Clay

これで、コンテンツ チームは、ゲーム ワールドに持っている物理マテリアルに特定的になれます。湿った粘土の足音サウンドも、可能です。湿った粘土の足音サウンドを持っていない場合は、見つかるまで階層を調べて、見つからない場合には、 Default にあるデフォルトの足音サウンドで手を打つことができます。

階層を使用する

これで、コード サポートとパラメタラ化された物理マテリアル階層を持つことになり、物理マテリアルをマテリアルに割り当てることができます。物理マテリアルを割り当てた後は、ゲームで再生されるのを聴くことができるはずです。

コンテンツの提案

足音(例の継続として)を作成するときに、ソース サウンドとピッチの両方をランダム化した、減衰のある足音の SoundCue をサウンド チームに作ってもらう必要があります。これにより、より説得力のある足音サウンドになります。その上、物理マテリアルシステムに対して正確な抽象化が提供されます。

サンプル コード

/**
*  C++ ランドからの足音を立てろと告げるイベント。
**/
event PlayFootStepSound(int FootDown)
{
   local vector PawnLoc;
   local float CurrHeight;

   local Actor TraceActor;

   local vector out_HitLocation;
   local vector out_HitNormal;
   local vector TraceDest;
   local vector TraceStart;
   local vector TraceExtent;
   local TraceHitInfo HitInfo;

   // kk ここでは、tracez0r で下に下に地面の下まで追跡する必要があるぜ、ベイビー!
   // 注: これは最終的には C++ ランドに移す予定。
   PawnLoc = self.Location;
   CurrHeight = self.GetCollisionHeight();

   TraceStart = PawnLoc;
   TraceDest = PawnLoc - ( Vect(0, 0, 1 ) * CurrHeight ) - Vect(0, 0, 15 );

   // トレース(追跡)ダウンして何の上に立っているかを見る。
   TraceActor = Trace( out_HitLocation, out_HitNormal, TraceDest, TraceStart, false, TraceExtent, HitInfo, true );

   //DrawPersistentDebugLine( TraceStart, TraceDest, 255, 0, 0 );

   if( TraceActor != none )
   {
      // 実際のサウンドをここでプレイ。
      ActuallyPlayFootStepSound( FootDown, HitInfo );
      MakeNoise( 0.1f, 'NOISETYPE_FootStep' );
   }
   // そうでないと何にもぶつからず空気をうつだけ。
   else
   {
   //   Log( " We are in the air" );
   }

}

/**
* こうすると、どのマテリアルの上に立っているかを見つけ出し、
* 的確な足音を出します。
* PhysicalMaterial ツリーを参照してスポーンさせる有効な効果を見つけます。
*見つからないときは、 .uc file にかかれた効果にデフォルトとして落ち着きます。
* その武器のために。
**/
function ActuallyPlayFootStepSound( int FootDown, TraceHitInfo HitInfo )
{
   local PhysicalMaterial ParentPhysMaterial;
   local SoundCue SC;
   local SoundCue FootStepSound;

   // XO5 HAX0R
   // 雨の中にいるのであれば、水の足音をプレイ。
   //注: 今のところ、テレインはトレースできるマテリアルを返さないため、こうしなければなりません。
   //if( IsTimerActive( 'DropRainDropsOnToPawn' ) == TRUE )
   if( bShouldPlayWetFootSteps == TRUE )
   {
      Self.PlaySound( SoundCue'FootSteps.SoundCues.Footsteps_Marcus_Water', FALSE, TRUE );
      return;
   }


   // もしも PhysicalMaterial がないときは、
   if( HitInfo.PhysMaterial != none )
   {
      FootStepSound = GetFootStepSound( HitInfo.PhysMaterial, FootDown );
   }
   else
   {
      // マテリアルがあるかチェック
      // マテリアルがなければ、デフォルトの PS_DefaultImpactEffect を使わなければなりません。
      if( HitInfo.Material != none )
      {
         FootStepSound = GetFootStepSound( HitInfo.Material.PhysMaterial, FootDown );
      }
      else
      {
         // いつも "デフォルトの足音" つまり dirt step (ドロの足音)をプレイ。
         Self.PlaySound( SoundCue'FootSteps.SoundCues.Footsteps_Marcus_Dirt', FALSE, TRUE );
         return;
      }
   }


   // ここでは "hierarchy"(階層) を参照して、もし適応するアトリビュート(要素)の中に見つからず、
   // 腹ペコの私たちに、コンテンツが何もデータを提供しない場合には、
   // 多分、何かしらのデフォルトをプレイするコードがあったほうがいいだろう。

   // PhysMaterial (物理マテリアル)が何もなければ。
   if( HitInfo.PhysMaterial != none )
   {
      ParentPhysMaterial = HitInfo.PhysMaterial.Parent;
   }
   // ここで、parent phys material (物理マテリアルの親)を設定。
   else
   {
      // material に phys material があるかをチェック。
      if( HitInfo.Material.PhysMaterial != none )
      {
         ParentPhysMaterial = HitInfo.Material.PhysMaterial.Parent;
      }
      else
      {
         ParentPhysMaterial = none;
      }
   }


   // これはツリー上を、 parent が null か、 footstep sound が見つかるまでたどる。
   // その時点で、脱出(exception (例外)のケースです)。
   // しかし、 .uc ランドには例外というものは存在しない。
   while( ( FootStepSound != none )
      && ( ParentPhysMaterial != none )
      )
   {
      // parent (親)のデータをチェック。
      FootStepSound = GetFootStepSound( ParentPhysMaterial, FootDown );
      ParentPhysMaterial = ParentPhysMaterial.Parent;
   }


   // material based effect (マテリアルベースの効果)を使用
   if( FootStepSound != none )
   {
      //Log( " Playing Sound: " $ FootStepSound );
      SC = FootStepSound;
   }
   // デフォルトの行動をとる。
   else
   {
      //Log( " Playing Default Sound" );
      SC = SoundCue'FootSteps.SoundCues.Footsteps_Marcus_Dirt';
   }

   Self.PlaySound( SC, FALSE, TRUE );
}


/**
*  現在の PhysicalMaterial (物理マテリアル)の Sound (サウンド)が valid (有効)かを確認。
**/
function SoundCue GetFootStepSound( PhysicalMaterial PMaterial, int FootDown )
{
   local SoundCue Retval;

   Retval = none;

   // 私たちの Specific properties (特定のプロパティ)が exists (見つかった)ので function (関数)を呼び出して脱出。
   //
   if( ( none != PMaterial )
      && ( none != PMaterial.PhysicalMaterialProperty )
      && ( none != WarPhysicalMaterialProperty(PMaterial.PhysicalMaterialProperty) )
      && ( none != WarPhysicalMaterialProperty(PMaterial.PhysicalMaterialProperty).WarPhysicalMaterialFootSteps )
      )
   {
      Retval = GetSpecificFootStepSound( WarPhysicalMaterialProperty(PMaterial.PhysicalMaterialProperty).WarPhysicalMaterialFootSteps, FootDown );
   }
   else
   {
      Retval = none;
   }

   return Retval;
}


/**
* それぞれの Object はこれを上書きし、参照されるObject に準じたデータを return (返す)。
* (例:.  GetSpecificFootStepSound は marcus でコールされたら、
* marcus footstep sound をさがし、 locust (虫のバッタ)で コールされたら locust sound をさがす)
**/
function SoundCue GetSpecificFootStepSound( WarPhysicalMaterialFootSteps FootStepSounds, int FootDown )
{
   local SoundCue Retval;

   // 必要な計算その他を行う。
   Retval = None;

   return Retval;
}


e.g. in class BigOgre


function SoundCue GetSpecificFootStepSound( MyGamePhysicalMaterialFootSteps FootStepSounds, int FootDown )
{
   local SoundCue Retval;

   // 必要な計算その他を行う。
   Retval = SoundCue'FootSteps.SoundCues.Footsteps_Player_Dirt';  // あるいは、これを config にして、
値を .ini ファイルに保存して、非プログラマーが編集できるようにする。

   return Retval;
}