当前位置: 首页 > article >正文

【Unity开发】控制手机移动端的震动

请添加图片描述

🐾 个人主页 🐾

阿松爱睡觉,横竖醒不来
🏅你可以不屠龙,但不能不磨剑🗡

目录

  • 一、前言
  • 二、Unity的Handheld.Vibrate()
  • 三、调用Android原生代码
  • 四、NiceVibrations插件
  • 五、DeviceVibration插件
  • 六、控制游戏手柄震动
  • 七、结语

一、前言

最近开发了一个新的功能——特定情况下让手机震动,例如点击界面中的按钮,手机震动一下。这也是第一次写移动端的震动的功能,虽然unity有自带的控制移动设备震动的API,但是API太过于单一不太符合功能要求,因为他只有最简单的0.5秒的震动,不能控制震动的时长和强度。然而对于一个按钮的震动反馈来讲,0.5秒的时长有点长了。

上网查阅了大量的相关的资料,最终还不错的解决的功能的开发,所以在这里就罗列出我找到的所有能控制手机震动的API插件。

最后还有控制游戏手柄震动的API

二、Unity的Handheld.Vibrate()

这是Unity自带的API,这个方法可以触发移动设备的震动。我们直接看下使用的示例

// 判断当前设备是否支持震动(最好检查一下,万一手机不支持或者马达坏了有可能报错)
if (SystemInfo.supportsVibration)
{Handheld.Vibrate();
}
else
{Debug.Log("设备不支持震动");
}

哦对了,一般是Unity自带的API的话,也是同时支持IOS系统的,但是下面说的这个就只支持安卓系统。

三、调用Android原生代码

这个方法是直接通过调用Android的Java API来控制震动时长的,所以为什么说只支持安卓系统不支持IOS系统,就是因为直接用的Android的Java API。直接来看下下如何使用吧。

方法还是比较简单的,先创建一个用于调用Android原生代码的C#脚本:

using UnityEngine;
public class VibrationManager : MonoBehaviour
{public static void Vibrate(long milliseconds){if (Application.platform == RuntimePlatform.Android){try{using (AndroidJavaClass unityPlayer = new AndroidJavaClass("com.unity3d.player.UnityPlayer")){using (AndroidJavaObject currentActivity = unityPlayer.GetStatic<AndroidJavaObject>("currentActivity")){using (AndroidJavaObject vibrator = currentActivity.Call<AndroidJavaObject>("getSystemService", "vibrator")){if (vibrator != null){vibrator.Call("vibrate", milliseconds);}}}}}catch (System.Exception e){Debug.LogError("VibrationManager: Error while trying to vibrate - " e.Message);}}}
}

然后就可以在需要震动的地方调用这个方法:

VibrationManager.Vibrate(1000); // 震动1000毫秒

当然你也可以直接把 Vibrate() 方法写在要使用的脚本文件中,就不用单独写一个脚本弄一个静态函数了。使用的时候就直接 Vibrate(1000) 就可以,简介明了!

四、NiceVibrations插件

我在项目中使用的插件就是这个,这个插件灵活性很高,且简单易操作,而且支持Android和IOS。
直接来说一下插件导入之后如何使用

首先要引入命名空间

using MoreMountains.NiceVibrations

然后就是在需要的地方调用代码了。

// 普通的振动
MMVibrationManager.Vibrate();// 不同模式的振动
MMVibrationManager.Haptic(HapticTypes.Selection);1.HapticTypes.Selection:极轻微振动——可用于点击按钮2.HapticTypes.Success:普通振动——可用于游戏胜利3.HapticTypes.Warning:普通振动——可用于游戏提示4.HapticTypes.Failure:普通振动——可用于游戏失败5.HapticTypes.LightImpact:轻微振动6.HapticTypes.MediumImpact:中度振动7.HapticTypes.HeavyImpact:重度振动8.HapticTypes.RigidImpact:强硬而时间稍长一些的振动9.HapticTypes.SoftImpact:柔软而时间稍长一些的振动// 瞬间振动,震动时长大致只有0.1s左右
MMVibrationManager.TransientHaptic(float intensity, float sharpness);参数:float			intensity 		强度0-1float 			sharpness		感知度0-1//还有几个默认的参数,bool 			alsoRumble = falseMonoBehaviour 	coroutineSupport = nullint 			controllerID = -1//连续的振动
MMVibrationManager.ContinuousHaptic(float intensity, float sharpness, float duration, HapticTypes fallbackOldiOS, this);
参数:float			intensity 							强度0-1float 			sharpness							感知度0-1float 			duration							持续时间HapticTypes 	fallbackOldiOS = HapticTypes.None	振动类型//控制全局的Haptic振动开启或关闭
MMVibrationManager.SetHapticsActive(true);
MMVibrationManager.SetHapticsActive(false);//获取设备是否支持Haptic振动
bool isSupported = MMVibrationManager.HapticsSupported();

