目录
Unity 基础 之 实现简单监听晃动(摇一摇)手机设备震动手机设备的事件的功能
一、简单介绍
二、知识点
三、实现原理
四、注意事项
五、实现步骤
六、关键代码
Unity中的一些基础知识点。
本节介绍,在 Unity 种,实现监听手机晃动(摇一摇)触发的事件,并震动手机的功能。
Unity简化了重力感应的开发, 通过访问Input.acceleration属性,取回加速度传感器的值;
Unity3D中重量的取值范围是 -1.0 到 +1.0;
X轴:home按键在下手机面朝天向右旋转90度重力分量为+1.0 向左旋转90度重力分量为-1.0
Y轴:home按键在上手机背朝自己重力分量为+1.0 home按键在下手机面朝自己重力分量为-1.0
Z轴:手机面朝地面重力分量为+1.0 手机面朝天空重力分量为-1.0
unity中使用Input.acceleration的x,y,z属性即可获得重力分量:
Input.acceleration.x; 重力感应X轴的重力分量
Input.acceleration.y; 重力感应Y轴的重力分量
Input.acceleration.z; 重力感应Z轴的重力分量
1、监听 Input.acceleration.y, 重力感应Y轴的重力分量
2、当 Y轴的重力分量 变化差值查过一定数值,即可判定为晃动,触发晃动事件
1、这里 监听 Input.acceleration.y, 重力感应Y轴的重力分量,你可以根据需要监听其他轴,或多轴监听产生不同效果
2、变化差值,根据需要进行调整,不唯一
1、打开 Unity ,新建工程
2、在工程中新建脚本,ShakePhoneWithVibrateWrapper 实现晃动手机触发震动的功能,MonoSingleton 单例,TestShakePhonrWithVibrateWrapper 测试 ShakePhoneWithVibrateWrapper 脚本功能
3、TestShakePhonrWithVibrateWrapper 挂载到场景中
4、打包到手机设备上测试
5、晃动(摇一摇)手机,触发 震动事件
1、ShakePhoneWithVibrateWrapper
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace XANTools
{
///
/// 摇一摇且震动手机功能
/// 知识点:
/// 1、Unity简化了重力感应的开发, 通过访问Input.acceleration属性,取回加速度传感器的值;
/// 2、首先我们看一下重力传感器的方向问题。Unity3D中重量的取值范围是 -1.0 到 +1.0;
///
public class ShakePhoneWithVibrateWrapper : MonoSingleton
{
//手机晃动的有效距离
public float Distance { get => distance;
set {
distance = Mathf.Clamp01(value);
}
}
///
/// 初始化摇一摇功能
///
/// 摇一摇触发后的监听事件
/// 摇一摇的的敏感度(0,1)
public void Init(Action shakeListener ,float shakeSensitive =0.5f)
{
shakeAction = shakeListener;
Distance = shakeSensitive;
}
void Update()
{
Shake();
}
///
/// 摇一摇功能
///
void Shake() {
new_y = Input.acceleration.y;
currentShakeDistance = new_y - old_y;
old_y = new_y;
if (currentShakeDistance > Distance)
{
//实现手机晃动震动效果
Handheld.Vibrate();
// 摇一摇事件
if (shakeAction != null) {
shakeAction();
}
}
}
//记录上一次的重力感应的Y值
private float old_y = 0;
//记录当前的重力感应的Y值
private float new_y;
//当前手机晃动的距离
private float currentShakeDistance = 0;
//手机晃动的有效距离
private float distance = 0.75f;
// 触发摇一摇震动后的委托事件
Action shakeAction;
}
}
2、TestShakePhonrWithVibrateWrapper
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using XANTools;
public class TestShakePhonrWithVibrateWrapper : MonoBehaviour
{
// Start is called before the first frame update
void Start()
{
ShakePhoneWithVibrateWrapper.Instance.Init(() => Debug.Log("触发摇一摇震动事件"));
}
}
3、MonoSingleton
using UnityEngine;
public abstract class MonoSingleton : MonoBehaviour where T : MonoBehaviour
{
private static T instance = null;
private static readonly object locker = new object();
private static bool bAppQuitting;
public static T Instance
{
get
{
if (bAppQuitting)
{
instance = null;
return instance;
}
lock (locker)
{
if (instance == null)
{
// 保证场景中只有一个 单例
T[] managers = Object.FindObjectsOfType(typeof(T)) as T[];
if (managers.Length != 0)
{
if (managers.Length == 1)
{
instance = managers[0];
instance.gameObject.name = typeof(T).Name;
return instance;
}
else
{
Debug.LogError("Class " + typeof(T).Name + " exists multiple times in violation of singleton pattern. Destroying all copies");
foreach (T manager in managers)
{
Destroy(manager.gameObject);
}
}
}
var singleton = new GameObject();
instance = singleton.AddComponent();
singleton.name = "(singleton)" + typeof(T);
singleton.hideFlags = HideFlags.None;
DontDestroyOnLoad(singleton);
}
instance.hideFlags = HideFlags.None;
return instance;
}
}
}
protected virtual void Awake()
{
bAppQuitting = false;
}
protected virtual void OnDestroy()
{
bAppQuitting = true;
}
}
备注:ShakePhoneWithVibrateWrapper Update 监听可能会监听不到,可以协程监听
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace XANTools
{
///
/// 摇一摇且震动手机功能
/// 知识点:
/// 1、Unity简化了重力感应的开发, 通过访问Input.acceleration属性,取回加速度传感器的值;
/// 2、首先我们看一下重力传感器的方向问题。Unity3D中重量的取值范围是 -1.0 到 +1.0;
///
public class ShakePhoneWithVibrateWrapper : MonoSingleton
{
//手机晃动的有效距离
public float Distance { get => distance;
set {
distance = Mathf.Clamp01(value);
}
}
///
/// 初始化摇一摇功能
///
/// 摇一摇触发后的监听事件
/// 摇一摇的的敏感度(0,1)
public void Init(Action shakeListener ,float shakeSensitive =0.5f)
{
shakeAction = shakeListener;
Distance = shakeSensitive;
StartCoroutine(ShakeCor());
}
void Update()
{
//Shake();
}
IEnumerator ShakeCor() {
Debug.Log(GetType()+"/Shake Init OK ,Start to Listen/");
while (true) {
yield return new WaitForEndOfFrame();
Shake();
// 触发一次摇一摇后,间隔一定时间再次监听
if (isShake ==true)
{
yield return new WaitForSeconds(intervalShakeTime);
isShake = false;
}
}
}
///
/// 摇一摇功能
///
void Shake() {
new_y = Input.acceleration.y;
currentShakeDistance_y = new_y - old_y;
old_y = new_y;
new_x = Input.acceleration.x;
currentShakeDistance_x = new_x - old_x;
old_x = new_x;
if (currentShakeDistance_y > Distance || currentShakeDistance_x > Distance)
{
isShake = true;
// 摇一摇事件
if (shakeAction != null) {
shakeAction();
}
//实现手机晃动震动效果
Handheld.Vibrate();
Debug.Log(GetType() + "/Shake .../");
}
}
//记录上一次的重力感应的Y值
private float old_y = 0;
//记录当前的重力感应的Y值
private float new_y;
//当前手机晃动的距离
private float currentShakeDistance_y = 0;
//记录上一次的重力感应的X值
private float old_x = 0;
//记录当前的重力感应的X值
private float new_x;
//当前手机晃动的距离
private float currentShakeDistance_x = 0;
//手机晃动的有效距离
private float distance = 0.75f;
// 触发摇一摇震动后的委托事件
Action shakeAction;
// 是否触发
bool isShake = false;
// 触发一次的间隔时间
float intervalShakeTime = 0.1f;
}
}