Unity3D技术之键盘、操纵杆和游戏手柄输入实现详解

输入桌面
Unity 支持键盘、操纵杆和游戏手柄输入。
可以在输入管理器 (Input Manager) 中创建虚拟轴和按钮,终端用户可以在简洁美观的配置对话框中配置键盘。

Unity3D技术之键盘、操纵杆和游戏手柄输入实现详解_第1张图片  


您可以设置操纵杆、手柄、键盘和鼠标,然后通过简单的脚本界面访问所有设置。
在脚本中,所有虚拟轴都按照名称访问。
在创建之时,所有工程都有以下默认的输入轴:
1、 水平线 (Horizontal) 和垂直线 (Vertical) 映射至 w、a、s、d 和方向键。

2、Fire1、Fire2、Fire3 分别映射至 Control、Option (Alt) 和 Command 键。

3、 Mouse X 和 Mouse Y 映射至鼠标移动增量。

4、 Window Shake X 和 Window Shake Y 对应窗口的移动。

添加新的输入轴

如需添加新的虚拟轴,转到编辑 (Edit)->工程设置 (Project Settings)->输入 (Input) 菜单。也可在这里更改每个轴的设置。

Unity3D技术之键盘、操纵杆和游戏手柄输入实现详解_第2张图片  

每个轴可以对应操纵杆、鼠标的两个按钮或两个键盘按键。


名称 (Name) 用来在脚本中检查该轴的字符串名称。 
描述名称 (Descriptive Name) 配置 (Configuration) 对话框输入选项卡中显示的正名称,用于独立构建。 
描述负名称 (Descriptive Negative Name) 配置 (Configuration) 对话框输入选项卡中显示的负名称,用于独立构建。 
负按钮 (Negative Button) 用于在负方向移动轴。 
正按钮 (Positive Button) 用于在正方向移动轴。 
备选负按钮 (Negative Button) 用来在负方向移动轴的备选按钮。 
备选正按钮 (Alt Positive Button) 用来在正方向移动轴的备选按钮。 
重力 (Gravity) 在没有按任何按钮时,轴下降到 0 的每秒单位速度。 
死亡 (Dead) 模拟死区的大小。所有在这个范围内的模拟设备值将映射为 0。 
灵敏度 (Sensitivity) 轴向目标值移动的每秒单位速度。该功能仅用于数码设备。 
捕捉 (Snap) 如果启用,按下相反方向的按钮时,轴值将自动归零。 
反向 (Invert) 如果启用,按下负按钮 (Negative Button) 将提供正值,反之亦然。 
类型 (Type) 控制此轴的输入类型。 
轴 (Axis) 连接设备的轴将控制这个轴。 
操纵杆 (Joy Num) 连接操纵杆将控制这个轴。 

这些设置可用来微调输入的外观和感觉。他们在编辑器均带有工具提示。
使用脚本中的输入轴

从像这样的脚本,可以查询当前状态,如下所示:
value = Input.GetAxis (“Horizontal”);
轴值在 -1 到 1 之间。中间位置为 0。 这是在操纵杆输入和键盘输入的情况下。
但是,鼠标增量和 Window Shake 增量是指鼠标或视窗在最后一帧移动的距离。这意味着,当用户快速移动鼠标时,它可能大于 1 或小于 -1。
您可以创建多个名称相同的轴。在获得输入轴时,绝对值最大的轴将被返回。这使得为一种以上输入设备指定同一个轴名称成为可能。例如,为键盘输入创建 一个轴,并且为操纵杆创建另一根名称相同的轴。如果用户使用操纵杆,输入将来自操纵杆,否则,输入将来自键盘。有了这种方法,在编写脚本时,您无需再考虑 输入的来源。
按钮名称

要映射一个键到一个轴,您必须在检视器中的正按钮 (Positive Button) 或负按钮 (Negative Button) 属性中输入按键名称。
按键名称遵循以下惯例:
1、 标准键: “a”、”b”、”c”、…

2、 数字键:”1〃、”2〃、”3〃、 …

3、 方向键:“上 (up)”、“下 (down)”、“左 (left)”、“右 (right)”

4、小键盘键:”[1]”、”[2]”、”[3]”、”[+]”、”[=]”

5、修改键:”right shift”、”left shift”、”right ctrl”、”left ctrl”、”right alt”、”left alt”、”right cmd”、”left cmd”

6、鼠标按钮:”mouse 0〃、”mouse 1〃、”mouse 2〃, …

7、 操纵杆按钮(从任意操纵杆):”joystick button 0〃、”joystick button 1〃、”joystick button 2〃、 …

8、操纵杆按钮(从指定操纵杆):”joystick 1 button 0〃、”joystick 1 button 1〃、”joystick 2 button 0〃、…

9、 特殊键:”backspace”、”tab”、”return”、”escape”、”space”、”delete”、”enter”、”insert”、”home”、”end”、”page up”、”page down”

10、 功能键:”f1〃、”f2〃、”f3〃、…
在脚本界面和检视器中,用来识别按键的名称是一样的。
value = Input.GetKey (“a”);
移动输入

