怎么在UE游戏中加入原生振动效果

我是做振动触感的。人类的五感“视听嗅味触”,其中的“触”就是触觉,是指皮肤、毛发与物体接触时的感觉。触感可以带来更加逼真的沉浸式体验。但也许过于司空见惯,也是习以为常,很多人漠视了触感的价值。大家对触感的认知还远远不够。于是,我一直在思考场景,想着在能加振动的地方都加上振动,让大家能够切实体验到,尽力地推一推。触感是很适合加在游戏里的。拿游戏引擎来说,Unreal Engine对振动效果就有原生支持。那么,怎么在游戏里添加振动体呢?

其实很简单,分三步就能做到。先说说游戏品类。我觉得射击游戏是比较适合加振动的,比如开枪、爆炸这些场景,传统的方式是使用声光来渲染氛围,但如果增加振动反馈,可以让玩家体验再上一个台阶。我用的是UE 4.27,首先创建一个基于“第一人称游戏”模板的游戏(使用C++):

第一步:在UE编辑器里创建振动资源。在编辑器的“内容浏览器”,鼠标右键菜单里选择:其他 | 强制反馈效果。其实,这个菜单选项的英文原版是“Force Feedback Effect”,这里的Force是“力”的意思,被翻译成了“强制”,也真是无语了……新建的资源文件命名为Gunshot,在硬盘上实为一个.uasset文件。

第二步:编辑振动效果。在“内容浏览器”里双击Gunshot图标,即可打开振动效果编辑界面。振动效果是通过“通道”下发的,一个振动效果可以由一个或者多个通道组合来定义。每个通道最多可以控制四个马达,分别是左侧大马达、左侧小马达、右侧大马达、右侧小马达。至于哪个马达需要振动,则由右侧的勾选项来决定。振动的具体效果由“曲线”来表示。下图右侧的坐标系,横坐标表示时间,纵坐标表示振动强度。可以在坐标系里点击鼠标右键,然后创建折线的“关键帧”。本例中,我们在0、0.25、1.00、1.25四个位置分别创建一个关键帧,然后拖动关键帧的点,形成图中这样的梯形:

关闭振动效果编辑窗口,回到“内容浏览器”,如果此时已有一个Xbox手柄连接到PC上,则可以点击Gunshot图标上的播放按钮,即刻体验手柄的振动效果。如果对振动效果不满意,则双击进去继续修改。

振动效果创作完毕后,记得执行一次烘焙,UE编辑器菜单入口:文件 | 烘焙Windows的内容。

第三步:编写控制代码。我们想在开枪的时候让游戏手柄振动一下,模拟枪械的后座力。在UE编辑器里,执行菜单命令:文件 | 生成Visual Studio项目,以及文件 | 打开Visual Studio,在HapticFpsCharacter.cpp文件中,发现开枪事件“Fire”绑定了AHapticFpsCharacter::OnFire函数,那么我们在这个函数里播放振动效果就行了。

先在HapticFpsCharacter.h文件定义一个成员变量,用于保存振动效果素材对象的引用:

UCLASS(config=Game)
class AHapticFpsCharacter : public ACharacter
{private:/* UE native force feedback */UForceFeedbackEffect* GunshotVibrationEffect;
};

然后在HapticFpsCharacter.cpp文件AHapticFpsCharacter类的构造函数中找到这个资源文件,并进行保存:

static ConstructorHelpers::FObjectFinder<UForceFeedbackEffect> ForceFeedbackAsset(TEXT("/Game/FirstPerson/Gunshot"));
if (ForceFeedbackAsset.Succeeded()) {GunshotVibrationEffect = ForceFeedbackAsset.Object;
}

最后,在OnFire函数中使用APlayerController类的ClientPlayForceFeedback函数播放振动效果:

if (GunshotVibrationEffect && Controller && Controller->IsA(APlayerController::StaticClass())) {FForceFeedbackParameters Params;Params.bPlayWhilePaused = false;Params.bLooping = false;Params.Tag = NAME_None;APlayerController* PC = Cast<APlayerController>(Controller);PC->ClientPlayForceFeedback(GunshotVibrationEffect, Params);
}

用一张图来总结上述三个步骤:

完整的游戏工程源代码分享在我的GitHub:https://github.com/luqiming666/HapticFps。实际测试结果:UE原生振动在PC上对Xbox游戏手柄生效,在iPhone上也能振,但在Android手机上不振。如果想要在各种终端设备上都有一致的高品质振动效果,还得看RichTap,欲知详情,请访问官网:richtap-haptics.com。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/585678.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

计算机的组成

&#x1f407;明明跟你说过&#xff1a;个人主页 &#x1f3c5;个人专栏&#xff1a;《Kubernetes航线图&#xff1a;从船长到K8s掌舵者》 &#x1f3c5; &#x1f516;行路有良友&#xff0c;便是天堂&#x1f516; 目录 一、电脑硬件的五大单元 二、CPU的架构 1、指令…

