Unity 之 移动设备的触控操作

Posted mimime

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Unity 之 移动设备的触控操作相关的知识,希望对你有一定的参考价值。

http://blog.csdn.net/anyuanlzh/article/details/18367941

 

    这篇博文将简单的记录,如何用unity处理在移动设备上的触控操作。
    iOSAndroid设备能够支持多点触控。在unity中你可以通过Input.touches属性集合访问在最近一帧中触摸在屏幕上的每一根手指的状态数据。简单的触控响应实现起很简单,不过一些复杂的触控响应或触控手势什么的,还是使用一些第三方的插件吧,当然你也可以自己封装。不管什么情况,了解决unity原生api还是非常必要的。    

相关的api
    1、Toch类:用来记录一个手指触摸在屏幕上的状态与位置的各种相关数据。这其它中只有两个属性是你要注意的,就是Touch.fingerId和Touch.tapCount。
               Touch.fingerId: 一个Touch的标识。Input.touches数组中的同一个索引在两帧之前,指向的可不一定是同一个Touch。用来标识某个具体的touch一定要用fingerId,在分析手势时、或处理多点触控时,fingerId是非常重要的。
               Touch.tapCount: 点击的总人数,这个属性可以用来模拟“双击”的效果。
               这里先普及一个概念吧,一个touch的生命周期是:当一个手指接触到触屏时,产生一个Touch,并分配它一个fingerId,到这个手指离开触屏这个touch就有了。在它整个生命周期里,它的figerId是不会变的。死掉的touch所使用过fingerId当也会被之后的touch多次使用。ps:其实也不是手指一离开,这个touch就立马死掉。还有一种特殊的情况就是:在手指敲开的地方,在一个很短的时间内,一个手指又回到这个地方的话,这个touch没不会死掉,这个也是Touch.tapCount属于的由来吧。这个touch生命周期,是我自己理解的,实际情况是不是这样就不知道了,料想也不会差的太多。
    2、TouchPhase枚举:它列表描述了手指触摸的几种状态。对应Touch类中的phase属性。这是状态分别是:Began、Move、Stationary、Ended、Canceled。
    3、Input.touches:一个Touch数组,代表着当前帧,所有手指在屏幕上的触碰状态与相关数据。(只读)
    4、Input.touchCount: 触摸数量,相当于Input.touches.Length。(只读)
    5、Input.multiTouchEnabled:设置与指示当前系统(注意不是指设备哦!)是否启用多点触控。不过这个属性有点怪,我在电脑上测试给它赋false不会报错但完全是没有用的,它的值一值是true. 不过在我的安卓手机上测试是正常的!Ture表示支持多点触控(一般是5点);False表示单点触控。
    6、Input.GetTouch(int index):安索引值获取一个Touch对象。

下面一个测试Demo
1、简述:
         这个Demo主要是让你的触摸可视化的显示在你的手机(或平板)屏幕上;
         并实时记录和显示了手指在屏幕上的状态和相关数据。
2、相关截图:
技术分享
3、脚本就一个

