Unity全面入门笔记18-几何输入

输入监控

鼠标几何输入

  • 鼠标点击事件

使用GetMouseButton来获取鼠标按键的事件:

public static bool Input.GetMouseButton(int button);
public static bool Input.GetMouseButtonUp(int button);
public static bool Input.GetMouseButtonDown(int button);

其中,button为0时获得的是鼠标左键,1则为鼠标右键,2为鼠标中键。

  • 鼠标座标信息
public static Vector3 Input.mousePosition;

该属性返回鼠标的屏幕座标。屏幕座标是根据像素来确定的二维向量,以屏幕的左下角为(0, 0),以屏幕的右上角为(Screen.width, Screen.height)。而z轴座标则始终为0。

使用Camera的座标转换功能可以将刚得到的屏幕座标转化为世界空间座标:

public class MousePosition : MonoBehaviour
{
	Camera mainCamera;
	
	private void Start()
	{
		mainCamera = Camera.main;
	}

	private void Update()
	{
		Debug.Log(mainCamera.ScreenToWorldPoint(Input.mousePosition));
	}
}

Camera的座标转换功能之后详述。

通过GetAxis可以快速获得鼠标在屏幕座标的偏移量:

public static float Input.GetAxis(string axisName);
public static float Input.GetAxisRaw(string axis Name);

使用"Mouse X"和"Mouse Y"这两个轴名,可以检测鼠标座标在上一帧到这一帧的变化量:

public class MousePosition : MonoBehaviour
{
	private void Update()
	{
		Debug.Log(new Vector2(Input.GetAxis("Mouse X"),Input.GetAxis("Mouse Y")));
	}
}
  • 鼠标滚轮
public static float Input.mouseScrollDelta;

每帧检测,向上滚动返回正数,向下滚动返回负数,不滚动返回零。一般情况下返回1.0或-1.0,在滚动极快的情况下有可能出现2.0和-2.0。测试结果可能与所用的鼠标有关。

使用GetAxis(“Mouse ScrollWheel”)也可以获取鼠标滚轮信息:

public class ScrollWheel : MonoBehaviour
{
	private void Update()
	{
		Debug.Log(Input.GetAxis("Mouse ScrollWheel"));
	}
}

这个方法返回的值同样在向上时为正,在向下时为负,在不滚动时为0,但其值一般情况下是0.1和-0.1,较快时出现0.2、-0.2。

触摸屏几何输入

  • Touch类

Unity封装了Touch类来处理触摸屏事件。每当一个触摸事件产生,就会按顺序生成一个Touch实例,并持续跟踪这个触摸,直到手指完全离开屏幕。这个列表可以通过Touch.touches来访问。

public static int Input.touchCount;
public static Touch[] Input.touches;
public static Touch Input.GetTouch(int index);

默认情况下可以将单个手指的触碰解读为鼠标左键,将双指触碰解读为鼠标右键,并用mousePosition获取单个触摸发生的位置。开发者可以手动关闭这个功能:

public static bool Input.simulateMouseWithTouches = true; 

追踪这个Touch实例可以获得的消息有:

public int Touch.fingerID;
public Vector2 Touch.position;
public Vector2 Touch.deltaPosition;
public TouchPhase Touch.phase;
public float Touch.deltaTime;
public int Touch.tapCount;

fingerID:返回这个触摸在Input.touches中的下标。当其他触摸结束时,这个下标有可能改变。

position:返回这个触摸的屏幕座标。

deltaPosition:返回这个触摸的位置在上一帧到这一帧的变化量。

phase:用于检测这个触摸的状态。

TouchPhase.Began:表示在这一帧中刚检测到触摸状态,开始追踪触摸点。

TouchPhase.Stationary:表示在这一帧中触摸点几乎没有位移。

TouchPhase.Move:表示在这一帧中触摸点的位移大于阈值,理解为拖动。

TouchPhase.Ended:当手指离开屏幕时,Touch对象不会立刻删除,而是在一定时间内继续跟踪。如果手指在这段时间内重新落下,且位移没有超过阈值,则理解为双击或多击。否则Touch就会进入Ended状态,并在下一帧中被删除。

TouchPhase.Canceled:表示这一帧中因为手指触摸数量过多、手机进入脸颊模式、应用被来电打断等事件,操作系统停止提供触摸点,而使程序对这个Touch的追踪被取消,这也将导致在下一帧中对应的Touch被删除。

deltaTime:当前时间与上一次触摸数据更新时间的间隔。

tapCount:短时间内连续点击的次数,只有两次点击的位置足够靠近才会被计入tapCount,否则会被理解为两次不同的触摸。

实例:使用触摸拖动来实现物体旋转:

public class DragRotating : MonoBehaviour
{
	[SerializeField]
	private float dragSpeed = 1;
	[SerializeField]
	private Transform target;
	private Camera mainCamera;
	
	private void Start()
	{
		mainCamera = Camera.main;
	}
	
	private void FixedUpdate()
	{
		Drag();
	}
	
	private void Drag()
	{
		if(Input.touchCount == 0) return;
		Touch touch = Input.GetTouch(0);
		Vector3 axis = Vector3.Cross(touch.deltaPosition, mainCamera.transform.forward);
		target.Rotate(axis, touch.deltaPosition.magnitude * dragSpeed, Space.World);
	}
}

有些移动端(如IPad和Surface)可以获取按压的力度:

public static bool Input.touchPressureSupported;
public float Touch.maximumPossiblePressure;
public float Touch.pressure;

其它移动端几何输入

  • 手机重力感应
public static Vector2 Input.acceleration;

获得手机的加速度数据,根据手机倾斜的角度,手机右侧向下倾斜时x为负,左侧向下倾斜时x为正,手机上方向下倾斜时y为正,下方向下倾斜时y为负,可以得到-1.0至1.0的浮点数。

注:3D世界座标y轴朝上,x-z平面才是地面,所以想让物体沿地面运动则必须注意三个轴对应的位置。

实例:使用手机重力感应实现3D滚球

[RequireComponent(typeof(Rigidbody))]
public class GravityBall : MonoBehaviour
{
	[SerializeField]
	private float speed;
	
	private Rigidbody rgb;
	private void Start()
	{
		rgb = GetComponent<Rigidbody>();
	}
	
	private void FixedUpdate()
	{
		Vector2 acceleration = Input.acceleration;
		if(acceleration.sqrMagnitude > 1) acceleration.Normalize();
		Vector3 direction = new Vector3(acceleration.x, 0, acceleration.y);
		rgb.velocity = direction * speed;
	}
}

  • 指南针和陀螺仪

在移动端上除了Input.acceleration外,还有Input.gyro来获取手机的三轴角速度(陀螺仪),以及使用Input.compass来获得手机的磁向量(指南针)。综合使用这三个属性,利用互补滤波可以计算出手机具体的空间状态。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章