日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Unity实现安卓虚拟摇杆多点触控

發(fā)布時間:2023/12/14 编程问答 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 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.TouchCountint, 觸控點數(shù)量,即當前按下的手指數(shù)
Input.touchesTouch[],當前所有的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>();//fingerId與搖桿的映射private List<JoyStick> joyList = new List<JoyStick>();//UI上所有的搖桿public void AddJoy(JoyStick joy){joyList.Add(joy);//添加搖桿,由JoyStick在開始時調(diào)用}// Update is called once per framevoid Update(){foreach(var touch in Input.touches)//遍歷所有的觸控點{if(touch.phase == TouchPhase.Began)//有新的觸控點{foreach(var joy in joyList){ if (joy.inTouchArea(touch.position) //判斷是否在可觸控范圍內(nèi)&& !id2JoyDic.ContainsValue(joy)) //如果對應(yīng)的搖桿已經(jīng)有觸控點就忽略{id2JoyDic.Add(touch.fingerId, joy);//加入新的觸控點,綁定搖桿}}}if (id2JoyDic.ContainsKey(touch.fingerId))//如果該觸控點已經(jīng)綁定了搖桿{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 float xAxis = 0;//public float yAxis = 0;public UnityEvent onDown,onDrag,onUp;//按下、滑動、抬起的事件// Start is called before the first frame updatevoid Start(){if (isFixedArea){touchArea = circle;//如果固定位置,則把可觸控區(qū)域設(shè)為大圈的區(qū)域}else{touchArea = this.GetComponent<RectTransform>();}maxOffset = Mathf.Min(circle.rect.width, circle.rect.height)/2;//計算大圈的最小半徑作為小圈的最大移動距離touchEvent.AddJoy(this);//注冊搖桿}/// <summary>/// 讀取觸控操作,由TouchEvent調(diào)用/// </summary>/// <param name="touch"></param>public void ReadTouch(Touch touch){if(touch.phase == TouchPhase.Began){//如果手指按下circle.position = touch.position;//把大圈移動到手指按下的位置onDown.Invoke();//觸發(fā)按下事件}else if(touch.phase == TouchPhase.Moved || touch.phase == TouchPhase.Stationary){//如果手指已經(jīng)按下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;//限制搖桿的移動}//xAxis = offset.x / maxOffset;//計算歸一化偏移量//yAxis = offset.y / maxOffset;//print(string.Format("xAxis: {0} -- yAxis: {1}", xAxis, yAxis));onDrag.Invoke();//觸發(fā)滑動事件}else if(touch.phase == TouchPhase.Ended){//如果手指抬起point.position = circle.position;//重置小圈的位置到大圈的中心onUp.Invoke();//觸發(fā)抬起事件}}/// <summary>/// 判斷某一點是否在可觸控范圍(矩形)內(nèi),由TouchEvent調(diào)用/// </summary>/// <param name="pos"></param>/// <returns></returns>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.cst掛在任意物體上,我這里掛在了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)容還不錯,歡迎將生活随笔推薦給好友。