UDN
Search public documentation:

DevelopmentKitGemsCreatingAModularPawnCH
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

虚幻开发工具包主页 > 虚幻开发工具包说明 > 如何创建模块化 pawn

如何创建模块化 pawn


于 2011 年 6 月对 UDK 进行最后测试
可以与 PC 和 iOS 兼容

概述


现在很多游戏允许玩家自定义他们的虚拟人物的外观。虽然附件通过插槽或骨骼对于非动画或单独的动画作用非常大;但是在您希望虚拟角色像单独的实体一样移动时它们起不到多大作用。例如,假设您希望允许玩家通过选择衬衫和裤子创建角色。因为将这些部分合成在一起后会组成一个类人生物,在动画没有正确同步的时候,它将会看上去非常不真实。

在这个示例中,我们使 Lauryn 具有不同的肩垫排列,不同的战靴和不同的手臂。阴影和动画可以轻而易举地自动运行。

ModularPawnTitle.jpg

方法


有两种方法可以实现这个效果。
  • 根据 actor 的多骨架网格物体组件 - 这种方法灵活性最好,因为它可以对这个骨架网格物体运行时间更改。然而,这种方法可能会影响性能,因为每个骨架网格物体 actor 都会成为另一个绘制调用。
  • 合成网格物体 (只适用于授权用户) - 这种方法可以合成网格物体,使用多个网格物体生成一个单独的网格物体。这种方法将不会在这篇说明文章中进行说明。

相关主题

编写模块化 pawn 脚本


这是一个可以定义多个骨架网格物体组件的模块化 pawn 类。每个骨架网格组件代表一个 pawn 的一个部分,它可以被替换为另一个部分。只有一个骨架网格物体组件是父代骨架网格物体组件,在这个实例中指的是头部骨架网格物体组件。

父代骨架网格物体组件主要负责计算供它的所有子代骨架网格物体组件使用的骨架动画数据。所有子代骨架网格物体组件同时也会从它们的父代接收到所有平移、旋转和缩放数据。

为了得到最好的结果,请确保所有骨架网格物体使用的是相同的骨架,而且这些网格物体是为同一个动画而设计的。应该将所有顶点直接映射到这个骨架,因为在导出之前不需要使每个骨架网格物体回到中心位置。

最后,所有子代骨架网格物体组件都会将它们的阴影父代设置为相同的父代网格物体组件。这样可以在渲染动态阴影的时候产生更好的性能,同时可以防止阴影重叠问题出现。

ModularPawn.uc
class ModularPawn extends UTPawn
  Placeable;

// 表示头部的骨架网格物体。父代骨架网格物体组件。
var(ModularPawn) const SkeletalMeshComponent HeadSkeletalMesh;
// 表示人体躯干的骨架网格物体。头部骨架网格物体组件的子代。
var(ModularPawn) const SkeletalMeshComponent TorsoSkeletalMesh;
// 表示手臂的骨架网格物体。头部骨架网格物体组件的子代。
var(ModularPawn) const SkeletalMeshComponent ArmsSkeletalMesh;
// 表示大腿的骨架网格物体。头部骨架网格物体组件的子代。
var(ModularPawn) const SkeletalMeshComponent ThighsSkeletalMesh;
// 表示战靴的骨架网格物体。头部骨架网格物体组件的子代。
var(ModularPawn) const SkeletalMeshComponent BootsSkeletalMesh;
// 表示左肩垫的骨架网格物体。头部骨架网格物体组件的子代。
var(ModularPawn) const SkeletalMeshComponent LeftShoulderPadSkeletalMesh;
// 表示右肩垫的骨架网格物体。头部骨架网格物体组件的子代。
var(ModularPawn) const SkeletalMeshComponent RightShoulderPadSkeletalMesh;

