UDN
Search public documentation:

PhysicalMaterialPropertyKR
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 홈 > 피직스 > 피지컬 머티리얼 프로퍼티

피지컬 머티리얼 프로퍼티


문서 변경내역: James Tan 작성. 홍성진 번역.

개요


UE3 에서는 머티리얼 또는 머티리얼 인스턴스 불변(Constant)피지컬 머티리얼 을 붙일(attach) 수 있습니다. 머티리얼에 프로퍼티를 추가하는 것과는 달리, 붙이기를 통해 피지컬 머티리얼 프로퍼티 오브젝트를 여러 머티리얼에 재사용할 수 있습니다.

간단한 예를 들면 다음과 같습니다: 월드의 모든 자갈길에 적용한 자갈길 머티리얼이 있습니다. 자갈길 머티리얼엔 GravelPhysicalMaterial 라는 피지컬 머티리얼이 있습니다. GravelPhysicalMaterial 에는 피지컬 머티리얼 프로퍼티 오브젝트를 만들어, 이 머티리얼을 밟았을 때 재생되는 발소리를 저장합니다.

이제 하나의 동일 머티리얼에 피지컬 머티리얼이 둘 지원됩니다. 충돌이 발생하면 선 검사 코드로 맞은 트라이앵글을 찾아, 그 위치의 텍스처 UV 를 구하여 마스크 텍스처 속에서 찾아봐(look up) 맞은 픽셀이 검정인지 하양인지를 알아냅니다. 그에 해당하난 피지컬 머티리얼이 반환되는 것이죠. 자세한 정보는 Physical Material Mask KR 페이지를 참고하시기 바랍니다.

Unrealscript 예제


PhysicalMaterial.uc 를 살펴 봅시다.

Specifically:

PhysicalMaterial.uc
var(PhysicalProperties) export editinline PhysicalMaterialPropertyBase PhysicalMaterialProperty;

PhysicalMaterialPropertyBase.uc 에는 읽어볼 만한 코멘트가 달려 있습니다!

상황에 맞는 발소리를 구하고, 다른 깔끔한 피지컬 머티리얼 기반 이펙트에 쓸 틀을 놓으려면, PhysicalMaterialPropertyBase 서브클래스를 만들면 됩니다:

MyGamePhysicalMaterialProperty.uc
class MyGamePhysicalMaterialProperty extends PhysicalMaterialPropertyBase
  collapsecategories
  editinlinenew
  hidecategories(Object);

var(Sounds) const SoundCue FootStepSoundCue;

자 이제 (AnimNotify_Footstep 든 다른 어떤 메서드를 통해서든) 폰이 걸을 때마다 PlayFootStepSound() 호출, 해당 이벤트를 올바른 폰에 전송할 수 있습니다. 그러면 폰이 걷고 있는 표면에 따라 재생할 소리를 결정할 수 있습니다. 예를 들어 플레이어가 자갈길을 따라 걷고 있습니다. 발을 내려놓으면 PlayFootStepSound() 가 호출되고, 트레이싱을 하여, 피지컬 머티리얼을 찾아내고, 저장된 SoundCue 를 구하여 재생합니다.

분명 위와 같이 피지컬 머티리얼과 프로퍼티 프레임워크를 사용한다면, 온갖 종류의 (충격음, 적중 효과, 데칼, 발소리 등) 상황에 엄청 잘 들어맞는 기능을 낼 수 있을 것입니다.

피지컬 머티리얼 계층구조


프로그래머가 위와 같은 특정 게임 클래스를 만들었다면, 콘텐츠 팀은 피지컬 머티리얼 계층구조를 만들어 게임 디자인 상의 필요에 따라 이펙트를 채워넣기 시작하면 됩니다.

콘텐츠 제작자용 세부사항

PhysicalMaterial 에 있는 PhysicalMaterial Parent 변수로, 피지컬 머티리얼의 계층구조를 만들어 (우리 예에서는) FootStep (발소리) 계층구조를 만들 수 있습니다. 즉 예를 들어 디폴트 -> 찰흙 -> 진흙 계층구조를 예로 들어 보겠습니다. 이제 콘텐츠 팀이 게임 월드에 있는 피지컬 머티리얼에 정말 구체적인 작업을 할 수 있습니다. 진흙 발소리가 나게하고 싶을 때는 그렇게 하면 됩니다. 진흙 발소리가 없으면 찾을 때까지 계층구조를 뒤져 보다가, 결국 없으면 기본 디폴트 발소리가 됩니다.

계층구조 사용하기

이제 코드도 지원되고 피지컬 머티리얼 계층구조도 파라미터로 만들었으니, 피지컬 머티리얼을 머티리얼에 할당하면 됩니다. 그러면 게임에서 재생되는 소리를 들을 수 있습니다.

콘텐츠 제안


(우리 예제를 계속해서) 발소리를 만들 때, 사운드 팀에게 두 가지 음원 모두에다 피치와 감쇠를 조금씩 달리하여 랜덤한 발소리의 SoundCue 를 만들도록 하십시오. 그래야 발소리가 조금 더 실감이 납니다. 게다가 피지컬 머티리얼 시스템의 추상화도 올바르게 됩니다.

언리얼 토너먼트 3 예제


언리얼 토너먼트 3 에서 구현된 발소리 시스템은, 피지컬 머티리얼 프로퍼티에다 그 머티리얼에 관련된 사운드큐 대신 표면의 유형을 저장하는 것이었습니다. 거기서 UTPawn 은 SoundGroupClass 안에 저장된 사운드큐 중 적합한 것을 찾아봅니다.

UTPawn.uc
simulated function name GetMaterialBelowFeet()
{
  local vector HitLocation, HitNormal;
  local TraceHitInfo HitInfo;
  local UTPhysicalMaterialProperty PhysicalProperty;
  local actor HitActor;
  local float TraceDist;

  TraceDist = 1.5 * GetCollisionHeight();

  HitActor = Trace(HitLocation, HitNormal, Location - TraceDist*vect(0,0,1), Location, false,, HitInfo, TRACEFLAG_PhysicsVolumes);
  if ( WaterVolume(HitActor) != None )
  {
    return (Location.Z - HitLocation.Z < 0.33*TraceDist) ? 'Water' : 'ShallowWater';
  }
  if (HitInfo.PhysMaterial != None)
  {
    PhysicalProperty = UTPhysicalMaterialProperty(HitInfo.PhysMaterial.GetPhysicalMaterialProperty(class'UTPhysicalMaterialProperty'));
    if (PhysicalProperty != None)
    {
      return PhysicalProperty.MaterialType;
    }
  }
  return '';
}

simulated function ActuallyPlayFootstepSound(int FootDown)
{
  local SoundCue FootSound;

  FootSound = SoundGroupClass.static.GetFootstepSound(FootDown, GetMaterialBelowFeet());
  if (FootSound != None)
  {
    PlaySound(FootSound, false, true,,, true);
  }
}

simulated event PlayFootStepSound(int FootDown)
{
  local PlayerController PC;

  if ( !IsFirstPerson() )
  {
    ForEach LocalPlayerControllers(class'PlayerController', PC)
    {
      if ( (PC.ViewTarget != None) && (VSizeSq(PC.ViewTarget.Location - Location) < MaxFootstepDistSq) )
      {
        ActuallyPlayFootstepSound(FootDown);
        return;
      }
    }
  }
}