Unity的输入主要都在Input类中实现,输入不光包括键盘,鼠标和触屏的输入,还包括设备姿态,加速度,罗盘,陀螺仪等。
键盘按键输入
键盘按键的主要方法有3个:
- GetKey:按住某个按键,按住不放会一直返回。
- GetKeyDown:按下某个按键,按住只会在第一帧返回。
- GetKeyUp:释放某个按键。
void Update()
{
if (Input.GetKey(KeyCode.A))
{
Debug.Log("A");
}
}
这种方法,不光可以用于检测键盘按键,还可以用于检测鼠标按键(KeyCode.Mouse0)或者游戏手柄按键(KeyCode.Joystick1Button0)。
鼠标输入
鼠标按键除了可以用上面的Input.GetKey(GetKeyDown、GetKeyUp),还可以用Input.GetMouseButton(GetMouseButtonDown、GetMouseButtonUp)方法。输入值是整数,0代表鼠标左键,1代表鼠标右键,2代表鼠标右键。
void Update()
{
...
if (Input.GetMouseButton(0))
{
Debug.Log("mouse left down");
}
}
鼠标位置通过Input.mousePosition方法获取,返回的是一个Z轴为0的三维数,单位是像素。屏幕或窗口的左下角坐标为 (0.0, 0.0,0.0)。 屏幕或窗口的右上角坐标为 (Screen.width, Screen.height,0.0)。
void Update()
{
...
Debug.Log(Input.mousePosition);
}
鼠标滚动用Input.mouseScrollDelta方法获取,返回的是一个X轴为0的二位数。Y轴为正表示向上滚动,Y轴为负表示向下滚动。
void Update()
{
...
Debug.Log(Input.mouseScrollDelta);
}
触屏输入
触屏输入不光有位置和点击,最主要的是多了多点支持。通常先通过Input.touchCount属性来判断是否有点击,然后通过Input.GetTouch获得具体的触控(Touch),通过具体的触控来获取位置和状态等信息。
触屏点击状态通过Touch.phase属性获取,有下列状态。
- Began:手指触摸了屏幕。
- Moved:手指在屏幕上进行了移动。
- Stationary:手指正在触摸屏幕但尚未移动。
- Ended:从屏幕上抬起了手指。这是最后一个触摸阶段。
- Canceled:系统取消了对触摸的跟踪。
void Update()
{
...
if (Input.touchCount > 0)
{
Debug.Log(Input.GetTouch(0).phase);
}
}
触屏点击位置通过Touch. position属性获取,返回值为一个二维数,屏幕或窗口的左下角坐标为 (0, 0)。屏幕或窗口的右上角坐标为 (Screen.width, Screen.height)。
void Update()
{
...
if (Input.touchCount > 0)
{
Debug.Log(Input.GetTouch(0).position);
}
}
触屏输入通常会涉及到多点控制,例如拖动,旋转,缩放等。通常建议使用插件而不是自己写,例如LeanTouch,可以方便的实现拖动,旋转缩放等触屏操作。
Input Manager虚拟按键输入
- Negative Button, Positive Button 用于分别沿负向和正向推动轴的控件。
- Alt Negative Button, Alt Positive Button 用于分别沿负向和正向推动轴的备用控件。
- Gravity 不存在输入时,轴下降到中性点的速度(以单位/秒表示)。
- Dead 在运行时,所有模拟设备在该范围内的输入将被视为 null。
- Sensitivity 轴向目标值移动的速度(以单位/秒表示)。仅用于数字设备。
- Snap 如果启用此属性,按下对应于反方向的按钮时,轴值将重置为零。
- Type 这是控制此轴的输入类型。从以下值中进行选择:
键或鼠标按钮 (Key or Mouse button)
鼠标移动 (Mouse Movement)
游戏杆轴 (Joystick Axis) - Axis 这是用于控制此轴的连接设备的轴。
- JoyNum 这是控制此轴的连接游戏杆。可以选择特定游戏杆,或查询所有游戏杆的输入。
最常用的有“Horizontal”和“Vertical”,在键盘上按下方向键或者“A”、“S”、“D”、“W”键,用以控制角色在场景中移动。还有“Mouse X”和“Mouse Y”,当鼠标有移动的时候会有对应输入,常用于第一人称视角的射击游戏中调整视角方向。
使用方法是Input.GetAxis方法中传入Name属性即可,这种方法常用于方向相关的输入。
public Transform ball;
void Update()
{
ball.Translate(new Vector3(Input.GetAxis("Horizontal"), Input.GetAxis("Vertical"),0 ) * 10 * Time.deltaTime);
}
也可以用Input.GetButtonDown方法,常用于跳跃,开火等的输入。
void Update()
{
if(Input.GetButtonDown("Jump")){
Debug.Log("Jump");
}
}
点击物体
点击物体在Unity中也是很常见的操作。点击的目的有时候是选中物体便于操作,例如游戏中的拾取物品,点击敌人发动攻击,有时候是移动,点击地面上的点让玩家移动过去。
点击物体有4种实现方式,但是统一的要求都是,被点击的物体必须包括一个Collider组件。
MonoBehaviour事件
MonoBehaviour类下有多个事件可以用于点击物体或者相关的操作。
public class HitObjController : MonoBehaviour
{
private void OnMouseDown()
{
Debug.Log("OnMouseDown");
}
private void OnMouseDrag()
{
Debug.Log("OnMouseDrag");
}
private void OnMouseEnter()
{
Debug.Log("OnMouseEnter");
}
private void OnMouseExit()
{
Debug.Log("OnMouseExit");
}
private void OnMouseOver()
{
Debug.Log("OnMouseOver");
}
private void OnMouseUp()
{
Debug.Log("OnMouseUp");
}
private void OnMouseUpAsButton()
{
Debug.Log("OnMouseUpAsButton");
}
}
将脚本添加到被点击的游戏对象上即可。
编辑器设置事件系统响应
public class HitObjController : MonoBehaviour
{
public void OnClicked()
{
Debug.Log("clicked");
}
}
需要为被点击游戏对象添加【Event Trigger】组件,在场景中添加【Event System】游戏对象,为摄像机添加【Physics Raycaster】射线组件。
脚本监听事件系统事件
这种方法和编辑器事件系统响应的方法本质上是一样的,区别仅仅是在编辑器设置还是在脚本设置。
using UnityEngine.EventSystems;
public class HitObjController : MonoBehaviour, IPointerClickHandler
{
public void OnPointerClick(PointerEventData eventData)
{
Debug.Log("OnPointerClick");
}
}
需要在场景中添加【Event System】游戏对象,为摄像机添加【Physics Raycaster】射线组件。
射线检测
射线检测是用的最多的一种方法,原因是适应范围广。首先,支持多点触摸情况下的操作,其次,能返回触控点的坐标。当需要实现点击移动的时候,就需要用到这个坐标。
射线检测的原理是这样的,点击屏幕以后,通过Camera.ScreenPointToRay方法,将屏幕上的点映射到对应的摄像机,然后从摄像机发射出一条射线。通过Physics.Raycast方法检测射线是否照射到游戏对象,并且返回一个RaycastHit类型的对象。RaycastHit对象包含射线照射到的游戏对象的点的坐标。
鼠标点击
void Update()
{
if (Input.GetMouseButtonDown(0))
{
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
if (Physics.Raycast(ray, out RaycastHit hit))
{
Debug.Log("GetMouseButtonDown");
}
}
}
触屏点击
void Update()
{
if (Input.touchCount > 0)
{
if (Input.touches[0].phase == TouchPhase.Began)
{
Ray ray = Camera.main.ScreenPointToRay(Input.touches[0].position);
if (Physics.Raycast(ray, out RaycastHit hit))
{
Debug.Log("Touch[0] began");
}
}
}
}
通过hit.point即可获得点击点的坐标。
UI击穿
当一个场景中,启用了鼠标点击输入(或者触屏输入)和UI的交互游戏对象的时候,当点击UI的时候,会同时触发2者的事件,这个时候就称为UI击穿。
添加判断即可保证点击UI的时候不触发鼠标点击或者触屏点击。
if (Input.GetMouseButtonUp(0) && !EventSystem.current.IsPointerOverGameObject())
{
Debug.Log("mouse hit");
}
if (Input.touchCount == 1)
{
if (Input.touches[0].phase == TouchPhase.Began
&& !EventSystem.current.IsPointerOverGameObject(Input.touches[0].fingerId))
{
Ray ray = Camera.main.ScreenPointToRay(Input.touches[0].position);
}
}
B站视频链接:https://www.bilibili.com/video/BV1VU4y1W7zg/
B站视频链接:https://www.bilibili.com/video/BV1Ky4y1J79r/