除了上面的一下触发震动的操作,还有一下事件的回调可以绑定,但是仅限于 MMVibrationManager.Haptic 的震动

//OnEnable进行绑定
private void OnEnable()
{MMNViOSCoreHaptics.OnHapticPatternStopped += OnHapticsStopped;MMNViOSCoreHaptics.OnHapticPatternError += OnHapticsError;MMNViOSCoreHaptics.OnHapticPatternReset += OnHapticsReset;
}//OnDisable时解除绑定
private void OnDisable()
{MMNViOSCoreHaptics.OnHapticPatternStopped -= OnHapticsStopped;MMNViOSCoreHaptics.OnHapticPatternError -= OnHapticsError;MMNViOSCoreHaptics.OnHapticPatternReset -= OnHapticsReset;
}//振动结束
protected virtual void OnHapticsStopped()
{//一些处理逻辑
}//振动错误
protected virtual void OnHapticsError()
{//一些处理逻辑
}//振动重置
protected virtual void OnHapticsReset()
{//一些处理逻辑
}

MMVibrationManager.TransientHapticMMVibrationManager.ContinuousHaptic 的事件也有,但是比较少,只有结束事件

private void OnEnable()
{MMNViOSCoreHaptics.OnHapticPatternStopped += OnHapticsStopped;
}private void OnDisable()
{MMNViOSCoreHaptics.OnHapticPatternStopped -= OnHapticsStopped;
}//振动结束
protected virtual void OnHapticsStopped()
{}

五、DeviceVibration插件

插件的灵活度还可以,对于日常简单的开发就够用了,但是导入的时候需要自己处理一下意外情况(比如报错)。

