1. 程式人生 > >在unity中實現方向盤UI的隨著觸控轉動和手指離開復位功能

在unity中實現方向盤UI的隨著觸控轉動和手指離開復位功能

      遇到的需求是 方向盤模擬模擬UI,旋轉是按住方向盤轉動,限制只能左轉一圈半和右轉一圈半,鬆手時方向盤自動復位。

      先上最終效果圖:

      

      下面說一下具體實現過程。首先是要實現方向盤跟著滑鼠位置旋轉。思路是按下滑鼠後每一幀都記錄按下的點跟以方向盤0中心為座標原點的y座標軸的角度,如下圖黃色∠1所示(黑點為滑鼠上一幀位置,紅點為滑鼠當前幀位置)

     

      然後用當前幀角度藍色∠2跟上一幀角度黃色∠1比較,得出一個差值黑色∠3。用transform.Rotate()方法旋轉這個差值即可讓方向盤跟著滑鼠轉動。

      第二個需求是讓方向盤左右旋轉不能超過一圈半,也就是450°。這個需求的實現是自定義一個float欄位,用來記錄旋轉的總角度,用∠1和∠2的差值正負判定當前滑鼠是在順時針轉還是逆時針轉,判定當前角度對於總角度是加還是減。

      這兒說一下unity自帶的倆方法:

      Vector3.Angle(Vector3 from,Vector3 to) 這個方法用來計算兩個位置相對於座標(0,0,0)的夾角,返回的值始終在[0,180]之間。

      Vector3.Cross(Vector3 lhs,Vector3 rhs)這個方法用來計算兩個位置的叉乘結果,返回一個Vector3 v3,計算順逆時針是在平面內進行的,忽略y軸,則v3.z>0,rhs在lhs的順時針方向;v3.z = 0,rhs跟lhs平行;v3.z<0,rhs在lhs的逆時針方向。

      (關於點乘叉乘更詳細的介紹戳: http://blog.csdn.net/liqiangeastsun/article/details/50331933)

      復位很簡單,就是監測到滑鼠放開方向盤時讓之前說的記錄旋轉的總角度遞加或者遞減至0,讓方向盤角度等於這個總角度就可以了。

      以下是程式碼:

public Canvas CanvasRoot;//畫布 
    private RectTransform m_RectTransform;//座標

    private bool m_IsFirst = true;           //用於記錄第一幀按下滑鼠時滑鼠的位置,便於計算
    private Vector3 m_CurrentPos;            //記錄當前幀滑鼠所在位置
    private bool m_IsClockwise;              //是否順時針
    private float m_RoundValue = 0;          //記錄總的旋轉角度 用這個數值來控制一圈半
    private bool m_IsTuringSteeringWheel;    //是否在轉方向盤 用這個判斷復位

    void Start()
    {
        CanvasRoot = GameObject.Find("Canvas").GetComponent<Canvas>();
        m_RectTransform = CanvasRoot.transform as RectTransform;
    }


    void Update()
    {

        if (Input.GetMouseButton(0) && EventSystem.current.currentSelectedGameObject == gameObject)                 //當滑鼠點選到方向盤時
        {
            m_IsTuringSteeringWheel = true;
            Vector2 pos;
            if (RectTransformUtility.ScreenPointToLocalPointInRectangle(m_RectTransform, Input.mousePosition, CanvasRoot.worldCamera, out pos))    //獲取滑鼠點選位置
            {

                pos.x = pos.x + (Screen.width / 2) - GetComponent<RectTransform>().position.x;
                pos.y = pos.y + (Screen.height / 2) - GetComponent<RectTransform>().position.y;

                Vector3 pos3 = new Vector3(pos.x, pos.y, 0);                           //計算後滑鼠以方向盤圓心為座標原點的座標位置

                if (m_IsFirst)
                {
                    m_CurrentPos = pos3;
                    m_IsFirst = false;
                }

                Vector3 currentPos = Vector3.Cross(pos3, m_CurrentPos);             //計算當前幀和上一幀手指位置 用於判斷旋轉方向
                if (currentPos.z > 0)
                {
                    m_IsClockwise = true;
                }
                else if (currentPos.z < 0)
                {
                    m_IsClockwise = false;
                }

                if(m_CurrentPos != pos3)                                 //範圍內讓方向盤隨著手指轉動
                {
                    if(m_IsClockwise)
                    {
                        if (m_RoundValue <= 540)
                        {
                            m_RoundValue += Vector3.Angle(m_CurrentPos, pos3);

                            transform.Rotate(new Vector3(0, 0, -Vector3.Angle(m_CurrentPos, pos3)));
                        }
                    }

                    else
                    {
                        if (m_RoundValue >= -540)
                        {
                            m_RoundValue -= Vector3.Angle(m_CurrentPos, pos3);

                            transform.Rotate(new Vector3(0, 0, Vector3.Angle(m_CurrentPos, pos3)));
                        }
                    }

                }
                m_CurrentPos = pos3;

            }

        }
        if (Input.GetMouseButtonUp(0))
        {
            m_IsFirst = true;
            m_IsTuringSteeringWheel = false;
        }

        if (!m_IsTuringSteeringWheel && m_RoundValue != 0)               //復位
        {
            if (m_RoundValue >= 0)
            {
                m_RoundValue -= 8f;               //復位速度
                if (m_RoundValue < 0)
                    m_RoundValue = 0;
                transform.rotation = Quaternion.Euler(new Vector3(0, 0, -m_RoundValue));
            }
            else
            {

                m_RoundValue += 8f;
                if (m_RoundValue > 0)
                    m_RoundValue = 0;
                transform.rotation = Quaternion.Euler(new Vector3(0, 0, -m_RoundValue));

            }
        }
    }
}

