虚幻引擎_玩家控制器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

相关推荐
天人合一peng4 小时前
unity 生成标记根据背景色标记变色
unity·游戏引擎
天人合一peng7 小时前
unity 生成标记根据背景色变色为明显的颜色
unity·游戏引擎
魔士于安8 小时前
Unity 超市总动员 超市收银台 超市货架 超市购物手推车 超市常见商品
游戏·unity·游戏引擎·贴图·模型
CandyU28 小时前
Unity —— 数据持久化
unity·游戏引擎
zh路西法8 小时前
【Unity实现Oneshot胶卷显形】游戏窗口化与Win32API的使用
游戏·unity·游戏引擎
迪捷软件9 小时前
显控系统虚拟仿真的工程化路径
游戏引擎·cocos2d
Swift社区14 小时前
传统游戏引擎 vs 鸿蒙 System 架构
架构·游戏引擎·harmonyos
mxwin1 天前
Unity Shader 半透明物体为什么不能写入深度缓冲?
unity·游戏引擎·shader
晚枫歌F1 天前
三层时间轮的实现
网络·unity·游戏引擎
努力长头发的程序猿1 天前
Unity使用ScriptableObject序列化资源
unity·游戏引擎