[csharp] view plain copy
 
 技术分享技术分享
  1. /* 
  2.  * author: AnYuanLzh 
  3.  * date:   2014/01/18 
  4.  * */  
  5. using UnityEngine;  
  6. using System.Collections;  
  7. using System.Collections.Generic;  
  8.   
  9.   
  10. public class MyTouch : MonoBehaviour  
  11. {  
  12.     /// <summary>  
  13.     /// 定义的一个手指类  
  14.     /// </summary>  
  15.     class MyFinger  
  16.     {  
  17.         public int id = -1;  
  18.         public Touch touch;  
  19.   
  20.         static private List<MyFinger> fingers = new List<MyFinger>();  
  21.         /// <summary>  
  22.         /// 手指容器  
  23.         /// </summary>  
  24.         static public List<MyFinger> Fingers  
  25.         {  
  26.             get  
  27.             {  
  28.                 if(fingers.Count==0)  
  29.                 {  
  30.                     for(int i=0; i<5; i++)  
  31.                     {  
  32.                         MyFinger mf = new MyFinger();  
  33.                         mf.id = -1;  
  34.                         fingers.Add(mf);  
  35.                     }  
  36.                 }  
  37.                 return fingers;  
  38.             }  
  39.         }  
  40.   
  41.     }  
  42.   
  43.     // 小圈圈:用来实时显示手指触摸的位置  
  44.     GameObject[] marks = new GameObject[5];  
  45.     public GameObject markPerfab = null;  
  46.   
  47.     // 粒子效果:来所显示手指手动的大概路径  
  48.     ParticleSystem[] particles = new ParticleSystem[5];  
  49.     public ParticleSystem particlePerfab = null;  
  50.   
  51.   
  52.     // Use this for initialization  
  53.     void Start ()  
  54.     {  
  55.         // init marks and particles  
  56.         for(int i=0; i<MyFinger.Fingers.Count; i++)  
  57.         {  
  58.             GameObject mark = Instantiate(markPerfab, Vector3.zero, Quaternion.identity) as GameObject;  
  59.             mark.transform.parent = this.transform;  
  60.             mark.SetActive(false);  
  61.             marks[i] = mark;  
  62.   
  63.             ParticleSystem particle = Instantiate(particlePerfab, Vector3.zero, Quaternion.identity) as ParticleSystem;  
  64.             particle.transform.parent = this.transform;  
  65.             particle.Pause();  
  66.             particles[i] = particle;  
  67.         }  
  68.     }  
  69.       
  70.     // Update is called once per frame  
  71.     void Update ()  
  72.     {  
  73.         Touch[] touches = Input.touches;  
  74.   
  75.         // 遍历所有的已经记录的手指  
  76.         // --掦除已经不存在的手指  
  77.         foreach(MyFinger mf in MyFinger.Fingers)  
  78.         {  
  79.             if(mf.id == -1)  
  80.             {  
  81.                 continue;  
  82.             }  
  83.             bool stillExit = false;  
  84.             foreach(Touch t in touches)  
  85.             {  
  86.                 if(mf.id == t.fingerId)  
  87.                 {  
  88.                     stillExit = true;  
  89.                     break;  
  90.                 }  
  91.             }  
  92.             // 掦除  
  93.             if(stillExit == false)  
  94.             {  
  95.                 mf.id = -1;  
  96.             }  
  97.         }  
  98.         // 遍历当前的touches  
  99.         // --并检查它们在是否已经记录在AllFinger中  
  100.         // --是的话更新对应手指的状态,不是的放放加进去  
  101.         foreach(Touch t in touches)  
  102.         {  
  103.             bool stillExit = false;  
  104.             // 存在--更新对应的手指  
  105.             foreach(MyFinger mf in MyFinger.Fingers)  
  106.             {  
  107.                 if(t.fingerId == mf.id)  
  108.                 {  
  109.                     stillExit = true;  
  110.                     mf.touch = t;  
  111.                     break;  
  112.                 }  
  113.             }  
  114.             // 不存在--添加新记录  
  115.             if(!stillExit)  
  116.             {  
  117.                 foreach(MyFinger mf in MyFinger.Fingers)  
  118.                 {  
  119.                     if(mf.id == -1)  
  120.                     {  
  121.                         mf.id = t.fingerId;  
  122.                         mf.touch = t;  
  123.                         break;  
  124.                     }  
  125.                 }  
  126.             }  
  127.         }  
  128.   
  129.         // 记录完手指信息后,就是响应相应和状态记录了  
  130.         for(int i=0; i< MyFinger.Fingers.Count; i++)  
  131.         {  
  132.             MyFinger mf = MyFinger.Fingers[i];  
  133.             if(mf.id != -1)  
  134.             {  
  135.                 if(mf.touch.phase == TouchPhase.Began)  
  136.                 {  
  137.                     marks[i].SetActive(true);  
  138.                     marks[i].transform.position = GetWorldPos(mf.touch.position);  
  139.   
  140.                     particles[i].transform.position = GetWorldPos(mf.touch.position);  
  141.                 }  
  142.                 else if(mf.touch.phase == TouchPhase.Moved)  
  143.                 {  
  144.                     marks[i].transform.position = GetWorldPos(mf.touch.position);  
  145.   
  146.                     if(!particles[i].isPlaying)  
  147.                     {  
  148.                         particles[i].loop = true;  
  149.                         particles[i].Play();  
  150.                     }  
  151.                     particles[i].transform.position = GetWorldPos(mf.touch.position);  
  152.                 }  
  153.                 else if(mf.touch.phase == TouchPhase.Ended)  
  154.                 {  
  155.                     marks[i].SetActive(false);  
  156.                     marks[i].transform.position = GetWorldPos(mf.touch.position);  
  157.   
  158.                     particles[i].loop = false;  
  159.                     particles[i].Play();  
  160.                     particles[i].transform.position = GetWorldPos(mf.touch.position);  
  161.                 }  
  162.                 else if(mf.touch.phase == TouchPhase.Stationary)  
  163.                 {  
  164.                     if(particles[i].isPlaying)  
  165.                     {  
  166.                         particles[i].Pause();  
  167.                     }  
  168.                     particles[i].transform.position = GetWorldPos(mf.touch.position);  
  169.                 }  
  170.             }  
  171.             else  
  172.             {  
  173.                 ;  
  174.             }  
  175.         }  
  176.   
  177.         // exit  
  178.         if(Input.GetKeyDown(KeyCode.Home) || Input.GetKeyDown(KeyCode.Escape))  
  179.         {  
  180.             Application.Quit();  
  181.         }  
  182.   
  183. //      // test  
  184. //      if(Input.GetMouseButtonDown(0))  
  185. //      {  
  186. //          GameObject mark = Instantiate(markPerfab, Vector3.zero, Quaternion.identity) as GameObject;  
  187. //          mark.transform.parent = this.transform;  
  188. //          mark.transform.position = GetWorldPos(Input.mousePosition);  
  189. //  
  190. //          ParticleSystem particle = Instantiate(particlePerfab, Vector3.zero, Quaternion.identity) as ParticleSystem;  
  191. //          particle.transform.parent = this.transform;  
  192. //          particle.transform.position = GetWorldPos(Input.mousePosition);  
  193. //          particle.loop = false;  
  194. //          particle.Play();  
  195. //      }  
  196.     }  
  197.   
  198.     /// <summary>  
  199.     /// 显示相关高度数据  
  200.     /// </summary>  
  201.     void OnGUI()  
  202.     {  
  203.         GUILayout.Label("支持的手指的数量:" + MyFinger.Fingers.Count);  
  204.         GUILayout.BeginHorizontal(GUILayout.Width(Screen.width));  
  205.         for(int i=0; i< MyFinger.Fingers.Count; i++)  
  206.         {  
  207.             GUILayout.BeginVertical();  
  208.             MyFinger mf = MyFinger.Fingers[i];  
  209.             GUILayout.Label("手指" + i.ToString());  
  210.             if(mf.id != -1)  
  211.             {  
  212.                 GUILayout.Label("Id: " + mf.id);  
  213.                 GUILayout.Label("状态: " + mf.touch.phase.ToString());  
  214.             }  
  215.             else  
  216.             {  
  217.                 GUILayout.Label("没有发现!");  
  218.             }  
  219.             GUILayout.EndVertical();  
  220.         }  
  221.         GUILayout.EndHorizontal();  
  222.     }  
  223.   
  224.     public Vector3 GetWorldPos(Vector2 screenPos)  
  225.     {  
  226.         return Camera.main.ScreenToWorldPoint(new Vector3(screenPos.x, screenPos.y, Camera.main.nearClipPlane + 10));  
  227.     }  
  228.   
  229.   
  230. }  

 

4、相关下载(点下面的链接)
           项目文件 和 发布好的apk,下载点这里(不需要下载积分)。
   注:这个apk对android系统的要求是Android4.0及以上版本。

如有转载请在文首注明出处,AnYuanLzh:http://blog.csdn.net/anyuanlzh/article/details/18367941



















以上是关于Unity 之 移动设备的触控操作的主要内容,如果未能解决你的问题,请参考以下文章

Unity Notes之屏幕触点轨迹的平滑

安卓Tv开发移动智能电视之焦点控制(触控事件)

某地市移动城域网络运维架构分析以及日常工作

unity 在mac 中 怎么用触控板 让界面旋转

怎么改变swiper2点击按钮之后就不能自动播放

Swiper之初识