输入监控
鼠标几何输入
使用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。
触摸屏几何输入
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来获得手机的磁向量(指南针)。综合使用这三个属性,利用互补滤波可以计算出手机具体的空间状态。