Unity移動(dòng)設(shè)備重力感應(yīng)(陀螺儀)

移動(dòng)設(shè)備游戲中經(jīng)常會(huì)遇到重力感應(yīng)的開(kāi)發(fā),Unity簡(jiǎn)化了重力感應(yīng)的開(kāi)發(fā),?通過(guò)訪問(wèn)Input.acceleration屬性,取回加速度傳感器的值。首先我們看一下重力傳感器的方向問(wèn)題。Unity3D中重量的取值范圍是 -1.0 到 +1.0.

X軸:home按鍵在下手機(jī)面朝天向右旋轉(zhuǎn)90度重力分量為+1.0? 向左旋轉(zhuǎn)90度重力分量為-1.0

Y軸:home按鍵在上手機(jī)背朝自己重力分量為+1.0 home按鍵在下手機(jī)面朝自己重力分量為-1.0

Z軸:手機(jī)面朝地面重力分量為+1.0 手機(jī)面朝天空重力分量為-1.0


為了詳細(xì)說(shuō)明手機(jī)移動(dòng)帶來(lái)的每個(gè)軸項(xiàng)的數(shù)值的變化,我在筆記本上面簡(jiǎn)單畫(huà)了一下簡(jiǎn)圖,感覺(jué)更詳細(xì)一些:


如上圖,手機(jī)平放到桌面xyz軸的分量是(0,0,-1),為了讓其為標(biāo)準(zhǔn)化(0,0,0),需要z軸加上1來(lái)讓其標(biāo)準(zhǔn)化。x軸從左到右抬起變化范圍[-1,0],0是垂直水平面,然后就是[0,-1],直到手機(jī)完全覆蓋到水平桌面。y和z軸的變化如上圖。

tips:手機(jī)里面的坐標(biāo)系如A,unity里面的坐標(biāo)系如B,需要注意一下,兩個(gè)坐標(biāo)系是不一樣的

上面分析完了直接上代碼:

using System;

using System.Collections;

using System.Collections.Generic;

using UnityEngine;

using UnityEngine.UI;

public class GyroCtrl : MonoBehaviour

{

? ? public GameObject target;? ? //被移動(dòng)的對(duì)象

? ? //

? ? public float maxOffsetX = 10f;? ? // 最大傾斜角 35?

? ? public float maxOffsetY = 10f;? ? // 最大傾斜角 35

? ? public float maxOffsetZ = 1f;? ? // 最大傾斜角 35

? ? public float posFactor = 0f;? ? // 位移的系數(shù)

? ? public float lerpFactor = 5f;? ? // 差值系數(shù)

? ? Vector3 m_MobileOrientation;? //手機(jī)陀螺儀變化的值

? ? Vector3 m_targetTransform;

? ? Vector3 m_targetPos;

? ? void Awake()

? ? {

? ? ? ? m_targetTransform = Vector3.zero;

? ? ? ? m_targetPos = Vector3.zero;

? ? ? ? //Input.gyro.enabled = true;

? ? }

? ? void Start()

? ? {

? ? ? ? if (target == null)

? ? ? ? {

? ? ? ? ? ? target = gameObject;

? ? ? ? }

? ? }

? ? //運(yùn)用手機(jī)的X軸的變化來(lái)改變target對(duì)象的Y軸旋轉(zhuǎn),X軸移動(dòng); Y軸的變化來(lái)改變target對(duì)象的X軸旋轉(zhuǎn),Y軸移動(dòng);Z軸的變化只去改變target對(duì)象的Z軸位置

? ? void LateUpdate()

? ? {

? ? ? ? if (target == null)

? ? ? ? ? ? return;

? ? ? ? m_MobileOrientation = Input.acceleration;

? ? ? ? m_targetTransform.x = Mathf.Lerp(m_targetTransform.x, m_MobileOrientation.y * maxOffsetY, Time.deltaTime * lerpFactor);

? ? ? ? m_targetTransform.y = Mathf.Lerp(m_targetTransform.y, -m_MobileOrientation.x * maxOffsetX, Time.deltaTime * lerpFactor);

? ? ? ? m_targetTransform.z = Mathf.Lerp(m_targetTransform.z, (-m_MobileOrientation.x) * maxOffsetZ, Time.deltaTime * lerpFactor);

? ? ? ? m_targetPos.x = m_targetTransform.x;

? ? ? ? m_targetPos.y = m_targetTransform.y;

? ? ? ? m_targetPos.z = m_targetTransform.z;

? ? ? ? target.transform.localPosition = Vector3.Lerp(target.transform.localPosition, m_targetPos * posFactor, Time.deltaTime * lerpFactor);

? ? ? ? target.transform.localRotation = Quaternion.Euler(m_targetTransform);

? ? ? ? //target.transform.localRotation = Quaternion.Lerp(target.transform.localRotation, Quaternion.Euler(m_targetTransform), Time.deltaTime * lerpFactor);

? ? }

}

下面代碼為策劃配置系數(shù)調(diào)試用的代碼,主要是開(kāi)放了一些開(kāi)關(guān),讓策劃配置好了之后,在應(yīng)用到上面的GyroCtrl .cs里面

策劃配置代碼我也一起貼出來(lái),僅供參考

tips:我們當(dāng)時(shí)分了七層個(gè)層,每個(gè)層的移動(dòng)速度都不一樣,感覺(jué)分三層,前中后,保證三層的移動(dòng)速度不一樣就行了

using System;

using System.Collections;

using System.Collections.Generic;

using UnityEngine;

using UnityEngine.UI;

public class Gyro : MonoBehaviour

