生活随笔
收集整理的這篇文章主要介紹了
Unity实现安卓虚拟摇杆多点触控
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
代碼示例在最下面 效果如圖:
1. Unity對于觸屏操作的支持
1.1. Touch結(jié)構(gòu)體
Unity使用結(jié)構(gòu)體Touch定義觸屏設(shè)備的輸入,每一個觸控點(可以理解為每一個手指)對應(yīng)一個Touch,其中主要的屬性如下:
屬性含義 fingerId 觸控點的編號,在該觸控點的生命周期內(nèi)(從點下到抬起)是不變的 phase 觸控點的狀態(tài),是一個Touch.Phase枚舉,包括: Began(手指按下), Move(手指滑動), Stationary(手指已經(jīng)按下且保持不動), Ended(手指抬起), Canceled(系統(tǒng)停止跟蹤該觸控點) position 觸控點在屏幕的坐標(屏幕坐標系)
其他的屬性參考https://docs.unity3d.com/ScriptReference/Touch.html
1.2. fingerId分配
需要注意的是對于fingerId的分配,類似于下面的過程: 使用一個數(shù)組表示哪些觸控點當前被激活,初始為: [0][0][0][0][0] 其中0表示未激活,1表示已激活。每按下一個手指時,從頭尋找第一個未激活的空位,把它的索引賦給fingerId,例如按下第一個手指后,數(shù)組變?yōu)?#xff1a; [1][0][0][0][0] 手指①的fingerId=0,這個時候再按下第二個手指,數(shù)組變?yōu)?#xff1a; [1][1][0][0][0] 手指①的fingerId=0,手指②的fingerId=1,這個時候松開第一個手指,數(shù)組變?yōu)?#xff1a; [0][1][0][0][0] 手指②的fingerId不變,還是1,這時候再按下第三個手指,數(shù)組變?yōu)?#xff1a; [1][1][0][0][0] 手指②的fingerId不變,還是1,把數(shù)組的0號為給手指③,因此手指③的fingerId=0
1.3. Input類
Untiy的Input類中與Touch有關(guān)的API如下:
函數(shù)含義 Input.TouchCount int, 觸控點數(shù)量,即當前按下的手指數(shù) Input.touches Touch[],當前所有的Touch結(jié)構(gòu)體數(shù)組 Input.GetTouch(int index) 返回第index個Touch,index與fingerId無關(guān) Input.multiTouchEnabled{get;set;} 是否支持多點觸控
2. 多點觸控
當存在多個搖桿時,需要控制每個搖桿對應(yīng)的fingerId,這里把搖桿類命名為JoyStick ,另外定義一個控制類TouchEvent 用于管理Touch與JoyStick的對應(yīng)關(guān)系,TouchEvent在每次Update中讀取所有的Touch:
如果是新按下的就判斷是否處于某個搖桿的可觸發(fā)區(qū)域,如果是就綁定,并讓該搖桿讀取該Touch; 如果是已經(jīng)按下的手指就判斷是否有綁定的搖桿,如果有就讓該搖桿讀取該Touch; 如果是抬起的手指,也先判斷是否有綁定并讀取,然后移除這個綁定
代碼如下: TouchEvent.cs
using System. Collections ;
using System. Collections. Generic ;
using UnityEngine ; public class TouchEvent : MonoBehaviour
{ private Dictionary< int , JoyStick> id2JoyDic
= new Dictionary< int , JoyStick> ( ) ; private List< JoyStick> joyList
= new List< JoyStick> ( ) ; public void AddJoy ( JoyStick joy
) { joyList
. Add ( joy
) ; } void Update ( ) { foreach ( var touch
in Input
. touches
) { if ( touch
. phase
== TouchPhase
. Began
) { foreach ( var joy
in joyList
) { if ( joy
. inTouchArea ( touch
. position
) && ! id2JoyDic
. ContainsValue ( joy
) ) { id2JoyDic
. Add ( touch
. fingerId
, joy
) ; } } } if ( id2JoyDic
. ContainsKey ( touch
. fingerId
) ) { id2JoyDic
[ touch
. fingerId
] . ReadTouch ( touch
) ; if ( touch
. phase
== TouchPhase
. Canceled
|| touch
. phase
== TouchPhase
. Ended
) { id2JoyDic
. Remove ( touch
. fingerId
) ; } } } }
}
3. 搖桿實現(xiàn)思路
搖桿就是一個大圈+一個小圈組成,并且有一個可以觸發(fā)的區(qū)域,如圖: 矩形白色區(qū)域代表可以開始觸控的區(qū)域,當手指按下時,把大圈的位置設(shè)為Touch的position,當手指滑動時,讓小圈跟著動,并且限制它相對大圈的最大距離。 代碼如下: JoyStick.cs
using System. Collections ;
using System. Collections. Generic ;
using UnityEngine ;
using UnityEngine. Events ;
using UnityEngine. UI ; public class JoyStick : MonoBehaviour
{ public TouchEvent touchEvent
; public bool isFixedArea
= false ; private RectTransform touchArea
; public RectTransform circle
; public RectTransform point
; private float maxOffset
; public UnityEvent onDown
, onDrag
, onUp
; void Start ( ) { if ( isFixedArea
) { touchArea
= circle
; } else { touchArea
= this . GetComponent < RectTransform> ( ) ; } maxOffset
= Mathf
. Min ( circle
. rect
. width
, circle
. rect
. height
) / 2 ; touchEvent
. AddJoy ( this ) ; } public void ReadTouch ( Touch touch
) { if ( touch
. phase
== TouchPhase
. Began
) { circle
. position
= touch
. position
; onDown
. Invoke ( ) ; } else if ( touch
. phase
== TouchPhase
. Moved
|| touch
. phase
== TouchPhase
. Stationary
) { Vector3 prePointPos
= point
. position
; Vector3 offset
= new Vector3 ( touch
. position
. x
, touch
. position
. y
, 0 ) - prePointPos
; point
. position
+= offset
; if ( ( point
. position
- circle
. position
) . magnitude
> maxOffset
) { point
. position
= circle
. position
+ ( point
. position
- circle
. position
) . normalized
* maxOffset
; } onDrag
. Invoke ( ) ; } else if ( touch
. phase
== TouchPhase
. Ended
) { point
. position
= circle
. position
; onUp
. Invoke ( ) ; } } public bool inTouchArea ( Vector2 pos
) { Rect rect
= touchArea
. rect
; rect
. x
+= touchArea
. position
. x
; rect
. y
+= touchArea
. position
. y
; return rect
. Contains ( pos
) ; } public void OnDownTest ( ) { print ( "down" ) ; } public void OnDragTest ( ) { print ( "drag" ) ; } public void OnUpTest ( ) { print ( "up" ) ; }
}
4. 代碼使用
把TouchEven.cs t掛在任意物體上,我這里掛在了EventSystem上 每一個搖桿如圖中紅框所示,
Joy1是一個panel,它在屏幕上的大小就代表了可觸發(fā)的區(qū)域 circle是image,表示大圈 joy是image,表示小圈 三個搖桿場景如圖: 把JoyStick.cs掛在Joy1上,把circle賦給circle,joy賦給point,把TouchEvent也賦好值,如圖:
5. 在手機上實時調(diào)試
在手機上安裝Unity Remote app ,下載鏈接: 鏈接:https://pan.baidu.com/s/1moiz-4It5euHtpd86cLwgQ 提取碼:z0fy 在Unity中點擊edit->project settings,設(shè)置Editor,如圖: 手機打開USB調(diào)試,連接電腦,然后運行,記得調(diào)整好分辨率
總結(jié)
以上是生活随笔 為你收集整理的Unity实现安卓虚拟摇杆多点触控 的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔 網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔 推薦給好友。