蓝桥杯刷题第六天(昨天忘记发了)

今天想从不一样的角度来解题&#xff1a;从时间紧张暴力求解到思路阔达直接通过所有案例 暴力方法&#xff1a; 思路第一眼看到这个问题我就想到了第一个思路就是先用两个数组一个存石子数一个存颜色状态&#xff0c;每次遍历一遍看看有没有相邻石子颜色一样且为和最小的。 im…

int的最大值加1会变成int的最小值

一、概要 int是4个字节&#xff0c;总共是32个bit位&#xff0c;所以总共能表示2^32个数 int的最大值是2^31-1&#xff0c;也就是2147483647&#xff0c;大约21亿多 减的那个1表示自然数0的位置 int的最小值是-2^31&#xff0c;也就是-2147483648&#xff0c;大约负的21亿多…

【Cadence Allegro】如何差分对走线

一、创建espice模型 shift+F2或者“Analyze-Model Assigment”创建espice模型,这个操作是为了让差分线路里的串接电阻(或电感电容)变为xnet类型方便准确等长走线。 Cadence Allegro Xnet的创建详细教程 - 知乎Cadence Allegro Xnet的创建详细教程Xnet是指在无源器件的两端,…

瑞_23种设计模式_迭代器模式

文章目录 1 迭代器模式&#xff08;Iterator Pattern&#xff09;★★★1.1 介绍1.2 概述1.3 迭代器模式的结构1.4 中介者模式的优缺点1.5 中介者模式的使用场景 2 案例一2.1 需求2.2 代码实现 3 案例二3.1 需求3.2 代码实现 4 JDK源码解析 &#x1f64a; 前言&#xff1a;本文…

OpenHarmony实战:命令行工具hdc安装应用指南

一、工具概述 hdc&#xff08;OpenHarmony Device Connector&#xff09;是为开发人员提供的用于设备连接调试的命令行工具&#xff0c;该工具需支持部署在 Windows/Linux/Mac 等系统上与 OpenHarmony 设备&#xff08;或模拟器&#xff09;进行连接调试通信。 简言之&#xf…

HarmonyOS 应用开发之featureAbility接口切换particleAbility接口切换

featureAbility接口切换 FA模型接口Stage模型接口对应d.ts文件Stage模型对应接口getWant(callback: AsyncCallback<Want>): void; getWant(): Promise<Want>;ohos.app.ability.UIAbility.d.tslaunchWant: Want;startAbility(parameter: StartAbilityParameter, c…

JVM—类加载子系统

JVM—类加载子系统 JVM的类加载是通过ClassLoader及其子类来完成的。 有哪些类加载器 类加载器如下&#xff1a; 启动类加载器&#xff08;BootStrap ClassLoader&#xff09;&#xff1a;负责加载JAVA_HOME\lib目录或通过-Xbootclasspath参数指定路径中的且被虚拟机认可&am…

深入探究Shiro反序列化漏洞

Shiro反序列化漏洞 什么是shiro反序列化漏洞环境搭建漏洞判断rememberMe解密流程代码分析第一层解密第二层解密2.1层解密2.2层解密 exp 什么是shiro反序列化漏洞 Shiro是Apache的一个强大且易用的Java安全框架,用于执行身份验证、授权、密码和会话管理。使用 Shiro 易于理解的…

Vue项目登录页实现获取短信验证码的功能

之前我们写过不需要调后端接口就获取验证码的方法,具体看《无需后端接口,用原生js轻松实现验证码》这个文章。现在我们管理后台有个需求,就是登录页面需要获取验证码,用户可以输入验证码后进行登录。效果如下,当我点击获取验证码后能获取短信验证码: 这里在用户点击获取…

手搓Docker-Image-Creator(DIC)工具(03):实现alpine+jre的镜像

此篇博客将介绍如何使用 Docker 创建一个alpine3.10-jre1.8.0_401 的 Docker 镜像&#xff0c;并使用 Docker 运行起来。将用到 Dockerfile 的 COPY 命令、RUN 命令、ENV 命令&#xff0c;最终实现基于单一应用的 Dockerfile 构建镜像和运行。 紧急修改&#xff1a;代码我是在m…

【机器学习300问】60、图像分类任务中,训练数据不足会带来什么问题?如何缓解图像数据不足带来的问题?

在机器学习中&#xff0c;绝大部分模型都需要大量的数据进行训练和学习&#xff08;包括有监督学习和无监督学习&#xff09;&#xff0c;然而在实际应用中经常会遇到训练数据不足的问题。就比如图像分类这样的计算机视觉任务&#xff0c;确实依赖于大规模且多样化的训练数据以…