相關推薦

unity實現方向盤UI隨著觸控轉動手指離開復位功能

      遇到的需求是 方向盤模擬模擬UI,旋轉是按住方向盤轉動,限制只能左轉一圈半和右轉一圈半,鬆手時方向盤自動復位。       先上最終效果圖:              下面說一下具體實現過程。首先是要實現方向盤跟著滑鼠位置旋轉。思路是按下滑鼠後每一幀都記錄按下

unity實現三個Logo圖片進行3秒鐘的若隱若現後互相切換Logo圖片

date += srp val logs ima 精靈 texture 透明 private List<Sprite> storeTexture; public void Start() { storeTextu

關於Unity實現繩索物理效果 Obi - Advanced Rope Simulation插件解析

阻尼 旋轉 eval mil 抖動 amp ola all 動作 Obi - Advanced Rope Simulation 繩索插件學習文檔 插件分享: 鏈接:https://pan.baidu.com/s/1eTwZOrg 密碼:p8wa //插件導入有錯誤產生,將

Unite 2018 | 《崩壞3》:在Unity實現高品質的卡通渲染

width diffuse 動態生成 LG 編輯 www. tgs term 謝謝 本篇文章為Unity官方論壇發布的文章 由於全是幹貨,為了方便自己查找,也為了避免刪除找不到了 於是復制了過來。。。 原文地址: http://forum.china.unity3d.c

C#或unity實現正弦函式

C#或unity中實現正弦函式 本類用於第一,需要繪製一條正弦曲線的朋友;第二,需要根據正弦曲線控制物體運動的朋友;裡面都有註釋,程式碼如下: unity中使用的程式碼: public class Curvy_Sin { /// <summary> /// 週期

Unity實現控制物體以自定義的速度沿Y軸旋轉90度(也可自定義度數)後停止,然後返回原來位置

1、需要控制沿Y軸旋轉的物體,如下所示: 2、編寫控制該物體旋轉的指令碼,如下所示:  using UnityEngine; using System.Collections; public class Test_CycleRoate : MonoBehaviour {

unity實現簡單的程式紋理 10.3.1

using UnityEngine; using System.Collections; using System.Collections.Generic; //在unity中實現簡單的程式紋理 10.3.1 //在編輯模式執行 [ExecuteInEditMo

Unity實現相機抖動特效

為了增加遊戲的真實感,一般我們會為遊戲新增一些螢幕抖動特效。下面簡單介紹幾種實現方式: 1.通過指令碼 相機抖動實現: using UnityEngine; using System.Collections; public class Came

初探CardBoard:(1)在Unity實現簡單VR場景

為何使用CardBoard 現在的VR越來越流行,各種裝置也是百花齊放。然而,對於研究VR剛剛起步的小白來說,昂貴的裝置(例如HTC)並不一定是最佳選擇。那麼Google 的CardBoard就映入了我眼前。 價格低廉 使用它僅僅需要以下裝置: 一個光學盒子

Unity實現一個狀態機

維基百科:有限狀態機(英語:finite-state machine,縮寫:FSM)又稱有限狀態自動機,簡稱狀態機,是表示有限個狀態以及在這些狀態之間的轉移和動作等行為的數學模型。 本文參照quick

unity實現一個類似x光掃描效果

先來看下效果:原理很簡單,首先獲取頂點到攝像機的觀察方向,然後與頂點的法線方向進行點積算出投影的長度最後再乘以我們設定的顏色值即為最終要輸出的顏色。這裡要注意觀察方向與法線方向要進行歸一化。shader程式碼:Shader "Custom/XLight" { Propert

如何在Unity實現文字的漸隱效果?

 1.首先建立一個GUIText物件。2.在Project面板中新建一個C#指令碼命名為FadingMessage,雙擊該指令碼進行編輯,新增如下程式碼。 using UnityEngine; using System.Collections;   public clas

unity實現一個光照越強透明度越高的shader

可能描述的不清楚,先看下效果: 就是這樣,被燈光照亮的部分,會變透明,而且越亮透明度越高。 這裡主要就是通過計算當先位置的法線在燈光方向上的投影大小,投影越大則亮度越高, 因為透明度為0-1,所這裡我們把(1-亮度)作為透明度即可。 完整的shader程式碼: Shad

Unity實現TreeView

在Unity中要實現如下的樹形狀結構顯示,是比較複雜的,相比於專門做二維的軟體,效果也不咋樣;但想想畢竟Unity主要是開發三維場景的工具,用來做二維介面確實有點可笑,但是也不是說不能實現,只要Unity有Image,那什麼都是可以實現的...【Demo下載地址】 如何實

unity實現鍵盤打字的效果

UI中的設定如圖所示: 其中Text指令碼中的程式碼如下所示: using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEn

Unity實現FSM有限狀態機

簡介 有限狀態機,(英語:Finite-state machine, FSM),又稱有限狀態自動機,簡稱狀態機,是表示有限個狀態以及在這些狀態之間的轉移和動作等行為的數學模型 -- 引用百度百科的解釋: 有限狀態機(FSM)是遊戲AI的一種常用模型,我做一個簡單的

unity實現簡單物件池,附教程原理

Unity物件池的建立與使用 本文提供全流程,中文翻譯。 Chinar 堅持將簡單的生活方式,帶給世人!(擁有更好的閱讀體驗 —— 高解析度使用者請根據需求調整網頁縮放比例) Chinar —— 心分享、心創新!助力快速完成 Unity

Unity實現Camera縮放旋轉

先上效果圖:把縮放和旋轉分開說吧縮放:原理很簡單:1.先儲存相機與玩家的的位置偏移offset2.獲取使用者輸入(滾輪)3.將滾輪輸入乘一個合理的係數,也可以稱為縮放速度啦4.將offset數值更新ps:第四步用到了vector3.normalized,首先獲取到offset

Unity實現放大鏡的功能

以上方式用於實現3D世界中的放大鏡效果很好,但是,如果需要實現UI中介面元素的區域性放大,則會稍微複雜一點,具體的方式,我做了一個演示專案,可以在演示專案中檢視,地址工程:https://github.com/USuperMe/Mangnifier

unity實現機械臂的模擬操作的方法

最近需要在專案中用unity3D實現一個多自由度機械臂的模擬,由於是模擬而不是做遊戲,所以對位置、速度還有時間控制方面的要求比較嚴格,本文中機械臂的實現只涉及運動學而不考慮動力學等。傳統方法中實現機械臂可以採用hingejoint(鉸鏈關節)來實現,鉸鏈關節的具體方法詳見un