Unity 之 移动设备的触控操作

这篇博文将简单的记录,如何用unity处理在移动设备上的触控操作。
    iOS和Android设备能够支持多点触控。在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、脚本就一个


using UnityEngine;
using System.Collections;
using System.Collections.Generic;


public class MyTouch : MonoBehaviour
{
	/// <summary>
	/// 定义的一个手指类
	/// </summary>
	class MyFinger
	{
		public int id = -1;
		public Touch touch;

		static private List<MyFinger> fingers = new List<MyFinger>();
		/// <summary>
		/// 手指容器
		/// </summary>
		static public List<MyFinger> Fingers
		{
			get
			{
				if(fingers.Count==0)
				{
					for(int i=0; i<5; i++)
					{
						MyFinger mf = new MyFinger();
						mf.id = -1;
						fingers.Add(mf);
					}
				}
				return fingers;
			}
		}

	}

	// 小圈圈:用来实时显示手指触摸的位置
	GameObject[] marks = new GameObject[5];
	public GameObject markPerfab = null;

	// 粒子效果:来所显示手指手动的大概路径
	ParticleSystem[] particles = new ParticleSystem[5];
	public ParticleSystem particlePerfab = null;


	// Use this for initialization
	void Start ()
	{
		// init marks and particles
		for(int i=0; i<MyFinger.Fingers.Count; i++)
		{
			GameObject mark = Instantiate(markPerfab, Vector3.zero, Quaternion.identity) as GameObject;
			mark.transform.parent = this.transform;
			mark.SetActive(false);
			marks[i] = mark;

			ParticleSystem particle = Instantiate(particlePerfab, Vector3.zero, Quaternion.identity) as ParticleSystem;
			particle.transform.parent = this.transform;
			particle.Pause();
			particles[i] = particle;
		}
	}
	
	// Update is called once per frame
	void Update ()
	{
		Touch[] touches = Input.touches;

		// 遍历所有的已经记录的手指
		// --掦除已经不存在的手指
		foreach(MyFinger mf in MyFinger.Fingers)
		{
			if(mf.id == -1)
			{
				continue;
			}
			bool stillExit = false;
			foreach(Touch t in touches)
			{
				if(mf.id == t.fingerId)
				{
					stillExit = true;
					break;
				}
			}
			// 掦除
			if(stillExit == false)
			{
				mf.id = -1;
			}
		}
		// 遍历当前的touches
		// --并检查它们在是否已经记录在AllFinger中
		// --是的话更新对应手指的状态,不是的放放加进去
		foreach(Touch t in touches)
		{
			bool stillExit = false;
			// 存在--更新对应的手指
			foreach(MyFinger mf in MyFinger.Fingers)
			{
				if(t.fingerId == mf.id)
				{
					stillExit = true;
					mf.touch = t;
					break;
				}
			}
			// 不存在--添加新记录
			if(!stillExit)
			{
				foreach(MyFinger mf in MyFinger.Fingers)
				{
					if(mf.id == -1)
					{
						mf.id = t.fingerId;
						mf.touch = t;
						break;
					}
				}
			}
		}

		// 记录完手指信息后,就是响应相应和状态记录了
		for(int i=0; i< MyFinger.Fingers.Count; i++)
		{
			MyFinger mf = MyFinger.Fingers[i];
			if(mf.id != -1)
			{
				if(mf.touch.phase == TouchPhase.Began)
				{
					marks[i].SetActive(true);
					marks[i].transform.position = GetWorldPos(mf.touch.position);

					particles[i].transform.position = GetWorldPos(mf.touch.position);
				}
				else if(mf.touch.phase == TouchPhase.Moved)
				{
					marks[i].transform.position = GetWorldPos(mf.touch.position);

					if(!particles[i].isPlaying)
					{
						particles[i].loop = true;
						particles[i].Play();
					}
					particles[i].transform.position = GetWorldPos(mf.touch.position);
				}
				else if(mf.touch.phase == TouchPhase.Ended)
				{
					marks[i].SetActive(false);
					marks[i].transform.position = GetWorldPos(mf.touch.position);

					particles[i].loop = false;
					particles[i].Play();
					particles[i].transform.position = GetWorldPos(mf.touch.position);
				}
				else if(mf.touch.phase == TouchPhase.Stationary)
				{
					if(particles[i].isPlaying)
					{
						particles[i].Pause();
					}
					particles[i].transform.position = GetWorldPos(mf.touch.position);
				}
			}
			else
			{
				;
			}
		}

		// exit
		if(Input.GetKeyDown(KeyCode.Home) || Input.GetKeyDown(KeyCode.Escape))
		{
			Application.Quit();
		}

//		// test
//		if(Input.GetMouseButtonDown(0))
//		{
//			GameObject mark = Instantiate(markPerfab, Vector3.zero, Quaternion.identity) as GameObject;
//			mark.transform.parent = this.transform;
//			mark.transform.position = GetWorldPos(Input.mousePosition);
//
//			ParticleSystem particle = Instantiate(particlePerfab, Vector3.zero, Quaternion.identity) as ParticleSystem;
//			particle.transform.parent = this.transform;
//			particle.transform.position = GetWorldPos(Input.mousePosition);
//			particle.loop = false;
//			particle.Play();
//		}
	}

	/// <summary>
	/// 显示相关高度数据
	/// </summary>
	void OnGUI()
	{
		GUILayout.Label("支持的手指的数量:" + MyFinger.Fingers.Count);
		GUILayout.BeginHorizontal(GUILayout.Width(Screen.width));
		for(int i=0; i< MyFinger.Fingers.Count; i++)
		{
			GUILayout.BeginVertical();
			MyFinger mf = MyFinger.Fingers[i];
			GUILayout.Label("手指" + i.ToString());
			if(mf.id != -1)
			{
				GUILayout.Label("Id: " + mf.id);
				GUILayout.Label("状态: " + mf.touch.phase.ToString());
			}
			else
			{
				GUILayout.Label("没有发现!");
			}
			GUILayout.EndVertical();
		}
		GUILayout.EndHorizontal();
	}

	public Vector3 GetWorldPos(Vector2 screenPos)
	{
		return Camera.main.ScreenToWorldPoint(new Vector3(screenPos.x, screenPos.y, Camera.main.nearClipPlane + 10));
	}


}

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

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


阅读更多
个人分类: Unity3D
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

关闭
关闭
关闭