插件里面也自带使用的示例,有一个Scene示例场景,可以打包成移动端自己测试一下,下面就是它的示例代码,看起来还是比较简介的。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.IO;namespace BrainCheck {public enum VibrationIntensity {vibrationIntensity_1,vibrationIntensity_2,vibrationIntensity_3,vibrationIntensity_4,vibrationIntensity_5,vibrationIntensity_6,vibrationWithDelay}public class DemoScript : MonoBehaviour{public VibrationIntensity myOption;void OnMouseUp() {StartCoroutine(BtnAnimation());}private IEnumerator BtnAnimation(){Vector3 originalScale = gameObject.transform.localScale;gameObject.transform.localScale = 0.9f * gameObject.transform.localScale;yield return new WaitForSeconds(0.2f);gameObject.transform.localScale = originalScale;ButtonAction();}private void ButtonAction() {switch(myOption) {case VibrationIntensity.vibrationIntensity_1:BrainCheck.VibrationIntensityBridge.vibrationIntensity_1();break;case VibrationIntensity.vibrationIntensity_2:BrainCheck.VibrationIntensityBridge.vibrationIntensity_2();break;case VibrationIntensity.vibrationIntensity_3:BrainCheck.VibrationIntensityBridge.vibrationIntensity_3();break;case VibrationIntensity.vibrationIntensity_4:BrainCheck.VibrationIntensityBridge.vibrationIntensity_4();break;case VibrationIntensity.vibrationIntensity_5:BrainCheck.VibrationIntensityBridge.vibrationIntensity_5();break;case VibrationIntensity.vibrationIntensity_6:BrainCheck.VibrationIntensityBridge.vibrationIntensity_6();break;case VibrationIntensity.vibrationWithDelay:#if UNITY_IOSBrainCheck.VibrationIntensityBridge.vibrationWithDelay(4, 6);#endif#if UNITY_ANDROIDBrainCheck.VibrationIntensityBridge.vibrationWithDelay(6000, 400);#endifbreak;}}}
}

六、控制游戏手柄震动

这个相对来说比较简单,没必要另外单独一篇文章进行讲述了,索性直接放在了一起说。

unity中的 Input.SetVibration 方法可以设置手柄的左右震动马达强度。震动强度是一个0到1之间的浮点数,其中0表示无震动,1表示最大震动强度。

直接看下示例:(以Xbox手柄为例)

using UnityEngine;
public class GamepadVibrationExample : MonoBehaviour
{void Update(){// 检测手柄按钮输入,例如按下"A"键时震动if (Input.GetKeyDown(KeyCode.JoystickButton0)) // Xbox手柄的"A"键通常对应JoystickButton0{// 设置手柄震动,左马达和右马达的震动强度分别为0.5和1.0Input.SetVibration(0, 0.5f, 1.0f);}// 检测手柄按钮输入,例如按下"B"键时停止震动if (Input.GetKeyDown(KeyCode.JoystickButton1)) // Xbox手柄的"B"键通常对应JoystickButton1{// 停止手柄震动Input.SetVibration(0, 0.0f, 0.0f);}}
}

七、结语

插件就这么多,仅供交流学习,有什么问题也欢迎再评论区留言或者私信,我看到的话会及时回复,下期见,拜拜。

请添加图片描述

请添加图片描述

相关文章:

【Unity开发】控制手机移动端的震动

&#x1f43e; 个人主页 &#x1f43e; 阿松爱睡觉&#xff0c;横竖醒不来 &#x1f3c5;你可以不屠龙&#xff0c;但不能不磨剑&#x1f5e1; 目录 一、前言二、Unity的Handheld.Vibrate()三、调用Android原生代码四、NiceVibrations插件五、DeviceVibration插件六、控制游戏手…...

JAVA中的注解和泛型

目录 JAVA注解介绍 概念 注解的本质 4种标准元注解 自定义注解 泛型介绍 泛型的定义 JAVA泛型 泛型方法( ) 泛型类&#xff08; &#xff09; 类型通配符 类型擦除 JAVA注解介绍 概念 注解是 JDK 5.0 引入的一种元数据机制&#xff0c;用来对代码进行标注。它不会影…...

Cesium快速入门到精通系列教程二:添加地形与添加自定义地形、相机控制

一、添加地形与添加自定义地形 在 Cesium 1.93 中添加地形可以通过配置terrainProvider实现。Cesium 支持多种地形数据源&#xff0c;包括 Cesium Ion 提供的全球地形、自定义地形服务以及开源地形数据。下面介绍几种常见的添加地形的方法&#xff1a; 使用 Cesium Ion 全球地…...

汽车零配件---ecu开发工厂学习

ecu成品制作工艺流程 一、PCB 设计与制作&#xff08;打板&#xff09; 工艺流程步骤 需求分析与电路设计 根据 ECU 功能&#xff08;如发动机控制、变速箱控制&#xff09;确定所需芯片&#xff08;如 MCU、传感器接口芯片&#xff09;、外围电路&#xff08;如电源、通信接…...

python学习打卡day43

DAY 43 复习日 作业&#xff1a; kaggle找到一个图像数据集&#xff0c;用cnn网络进行训练并且用grad-cam做可视化 浙大疏锦行 数据集使用猫狗数据集&#xff0c;训练集中包含猫图像4000张、狗图像4005张。测试集包含猫图像1012张&#xff0c;狗图像1013张。以下是数据集的下…...

Microsoft Word使用技巧分享(本科毕业论文版)

小铃铛最近终于完成了毕业答辩后空闲下来了&#xff0c;但是由于学校没有给出准确地参考模板&#xff0c;相信诸位朋友们也在调整排版时感到头疼&#xff0c;接下来小铃铛就自己使用到的一些排版技巧分享给大家。 注&#xff1a;以下某些设置是根据哈尔滨工业大学&#xff08;威…...

windows安装多个版本composer

一、需求场景 公司存在多个项目&#xff0c;有的项目比较老&#xff0c;需要composer 1.X版本才能使用 新的项目又需要composer 2.X版本才能使用 所以需要同时安装多个版本的composer二、下载多个版本composer #composer官网 https://getcomposer.org/download/三、放到指定目…...

【办公类-22-05】20250601Python模拟点击鼠标上传CSDN12篇

、 背景需求: 每周为了获取流量券,每天上传2篇,获得1500流量券,每周共上传12篇,才能获得3000和500的券。之前我用UIBOT模拟上传12篇。 【办公类-22-04】20240418 UIBOT模拟上传每天两篇,获取流量券,并删除内容_csdn 每日任务流量券-CSDN博客文章浏览阅读863次,点赞18…...

贪心算法应用:边着色问题详解

贪心算法应用&#xff1a;边着色问题详解 贪心算法是一种在每一步选择中都采取当前状态下最优的选择&#xff0c;从而希望导致结果是全局最优的算法策略。边着色问题是图论中的一个经典问题&#xff0c;贪心算法可以有效地解决它。下面我将从基础概念到具体实现&#xff0c;全…...

【蓝桥杯】包子凑数

包子凑数 题目描述 小明几乎每天早晨都会在一家包子铺吃早餐。他发现这家包子铺有 NN 种蒸笼&#xff0c;其中第 ii 种蒸笼恰好能放 AiAi​ 个包子。每种蒸笼都有非常多笼&#xff0c;可以认为是无限笼。 每当有顾客想买 XX 个包子&#xff0c;卖包子的大叔就会迅速选出若干…...

ck-editor5的研究 (2):对 CKEditor5 进行设计,并封装成一个可用的 vue 组件

前言 在上一篇文章中—— ck-editor5的研究&#xff08;1&#xff09;&#xff1a;快速把 CKEditor5 集成到 nuxt 中 &#xff0c;我仅仅是把 ckeditor5 引入到了 nuxt 中&#xff0c;功能还不算通用。 这一篇内容将会对其进行设计&#xff0c;并封装成可复用的 vue 组件&…...

Java-redis实现限时在线秒杀功能

1.使用redisson pom文件添加redisson <!--redisson--><dependency><groupId>org.redisson</groupId><artifactId>redisson-spring-boot-starter</artifactId><version>3.23.4</version></dependency> 2.mysql数据库表设…...

simulink mask、sfunction和tlc的联动、接口

这里全部是讲的level2 sfunction&#xff08;用m语言编写&#xff09;&#xff0c;基于matlab 2020a。 1.mask的参数操作 1&#xff09;mask通过set_param和get_param这2个函数接口对mask里面定义的Parameters&Dialog的参数的大部分属性进行读写&#xff0c;一般是Value值…...

VMWare安装常见问题

如果之前安装过VMWare软件&#xff0c;只要是 15/16 版本的&#xff0c;可以正常使用的&#xff0c;不用卸载&#xff01;&#xff01;&#xff01; 如果之前安装过&#xff0c;卸载了&#xff0c;一定要保证通过正常的渠道去卸载&#xff08;通过控制面板卸载软件&#xff09…...

set_property LOC约束

##下列指令是用于清除自带GT CELL相关的LOC约束&#xff0c;或者覆盖 ##你需要把IP中自带的GT cell相关的LOC约束清除掉&#xff0c;或者覆盖掉 ##以下命令可以用来覆盖GT_CHANNEL的LOC约束, 在这条命令之后执行你自己的physical constraint: ##GT的channel的相关管脚有两种设计…...

【北邮 操作系统】第十二章 文件系统实现

一、文件的物理结构 1.1 文件块、磁盘块 类似于内存分页&#xff0c;磁盘中的存储单元也会被分为一个个“块/磁盘块/物理块”。很多操作系统中&#xff0c;磁盘块的大小与内存块、页面的大小相同 内存与磁盘之间的数据交换(即读/写操作、磁盘I/0)都是以“块”为单位进行的。即…...

Docker 插件生态:从网络插件到存储插件的扩展能力解析

Docker 容器技术以其轻量、快速、可移植的特性,迅速成为构建和部署现代应用的核心工具。然而,尽管 Docker Engine 自身功能强大,但在面对多样化的生产环境和复杂业务需求时,仅靠核心功能往往无法满足所有场景。 例如,跨主机的容器网络通信、异构存储系统的持久化数据管理…...

WordPress搜索引擎优化的最佳重定向插件:进阶指南

在管理网站时&#xff0c;我们经常需要调整网页地址或修复错误链接。这时&#xff0c;通过重定向不仅能有效解决这些问题&#xff0c;还能显著提升网站在搜索引擎中的排名。对于熟悉基础重定向插件的用户来说&#xff0c;一些功能更强大的工具可以帮助你更全面地管理网站&#…...

org.junit.runners.model.InvalidTestClassError:此类问题的解决

不知道大家是否遇见过以上这种情况&#xff0c;我也是今天被这个错误搞得很烦&#xff0c;后来通过网上查找资料终于找到了问题所在————就是简单的Test注解的错误使用 Test注解的注意情况 &#xff1a;1 权限必须是public 2 不能有参数 3 返回值类型是void 4 本类的其他的…...

用户管理页面(解决toggleRowSelection在dialog用不了的隐患,包含el-table的plus版本的组件)

新增/编辑/删除/分配角色&#xff0c;图片上传在此文章分类下另一个文章 1.重点分配角色&#xff1a; <template><!-- 客户资料 --><div class"pageBox"><elPlusTable :tableData"tableData" :tablePage"tablePage" onSi…...

打卡第35天:GPU训练以及类的Call方法

知识点回归&#xff1a; 1.CPU性能的查看&#xff1a;看架构代际、核心数、线程数 2.GPU性能的查看&#xff1a;看显存、看级别、看架构代际 3.GPU训练的方法&#xff1a;数据和模型移动到GPU device上 4.类的call方法&#xff1a;为什么定义前向传播时可以直接写作self.fc1(x)…...

Linux-GCC、makefile、GDB

GCC gcc -E test.c -o test.i预处理(-o指定文件名) gcc -S test.i -o test.s编译gcc -c test.s -o test.o汇编gcc test.o -o test链接(生成一个可执行程序的软连接) gcc test.c -o test一条指令可以完成以上所有内容 gcc *.c -I(大写的i) include由于在main.c中找不到当前文件…...

[MySQL初阶]MySQL(7) 表的内外连接

标题&#xff1a;[MySQL初阶]MySQL(7)表的内外连接 水墨不写bug 文章目录 一. 内连接 (INNER JOIN)二. 外连接 (OUTER JOIN)关键区别总结 三、 如何选择 在 MySQL 中&#xff0c;连接&#xff08;JOIN&#xff09;用于根据两个或多个表之间的相关列组合行。内连接&#xff08;I…...

Spring Boot中Excel处理完全指南:从基础到高级实践

Excel处理基础知识 1.1 为什么需要在应用中处理Excel文件&#xff1f; 在企业应用开发中&#xff0c;Excel文件处理是一个非常常见的需求&#xff0c;主要用于以下场景&#xff1a; 数据导入&#xff1a;允许用户通过Excel上传批量数据到系统 数据导出&#xff1a;将系统数据…...

Windows下NVM的安装与使用

本文将介绍windows下nvm相关知识。 在不同的项目中可能会使用不同版本的Node.js&#xff0c;例如A项目中需要node>18&#xff1b;B项目中需要node>20。这时候就需要使用NVM切换不同的node版本。进而可以在同一台设备上使用多个node版本。 一、NVM是什么&#xff1f; n…...

Ubuntu挂起和休眠

Ubuntu挂起和休眠 1. 挂起&#xff08;Suspend&#xff09;2. 休眠&#xff08;Hibernate&#xff09;3. 混合挂起&#xff08;Hybrid-Sleep&#xff09;注意事项图形界面操作 在 Ubuntu 系统中&#xff0c;挂起&#xff08;Suspend&#xff09;和休眠&#xff08;Hibernate&am…...

【R语言编程绘图-mlbench】

mlbench库简介 mlbench是一个用于机器学习的R语言扩展包&#xff0c;主要用于提供经典的基准数据集和工具&#xff0c;常用于算法测试、教学演示或研究场景。该库包含多个知名数据集&#xff0c;涵盖分类、回归、聚类等任务。 包含的主要数据集 BostonHousing 波士顿房价数据…...

云服务器部署Gin+gorm 项目 demo

更多个人笔记见&#xff1a; &#xff08;注意点击“继续”&#xff0c;而不是“发现新项目”&#xff09; github个人笔记仓库 https://github.com/ZHLOVEYY/IT_note gitee 个人笔记仓库 https://gitee.com/harryhack/it_note 个人学习&#xff0c;学习过程中还会不断补充&…...

MySQL数据一致性守护者:pt-table-checksum原理与实战全解析

MySQL数据一致性守护者:pt-table-checksum原理与实战全解析 在MySQL主从复制环境中,数据一致性是DBA和运维人员最关心的问题之一。主从数据不一致可能导致业务逻辑错误、报表数据失真甚至系统故障。Percona Toolkit中的pt-table-checksum工具正是为解决这一痛点而生,它能够…...

检索器组件深入学习与使用技巧 BaseRetriever 检索器基类

1. BaseRetriever 检索器基类 在 LangChain 中&#xff0c;传递一段 query 并返回与这段文本相关联文档的组件被称为 检索器&#xff0c;并且 LangChain 为所有检索器设计了一个基类——BaseRetriever&#xff0c;该类继承了 RunnableSerializable&#xff0c;所以该类是一个 …...