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


🐾 个人主页 🐾

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


目录

一、前言

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

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

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

二、Unity的Handheld.Vibrate()

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

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

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

三、调用Android原生代码

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

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

csharp 复制代码
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);
            }
        }
    }
}

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

csharp 复制代码
VibrationManager.Vibrate(1000); // 震动1000毫秒

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

四、NiceVibrations插件

我在项目中使用的插件就是这个,这个插件灵活性很高,且简单易操作,而且支持Android和IOS。

直接来说一下插件导入之后如何使用

首先要引入命名空间

using MoreMountains.NiceVibrations

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

csharp 复制代码
// 普通的振动
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-1
		float 			sharpness		感知度0-1
		//还有几个默认的参数,
		bool 			alsoRumble = false
		MonoBehaviour 	coroutineSupport = null
		int 			controllerID = -1

//连续的振动
MMVibrationManager.ContinuousHaptic(float intensity, float sharpness, float duration, HapticTypes fallbackOldiOS, this);
参数:
		float			intensity 							强度0-1
		float 			sharpness							感知度0-1
		float 			duration							持续时间
		HapticTypes 	fallbackOldiOS = HapticTypes.None	振动类型

//控制全局的Haptic振动开启或关闭
MMVibrationManager.SetHapticsActive(true);
MMVibrationManager.SetHapticsActive(false);

//获取设备是否支持Haptic振动
bool isSupported = MMVibrationManager.HapticsSupported();

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

csharp 复制代码
//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 的事件也有,但是比较少,只有结束事件

csharp 复制代码
private void OnEnable()
{
    MMNViOSCoreHaptics.OnHapticPatternStopped += OnHapticsStopped;
}
 
private void OnDisable()
{
    MMNViOSCoreHaptics.OnHapticPatternStopped -= OnHapticsStopped;
}

//振动结束
protected virtual void OnHapticsStopped()
{
 
}

五、DeviceVibration插件

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

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

csharp 复制代码
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_IOS
				  BrainCheck.VibrationIntensityBridge.vibrationWithDelay(4, 6);
				#endif
				#if UNITY_ANDROID
				  BrainCheck.VibrationIntensityBridge.vibrationWithDelay(6000, 400);
				#endif
			      break;
			}
	    }
	}
}

六、控制游戏手柄震动

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

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

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

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

七、结语

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

相关推荐
三巧13 分钟前
Godot 敌人生成半径和围墙不匹配,导致敌人错误的生成在围墙外的解决代码
游戏引擎·godot
技术小甜甜15 分钟前
【Godot引擎】如何使用内置的全局搜索功能提升开发效率
游戏引擎·godot
技术小甜甜17 分钟前
【Godot】如何导出 Release 版本的安卓项目
android·游戏引擎·godot
XR-AI-JK9 小时前
Unity VR/MR开发-VR设备与适用场景分析
unity·vr·mr
ChiLi_Lin10 小时前
Unity异常上报飞书工具
unity·游戏引擎·飞书
Magnum Lehar12 小时前
vulkan游戏引擎的makefile启动环境实现
游戏引擎
地狱为王20 小时前
基于VLC的Unity视频播放器(四)
unity·游戏引擎·音视频
21 小时前
Unity与Excel表格交互热更方案
unity·游戏引擎·excel
装大炮的自行车1 天前
【Unity】R3 CSharp 响应式编程 - 使用篇(集合)(三)
windows·unity·游戏引擎