defaultproperties
{
  // 删除 UTPawn 的已定义骨架网格物体
  Components.Remove(WPawnSkeletalMeshComponent)

  // 创建动画序列
  Begin Object class=AnimNodeSequence Name=AnimNodeSequence
  End Object

  // 创建头部骨架网格物体组件
  Begin Object Class=SkeletalMeshComponent Name=HeadSkeletalMeshComponent
    bCacheAnimSequenceNodes=false
    AlwaysLoadOnClient=true
    AlwaysLoadOnServer=true
    bOwnerNoSee=true
    CastShadow=true
    BlockRigidBody=true
    bUpdateSkelWhenNotRendered=false
    bIgnoreControllersWhenNotRendered=true
    bUpdateKinematicBonesFromAnimation=true
    bCastDynamicShadow=true
    RBChannel=RBCC_Untitled3
    RBCollideWithChannels=(Untitled3=true)
    LightEnvironment=MyLightEnvironment
    bOverrideAttachmentOwnerVisibility=true
    bAcceptsDynamicDecals=false
    AnimTreeTemplate=AnimTree'CH_AnimHuman_Tree.AT_CH_Human'
    bHasPhysicsAssetInstance=true
    TickGroup=TG_PreAsyncWork
    MinDistFactorForKinematicUpdate=0.2
    bChartDistanceFactor=true
    RBDominanceGroup=20
    MotionBlurScale=0.0
    bUseOnePassLightingOnTranslucency=true
    bPerBoneMotionBlur=true
    // 设置动画节点序列,以便我们可以测试这个动画。
    Animations=AnimNodeSequence
  End Object
  HeadSkeletalMesh=HeadSkeletalMeshComponent
  Components.Add(HeadSkeletalMeshComponent)

  // 创建人体躯干骨架网格物体组件
  Begin Object Class=SkeletalMeshComponent Name=TorsoSkeletalMeshComponent
    bCacheAnimSequenceNodes=false
    AlwaysLoadOnClient=true
    AlwaysLoadOnServer=true
    bOwnerNoSee=true
    CastShadow=true
    BlockRigidBody=true
    bUpdateSkelWhenNotRendered=false
    bIgnoreControllersWhenNotRendered=true
    bUpdateKinematicBonesFromAnimation=true
    bCastDynamicShadow=true
    RBChannel=RBCC_Untitled3
    RBCollideWithChannels=(Untitled3=true)
    LightEnvironment=MyLightEnvironment
    bOverrideAttachmentOwnerVisibility=true
    bAcceptsDynamicDecals=false
    bHasPhysicsAssetInstance=true
    TickGroup=TG_PreAsyncWork
    MinDistFactorForKinematicUpdate=0.2
    bChartDistanceFactor=true
    RBDominanceGroup=20
    MotionBlurScale=0.0
    bUseOnePassLightingOnTranslucency=true
    bPerBoneMotionBlur=true
    // 将动画组件赋给头部骨架网格物体组件。这样可以保证
    // 将 pawn 作为一个骨架网格物体组件一样进行处理。
    ParentAnimComponent=HeadSkeletalMeshComponent
    // 将阴影父代组件赋给头部骨架网格物体组件。可以使用它加快
    // 渲染这个 pawn 的阴影的速度,以防阴影发生折叠现象。
    ShadowParent=HeadSkeletalMeshComponent
  End Object
  TorsoSkeletalMesh=TorsoSkeletalMeshComponent
  Components.Add(TorsoSkeletalMeshComponent)

  // 创建手臂骨架网格物体组件
  Begin Object Class=SkeletalMeshComponent Name=ArmsSkeletalMeshComponent
    bCacheAnimSequenceNodes=false
    AlwaysLoadOnClient=true
    AlwaysLoadOnServer=true
    bOwnerNoSee=true
    CastShadow=true
    BlockRigidBody=true
    bUpdateSkelWhenNotRendered=false
    bIgnoreControllersWhenNotRendered=true
    bUpdateKinematicBonesFromAnimation=true
    bCastDynamicShadow=true
    RBChannel=RBCC_Untitled3
    RBCollideWithChannels=(Untitled3=true)
    LightEnvironment=MyLightEnvironment
    bOverrideAttachmentOwnerVisibility=true
    bAcceptsDynamicDecals=false
    bHasPhysicsAssetInstance=true
    TickGroup=TG_PreAsyncWork
    MinDistFactorForKinematicUpdate=0.2
    bChartDistanceFactor=true
    RBDominanceGroup=20
    MotionBlurScale=0.0
    bUseOnePassLightingOnTranslucency=true
    bPerBoneMotionBlur=true
    // 将动画组件赋给头部骨架网格物体组件。这样可以保证
    // 将 pawn 作为一个骨架网格物体组件一样进行处理。
    ParentAnimComponent=HeadSkeletalMeshComponent
    // 将阴影父代组件赋给头部骨架网格物体组件。可以使用它加快
    // 渲染这个 pawn 的阴影的速度,以防阴影发生折叠现象。
    ShadowParent=HeadSkeletalMeshComponent
  End Object
  ArmsSkeletalMesh=ArmsSkeletalMeshComponent
  Components.Add(ArmsSkeletalMeshComponent)

  // 创建大腿骨架网格物体组件
  Begin Object Class=SkeletalMeshComponent Name=ThighsSkeletalMeshComponent
    bCacheAnimSequenceNodes=false
    AlwaysLoadOnClient=true
    AlwaysLoadOnServer=true
    bOwnerNoSee=true
    CastShadow=true
    BlockRigidBody=true
    bUpdateSkelWhenNotRendered=false
    bIgnoreControllersWhenNotRendered=true
    bUpdateKinematicBonesFromAnimation=true
    bCastDynamicShadow=true
    RBChannel=RBCC_Untitled3
    RBCollideWithChannels=(Untitled3=true)
    LightEnvironment=MyLightEnvironment
    bOverrideAttachmentOwnerVisibility=true
    bAcceptsDynamicDecals=false
    bHasPhysicsAssetInstance=true
    TickGroup=TG_PreAsyncWork
    MinDistFactorForKinematicUpdate=0.2
    bChartDistanceFactor=true
    RBDominanceGroup=20
    MotionBlurScale=0.0
    bUseOnePassLightingOnTranslucency=true
    bPerBoneMotionBlur=true
    // 将动画组件赋给头部骨架网格物体组件。这样可以保证
    // 将 pawn 作为一个骨架网格物体组件一样进行处理。
    ParentAnimComponent=HeadSkeletalMeshComponent
    // 将阴影父代组件赋给头部骨架网格物体组件。可以使用它加快
    // 渲染这个 pawn 的阴影的速度,以防阴影发生折叠现象。
    ShadowParent=HeadSkeletalMeshComponent
  End Object
  ThighsSkeletalMesh=ThighsSkeletalMeshComponent
  Components.Add(ThighsSkeletalMeshComponent)

  // 创建战靴骨架网格物体组件
  Begin Object Class=SkeletalMeshComponent Name=BootsSkeletalMeshComponent
    bCacheAnimSequenceNodes=false
    AlwaysLoadOnClient=true
    AlwaysLoadOnServer=true
    bOwnerNoSee=true
    CastShadow=true
    BlockRigidBody=true
    bUpdateSkelWhenNotRendered=false
    bIgnoreControllersWhenNotRendered=true
    bUpdateKinematicBonesFromAnimation=true
    bCastDynamicShadow=true
    RBChannel=RBCC_Untitled3
    RBCollideWithChannels=(Untitled3=true)
    LightEnvironment=MyLightEnvironment
    bOverrideAttachmentOwnerVisibility=true
    bAcceptsDynamicDecals=false
    bHasPhysicsAssetInstance=true
    TickGroup=TG_PreAsyncWork
    MinDistFactorForKinematicUpdate=0.2
    bChartDistanceFactor=true
    RBDominanceGroup=20
    MotionBlurScale=0.0
    bUseOnePassLightingOnTranslucency=true
    bPerBoneMotionBlur=true
    // 将动画组件赋给头部骨架网格物体组件。这样可以保证
    // 将 pawn 作为一个骨架网格物体组件一样进行处理。
    ParentAnimComponent=HeadSkeletalMeshComponent
    // 将阴影父代组件赋给头部骨架网格物体组件。可以使用它加快
    // 渲染这个 pawn 的阴影的速度,以防阴影发生折叠现象。
    ShadowParent=HeadSkeletalMeshComponent
  End Object
  BootsSkeletalMesh=BootsSkeletalMeshComponent
  Components.Add(BootsSkeletalMeshComponent)

  // 创建左肩垫骨架网格物体组件
  Begin Object Class=SkeletalMeshComponent Name=LeftShouldPadSkeletalMeshComponent
    bCacheAnimSequenceNodes=false
    AlwaysLoadOnClient=true
    AlwaysLoadOnServer=true
    bOwnerNoSee=true
    CastShadow=true
    BlockRigidBody=true
    bUpdateSkelWhenNotRendered=false
    bIgnoreControllersWhenNotRendered=true
    bUpdateKinematicBonesFromAnimation=true
    bCastDynamicShadow=true
    RBChannel=RBCC_Untitled3
    RBCollideWithChannels=(Untitled3=true)
    LightEnvironment=MyLightEnvironment
    bOverrideAttachmentOwnerVisibility=true
    bAcceptsDynamicDecals=false
    bHasPhysicsAssetInstance=true
    TickGroup=TG_PreAsyncWork
    MinDistFactorForKinematicUpdate=0.2
    bChartDistanceFactor=true
    RBDominanceGroup=20
    MotionBlurScale=0.0
    bUseOnePassLightingOnTranslucency=true
    bPerBoneMotionBlur=true
    // 将动画组件赋给头部骨架网格物体组件。这样可以保证
    // 将 pawn 作为一个骨架网格物体组件一样进行处理。
    ParentAnimComponent=HeadSkeletalMeshComponent
    // 将阴影父代组件赋给头部骨架网格物体组件。可以使用它加快
    // 渲染这个 pawn 的阴影的速度,以防阴影发生折叠现象。
    ShadowParent=HeadSkeletalMeshComponent
  End Object
  LeftShoulderPadSkeletalMesh=LeftShouldPadSkeletalMeshComponent
  Components.Add(LeftShouldPadSkeletalMeshComponent)

  // 创建右肩垫骨架网格物体组件
  Begin Object Class=SkeletalMeshComponent Name=RightShoulderPadSkeletalMeshComponent
    bCacheAnimSequenceNodes=false
    AlwaysLoadOnClient=true
    AlwaysLoadOnServer=true
    bOwnerNoSee=true
    CastShadow=true
    BlockRigidBody=true
    bUpdateSkelWhenNotRendered=false
    bIgnoreControllersWhenNotRendered=true
    bUpdateKinematicBonesFromAnimation=true
    bCastDynamicShadow=true
    RBChannel=RBCC_Untitled3
    RBCollideWithChannels=(Untitled3=true)
    LightEnvironment=MyLightEnvironment
    bOverrideAttachmentOwnerVisibility=true
    bAcceptsDynamicDecals=false
    bHasPhysicsAssetInstance=true
    TickGroup=TG_PreAsyncWork
    MinDistFactorForKinematicUpdate=0.2
    bChartDistanceFactor=true
    RBDominanceGroup=20
    MotionBlurScale=0.0
    bUseOnePassLightingOnTranslucency=true
    bPerBoneMotionBlur=true
    // 将动画组件赋给头部骨架网格物体组件。这样可以保证
    // 将 pawn 作为一个骨架网格物体组件一样进行处理。
    ParentAnimComponent=HeadSkeletalMeshComponent
    // 将阴影父代组件赋给头部骨架网格物体组件。可以使用它加快
    // 渲染这个 pawn 的阴影的速度,以防阴影发生折叠现象。
    ShadowParent=HeadSkeletalMeshComponent
  End Object
  RightShoulderPadSkeletalMesh=RightShoulderPadSkeletalMeshComponent
  Components.Add(RightShoulderPadSkeletalMeshComponent)
}

