Unity输入系统基础
输入
Unity 的输入系统是用于处理用户输入的核心模块,它使开发者能够捕获和响应来自键盘、鼠标、触摸屏、游戏手柄等各种输入设备的输入事件。Unity 的输入系统经历了几个重大版本的演变,目前主要有两种输入系统:经典输入系统和新的输入系统(Input System package)。
经典输入系统
经典输入系统是 Unity 早期版本中内置的输入系统,它通过一系列的公共变量和函数来提供输入处理。这些变量和函数可以在脚本中直接使用,例如:
- Input.GetAxis:获取轴的值,常用于处理模拟输入,如游戏手柄的摇杆或键盘的方向键。
- Input.GetButton:检查按钮是否被按下,适用于数字输入,如键盘按键或手柄按钮。
- Input.GetMouseButton 和 Input.GetMouseButtonDown:分别用于检测鼠标按钮是否被按下或是否被按下了一帧。
- Input.mousePosition:获取鼠标的屏幕坐标。
- Input.touchCount 和 Input.GetTouch:用于处理触摸屏输入。
经典输入系统的优点是简单易用,但是它的功能相对有限,对于复杂的输入处理和跨平台的支持不够灵活。
新的输入系统(Input System package)
新的输入系统是一个独立的 Unity Package,提供了更强大和灵活的输入处理能力。它允许开发者定义自定义的输入动作、绑定和处理程序,可以更精细地控制输入行为。新输入系统的主要特点包括:
- 可配置性:输入动作和绑定可以在编辑器中通过图形界面配置,无需编写代码。
- 跨平台支持:提供了广泛的设备和平台支持,可以很容易地处理不同设备和平台的输入差异。
- 高级功能:支持复合输入、延迟输入处理、输入过滤和变换等高级功能。
- 脚本控制:提供了丰富的 API,允许开发者在脚本中控制输入行为,如监听特定的输入事件、调整输入映射等。
新输入系统的核心概念包括:
- Input Actions:表示一个具体的输入事件,如跳跃或射击。
- Input Bindings:定义了如何从硬件输入(如按键、触控点)映射到 Input Actions。
- Input Controls:代表了具体的硬件输入源,如键盘上的某个键、手柄的某个按钮。
新输入系统的设计目的是为了提供更现代化、更灵活的输入处理框架,以适应各种游戏和应用的需求,尤其是在处理复杂的输入场景和跨平台开发时。
鼠标输入
在 Unity 中,鼠标输入主要包括以下几种类型:
鼠标按钮
- GetMouseButtonDown(int button): 检测鼠标按钮是否刚刚按下。
- GetMouseButton(int button): 检测鼠标按钮是否被按下。
- GetMouseButtonUp(int button): 检测鼠标按钮是否刚刚释放。
其中 button 参数可以是 0(左键)、1(右键)、2(中间键),或者更高的数值,具体取决于鼠标有多少个额外的按钮。一般在 Update 函数中每帧对按键进行检测
void Update() |
鼠标左键点击一次屏幕,控制台输出
鼠标位置
- mousePosition: 返回鼠标在屏幕坐标系中的位置,左下角为(0,0),右上角为(Screen.width, Screen.height)。
void Update() |
屏幕中点击鼠标右键,控制台输出
鼠标滚动
- GetAxis(“Mouse ScrollWheel”): 获取鼠标滚轮的滚动量,正数表示向上滚动,负数表示向下滚动。
float mouseScrollWheel = Input.GetAxis("Mouse ScrollWheel"); |
在窗口中滚动鼠标滚轮,控制台输出
鼠标移动
- GetAxis(“Mouse X”) 和 GetAxis(“Mouse Y”): 分别返回鼠标水平和垂直方向上的移动量。
void Update(){ |
移动鼠标,控制台输出
鼠标事件
对于 UI 元素,Unity 的 EventSystem 提供了对鼠标事件的支持.
- IPointerEnterHandler - OnPointerEnter - 当指针进入对象时调用
- IPointerExitHandler - OnPointerExit - 当指针退出对象时调用
- IPointerDownHandler - OnPointerDown - 在对象上按下指针时调用
- IPointerUpHandler - OnPointerUp - 松开指针时调用(在指针正在点-击的游戏对象上调用)
- IPointerClickHandler - OnPointerClick - 在同一对象上按下再松开指针时调用
- IBeginDragHandler - OnBeginDrag - 即将开始拖动时在拖动对象上调用
- IDragHandler - OnDrag - 发生拖动时在拖动对象上调用
- IEndDragHandler - OnEndDrag - 拖动完成时在拖动对象上调用
对于非 UI 元素,可以使用物理碰撞和射线投射技术来检测鼠标与 3D 世界中的物体的交互。
常用 API 有:
- OnMouseDown 在物体上按下鼠标
- OnMouseUp 在物体上抬起鼠标
- OnMouseDrag 在物体上拖动鼠标,每帧调用
- OnMouseEnter 鼠标进入物体
- OnMouseExit 鼠标移出物体
- OnMouseOver 鼠标位于物体上,每帧调用
键盘输入
在 Unity 中,键盘输入是游戏和应用程序中常见的用户交互方式之一。Unity 提供了多种方法来读取和处理键盘输入,这些方法可以分为两大类:基于事件的输入和基于轴的输入。
基于事件的输入
基于事件的输入用于检测键盘上的按键状态,主要包括以下几种方法:
- GetKey:检测按键是否一直被按下。
- GetKeyDown:检测按键是否在当前帧首次按下。
- GetKeyUp:检测按键是否在当前帧首次释放。
这些方法接受一个字符或按键名称作为参数,返回一个布尔值,表示按键的状态。如:
void Update() |
点击一次 A 键,控制台输出
还有三个 API 用于事件输入
- GetButton
- GetButtonDown
- GetButtonUp
这三个 API 的用法和之前的基本一样,只是传入的参数只能是 InputManager 中定义的轴键。以 InputManager 自带的 jump 为例:
代码格式:
if(Input.GetButtonDown("Jump")) |
运行时按 InputManager 中设置的 space(空格键),控制台输出:
如果传入的 Button Name 在 InputManager 中没有注册,运行游戏时会报错
if (Input.GetButtonDown("space")) |
错误信息:
基于轴的输入
基于轴的输入用于处理类似游戏手柄的模拟输入,但也可以用于键盘。Unity 为常用的键盘方向键定义了轴,例如:
- Horizontal:处理左右方向键或 A/D 键。
- Vertical:处理上下方向键或 W/S 键。
这些轴的值范围一般在-1 到 1 之间,其中-1 表示按键完全向左或向下,1 表示完全向右或向上。
float horizontal = Input.GetAxis("Horizontal"); |

Touch 输入
在 Unity 中,处理触摸输入对于开发移动平台(如 iOS 和 Android)的游戏和应用程序至关重要。Unity 提供了对多点触摸的支持,允许你检测和响应来自触摸屏的输入事件。触摸输入在 Unity 中主要通过 Input.touches 数组来访问,这个数组包含了所有当前正在触摸屏幕的手指的信息。
Input.touches 数组
Input.touches 是一个 Touch 类型的数组,包含了所有正在触摸屏幕的手指信息。每个 Touch 对象都有以下属性和方法:
- fingerId: 触摸的唯一索引。
- position:手指在屏幕上的位置(以像素为单位)。
- deltaPosition:自上次帧以来手指移动的距离。
- tapCount:连续的点击次数,对于快速多次点击同一位置的情况。
- phase:触摸事件的阶段,可以是 Began(开始)、Moved(移动)、Stationary(静止)、Ended(结束)或 Cancelled(取消)。
void Update() |
使用打包工具将场景打包成 Apk,勾选调试选项

在手机上运行程序,看到 Unity 控制台显示监听信息,然后点击手机屏幕,控制台输出

使用 Touch 输入拖动物体
void Update() |
鼠标事件模拟单个 touch
鼠标事件也可以用来模拟单个 touch 输入,在脚本中的 Input.mousePosition 也是单个手指点击的位置,所以 Unity 提供的鼠标事件也可以用来模拟输入,API:
- OnMouseDown 在物体上按下鼠标
- OnMouseUp 在物体上抬起鼠标
- OnMouseDrag 在物体上拖动鼠标,每帧调用
- OnMouseEnter 鼠标进入物体
- OnMouseExit 鼠标移出物体
- OnMouseOver 鼠标位于物体上,每帧调用
所以拖动物体可以用以下方法,而且无论在编辑器下还是打包到手机都可以触发事件
private void OnMouseDrag() |
但是 GetMouseButtonDown 等方法就模拟不了手机输入,也就是方法不会在点击屏幕时触发
触摸事件和鼠标事件对比
在 Unity 中,处理触摸事件(Touch Events)、鼠标事件(Mouse Events)有着不同的应用场景和特性,它们分别针对不同的输入设备和用户交互方式。下面是对其的对比:
触摸事件(Touch Events)
- 适用平台:主要针对移动设备(如智能手机和平板电脑)和触摸屏。
- 输入设备:触摸屏。
- 事件类型:通过 Input.touches 数组获取,包含了 Touch 对象,每个对象描述了一个触摸点的状态。
- 多点触摸:支持同时处理多个触摸点,适用于手势识别,如捏合缩放、多指滑动等。
鼠标事件(Mouse Events)
- 适用平台:桌面操作系统,如 Windows、macOS。
- 输入设备:鼠标。
- 事件类型:鼠标事件(例如“OnMouseDown”、“OnMouseDrag”和“OnMouseUp”)是 Unity 的内置事件函数,用于处理 Unity 编辑器内以及某些情况下独立应用程序中的鼠标交互。这些事件与具有 Collider 组件的游戏对象相关联,通常用于 Unity 编辑器中的测试和开发目的。
- 单点定位:相对于触摸事件,鼠标事件通常涉及单一输入点,即鼠标的位置。
在实际开发中,选择使用哪一种输入事件处理方式,主要取决于你的目标平台、游戏类型和用户交互设计。例如,对于一款移动平台的跑酷游戏,你可能主要依赖触摸事件来处理玩家的滑动和轻触操作;而对于一款桌面平台的策略游戏,你可能更多地使用鼠标事件来处理选择和拖拽操作。
陀螺仪输入
Unity 中的陀螺仪输入主要用于处理来自带有陀螺仪传感器的设备的运动数据,如智能手机和平板电脑。陀螺仪传感器能够测量设备绕三个轴的角速度,这对于实现基于运动的控制和增强现实(AR)应用非常有用。在 Unity 中,陀螺仪输入可以通过 Input.gyro 属性来访问。
Input.gyro 属性
Input.gyro 是一个 Gyroscope 类型的对象,提供了以下主要属性和方法:
- enabled: 设置或检索该陀螺仪的启用状态。
- attitude: 返回设备的姿态(即在空间中的方向)。
- rotationRate: 类似于 angularVelocity,但表示的是旋转速率,通常用于 AR 应用。
- rotationRateUnbiased: 与 rotationRate 类似,但去除了偏置,更准确地反映了实际的旋转速率。
- updateInterval: 返回或设置陀螺仪数据的更新间隔,单位为秒。
- userAcceleration: 返回用户给予设备的加速度。
检查设备支持
首先,你需要检查设备是否支持陀螺仪功能。
void Start() |
启用陀螺仪
在开始读取陀螺仪数据之前,必须先启用它
if (Input.gyro != null && !Input.gyro.enabled) |
获取陀螺仪数据
一旦陀螺仪被启用,可以通过以下方式获取数据:
旋转速率:Input.gyro.rotationRate, 返回一个 Vector3,表示设备在 X、Y、Z 轴上的角速度。
未校正的旋转速度:Input.gyro.rotationRateUnbiased,这将不考虑任何偏移或校准。
姿态:Input.gyro.attitude,这是一个 Quaternion,代表了设备相对于世界坐标系的姿态。
更新频率
陀螺仪的更新频率可能会影响性能和精度。可以通过 Input.gyro.updateInterval 属性来设置更新间隔(以秒为单位),默认值通常是 0.02 秒。
示例代码
通过陀螺仪实现旋转手机移动相机视角
void FixedUpdate() |
注意,陀螺仪数据可能会受到漂移的影响,因此在长时间运行的应用中,可能需要实现一些校准机制来处理这种问题。此外,陀螺仪的使用也会增加电池消耗,所以优化和测试是非常重要的。
EasyTouch
EasyTouch 是一个非常流行且功能丰富的 Unity 插件,主要用于处理触摸和手势输入,特别适合于移动平台的游戏开发。它提供了高度定制化的触摸输入处理,使得开发者可以轻松地在游戏内实现各种触摸操作,如点击、滑动、双击、长按、缩放、旋转等。
EasyTouch 的特点
- 广泛的触摸事件支持:EasyTouch 支持多种触摸事件,包括但不限于点击、长按、拖动、双击、多点触摸、缩放、旋转等。
- 虚拟控制器:它允许创建虚拟按钮、摇杆和其他控制元件,这些元件可以在屏幕上任意位置放置,非常适合需要复杂控制方案的游戏。
- 手势识别:EasyTouch 具有智能的手势识别功能,可以识别复杂的用户输入,如滑动手势的方向和速度,这在许多游戏中是必不可少的。
- 事件系统:插件内置了一套事件系统,可以方便地将触摸事件与游戏逻辑连接起来,无需复杂的编程。
- 自定义和可扩展:EasyTouch 允许开发者自定义和扩展其功能,可以添加自己的触摸事件处理器,以适应特定的游戏需求。
- 编辑器工具:它提供了一个强大的编辑器工具,可以直观地配置触摸事件和虚拟控制器,减少代码工作量。
- 性能优化:EasyTouch 设计时考虑了性能,确保即使在高负载下也能保持良好的响应性和游戏流畅度。
使用 EasyTouch 的基本步骤
- 导入插件:从 Unity Asset Store 下载并导入 EasyTouch 插件到 Unity 项目中。
- 创建 EasyTouch 控件:在场景中创建一个 EasyTouch 控件,里面可以对 EasyTouch 的参数进行设置

- 配置触摸事件:EasyTouch 提供多种使用方式包括使用脚本 API,使用 Quick Component 以及使用 EasyTouch Control
- 编写脚本:在游戏对象的脚本中,你可以订阅 EasyTouch Manager 发布的事件,从而根据不同的触摸事件执行相应的游戏逻辑。
- 测试和调试:使用 Unity 编辑器或在目标设备上测试触摸事件,确保一切按预期工作。
Easy Touch(Script) 组件
创建的 Easy Touch 带有一个同名的组件,结构如下:
- Enable Easy Touch : 是否启用 EasyTouch
- Enable Unity Remote : 是否启用 UnityRemote
GUI compatibility
GUI Compatibility(GUI 兼容性)设置是为了确保 EasyTouch 与 Unity 的旧版 GUI 系统(不是 UGUI,即 Unity 的 User Interface 系统)兼容。在 Unity 早期版本中,GUI 系统是用于创建用户界面的主要方式,但后来被新的 UGUI 系统所取代。当启用此选项时,EasyTouch 会在 GUI 事件发生时禁用手势识别,以防止与 GUI 控件的交互冲突。这是因为旧的 GUI 系统使用鼠标事件,而 EasyTouch 则使用自己的事件系统,两者之间可能存在冲突。
- Enable Unity UI detection:是否启用 UI 检测,取消勾选 EasyTouch 就取消对 UI 的控制
- Unity UI Compatibility:与 UGUI 的兼容性
- Auto update picked Unity UI:是否每一帧都检测 touch 下的物体是否符合要求。(比如滑动,如果滑动出了物体,指针下就没有 picked object 就会结束执行)
示例:
新建两个 Image

在红色 UI 上挂载脚本如下:
public class UICom: MonoBehaviour, IDragHandler |
在蓝色 UI 上新建组件 Quick Drag:

当关闭 Enable Unity UI detection 时蓝色的 image 拖动功能失效,启动该选项时无论 Unity UI compatibility 是否启用运行时都会将其禁用,然后蓝色 image 也可以实现拖动了
Automatic selection
Automatic Selection(自动选择)是一个功能,用于自动检测屏幕上的可交互对象。当启用此选项时,EasyTouch 会尝试根据触摸位置自动选择最接近的 UI 元素或者游戏对象。这对于实现点击、拖动等交互非常有用,可以减少手动编写选择逻辑的工作量。

- Enable auto-select:自动选择。开启时,可通过 EasyTouch 选择物体执行命令
- Picked Layers 3D:能够选取的层级
- Enable 2D collider:自动选择的 2D 层
- Add Camera:多相机的可选取。默认关联 MainCamera 。若添加某摄像机,位于其视口底下的物体也可被选取
General gesture properties
General Gesture Properties(通用手势属性)包含了一系列影响所有手势类型的基础设置。这里可以设置一些全局的手势行为.

- Priority to : 点击和滑动的优先级(主要针对比较模糊触碰)
- Stationary tolerance:静止精度,当手指在屏幕上时,如果滑动距离小于 15 即认为未滑动
- Long tap time:触发长按事件的最短间隔
- Double tap detection:双击事件触发的两次点击间隔,即点击两次时间间隔设置或者采用系统默认双击设置
- Swipe tolerance:滑动灵敏度
- always sent swipe event:即使误触(在灵敏度以下),也会发送事件
Two fingers gesture properties、
Two Fingers Gesture Properties(双指手势属性)专门针对需要两个手指的手势,如捏合(Pinch)、旋转(Rotate)和双指拖动(Two Finger Drag)。在这个部分,可以调整这些特定手势的参数

- Pick method:触发方式,Finger,只有两指都在物体上,才触发事件,Average 是当两指连线位于物体上,便会触发
- Enable swipe & drag:是否允许滑动或拖拽
- Enable Pinch:是否允许缩放
- Enable twist:是否允许旋转
Second finger simulation
Second Finger Simulation(第二根手指模拟)是一个高级功能,允许在只有一根手指触摸屏幕的情况下模拟第二根手指的行为。这在某些情况下可能是有用的,比如正在测试需要两指操作的功能,但目前只有单指可用。通过这个设置,可以定义在单指触控时如何模拟第二根手指的位置和行为,以便于开发和调试。
三种使用方式
使用 API
- EasyTouch4.x,需要通过绑定事件的方式
private void OnEnable() |
- EasyTouch5.x,不需要绑定事件,使用 Gesture 获取当前手指状态
private void Update() |
- 其他常用 API


更多到包中的 EasyTouch.pdf 查看
Quick Component
Quick Drag

- Allow on the axis:允许拖动的轴
- Allow pick over UI element:是否允许在 UI 元素底下拖拽
- Stop drag on collision enter:碰撞时停止拖拽
- Reset physics on drag: 拖拽时禁用刚体
Quick Enter-Over-Exit

- Allow multi-touches:允许多指操作
Quick LongTap

- 2 fingers gesture:需要两个手指长按才能触发
- Action triggering: 触发事件的时机分别是(Start,In progress,End)
Quick Pinch

- Gesture over me:手势必须位于具有 collider 的物体上(或者两个手指的连线在物体身上)
- Triggering: 触发时机,包括(In Progress,End)
- Pinch direction: 缩放方向,包括(All,Pinch In,Pinch Out)
- Enable simple action: 需要 Triggering 设置为 In Progress,用来设置双指实现的效果(缩放,移动,旋转)
- Action : 控制行为
- Affected axes: 控制的轴向
- Sensibility: 灵敏度
- Inverse axis: 是否反转轴
Quick Swipe

- Allow swipe start over me:是否允许从物体上开始滑动
其他参数类似 Quick Pinch
Quick Tap

- Action triggering:点击方式,包括单击双击
Quick Touch

- Action triggering:触摸方式,包括开始,按下和抬起
Quick Twist

参数类似 Quick Pinch
Easy Touch Trigger

- Testing on:作用对象是 UI 还是 3D 物体
- Only if on me:只有点击到当前物体时才会触发事件
- All the time,or other object:点击到其他物体,或者指定的物体时,也可触发
- Other receiver:其他接收者。即:当该物体触发事件后,要求 Receiver 做 Receiver 身上的 Method
EasyTouch Controls
Hierarchy 窗口空白处右键添加 Controls
InputManager
InputManager 是 EasyTouch 控制器的一个核心概念,它用于管理虚拟控制器的输入。可以创建多个 InputManager 实例,并为每个实例配置不同的控制器类型。每个 InputManager 都可以拥有一个或多个虚拟控制器,这些控制器可以在不同的游戏场景或不同的控制方案中使用。
Joystick
Joystick(摇杆)是一种常用的虚拟控制器,用于模拟传统游戏手柄上的摇杆。它通常由两个部分组成:底座(Base)和 Thumb(拇指触摸部分)。玩家可以通过触摸并移动 Thumb 来控制游戏中的角色或摄像机等。
底座:是 Joystick 的固定部分,玩家不能直接与其互动。
Thumb:玩家可以通过触摸并移动 Thumb 来控制游戏中的角色或摄像机等。
在 EasyTouch 中,你可以配置 Joystick 的各种属性,如:
主参数

- Activated : 是否激活
- Visible : 是否可见,不可见也就不能使用
- Use Fixed Update : 是否加入帧更新,适用物理控制
- Unregister at disabling time : 禁用时取消已经注册的事件
Position & Size

- Type:摇杆的类型,包括 Static 和 Dynamic,静态遥感位置固定,动态摇杆生成在第一次点击屏幕的位置,动态摇杆可以控制可生成区域,也可自定义区域(使用 Controls 中的 Area)
- Anchor:锚点设置,本质上就是 UI 元素,建议不要直接使用 Rect Transform 设置,存在某种 Bug,可以先使用提供的设置调到大概位置,再修改 Anchor 为 User Define,再在 Scene 中微调
- No offset thumb: 是否开启遥感偏移,关闭时鼠标点哪里,遥感就那个位置跟随,开启后遥感自动将位置移到鼠标对应遥感中心
- No return of the thumb: 是否放回遥感位置,即松开时摇杆是否归位
- Background size:背景图片大小
- Thumb size: 遥感大小
- Radius based on: 半径基于宽度还是高度,或者自定义
Axes properties

- Turn & Move direction Action:开启可以直接以第三人称控制移动和旋转
- Horizontal axis: 轴输入名称,惟一
- General setting
- React on : 触发方式点击或按下
- Dead zone method: 死区控制方式,传统或线性
- Dead length:死去范围
- Inverted axis:反转轴
- On/Off Threshold:开/关阈值,该值用于确定轴第一次被认为向下的阈值。使用此值,如果你想管理你的轴模式开/关,或基础上的直接行动向下轴。
- Speed: 控制的速度
- Direction action(optional)
- Auto link on tag : 根据 tag 自动连接
Other Controls
其他控件如 D-Pad,Button,TouchPad,Area 参数上都和 Joystick 相差不大,详情可在文档EasyTouchControls_UserDocumentation.pdf中查看.
结语
EasyTouch 插件大大简化了触摸输入的处理,使开发者能够更加专注于游戏的核心玩法和用户体验,而不是陷入底层触摸事件的细节处理中。如果你正在开发一款需要复杂触摸控制的移动游戏,EasyTouch 绝对是一个值得考虑的强大工具。