1.添加输入动作:IA_Jump
2.创造输入映射情境:
3.在C++里添加绑定操作:
Source/Crunch/Public/Player/CPlayerCharacter.h:
(1)重写PawnClientRestart()函数:
virtual void PawnClientRestart() override;
PawnClientRestart() 是虚幻引擎中用于处理客户端Pawn重启的重要虚函数,主要功能包括:
核心作用
当玩家控制的Pawn在客户端需要重新初始化时(如重生、切换Pawn等),该函数会被自动调用。典型应用场景包括:
- 玩家角色死亡后重生
- 多人游戏中切换控制的角色
- 载具上下车时的Pawn切换
与输入系统的关键配合
通常在此函数中需要重新绑定输入映射上下文(Input Mapping Context),确保客户端输入能正确响应。例如:
void AMyPawn::PawnClientRestart()
{
Super::PawnClientRestart();
if (APlayerController* PC = Cast<APlayerController>(GetController()))
{
if (UEnhancedInputLocalPlayerSubsystem* Subsystem = …)
{
Subsystem->AddMappingContext(DefaultMappingContext, 0);
}
}
}
执行时机
该函数在服务端调用RestartPlayer()后触发,位于客户端Pawn初始化链的末端。与之相关的调用顺序为:
GameMode::RestartPlayer()
→ PlayerController::ClientRestart()
→ Pawn::PawnClientRestart()
常见实现内容
- 重新初始化客户端特效/音效
- 重置HUD显示元素
- 同步角色状态到客户端
- 激活摄像机重置逻辑
注意事项
- 必须调用Super::PawnClientRestart()保留父类逻辑
- 仅客户端执行,服务端不会触发此函数
- 与PossessedBy()的调用时序需特别注意
void ACPlayerCharacter::PawnClientRestart()
{
Super::PawnClientRestart();
// 获取玩家控制器
APlayerController* OwningPlayerController = Cast<APlayerController>(GetController());
if (OwningPlayerController)
{
//获取本地玩家子系统
class ULocalPlayer* LocalPlayer = OwningPlayerController->GetLocalPlayer();
//获取本地玩家子系统
UEnhancedInputLocalPlayerSubsystem* Subsystem = LocalPlayer->GetSubsystem<UEnhancedInputLocalPlayerSubsystem>();
if (Subsystem)
{
//先移除旧的输入上下文
Subsystem->RemoveMappingContext(InputContext);
//绑定映射情境
Subsystem->AddMappingContext(InputContext, 0);
}
}
这段代码实现了虚幻引擎中玩家角色客户端重启时的输入系统重置逻辑,以下是关键分析:
执行流程
- 先调用父类PawnClientRestart()保证基础功能
- 通过GetController()获取玩家控制器并进行安全转换
- 逐层获取本地玩家和增强输入子系统
输入上下文处理
采用"先移除后添加"的稳妥方式:
Subsystem->RemoveMappingContext(InputContext); // 清理旧上下文
Subsystem->AddMappingContext(InputContext, 0); // 优先级设为0
典型应用场景
- 角色重生时重新激活输入控制
- 多人游戏中角色控制权切换
- 载具上下车时的输入切换
优化建议
- 可添加InputContext空指针检查
- 考虑将优先级参数设为可配置变量
- 对于频繁切换的场景可缓存Subsystem引用
与SetupPlayerInputComponent的关系
此函数处理输入映射的运行时更新,而SetupPlayerInputComponent负责初始绑定,两者共同构成完整的输入处理系统。
该实现符合UE5增强输入系统的最佳实践,能有效处理客户端输入重置需求。
思考:比较这两种方法的优缺点?多人游戏这两个方法都可以吗?
方法一:
void ACCPlayerController::BeginPlay()
{
Super::BeginPlay();
check(CCContext);//判断增强输入映射情境是否存在
//从本地角色身上获取到它的子系统
UEnhancedInputLocalPlayerSubsystem* Subsystem = ULocalPlayer::GetSubsystem<UEnhancedInputLocalPlayerSubsystem>(GetLocalPlayer());
// check(Subsystem);//检查子系统是否存在
if (Subsystem)
{
Subsystem->AddMappingContext(CCContext,0);//子系统配置情境
}
}
方法二:
void ACPlayerCharacter::PawnClientRestart()
{
Super::PawnClientRestart();
// 获取玩家控制器
APlayerController* OwningPlayerController = Cast<APlayerController>(GetController());
if (OwningPlayerController)
{
//获取本地玩家子系统
class ULocalPlayer* LocalPlayer = OwningPlayerController->GetLocalPlayer();
//获取本地玩家子系统
UEnhancedInputLocalPlayerSubsystem* Subsystem = LocalPlayer->GetSubsystem<UEnhancedInputLocalPlayerSubsystem>();
if (Subsystem)
{
//先移除旧的输入上下文
Subsystem->RemoveMappingContext(InputContext);
//绑定映射情境
Subsystem->AddMappingContext(InputContext, 0);
}
}
}
这两种方法都是用于设置增强输入映射上下文(Enhanced Input Mapping Context)的,但实现位置和逻辑有所不同。我来分析它们的优缺点和适用场景:
方法1(PlayerController::BeginPlay)优点:
方法1缺点:
方法2(Character::PawnClientRestart)优点:
方法2缺点:
多人游戏适用性:
两种方法在多人游戏中都可以使用,但有以下区别:
建议:
- 如果你的游戏输入映射简单且不会改变,使用方法1
- 如果需要动态切换输入映射或角色重生时需要重新绑定,使用方法2
- 在多人游戏中,方法2通常更可靠,特别是当玩家可能控制不同角色时
两种方法在多人游戏中都能工作,因为输入子系统是基于本地玩家的,每个客户端都会独立处理自己的输入映射。
(2)重写SetupPlayerInputComponent()方法:
void ACPlayerCharacter::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent)
{
Super::SetupPlayerInputComponent(PlayerInputComponent);
//增强输入组件
UEnhancedInputComponent* EnhancedInputComponent = Cast<UEnhancedInputComponent>(PlayerInputComponent);
if (EnhancedInputComponent)
{
//动作绑定
EnhancedInputComponent->BindAction(InputAction_Jump, ETriggerEvent::Triggered, this, &ACPlayerCharacter::Jump);
}
}
这段代码是虚幻引擎中用于设置玩家角色输入组件的典型实现,主要功能是绑定跳跃动作到增强输入系统。以下是关键点解析:
继承调用
通过Super::SetupPlayerInputComponent()确保父类输入逻辑先执行,这是虚幻引擎的标准做法
增强输入转换
将基础输入组件转换为UEnhancedInputComponent,这是使用UE5增强输入系统(Enhanced Input System)的必要步骤
动作绑定
使用BindAction方法将跳跃输入动作(InputAction_Jump)与角色的Jump方法关联,触发条件为ETriggerEvent::Triggered(按键按下时持续触发)
安全校验
通过if条件确保只在成功转换增强输入组件后才执行绑定,避免空指针异常6
扩展建议
实际项目中通常会继续绑定其他输入动作,例如:
EnhancedInputComponent->BindAction(InputAction_Move, ETriggerEvent::Triggered, this, &ACPlayerCharacter::Move);
EnhancedInputComponent->BindAction(InputAction_Look, ETriggerEvent::Triggered, this, &ACPlayerCharacter::Look);
该实现符合UE5最佳实践,建议在PawnClientRestart()中也确保输入映射上下文正确加载,形成完整的输入处理链
4.在蓝图里添加蓝图上下文和动作:
评论前必须登录!
注册