注意事项

在上面的类中,将 Anim Node Sequence 定义为允许您测试动画。它将会使动画树停止常规工作,因此,从类脚本或对象(在一个原型内)中删除这个 Anim Node Sequence,使这个动画树可以重新正常运行。

相关主题

模块化 Pawn 属性


在将一个 ModularPawn 放置在世界中后,打开它的属性窗口将会显示全部骨架网格物体。

ModularPawnProperties.jpg

展开每个骨架网格物体对象并正确设置这个骨架网格物体。父代骨架网格物体组件应该对 Anim Tree Template、Physics Asset 和 AnimSets 进行设置。在这个实例中,Head Skeletal Mesh 对象将会具有所有这些设置。

ModularPawnSettingProperties_A.jpg

在您设置每个骨架网格物体的时候,它们将会显示在编辑器中。

ModularPawnSetSkeletalMeshes.jpg

父代网格物体组件(头部骨架网格物体)会将一个 Anim Node Sequence 设置给 Animations 对象。展开这个 Animations 选项卡显示这个 Anim Node Sequence。将这个 Anim Seq Name 赋给可以在 Anim Sets 数列中找到的动画。它将会编辑器中更新骨架网格物体组件。要显示这个动画,请运行 PIE。

ModularPawnSettingAnimationProperties.jpg