{

? ? public GameObject target;? ? //被移動(dòng)的對(duì)象

? ? Vector3 m_MobileOrientation;? //手機(jī)陀螺儀變化的值

? ? Vector3 m_targetTransform;

? ? Vector3 m_targetPos;

? ? //

? ? public float maxOffsetX = 10f;? ? // 最大傾斜角 35?

? ? public float maxOffsetY = 10f;? ? // 最大傾斜角 35

? ? public float maxOffsetZ = 1f;? ? // 最大傾斜角 35

? ? public float posFactor = 0f;? ? // 位移的系數(shù)

? ? public float lerpFactor = 5f;? ? // 差值系數(shù)

? ? ///////////////////////

? ? private bool isGyro = true;

? ? private Button m_btn;

? ? private InputField m_inputField1;

? ? private InputField m_inputField2;

? ? private InputField m_inputField3;

? ? private InputField m_inputField4;

? ? private InputField m_inputField5;

? ? void Awake()

? ? {

? ? ? ? m_targetTransform = Vector3.zero;

? ? ? ? m_targetPos = Vector3.zero;

? ? ? ? //Input.gyro.enabled = true;

? ? }

? ? void Start()

? ? {

? ? ? ? m_btn = transform.Find("Node/Button").GetComponent();? ? ?

? ? ? ? m_inputField1 = transform.Find("Node/InputField1").GetComponent();

? ? ? ? m_inputField2 = transform.Find("Node/InputField2").GetComponent();

? ? ? ? m_inputField3 = transform.Find("Node/InputField3").GetComponent();

? ? ? ? m_inputField4 = transform.Find("Node/InputField4").GetComponent();

? ? ? ? m_inputField5 = transform.Find("Node/InputField5").GetComponent();

? ? ? ? m_btn.onClick.AddListener(OnButton);? ? ?

? ? ? ? m_inputField1.onEndEdit.AddListener(OnInputEnd1);

? ? ? ? m_inputField2.onEndEdit.AddListener(OnInputEnd2);

? ? ? ? m_inputField3.onEndEdit.AddListener(OnInputEnd3);

? ? ? ? m_inputField4.onEndEdit.AddListener(OnInputEnd4);

? ? ? ? m_inputField5.onEndEdit.AddListener(OnInputEnd5);

? ? }

? ? public void OnButton()

? ? {

? ? ? ? isGyro = !isGyro;

? ? ? ? target.transform.localPosition = Vector3.zero;

? ? ? ? target.transform.localRotation = Quaternion.identity;

? ? }

? ? public void OnInputEnd1(string strValue_)

? ? {

? ? ? ? maxOffsetX = Convert.ToInt32(strValue_);

? ? }

? ? public void OnInputEnd2(string strValue_)

? ? {

? ? ? ? maxOffsetY = Convert.ToInt32(strValue_);

? ? }

? ? public void OnInputEnd3(string strValue_)

? ? {

? ? ? ? maxOffsetZ = Convert.ToInt32(strValue_);

? ? }

? ? public void OnInputEnd4(string strValue_)

? ? {

? ? ? ? posFactor = Convert.ToInt32(strValue_);

? ? }

? ? public void OnInputEnd5(string strValue_)

? ? {

? ? ? ? lerpFactor = Convert.ToInt32(strValue_);

? ? }

? ? //運(yùn)用手機(jī)的X軸的變化來(lái)改變target對(duì)象的Y軸旋轉(zhuǎn),X軸移動(dòng); Y軸的變化來(lái)改變target對(duì)象的X軸旋轉(zhuǎn),Y軸移動(dòng);Z軸的變化只去改變target對(duì)象的Z軸位置

? ? void LateUpdate()

? ? {

? ? ? ? if (target == null)

? ? ? ? ? ? return;

? ? ? ? if (!isGyro)

? ? ? ? ? ? return;

? ? ? ? m_MobileOrientation = Input.acceleration;

? ? ? ? m_targetTransform.x = Mathf.Lerp(m_targetTransform.x, m_MobileOrientation.y * maxOffsetY, Time.deltaTime * lerpFactor);

? ? ? ? m_targetTransform.y = Mathf.Lerp(m_targetTransform.y, -m_MobileOrientation.x * maxOffsetX, Time.deltaTime * lerpFactor);

? ? ? ? m_targetTransform.z = Mathf.Lerp(m_targetTransform.z, (-m_MobileOrientation.x) * maxOffsetZ, Time.deltaTime * lerpFactor);

? ? ? ? m_targetPos.x = m_targetTransform.x;

? ? ? ? m_targetPos.y = m_targetTransform.y;

? ? ? ? m_targetPos.z = m_targetTransform.z;

? ? ? ? target.transform.localPosition = Vector3.Lerp(target.transform.localPosition, m_targetPos * posFactor, Time.deltaTime * lerpFactor);

? ? ? ? target.transform.localRotation = Quaternion.Euler(m_targetTransform);

? ? ? ? //target.transform.localRotation = Quaternion.Lerp(target.transform.localRotation, Quaternion.Euler(m_targetTransform), Time.deltaTime * lerpFactor);

? ? }

? ? protected void OnGUI()

? ? {

? ? ? ? if (target == null)

? ? ? ? ? ? return;

? ? ? ? GUILayout.Label("Input.acceleration: " + Input.acceleration);

? ? ? ? GUILayout.Label("Target localPosition: " + target.transform.localPosition);

? ? ? ? GUILayout.Label("Target localRotation: " + target.transform.localRotation);

? ? }

}

最終的游戲測(cè)試界面如下圖,僅供策劃調(diào)試參數(shù)用:


?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容