虚幻引擎_玩家控制器APlayerController(初阶)

这个文章主要讲控制器类的作用;

我会系统梳理 UE 中APlayerController(玩家控制器)能做的所有核心操作,这是理解 UE 玩家输入 / 控制逻辑的关键。我会按功能分类,用 "大白话 + 核心 API + 使用场景" 的形式,把玩家控制器的能力讲得清晰易懂,新手也能快速掌握。

核心前提(先明确)

APlayerController是 UE 中 "玩家和游戏世界交互的核心枢纽",所有和 "玩家输入、视角、控制对象、UI 交互" 相关的操作,几乎都由它负责。它的核心定位:玩家的 "总遥控器"+"感知中枢"

一、输入相关操作(最核心)

玩家控制器是处理所有玩家输入的 "入口",也是你之前代码中用到的核心能力。

核心操作 关键 API 大白话解释 典型场景
1. 获取鼠标光标碰撞点 GetHitResultUnderCursor() 把屏幕 2D 光标位置转成 3D 世界碰撞点 坦克瞄准、点击拾取物品、鼠标交互 UI / 世界物体
2. 绑定输入动作(新版) UEnhancedInputComponent->BindAction() 把输入映射上下文(IMC)里的动作绑定到函数(如 "Jump" 绑定到跳跃函数) 玩家移动、开火、跳跃等所有按键 / 手柄操作
3. 绑定输入轴(旧版) InputComponent->BindAxis() 绑定轴向输入(如 WASD 对应移动轴、鼠标移动对应视角轴) 角色移动、视角旋转(旧版输入系统)
4. 禁用 / 启用输入 SetInputMode() / EnableInput() / DisableInput() 控制玩家是否能输入(比如暂停菜单时禁用游戏输入,只允许 UI 输入) 暂停菜单、过场动画、UI 交互时锁定输入
5. 获取按键状态 IsInputKeyDown() / WasInputKeyJustPressed() 检测某个按键是否按住 / 刚按下 长按开火、按键连点检测
6. 设置输入模式 SetInputModeGameAndUI() / SetInputModeUIOnly() 切换输入模式(只游戏 / 只 UI / 游戏 + UI) 打开 UI 时让鼠标显示并能点按钮,同时保留游戏输入

示例代码(核心输入操作)

cpp 复制代码
// 1. 绑定输入动作(新版增强输入)
void AMyPlayerController::SetupInputComponent()
{
    Super::SetupInputComponent();
    if (UEnhancedInputComponent* EnhancedInputComp = Cast<UEnhancedInputComponent>(InputComponent))
    {
        // 绑定"移动"动作到处理函数
        EnhancedInputComp->BindAction(MoveAction, ETriggerEvent::Triggered, this, &AMyPlayerController::HandleMove);
        // 绑定"开火"动作到处理函数
        EnhancedInputComp->BindAction(FireAction, ETriggerEvent::Started, this, &AMyPlayerController::HandleFire);
    }
}

// 2. 禁用游戏输入,只允许UI输入(打开暂停菜单时)
void AMyPlayerController::OpenPauseMenu()
{
    FInputModeUIOnly InputMode;
    InputMode.SetWidgetToFocus(PauseMenuWidget->TakeWidget()); // 聚焦到暂停菜单UI
    SetInputMode(InputMode);
    bShowMouseCursor = true; // 显示鼠标光标
}

二、控制 Pawn / 角色(核心职责)

玩家控制器的核心作用是 "控制 Pawn(坦克 / 角色)",负责建立 / 解除控制关系,以及传递指令。

核心操作 关键 API 大白话解释 典型场景
1. 控制 Pawn Possess() / UnPossess() 绑定 / 解除和 Pawn 的控制关系(遥控器绑定 / 解绑坦克) 玩家出生控制角色、切换控制单位(比如切换坦克 / 飞机)
2. 获取当前控制的 Pawn GetPawn() / GetPawn<ATank>() 获取当前控制的角色 / 坦克(类型安全转换) 给控制的坦克发 "开火" 指令、获取坦克位置
3. 切换控制的 Pawn Possess(NewPawn) 切换控制对象(比如玩家从坦克切换到步兵) 载具切换、角色切换
4. 强制 Pawn 移动 / 转向 ClientSetLocation() / SetControlRotation() 强制控制的 Pawn 移动到指定位置 / 转向指定方向 传送玩家、剧情强制转向

