| | |—| | 重要提示:本页介绍输入管理器系统的一部分,这是旧版功能,不建议用于新项目。对于新项目中的移动设备输入,应使用 Input System Package。 |
在移动设备上,Input 类提供对触摸屏、加速度计和地理/位置输入的访问。
通过移动键盘可以访问移动设备上的键盘。
iPhone、iPad 和 iPod Touch 设备最多可跟踪五根手指同时触摸屏幕。可通过访问 Input.touches 属性数组来检索在最后一帧期间触摸屏幕的每根手指的状态。
Android 设备对其跟踪的手指数量没有统一限制。相反,此限制因设备而异,可能是旧设备上的双手指触摸到某些新设备上的五指触摸。
每根手指的触摸由 Input.Touch 数据结构表示:
| 属性: | 描述: | |
|---|---|---|
| fingerId | 触摸的唯一索引。 | |
| position | 触摸的屏幕位置。 | |
| deltaPosition | 自上一帧以来的屏幕位置变化。 | |
| deltaTime | 自上次状态变化以来经过的时间。 | |
| tapCount | iPhone/iPad 屏幕能够区分用户的快速手指点击。此计数器将记录用户在不将手指移到侧面的情况下点击屏幕的次数。Android 设备不计算点击次数,此字段始终为 1。 | |
| phase | 描述触摸状态,可帮助您确定用户是刚开始触摸屏幕、刚移动手指还是刚抬起手指。 | |
| Began | 手指刚触摸了屏幕。 | |
| Moved | 手指在屏幕上进行了移动。 | |
| Stationary | 手指正在触摸屏幕但自上一帧以来尚未移动。 | |
| Ended | 从屏幕上抬起了手指。这是触摸的最后一个阶段。 | |
| Canceled | 由于某种情况,例如用户将设备放在他们的脸部或同时执行超过五次触摸,系统取消了对触摸的跟踪。这是触摸的最后一个阶段。 | |
以下是一个示例脚本,只要用户点击屏幕,就会发出一条射线:
using UnityEngine;
public class TouchInput : MonoBehaviour
{
GameObject particle;
void Update()
{
foreach(Touch touch in Input.touches)
{
if (touch.phase == TouchPhase.Began)
{
// Construct a ray from the current touch coordinates
Ray ray = Camera.main.ScreenPointToRay(touch.position);
if (Physics.Raycast(ray))
{
// Create a particle if hit
Instantiate(particle, transform.position, transform.rotation);
}
}
}
}
}
随着移动设备的移动,内置的加速度计会报告沿三维空间中的三个主轴的线性加速度变化。硬件将沿每个轴的加速度直接报告为重力值。值 1.0 表示沿给定轴约 +1g 的荷载,而值 –1.0 表示 –1g。如果将设备竖直握住(主屏幕按钮位于底部)举到您正前方,则右侧为正 X 轴,上方为正 Y 轴,指向您的方向为正 Z 轴。
可通过访问 Input.acceleration 属性来检索加速度计值。
以下是使用加速度计移动对象的示例脚本:
using UnityEngine;
public class Accelerometer : MonoBehaviour
{
float speed = 10.0f;
void Update()
{
Vector3 dir = Vector3.zero;
// we assume that the device is held parallel to the ground
// and the Home button is in the right hand
// remap the device acceleration axis to game coordinates:
// 1) XY plane of the device is mapped onto XZ plane
// 2) rotated 90 degrees around Y axis
dir.x = -Input.acceleration.y;
dir.z = Input.acceleration.x;
// clamp acceleration vector to the unit sphere
if (dir.sqrMagnitude > 1)
dir.Normalize();
// Make it move 10 meters per second instead of 10 meters per frame...
dir *= Time.deltaTime;
// Move object
transform.Translate(dir * speed);
}
}
以下脚本显示了如何将低通滤波应用于加速度计读数:
using UnityEngine;
public class LowPassFilterExample : MonoBehaviour
{
float accelerometerUpdateInterval = 1.0f / 60.0f;
float lowPassKernelWidthInSeconds = 1.0f;
private float lowPassFilterFactor;
private Vector3 lowPassValue = Vector3.zero;
void Start()
{
lowPassFilterFactor = accelerometerUpdateInterval / lowPassKernelWidthInSeconds;
lowPassValue = Input.acceleration;
}
private void Update()
{
lowPassValue = LowPassFilterAccelerometer(lowPassValue);
}
Vector3 LowPassFilterAccelerometer(Vector3 prevValue)
{
Vector3 newValue = Vector3.Lerp(prevValue, Input.acceleration, lowPassFilterFactor);
return newValue;
}
}
LowPassKernelWidthInSeconds 的值越大,滤波值向当前输入样本收敛的速度越慢(反之亦然)。
您可以访问加速度计在帧内执行的所有测量。以下代码将展示在最后一帧内收集的所有加速度计事件的简单平均值:
public class AccelerationEvents : MonoBehaviour
{
void Update()
{
GetAccelerometerValue();
}
Vector3 GetAccelerometerValue()
{
Vector3 acc = Vector3.zero;
float period = 0.0f;
foreach(AccelerationEvent evnt in Input.accelerationEvents)
{
acc += evnt.acceleration * evnt.deltaTime;
period += evnt.deltaTime;
}
if (period > 0)
{
acc *= 1.0f / period;
}
return acc;
}
}