ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

UE5|蓝图项目学习日志[01]——增强输入系统“子系统”

UE5|蓝图项目学习日志[01]——增强输入系统“子系统” 提示本文内容仅代表作者新手个人观点仅供学习交流参考不构成任何专业建议。文中观点、结论如有疏漏欢迎大家讨论指正文章目录前言一、引入二、正篇1.功能实践2.超级拆解[1].增强输入[2].本地玩家[3].子系统[4].增强输入本地玩家子系统3.架构层级4.知识扩展[1].UE 里的多种 Subsystem[2]. Enhanced Iuput ActionIA_xxx节点介绍三、尾声前言此学习日志专栏是为了记录本人在学习UE过程中对一些知识的理解与心得目的是更好地入门UE的蓝图编辑、掌握特定功能实现的思维方法和具体问题的实际方案同时也会记录下我的学习进度与个人认为有趣且实用的灵感设计目前打算先从第一人称游戏基础功能实现开始若文章能给你带来启发与帮助便是此文之幸。一、引入相信大家在制作3D Action Game的初期建立人物移动、视角移动等动作输入系统时都绕不开这个节点本人刚开始就因为它奇怪的造型而感到新奇初学UE蓝图的小白可能并不是很理解这个在搭建系统时的作用尝试去拆解”增强输入本地玩家子系统“这个长难词就会发现它好像是几个无关的词组合而成但其实就是这一个简洁又复杂的节点可以处一隅、而窥UE核心架构思想的冰山一角。二、正篇1.功能实践我实现玩家的前后左右移动是通过经典的增强输入逻辑来编写的整套逻辑链如下配置输入映射、输入操作角色蓝图内逻辑链编写创建角色蓝图并设置GameModeIA_Move、IMC_Move运动逻辑玩家移动IA_Move、IMC_Player图标类型如下通俗来形容他们职责就是IA “我要做什么”IMC “用什么操作来触发它”角色蓝图内逻辑链是这样编写的同时IA_Move中的值类型要改为Axis2DIMC_Player要进行如下的输入映射设置很好现在我们构建了一条清晰的输入框架Created with Raphaël 2.3.0WASDIMC_PlayerIA_MoveBP_Player执行移动所以我们对它们开始有个大概的认识鼠标WASD 玩家实际按下的输入IMC 负责把“WASD”映射到某个动作IA_Move “移动”这个动作本身BP_Player 收到移动动作后执行具体逻辑这就是Enhanced Input的核心概念OK 此时你已经知道UE中的玩家移动怎么实现了一切都已经大功告成————了吗事实上你只是明白了实现流程但真要说清楚每个节点作用、为什么要经过IMC这一步、增强输入到底增强了个啥、是否存在其他子系统...又说不上来不是这啥而这些 才是本篇日志要深入探讨的内容。2.超级拆解为什么一定要经过IA这一环节为什么不能让IMC将输入直接映射到某个事件上相信有小伙伴一定心里这样想过UE为何如此喜欢制造麻烦让IMC把输入映射到具体蓝图事件上不就好了嘛。。。我其实刚开始也是有这个迷惑不过能想到这里说明你已经要开始了解UE的架构因为这个疑问其实正好触及Enhanced Input 的设计思想。W → MoveForwardS → MoveBackward上面这是传统输入系统Enhanced Input则可以变成W↓IMC_Move↓IA_Move↓输入值↓各种处理↓角色移动我们再请出我们的诡秘节点——增强输入玩家本地子系统此时用我们还拿的出手的断句能力来拆解它增强输入——上述的输入框架表现形式本地玩家—— 当前这台机器上实际控制的玩家子系统—— 某个更大系统下面的专门系统这里的“子”不是说它低级而是它属于某个生命周期/所有者并专门负责某一类功能。因此这个节点定义就是一个属于“本地玩家”的 Subsystem专门负责 Enhanced Input翻译成人话就是属于当前本地玩家的增强输入管理系统。[1].增强输入那“增强输入”到底增强了什么我们已经了解了增强输入的表现形式和设计思想核心可以理解成让输入不再只是“某个键按下了”而是可以对输入进行更加灵活的映射、转换、组合和处理让输入可以拥有数据类型、触发条件、修饰/转换、多个输入设备映射、不同 Mapping Context 动态切换等能力。它们具体表现在以下几层第一层Input ActionIA 实际上不只是一个“中转站”这是理解 UE 输入系统最关键的一点。我们可以把IA_Move理解成一个标准化的输入接口。例如IA_Move可以规定Value Type Axis2D于是它传出来的是X 左右Y 前后即W↓IA_Move↓(0, 1)所以 IA 本身还定义了这个输入是什么类型的数据。这就解释了为什么编写游戏中 IA 有不同类型例如IA_FireIA_AimIA_ReloadIA_MoveIA_Look它们虽然都是 Input Action但是承担的数据不同。可以简单理解IA_Fire↓Bool↓开 / 关IA_Move↓Vector2D↓X/YIA_Look↓Vector2D↓鼠标 X/Y所以 IA 并不是简单的“鼠标左键 → 这个事件”而是“定义一个游戏能够理解的输入数据接口。”第二层Input Mapping Context也就是IMC_FPSInput它定义“什么输入设备的什么输入对应哪个 IA”例如W ───────→ IA_MoveA ───────→ IA_MoveS ───────→ IA_MoveD ───────→ IA_Move鼠标 ────→ IA_Look左键 ────→ IA_Fire右键 ────→ IA_AimR ───────→ IA_Reload所以IA 游戏语言IMC 翻译规则这样做还有一个巨大的好处换设备比如来一个IA_Fire现在是鼠标左键 → IA_Fire,以后加手柄Gamepad RT → IA_Fire游戏角色完全不用改。还是IA_Fire↓BP_FPSPlayer↓开枪我们甚至可以同时鼠标左键 ─┐│手柄 RT ───┼──→ IA_Fire│触摸按钮 ──┘这样以后我们换键盘鼠标手柄触摸屏VR 控制器甚至修改按键绑定都不会把我们的游戏逻辑搞乱。这就是输入和游戏逻辑解耦。第三层Modifiers修饰器这个就是 Enhanced Input 很有意思的地方。比如W↓IA_Move得到(0,1)我们可以通过 Modifier 改变这个数据。例如输入↓Modifier↓改变输入↓IA可以做× 2或者取反或者…第四层Triggers触发器这个更重要。它可以定义“什么时候才算这个 IA 被触发”例如一般按下左键↓IA_Fire但我们可以设计长按↓IA_Aim或者按住某个键↓持续触发再或者连续输入达到条件↓触发小结所以 Enhanced Input 不只是键 → 事件而是由上述几个层次组成输入↓Mapping↓Modifier↓Trigger↓Input Action↓游戏逻辑[2].本地玩家这个很好理解Local Player 当前这台机器上实际控制的玩家\当前运行这个游戏实例的一个玩家输入身份。比如单机游戏电脑↓Local Player↓你的角色简单理解Local Player 谁在使用键盘鼠标谁拥有输入谁拥有摄像机谁拥有UI但是注意它不是角色。它也不是PlayerController。它是屏幕前的玩家比如你死亡角色Pawn死亡×但是Local Player√PlayerController√还存在。然后重新生成新的Pawn↑PlayerController重新控制我们的键盘仍然有效,所以输入绑定在Local Player如果输入绑定在PawnPawn死亡↓输入消失设计会很麻烦。所以 UE 把输入放Local Player|Enhanced Input Subsystem那为什么叫 Local因为有“本地”当然就有“非本地”。假设多人游戏服务器Server|—— Player A|——Player B|—— Player C但是你的电脑只操作Player A其他玩家(Remote Player): 他们没有你的键盘输入。[3].子系统最简单的理解Subsystem UE 帮你创建并管理的“专门负责某一类事情的系统对象”。它本质上还是一个对象/类。不是魔法!不是特殊的“节点”!就是 UE 帮你把一些系统功能组织起来。例如玩家对象├─ 角色移动├─ 生命值├─ 武器└─ …为什么叫“子系统”因为它是某个更大系统下面的专门系统。例如UE 游戏│├── 输入系统│├── 渲染系统│├── 音频系统│├── 物理系统│└── 网络系统而 Enhanced Input 又可以有自己专门的管理部分。所以整个游戏↓Local Player↓Enhanced Input Subsystem这里的“子”不是说它低级。而是它属于某个生命周期/所有者并专门负责某一类功能。那有local player的子系统难道还有不属于local player的子系统对完全有。而且这个问题问得非常关键因为我们已经开始接触 UE 的对象生命周期和架构层级了。Local Player Subsystem 不是“唯一一种 Subsystem”而是 Subsystem 的一种类型。因此我们可以把 UE 的 Subsystem 理解成“UE 根据不同的生命周期/归属提供不同位置的系统管理器。”现在我们拿Enhanced Input Local Player Subsystem做例子它属于Local Player它的生命周期大致是玩家加入↓Local Player 创建↓Local Player Subsystem 创建↓玩家存在期间一直使用↓Local Player 销毁↓Subsystem 也销毁所以Local Player适合放“某一个本地玩家自己的系统”。Enhanced Input 就非常适合放这里。因为不同玩家可能有不同的输入状态。类似的Subsystem 还有哪些有而且 UE 里其实不少。我们现在可以把 Subsystem 当成一种“按生命周期归属来组织系统功能”的架构而不是把它理解成某一个具体功能。常见的可以先记这几类表一1类型属于谁生命周期常见用途Engine SubsystemEngine整个 UE 运行期间全局引擎级功能eEditor SubsystemEditor编辑器运行期间编辑器工具、编辑器自动化Game Instance SubsystemGame Instance Subsystem一次游戏运行存档、全局游戏状态World SubsystemWorld当前 World当前地图/世界的系统Local Player SubsystemLocal Player当前本地玩家输入、玩家相关系统Game Instance 系列 / World 系列的其他专用 Subsystem对应对象对应对象生命周期具体系统功能各类型进一步说明与实例调用具体参考6.知识扩展好现在我们进行一次系统总结Subsystem就只用三个关键词服务对象它不是你的游戏角色。它专门提供某种服务。例如Enhanced Input Subsystem→ 提供输入管理服务生命周期它归属于某个东西例如Engine Subsystem→ 跟 Engine 生命周期Game Instance Subsystem→ 跟 GameInstance 生命周期World Subsystem→ 跟 World 生命周期Local Player Subsystem→ 跟 Local Player 生命周期你以后看到一个 Subsystem不要先问你以后看到一个 Subsystem不要先问“这个 Subsystem 是干什么的”第一步先问“它属于谁”这就是为什么 UE 要区分各种 Subsystem。自动管理我们通常不需要自己New ObjectCreate ObjectDestroy ObjectUE 会根据它所属的生命周期创建和管理。所以 Blueprint 里你经常看到Get XXX Subsystem意思就是“把 UE 已经管理好的那个系统对象拿出来给我用。”[4].增强输入本地玩家子系统我们已经将增强输入、本地玩家、子系统给进行了拆解并做出了较为清晰的定义与理解那么现在就是来整体看待这个节点——增强输入本地玩家子系统先看看它在增强输入框架中的位置111注意到它是一个管理者那他管谁答案是管IMC。假设我们的游戏里有很多输入模式IMC_FPSInput————FPS输入模式IMC_Menu—————菜单输入模式IMC_Inventory——————清单输入模式IMC_Vehicle————载具输入模式IMC_Cutscene——————过场动画输入模式玩家正常游戏IMC_FPSInput↓启用打开背包IMC_FPSInput↓降低优先级 / 禁用IMC_Inventory↓启用进入载具IMC_Vehicle↓启用各种输入模式可以动态切换。那么谁负责管理这些 Mapping Context就是Enhanced Input Local Player Subsystem所以this节点在蓝图中到底在干什么 它当然是在管理嘛它管理现在有哪些 IMC ——Has Mapping Context哪个 IMC 优先级高 ——Priority哪些 IMC 被添加 ——Add Mapping Context哪些 IMC 被移除 ——Remove Mapping Context当前玩家是谁 ——Local Player然后 Enhanced Input 系统根据这些配置去处理实际输入。所以结论它是一个功能/框架 作用域 这个功能挂到对应生命周期上的具体系统对象3.架构层级到了这一章差不多可以算是对前面的内容进行提炼、总结出UE的架构我们一起来将上面的系统层级一层一层地搭起来先是Enhanced Input输入框架Local Player│↓Enhanced Input Local Player Subsystem│↓IMC│Modifiers│↓把输入映射到 IA│┌─────┴─────┐↓ ↓IA_Move IA_Fire↓ ↓Triggered Triggered↓ ↓移动逻辑 开枪逻辑然后由Local Player Subsystem我们类推到了其他Subsystem可以看到逐级递减但要注意不是“功能等级更低”。而是“作用域Scope更小”更重要的是不是每个功能都有所有作用域版本再将两个层级图进行联系…我们此时可以把整个东西想成一个大公司完成一个巧妙的类比Enhanced Input 小部门玩家输入 员工发来的请求Subsystem 管理员“当前这个玩家启用了哪些规定”IMC 公司规定“什么操作对应什么业务”IA 业务名称“开火”“移动”“跳跃”Enhanced Input公司运行方式“整个公司是怎么运作的”大公司 UE 游戏里面有不同部门本地玩家部门引擎部门世界部门音频部门游戏实例部门…4.知识扩展现在来到了一个比较有趣的章节了我们要对前面涉及到的部分知识进行再扩展来增强我们对这个模块的整体认识[1].UE 里的多种 Subsystem我们在上文表一提到了6个Subsystem但我们主要先理解前5个Engine SubsystemUEEngine ↓ Engine Subsystem这是比较高层的。可以理解成整个 Unreal Engine 运行期间都存在的系统。它不专属于某一个玩家也不专属于某一个地图。Editor Subsystem这个比较特殊。它属于Unreal Editor 编辑器所以你在编辑器里工作 ↓ Editor Subsystem它通常用于编辑器工具自动化自定义编辑器功能资产处理编辑器扩展在做游戏运行时暂时不用太关注它。Game Instance Subsystem ⭐这个对以后做游戏非常有用。GameInstance ↓ Game Instance SubsystemGameInstance 的生命周期大概启动游戏 ↓ GameInstance ↓ Level1↓ Level2↓ Level3↓ 退出游戏它可以跨 Level 存在。所以如果以后做存档系统玩家全局数据任务进度游戏流程管理全局统计就很适合考虑GameInstance SubsystemWorld Subsystem ⭐这个属于当前 World。World ↓ World Subsystem例如关卡A↓ WorldA↓ World Subsystem切换关卡关卡B↓ WorldB↓ 新的 World Subsystem所以它适合只和当前地图/世界有关的系统。例如要做的游戏以后可能有当前关卡管理器敌人刷新管理环境事件管理当前地图状态Local Player Subsystem ⭐我们最先碰到的Local Player ↓ Enhanced Input Local Player Subsystem它属于某一个本地玩家。所以 玩家1↓ Local Player1↓ Input Subsystem1玩家2↓ Local Player2↓ Input Subsystem2它特别适合玩家自己独有的系统。Enhanced Input 就是一个非常典型的例子。[2]. Enhanced Iuput ActionIA_xxx节点介绍首先这个节点长这样 …那它每个引脚都有什么用、之间又有什么关联先理解几个白色执行引脚右边这些▶TriggeredStartedOngoingCanceledCompleted它们对应的是输入状态生命周期。假设按住 W整个过程没有按|↓ 按下|↓ 持续按住|↓ 松开|↓ 结束对应Started开始触发一次。例如按下 WStarted↓开始移动适合开枪跳跃开门按键交互Triggered触发⭐最常用例如按住 WW W W W W WTriggeredTriggeredTriggeredTriggered它会持续触发。. Ongoing进行中表示输入已经开始但还没有满足 Trigger 条件。比如 IA设置了Hold Trigger持续0.5秒那么按下Started:0.1秒Ongoing0.3秒Ongoing0.5秒TriggeredCompleted完成表示输入正常结束。例如按住鼠标按下Started持续Triggered松开Completed常用于松开蓄力停止瞄准停止冲刺Canceled取消表示输入被中断。例如设置长按攻击但是角色死亡了或者输入条件没有完成。那么Canceled然后是下面的⭕引脚Action Value这个当然最重要它就是输入携带的数据上面讨论IA时有解释过因此不在多赘述Triggered Seconds触发器持续时间比如Hold Trigger按住0.5秒触发Triggered Seconds 0.5Elapsed Seconds已经经过的时间。比如长按按住3秒Elapsed Seconds 3Triggered Seconds与Elapsed Second分别计的是哪里的时Triggered Seconds 当前 Input Action 已经处于 Triggered 状态的持续时间。也就是从触发成功Triggered开始计时到现在过去了多久。Elapsed Seconds 按住按键总共经过多久用表二2举个栗子时间状态Triggered SecondsElapsed Seconds0秒Started000.5秒Ongoing00.51秒Triggered011.5秒Triggered0.51.52秒Triggered12三、尾声终于来到本篇日志的尾声本篇日志帮大家拨开了节点的作用、为什么要经过IMC这一步、增强输入到底增强了个啥、是否存在其他子系统、UE的子系统部分如何架构的、对我们的游戏实例有什么启发等神秘面纱相信小伙伴们对此有了新的认识与体悟N(我)也在这过程中受益匪浅。当然还希望大家能够对自己学习过程中遇到的疑惑、难题进行自由地求索这样才能在后续的学习中挖掘新乐趣、探索新玩法、碰撞新火花。同时这也是我发的第一篇文章希望大家可以随便支持一手一起相互认识、学习交流也非常欢迎大家讨论指正我的文章。多谢观看表一 ↩︎表二 ↩︎
返回列表