《InsideUE4》GamePlay架构学习_Pawn

《InsideUE4》GamePlay架构学习

  • Pawn
    • 前言
    • Component
    • Actor
      • Pawn
    • DefaultPawn,SpectatorPawn,Character
      • DefaultPawn
      • SpectatorPawn
      • Character
    • 思考
      • 为何Actor也能接受Input事件?

Pawn

前言

本次系列是关于知乎InsideUE系列的学习记录。原作链接如下:原文链接

前面我们学习了大钊老师有关于Gameplay部分的各个层次内容。能理解UE的3D游戏世界是由Object->Actor+Component->Level->World->WorldContext->GameInstance->Engine来逐渐层层构建而成的。

接下来学习关于GamePlay部分的逻辑框架。

Note1:虽然本部分会涉及到游戏的业务逻辑编写部分,但并不打算详细讨论AI(BehaviorTree,Navigation等)。AI也是一个很大的话题,值得专门开个大章节讨论,我们现在不应该委屈她。
Note2:本部分也不会细讨论输入事件的处理,游戏逻辑确实一大部分是由输入事件驱动起来的,不过我们此时只是简单聊一下概念,后续会有章节再细讨论输入事件的路由流程。
Note3:联机游戏的游戏逻辑自然也是非常重要的,但为了简化本章节的概念,所以网络联机的逻辑同步等也都不会涉及。留待后续网络章节再好好的阐述。


Component

由之前的学习,Actor可以理解成一个小的容器,用来装进不同Components的功能,甚至能嵌套不同Actor的功能。

正确理解“功能”和“游戏业务逻辑”的区分是理解Component的关键要点。

有关于游戏业务逻辑应该是针对与特定游戏的特殊功能或是特殊规则,而功能应该是能够无痛迁移到其他项目的。

Component应该是功能的载体。

Actor

那么我的游戏逻辑要放在哪呢?

在Unity中,由于我们的Script都是以组件的形式放在物体身上,所以实际上逻辑都是在组件层运行的。这其中就包括了游戏的业务逻辑,只不过对于这些逻辑我们可能会采取一些设计模式来进行管理,比如我们通过自建的GameController对全局进行一些管理。

那么在UE中,上面强调了Components应该是综合了“功能”的概念,在看UE源码时,你会发现UE用了大量的继承,在这些里 ,UE特化了Pawn和Character,以及各种Controller来完成游戏逻辑。

Pawn

游戏中可能存在大量的Actors,在这些角色中,大部分是Level中静态的或者是自行运转的,可能只有少部分是能与玩家进行交互的。如与NPS的互动对话、特殊物品的按键交互。

于是 Pawn 应运而生,派生于AActor。
在这里插入图片描述

UE也是从Actor中再派生出了APawn,并定义了3块基本的模板方法接口:

  • 可被Controller控制
  • PhysicsCollision表示
  • MovementInput的基本响应接口

而Pawn本身的意思也可以是棋子的意思。
在这里插入图片描述
这就意味这玩家或者别的AI能够操作Pawn。但关键也在于,Pawn的重点应该放在被操作上,因此也就需要Controller来操作它。由于UE从FPS游戏进化而来,因此也把物理和移动有关的东西也放到了Pawn里。

DefaultPawn,SpectatorPawn,Character

这三位都是从多少跟Pawn有些关系的,可以放在一块讲。
在这里插入图片描述

DefaultPawn

从命名不难发现,这是方便我们偷懒弄的,一个默认的Pawn:DefaultPawn

上述的三件套在这具体为:

  • DefaultPawnMovementComponent
  • Spherical CollisionComponent
  • StaticMeshComponent

SpectatorPawn

上面也介绍了,UE的FPS是一大特色,玩过FPS游戏的都知道,一般有一个第三人称的不受地形、物理限制的观战视角,派生于DefaultPawn的SpectatorPawn就是为这一功能存在的。

ASpectatorPawn::ASpectatorPawn(const FObjectInitializer& ObjectInitializer): Super(ObjectInitializer.SetDefaultSubobjectClass<USpectatorPawnMovement>(Super::MovementComponentName).DoNotCreateDefaultSubobject(Super::MeshComponentName))
{SetCanBeDamaged(false);//SetRemoteRoleForBackwardsCompat(ROLE_SimulatedProxy);//bReplicates = true;BaseEyeHeight = 0.0f;bCollideWhenPlacing = false;SpawnCollisionHandlingMethod = ESpawnActorCollisionHandlingMethod::AlwaysSpawn;MovementComponent->bComponentShouldUpdatePhysicsVolume = false;static FName CollisionProfileName(TEXT("Spectator"));GetCollisionComponent()->SetCollisionProfileName(CollisionProfileName);
}

所以派生于DefaultPawn的SpectatorPawn提供了一个基本的USpectatorPawnMovement(不带重力漫游),并关闭了StaticMesh的显示,碰撞也设置到了“Spectator”通道。

Character

Character为我们提供了一个人形的Pawn供我们操作。
在这里插入图片描述
相对的,它拥有:

  • 像人一样行走的CharacterMovementComponent。
  • 尽量贴合的CapsuleComponent以及骨骼上蒙皮的网格(SkeletalMesh)。

思考

为何Actor也能接受Input事件?

上述Pawn能接收来自玩家的交互,但实际上EnableInput接口却是在Actor上的,同时InputComponent也是在Actor里面的。
在这里插入图片描述

官方的输入事件处理流程图也是表明了这一点:

在这里插入图片描述

理解这个问题的要点在于正确区分“输入响应”和“逻辑控制”。比如说WASD移动,Actor拥有最基本的输入响应,它可以响应WASD的按键事件。但是按键了之后呢?该如何移动?Pawn就定义了一个基本的MovementInput套路,相当于把WASD的输入响应再往前包装处理了一步。而“逻辑控制”指的是更高层上的比如寻路或自动巡逻等行为。


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部