示例代码(控制 Pawn)

cpp 复制代码
// 1. 出生时控制默认角色
void AMyPlayerController::BeginPlay()
{
    Super::BeginPlay();
    // 生成角色并控制
    AMyCharacter* SpawnedCharacter = GetWorld()->SpawnActor<AMyCharacter>(CharacterClass, SpawnPos, SpawnRot);
    Possess(SpawnedCharacter); // 绑定控制关系
}

// 2. 切换控制的坦克
void AMyPlayerController::SwitchToTank(ATank* NewTank)
{
    UnPossess(); // 先解绑当前控制的角色
    Possess(NewTank); // 绑定新坦克
}

三、视角 / 相机控制(玩家视觉)

玩家控制器负责管理玩家的视角和相机,决定玩家 "看到什么"。

核心操作 关键 API 大白话解释 典型场景
1. 设置控制旋转 SetControlRotation() 强制设置玩家的视角旋转(比如剧情强制看某个方向) 过场动画、提示玩家看目标点
2. 获取 / 设置相机位置 GetPlayerViewPoint() 获取当前玩家的相机位置和旋转(视角原点) 发射子弹(从相机位置射线检测)、第三人称视角计算
3. 启用 / 禁用鼠标视角 bShowMouseCursor / bEnableMouseOverEvents 显示 / 隐藏鼠标、启用鼠标悬停事件 UI 交互时显示鼠标,游戏时隐藏
4. 设置鼠标灵敏度 SetMouseSensitivity() 调整鼠标视角旋转的灵敏度 游戏设置里的灵敏度调节
5. 锁定视角 SetViewTarget() 切换相机视角目标(比如切到固定相机、第三人称→第一人称) 剧情相机、视角切换

示例代码(视角控制)

cpp 复制代码
// 1. 获取玩家相机位置(用于发射射线)
FVector CameraLocation;
FRotator CameraRotation;
GetPlayerViewPoint(CameraLocation, CameraRotation); // 获取相机位置和旋转

// 2. 剧情强制让玩家看向某个目标点
void AMyPlayerController::LookAtTarget(FVector TargetPos)
{
    FRotator LookAtRot = UKismetMathLibrary::FindLookAtRotation(GetPawn()->GetActorLocation(), TargetPos);
    SetControlRotation(LookAtRot); // 强制视角转向目标
}

四、UI/HUD 相关操作

玩家控制器是连接玩家和 UI 的桥梁,负责管理 HUD、弹窗、UI 输入等。

核心操作 关键 API 大白话解释 典型场景
1. 创建 / 销毁 HUD CreateHUD() / GetHUD() 创建玩家专属的 HUD(血条、弹药显示) 每个玩家有独立的 HUD(双人同屏)
2. 显示 UI 弹窗 ShowNotification() / 蓝图中创建 Widget 显示提示弹窗、加载界面、菜单 击杀提示、任务完成弹窗
3. 设置鼠标焦点 SetWidgetToFocus() 让鼠标聚焦到某个 UI 控件(比如输入框) 登录界面、聊天输入框
4. 启用鼠标悬停事件 bEnableMouseOverEvents 让 UI 响应鼠标悬停(比如按钮高亮) 所有 UI 交互场景

五、网络 / 多人游戏相关(进阶)

在多人游戏中,玩家控制器是 "本地玩家" 和 "服务器" 交互的核心,每个玩家有独立的控制器。

