UDN
Search public documentation:

ReplicationProxyJP
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 ホーム > ネットワーク & レプリケーション > プロキシのパターン

プロキシのパターン


概要


プロキシのパターンが使用されるのは、アクタまたはオブジェクトがクライアント上に存在しないが、クライアントによってそれらが視覚化または聴覚化されなければならない場合です。それらのアクタがクライアント上に存在しないため、サーバーが直接クライアントにレプリケートすることはできません。オブジェクトではレプリケーションがまったくサポートされていません。プロキシのパターンを利用することによって、プロキシ自体をレプリケートしなくても、プロキシを通じてクライアント上で、アクタまたはオブジェクトがサーバー上で行っていることをシミュレートすることができます。

武器アタッチメント


このパターンは、武器アタッチメントのために「Unreal Tournament」で使用されています。「Unreal Tournament 3」における 武器 は、武器を所有しているクライアントとサーバー間で関連しているにすぎません。しかし、クライアントは、使用する武器に関する情報も必要となります。そのためには、サーバー上で武器アタッチメントをセットし、さらにそれを全クライアントにレプリケートします。すると、サーバーとクライアント両方で武器アタッチメント アクタがスポーンされます。武器がサーバー上で更新されると、武器は変更のポーンオーナーに伝えます。 これらの変更はクライアントバージョンのポーンにレプリケートされ、さらにクライアントバージョンの武器アタッチメントを更新します。

UTPawn.uc
var repnotify class<UTWeaponAttachment> CurrentWeaponAttachmentClass;
var UTWeaponAttachment CurrentWeaponAttachment;

replication
{
  if (bNetDirty)
    CurrentWeaponAttachmentClass;
}

simulated event ReplicatedEvent(name VarName)
{
  if (VarName == 'CurrentWeaponAttachmentClass')
  {
    WeaponAttachmentChanged();
  }
}

simulated function WeaponAttachmentChanged()
{
  if ((CurrentWeaponAttachment == None || CurrentWeaponAttachment.Class != CurrentWeaponAttachmentClass) && Mesh.SkeletalMesh != None)
  {
    if (CurrentWeaponAttachment!=None)
    {
      CurrentWeaponAttachment.DetachFrom(Mesh);
      CurrentWeaponAttachment.Destroy();
    }

    if (CurrentWeaponAttachmentClass!=None)
    {
      CurrentWeaponAttachment = Spawn(CurrentWeaponAttachmentClass,self);
      CurrentWeaponAttachment.Instigator = self;
    }
    else
      CurrentWeaponAttachment = none;

    if (CurrentWeaponAttachment != None)
    {
      CurrentWeaponAttachment.AttachTo(self);
      CurrentWeaponAttachment.SetSkin(ReplicatedBodyMaterial);
      CurrentWeaponAttachment.ChangeVisibility(bWeaponAttachmentVisible);
    }
  }
}

simulated function WeaponFired(Weapon InWeapon, bool bViaReplication, optional vector HitLocation)
{
  if (CurrentWeaponAttachment != None)
  {
    if (!IsFirstPerson())
    {
      CurrentWeaponAttachment.ThirdPersonFireEffects(HitLocation);
    }
    else
    {
      CurrentWeaponAttachment.FirstPersonFireEffects(Weapon, HitLocation);

      if (class'Engine'.static.IsSplitScreen() && CurrentWeaponAttachment.EffectIsRelevant(CurrentWeaponAttachment.Location, false, CurrentWeaponAttachment.MaxFireEffectDistance))
      {
        CurrentWeaponAttachment.CauseMuzzleFlash();
      }
    }

    if (HitLocation != Vect(0,0,0) && (WorldInfo.NetMode == NM_ListenServer || WorldInfo.NetMode == NM_Standalone || bViaReplication))
    {
      CurrentWeaponAttachment.PlayImpactEffects(HitLocation);
    }
  }
}

UTWeaponAttachment.uc
simulated function CauseMuzzleFlash()
{
  local ParticleSystem MuzzleTemplate;

  if ((!WorldInfo.bDropDetail && !class'Engine'.static.IsSplitScreen()) || WorldInfo.IsConsoleBuild(CONSOLE_Mobile))
  {
    if (MuzzleFlashLight == None)
    {
      if (MuzzleFlashLightClass != None)
      {
        MuzzleFlashLight = new(Outer) MuzzleFlashLightClass;

        if (Mesh != None && Mesh.GetSocketByName(MuzzleFlashSocket) != None)
        {
          Mesh.AttachComponentToSocket(MuzzleFlashLight, MuzzleFlashSocket);
        }
        else if (OwnerMesh != None)
        {
          OwnerMesh.AttachComponentToSocket(MuzzleFlashLight, AttachmentSocket);
        }
      }
    }
    else
    {
      MuzzleFlashLight.ResetLight();
    }
  }

  if (MuzzleFlashPSC != none)
  {
    if (!bMuzzleFlashPSCLoops || !MuzzleFlashPSC.bIsActive)
    {
      if (Instigator != None && Instigator.FiringMode == 1 && MuzzleFlashAltPSCTemplate != None)
      {
        MuzzleTemplate = MuzzleFlashAltPSCTemplate;
      }
      else
      {
        MuzzleTemplate = MuzzleFlashPSCTemplate;
      }

      if (MuzzleTemplate != MuzzleFlashPSC.Template)
      {
        MuzzleFlashPSC.SetTemplate(MuzzleTemplate);
      }

      SetMuzzleFlashParams(MuzzleFlashPSC);
      MuzzleFlashPSC.ActivateSystem();
    }
  }

  SetTimer(MuzzleFlashDuration, false, 'MuzzleFlashTimer');
}

simulated function ThirdPersonFireEffects(vector HitLocation)
{
  local UTPawn P;

  if (EffectIsRelevant(Location,false,MaxFireEffectDistance))
  {
    CauseMuzzleFlash();
  }

  P = UTPawn(Instigator);
  if (P != None && P.GunRecoilNode != None)
  {
    P.GunRecoilNode.bPlayRecoil = true;
  }

  if (Instigator.FiringMode == 1 && AltFireAnim != 'None')
  {
    Mesh.PlayAnim(AltFireAnim,,, false);
  }
  else if (FireAnim != 'None')
  {
    Mesh.PlayAnim(FireAnim,,, false);
  }
}

注意

UTPawn および UTWeaponAttachment はともに特定の関数しか表示していません。ソースファイルをチェックしてロジック全体をご覧ください。

結論


このパターンが使用されるのは、クライアント上に存在しないアクタまたはオブジェクトに基づくエフェクトをクライアントが視覚化または聴覚化しなければならない場合です。武器アタッチメント以外にも、このパターンが有効となる便利なインスタンスにはつぎのものがあります。
  • ゲームプレイ エフェクトをもつアーマー / 衣服アタッチメント。
  • ゲームプレイ エフェクトをもつビークル (乗り物) 上の砲塔アタッチメント。