在 iOS 和 Android 平台,输入类别可以让您访问触摸屏、加速度计及地理/位置输入。
通过iOS 键盘可提供移动设备键盘访问。
多点触控屏幕


iPhone 和 iPod Touch 设备最多可同时追踪屏幕的五个触点。您可以访问 Input.touches 属性数组,检索最后一帧每个触点的状态。
Android 设备对于追踪的触点数量没有统一限制。相反,它根据设备的而有所不同,某些老旧设备可能是两点,而最新的设备可以到五点。每个触点都以一个 Input.Touch 数据结构表示:


手指索引 (fingerId) 每次触摸的唯一指数。 
位置 (position) 触摸在屏幕中的位置。 
增量位置 (deltaPosition) 最后一帧以来的屏幕位置变化。 
增量时间 (deltaTime) 最后一次状态变化以来的经过的时间。 
点击数 (tapCount) iPhone/iPad 屏幕可以分辨用户的快速触摸。这个计数器可以让您知道用户在不移动手指的情况下触摸屏幕的次数。Android 设备不会计算触摸的次数,因此,这个字段始终为 1。 
阶段 (phase) 描述所谓的触摸“阶段 (phase)” 或状态。它有助于确定用户是否刚开始触摸,是否用户移动手指,是否用户刚刚抬起手指。 

阶段主要分为以下几个部分:


开始 (Began) 手指刚刚接触屏幕。 
移动 (Moved) 手指在屏幕上移动。 
静止 (Stationary) 手指触摸屏幕,但自最后一帧以来并未移动。 
结束 (Ended) 手指离开屏幕,是触控的最后一个阶段。 
取消 (Canceled) 系统已取消触控跟踪,例如,用户将设备接触面部或同时超过 5 个触摸点。这是触控的最后一个阶段。 

下面是一个用户轻触屏幕即射出光线的脚本示例:

var particle : GameObject;
function Update () {
for (var touch : Touch in Input.touches) {
if (touch.phase == TouchPhase.Began) {
// Construct a ray from the current touch coordinates
var ray = Camera.main.ScreenPointToRay (touch.position);
if (Physics.Raycast (ray)) {
// Create a particle if hit
Instantiate (particle, transform.position, transform.rotation);
}
}
}
}





鼠标模拟

除原生的触摸支持以外,Unity iOS/Android 还提供鼠标模拟。您可以使用标准输入类中的鼠标功能。
加速度计

在移动设备移动的过程中,内置的加速度计报告在三维空间三个主要轴上的线性加速度改变。硬件将直接报告每根轴的加速度作为重力值。值为 1.0 代表所给出的轴的负载约为 +1g,而 -1.0 则代表 -1g。如果设备垂直放置(Home 键位于下方)于身体正前方,那么 X 轴在右边是正值,Y 轴在上方是正值,Z 轴则在指向您本人的一方为正值。
可以访问 Input.acceleration 属性,检索加速度计值。 以下是使用加速度计移动对象的脚本示例:

var speed = 10.0;
function Update () {
var dir : Vector3 = 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);
}




低通过滤器

加速度计读数可能被颠簸和噪音影响。在信号中应用低通滤波器有助于使其更平滑,并去除高频噪音。
以下脚本展示了如何将低通滤波器应用到加速度计读数:

var AccelerometerUpdateInterval : float = 1.0 / 60.0;
var LowPassKernelWidthInSeconds : float = 1.0;

private var LowPassFilterFactor : float = AccelerometerUpdateInterval / LowPassKernelWidthInSeconds; // tweakable
private var lowPassValue : Vector3 = Vector3.zero;
function Start () {
lowPassValue = Input.acceleration;
}

function LowPassFilterAccelerometer() : Vector3 {
lowPassValue = Mathf.Lerp(lowPassValue, Input.acceleration, LowPassFilterFactor);
return lowPassValue;
}




LowPassKernelWidthInSeconds 的值越大,过滤值在当前输入样本中汇集的速度越慢(反之亦然)。
在获取加速度计读数时,我希望它能尽可能精确,我该怎么做?

读取 Input.acceleration 变量并不等于采样硬件。简而言之,Unity 以 60Hz 的频率采样硬件,并将结果储存到变量中。事实上,事情并非如此简单 —— 在大量 CPU 负荷的情况下,加速度计采样不 会以相同的时间间隔发生。因此,系统可能一帧报告两个样本,而下一帧又只有一个样本。

您可以访问加速度计在每帧执行的所有测量。以下代码将举例说明最后一帧收集的所有加速度计事件的简单平均数:


var period : float = 0.0;
var acc : Vector3 = Vector3.zero;
for (var evnt : iPhoneAccelerationEvent in iPhoneInput.accelerationEvents) {
acc += evnt.acceleration * evnt.deltaTime;
period += evnt.deltaTime;
}
if (period > 0)
acc *= 1.0/period;
return acc;

你可能感兴趣的:(U3D教程)