核心操作 关键 API 大白话解释 典型场景
1. 判断是否是本地玩家 IsLocalPlayerController() 区分本地 / 远程控制器(多人游戏中只处理本地输入) 多人游戏中避免远程玩家执行本地逻辑
2. 服务器 RPC 调用 Server_XXX() / Client_XXX() 向服务器 / 客户端发送指令(比如开火指令同步) 多人游戏中同步玩家操作
3. 获取玩家 ID GetPlayerId() / GetUniqueID() 获取玩家的唯一标识(用于存档、排行榜) 玩家数据存储、多人游戏身份识别

示例代码(多人游戏判断)

cpp 复制代码
// 多人游戏中,只处理本地玩家的输入
void AMyPlayerController::HandleFire()
{
    if (!IsLocalPlayerController()) return; // 非本地玩家不执行
    Server_Fire(); // 向服务器发送开火指令
}

// 服务器端处理开火(RPC)
UFUNCTION(Server, Reliable)
void AMyPlayerController::Server_Fire()
{
    // 服务器验证并执行开火逻辑
    ATank* ControlledTank = GetPawn<ATank>();
    if (ControlledTank) ControlledTank->Fire();
}

六、其他实用操作(高频)

核心操作 关键 API 大白话解释 典型场景
1. 暂停 / 继续游戏 SetPause() / ClearPause() 暂停游戏(仅服务器 / 本地玩家能操作) 暂停菜单、游戏暂停功能
2. 传送玩家 TeleportTo() 把控制的 Pawn 传送到指定位置 快速旅行、复活传送
3. 播放音效 / 震动 ClientPlaySound() / ClientPlayHapticEffect() 给玩家播放音效、手柄震动 击中反馈、开火震动、提示音效
4. 获取本地玩家 GetLocalPlayer() 关联到 ULocalPlayer(输入子系统载体) 激活输入映射上下文(你之前的坦克代码)

总结(核心能力速记)

APlayerController的核心能力可以归纳为 4 大类,新手记住这 4 点就够了:

  1. 输入处理:接收 / 解析玩家的键盘 / 鼠标 / 手柄输入,绑定到业务逻辑;
  2. 控制 Pawn:绑定 / 解绑控制的角色 / 坦克,传递操作指令;
  3. 视角管理:控制玩家的相机视角、鼠标显示 / 隐藏、输入模式;
  4. UI 交互:管理玩家的 HUD/UI,处理 UI 输入和鼠标交互。

额外关键点:

  • 每个本地玩家对应一个APlayerController(双人同屏时 Player0/Player1 各有一个);
  • 玩家控制器不负责 "角色移动 / 开火",只负责 "接收输入并告诉角色该移动 / 开火";
  • 多人游戏中,只有本地玩家控制器处理输入,远程控制器只同步状态。

虚幻引擎_玩家控制器APlayerController(进阶)https://mp.csdn.net/mp_blog/creation/editor/156986537

相关推荐
呆呆敲代码的小Y3 小时前
【Unity工具篇】| Unity项目中如何使用LuBan插件,详细集成步骤
游戏·unity·游戏引擎·u3d·luban·免费游戏·unity工具
哈小奇12 小时前
Unity URP管线Linear空间丝绸材质
unity·游戏引擎·材质
哈小奇13 小时前
Unity URP管线Linear空间下玻璃效果
unity·游戏引擎
极客柒18 小时前
Unity 大地图高性能砍树顶点动画Shader
unity·游戏引擎
avi911121 小时前
UnityProfiler游戏优化-举一个简单的Editor调试
游戏·unity·游戏引擎·aigc·vibe coding·editor扩展
学嵌入式的小杨同学21 小时前
C 语言实战:动态规划求解最长公共子串(连续),附完整实现与优化
数据结构·c++·算法·unity·游戏引擎·代理模式
学嵌入式的小杨同学1 天前
顺序表(SqList)完整解析与实现(数据结构专栏版)
c++·算法·unity·游戏引擎·代理模式
Howrun7771 天前
虚幻引擎 C++ 制作“射击FPS游戏“
游戏·游戏引擎·虚幻
极客柒1 天前
Unity 大地图 高性能路径引导Shader
unity·游戏引擎