父代骨架网格物体组件(头部骨架网格物体)平移、旋转和缩放会影响子代骨架网格物体组件。如果您发现这个骨架网格物体组件无法放入碰撞圆柱体中,或者该骨架网格物体组件相对 pawn 旋转而言方位不正确,或者在这个骨架网格物体组件太小的情况下,可以调整这些设置。您还可以调整这些网格物体组件的子代;只是要记住这些是相对父代的设置。

ModularPawnSettingPrimitiveComponentProperties.jpg

相关主题

虚幻动画集编辑器


如果您希望在没有运行 PIE 的情况下显示模块化 pawn,那么您可以在虚幻动画集编辑器中进行这项操作。通过设置“多余的网格物体 #”字段(使用红色高亮显示的字段),您可以将多个网格物体赋给相同的骨架和动画。在这个示例中,大部分 Lauryn 的网格物体已经进行分配。但是,没有足够的插槽分配战靴。

ModularPawnSettingTheExtraMeshInAnimSet.jpg

在您设置了多余的网格物体之后,点击 Anim 选项卡显示动画列表。选择任意动画播放。您应该可以看到所有骨架网格物体动画效果。

ModularPawnPlayAnAnimationToTest.jpg

相关主题

何时使用...


这里还有另一种方法可以将东西附加在骨架网格物体上,而且使用的是插槽附件。这样的话,问题是应该在什么时候使用插槽附件和这种方法? 答案是在您需要动画同步的时候。在这种特殊情况喜爱,网格物体唯一需要做的是进行同步,这样看起来才像一个 pawn。不过,肩垫可以通过插槽附件完成。

相关主题