Unity 4 3D开发实战详解
上QQ阅读APP看书,第一时间看更新

4.3 常用的输入对象

有一点游戏开发经验的读者都知道,游戏开发中经常需要获取用户的输入情况,主要包括与触控动作相关的各个参数和按键的情况等。在一般的开发平台下,开发人员需要编写不少代码才能完成此项工作,而Unity 3D在设计平台时就充分考虑到了这一点。

针对这方面的需要,专门为开发人员提供了两个输入对象——Touch与Input。开发人员通过Touch与Input输入对象可以非常方便地获取用户输入的各种参数,包括触控的位置、按下的移动的位置、是哪个键等。下面将一一进行介绍。

4.3.1 Touch输入对象

在Unity中使用Touch输入对象来获取触控动作相关的各个参数。由于Unity 3D是跨平台的,而现今流行的Android平台和iPhone平台都是基于屏幕触控的,因此Touch输入对象是开发过程中经常遇到的问题,也是较难解决的问题。

解决Touch输入对象可以将Touch代码写在相应的脚本中,把脚本挂载到相应的游戏对象上即可。Unity提供了丰富的Touch事件的变量,下面将对Touch事件的变量进行详细介绍,具体的变量信息如表4-53所示。

表4-53 Touch输入对象的变量

各个变量在开发过程中将会一起相互配合使用,只有各个变量的相互配合才能解决实际的问题,具体实现如下面的代码片段所示:

1 var speed : float = 0.1;       //定义一个浮点型速度变量

2 function Update () {        //声明Update变量

3 if (Input.touchCount > 0 &&       //如果触控点大于0

4  Input.GetTouch(0).phase == TouchPhase.Moved) { //如果当前事件的状态是移动5    //创建一个坐标touchDeltaPosition并读取离开触控时点的坐标

6    var touchDeltaPosition:Vector2 = Input.GetTouch(0).deltaPosition;

7    transform.Translate (-touchDeltaPosition.x * speed,

8     -touchDeltaPosition.y * speed, 0); //移动一定的距离

9  } }

在游戏开发过程中还经常会遇到这样的触控问题,例如,子弹的生成与发射。当触控发射按钮就会生成一个子弹发射出去,这个在射击类游戏中是必不可少的环节,因此这样的触控问题也是必须解决的,具体实现如下面的代码片段所示:

1 var projectile : GameObject;      //声明一个子弹的游戏对象

2 function Update () {        //声明Update方法

3  for (var i = 0; i < Input.touchCount; ++i) {  //对触控点进行循环

4  if (Input.GetTouch(i).phase == TouchPhase.Began) {//如果触控的状态时开始触控

5  clone = Instantiate (projectile, transform.position, transform.rotation);//实例化一个子弹的游戏对象

6  } } }

在一些游戏开发过程还会在屏幕的固定区域块设置触控事件,因此对触控区域的划分也是经常要面对的问题,下面就对触控区域的划分进行用代码讲解,具体实现如下面的代码片段所示:

1 function Update(){        //声明Update方法

2   //如果触控点大于0并且当前触控事件的状态是开始触控

3 if(Input.touchCount>0&&Input.GetTouch(0).phase==TouchPhase.Began) {

4   var tposition=Input.GetTouch(0).position; //则声明一个变量并记录当前的触控位置

5   //设置第一个矩形触控区域

6   if(tposition.x<=250&&tposition.x>=60&&tposition.y>=700&&tposition.y<=820 ){

7    dateOrScore=0;      //将标志位dateOrScore置0

8   }//设置第一个矩形触控区域

9   if(tposition.x<=500&&tposition.x>=270&&tposition.y>=700&&tposition.y<=820 ){

10    dateOrScore=1;      //将标志位dateOrScore置1

11  } } }

4.3.2 Input输入对象

Input输入对象作为系统输入的接口,是外部事件信息与系统联系的纽带与桥梁,是一个项目所必须存在的,也是项目开发所必须解决的问题,因此,Input输入对象是开发过程中经常遇到的问题和必须解决的问题。

解决Input输入对象可以将Input代码写在相应的脚本中,把脚本挂载到相应的游戏对象上即可。Unity 提供了丰富的Input输入对象的变量和方法,下面将对Input输入对象的变量进行详细介绍,具体的变量信息如表4-54所示。

表4-54 Input事件的主要变量

下面将对各个变量进行详细介绍,将用真实的代码片段对变量的用法和用途进行讲解。

1.mousePosition变量

mousePosition变量是二维或三维的空间坐标,其一般需要用静态变量声明,如下面的代码片段所示:

static var mousePosition : Vector3 ; //声明mousePosition变量

当前鼠标光标位置的像素坐标是以屏幕或者窗口的左下角为(0,0),屏幕或窗口的右上角的坐标为(Screen.width,Screen.height)。

下面将用一段机枪开火的代码片段来说明mousePosition变量具体的用法与用途,具体实现如下面的代码片段所示:

1 var particle : GameObject;      //声明一个子弹的游戏对象

2 function Update () {       //声明Update方法

3 if (Input.GetButtonDown ("Fire1")) {   //判断开火按钮是否被按下

4  var ray : Ray = Camera.main.ScreenPointToRay (Input.mousePosition);// 构建一个当前位置的摄像机

5   if (Physics.Raycast (ray)) {

6    Instantiate (particle, transform.position, transform.rotation);// 实例化一个子弹

7  } } }

2.anyKey变量

anyKey变量是对当前键的持有权进行判定,其一般需要用静态变量声明,如下面的代码片段所示:

static var anyKey : boolean; //声明静态的anyKey变量

下面将用一段代码片段来说明anyKey变量具体的用法与用途,具体实现如下面的代码片段所示:

1 function Update() {        //声明Update方法

2  if(Input.anyKey)       //对键的持有权进行判定

3   Debug.Log("A key or mouse click has been detected");//若具有持有权,则打印消息

4 }

3.anyKeyDown变量

anyKeyDown变量是用户单击任何键或者鼠标按钮的标志,若单击则返回第一帧为true,其一般需要用静态变量声明,如下面的代码片段所示:

static var anyKeyDown : boolean; //声明anyKeyDown变量

下面将用一段代码片段来说明anyKeyDown变量具体的用法与用途,具体实现如下面的代码片段所示:

1 function Update() {        //声明Update方法

2  if(Input.anyKeyDown)      //对当前键是否被按下进行判定

3   Debug.Log("A key or mouse click has been detected");//若被按下则打印消息

4 }

4.inputString变量

inputString 变量是返回键盘输入的字符串,在项目开发的过程中也会遇到从键盘中输入命令来执行一些操作,一次对键盘输入的字符串就应该进行一系列操作,因此就需要inputString变量将键盘输入的字符串记录下来,具体实现如下面的代码片段所示:

1 function Update () {       //声明Update方法

2  for (var c : char in Input.inputString) { //对输入的字符串进行循环遍历

3   //如果遍历的字符c为\b 则执行下面的操作

4   if (c == "\b"[0]) {

5    if (guiText.text.Length != 0)   //对guiText的文本长度判断是否为0

6    guiText.text = guiText.text.Substring(0, guiText.text.Length - 1);//若长度不为0,

7   }

8   //如果遍历的字符c为\ n或者为\r,则执行下面的操作

9   else if (c == "\n"[0] || c == "\r"[0]) {

10   print ("User entered his name: " + guiText.text); //打印提示信息

11   }

12   //若果不是上面判断的字符,则执行下面的操作

13   else {

14   guiText.text += c;    //在guiText的文本内容后面添加上字符c

15   } } }

5.acceleration变量

acceleration变量是确定当前在三维坐标空间的线性加速度。在一些3D游戏的开发过程中也会遇到这样的问题,就是读取当前在三维坐标空间的线性加速度,以用来确定游戏下一步该怎么走,下面将用代码说明如何确定三维坐标空间的线性加速度以及各个坐标的分量,具体实现如下面的代码片段所示:

1 var speed = 10.0;       //声明速度变量等于10.0

2 function Update () {      //声明Update方法

3  var dir : Vector3 = Vector3.zero;  //确定一个三维空间坐标

4  dir.x = -Input.acceleration.y;   //获取当前三维空间坐标x轴的加速度分量

5  dir.z = Input.acceleration.x;   //获取当前三维空间坐标z轴的加速度分量

6  if (dir.sqrMagnitude > 1)    //对加速度数值进行判断

7   dir.Normalize();

8   dir *= Time.deltaTime;    //获取当前时间

9   transform.Translate (dir * speed); //按指定的速度移动

10 }

6.touches变量

touches变量是声明触控动作,从而确定一些触控动作的状态以及所要解决的问题,由于触控动作是项目开发过程中经常要面对和要解决的问题,因此 touches 变量也会经常用到,具体实现如下面的代码片段所示:

1 function Update () {         //声明Update方法

2  var fingerCount = 0;         //声明计数器fingerCount

3  for (var touch : Touch in Input.touches) {   //对触控事件进行循环

4  if (touch.phase != TouchPhase.Ended && touch.phase != TouchPhase.Canceled)//对触控事件进行判定

5   fingerCount++;         //计数器自加

6  }

7  if (fingerCount > 0)         //对计数器进行判定

8   print ("User has " + fingerCount + " finger(s) touching the screen");//打印说明信息

9 }

Input输入对象不仅拥有丰富的变量,而且还提供了大量的方法,下面将对Input输入对象的方法进行详细的介绍,具体的方法信息如表4-55所示。

表4-55 Input输入对象的主要方法

下面将对各个方法进行详细的介绍,将用真实的代码片段对方法的用法和用途进行讲解。

1.GetAxis方法

GetAxis 方法的作用是返回被标识的虚拟轴的值。这个方法的声明一般都是静态的,具体的方法声明如下所示:

static function GetAxis (axisName : String) : float; //声明静态的GetAxis方法

在开发过程中经常会在屏幕中添加一些 2D 的虚拟轴,可以通过触控事件或者鼠标事件改变虚拟轴的值来控制场景中的游戏对象的变换状态。因此GetAxis方法在开发过程中也会经常用到,首先讲述触控事件下的应用,具体实现如下面的代码片段所示:

1 var speed : float = 10.0;   //声明一个初始值为10.0的浮点型变量speed

2 var rotationSpeed : float = 100.0; //声明一个初始值为100.0的浮点型变量rotationSpeed

3 function Update () {    //声明Update方法

4  var translation : float = Input.GetAxis ("Vertical") * speed;//为声明的变量translation赋初值

5  var rotation : float = Input.GetAxis ("Horizontal") * rotationSpeed;//为声明的变量rotation赋初值

6  translation *= Time.deltaTime;//变量translation等于translation乘以当前时间

7   rotation *= Time.deltaTime; //变量rotation等于rotation乘以当前时间

8  transform.Translate (0, 0, translation); //使游戏对象移动给的距离

9  transform.Rotate (0, rotation, 0);   //使游戏对象旋转给的度数

10 }

上面说明了在触控事件下的GetAxis方法,但是很多时候也会用到鼠标事件,下面就是鼠标事件下的应用,具体实现如下面的代码片段所示:

1 var horizontalSpeed : float = 2.0; //声明一个初始值为2.0的浮点型变量horizontalSpeed

2 var verticalSpeed : float = 2.0; //声明一个初始值为2.0的浮点型变量verticalSpeed

3 function Update () {    //声明Update方法

4  var h : float = horizontalSpeed * Input.GetAxis ("Mouse X");//为声明的变量h赋初值

5  var v : float = verticalSpeed * Input.GetAxis ("Mouse Y");//为声明的变量v赋初值

6  transform.Rotate (v, h, 0);  //使游戏对象旋转给的度数

7 }

2.GetAxisRaw方法

GetAxisRaw方法的作用是返回被标识的虚拟轴的值与不平滑滤波应用,这个方法的声明一般都是静态的,具体的方法声明如下所示:

static function GetAxisRaw (axisName : String) : float; //声明静态的GetAxisRaw方法

GetAxisRaw方法也是虚拟轴的一个特殊应用,其具体实现如下面的代码片段所示:

1 function Update () {        //声明Update方法

2  var speed : float = Input.GetAxisRaw("Horizontal") * Time.deltaTime;//对声明的变量speed赋值

3  transform.Rotate (0, speed, 0);     //使游戏对象旋转给定的度数

4 }

3.GetButton方法

GetButton方法的作用是如果虚拟按钮被按下则返回true,由此进行一些事件的判定。这个方法的声明一般都是静态的,具体的方法声明如下所示:

static function GetButton (buttonName : String) : boolean; //声明静态的GetButton方法

例如一个射击类游戏,经常会在屏幕上设一个虚拟按钮作为子弹的发射按钮,在此就用这个功能的代码片段来讲解GetButton方法的使用,具体实现如下面的代码片段所示。

1 var projectile : GameObject;    //声明一个子弹的游戏对象

2 var fireRate : float = 0.5;    //声明一个初始值为0.5的浮点型变量fireRate

3 private var nextFire : float = 0.0; //声明一个初始值为0.0的浮点型私有变量nextFire

4 function Update () {      //声明Update方法

5  if (Input.GetButton ("Fire1") && Time.time > nextFire) {//对按钮Fire1和时间进行判定

6   nextFire = Time.time + fireRate; //变量nextFire等于当前时间加上变量fireRate

7  //声明一个游戏对象clone,并将实例化的子弹赋给clone

8  var clone : GameObject =Instantiate(projectile, transform.position, transform.rotation) as GameObject;

9  } }

4.GetButtonDown方法

GetButtonDown 方法的作用是当虚拟按钮在被按下的状态时被调用并返回 true,由此来判定一些事件的进展,这个方法的声明一般都是静态的,具体的方法声明如下所示:

static function GetButtonDown (buttonName : String) : boolean;//声明静态的GetButtonDown方法

GetButtonDown方法也是GetButton方法的一个特殊表现形态,其具体的使用方法与GetButton方法差不多,只是在按钮的不同状态下返回对应的值,具体实现如下面的代码片段所示:

1 var projectile : GameObject;    //声明一个子弹的游戏对象

2 function Update () {      //声明Update方法

3  if (Input.GetButtonDown ("Fire1")) { //判断是否被按下Fire1按钮

4   Instantiate (projectile, transform.position, transform.rotation);//若被按下,则实例化一个子弹

5  } }

5.GetButtonUp方法

GetButtonUp方法的作用是当虚拟按钮在被抬起的状态时被调用并返回true,由此来判定一些事件的进展,这个方法的声明一般都是静态的,具体的方法声明如下所示:

static function GetButtonUp (buttonName : String) : boolean;//声明静态的GetButtonUp方法

GetButtonUp方法也是GetButton方法的一个特殊表现形态,其具体的使用方法与GetButton方法差不多,只是在按钮的不同状态下返回对应的值,具体实现如下面的代码片段所示:

1 var projectile : GameObject;    //声明一个子弹的游戏对象

2 function Update () {      //声明Update方法

3  if (Input.GetButtonUp ("Fire1")) {  //判断是否被抬起Fire1按钮

4   Instantiate (projectile, transform.position, transform.rotation);//若被抬起,则实例化一个子弹

5  } }

6.GetKey方法

GetKey方法的作用是如果用户通过键名而获得的按键状态为按下时返回true,由此来判定一些事件的进展,这个方法的声明一般都是静态的,而且还有两种声明方法,分别是通过键名和键码来获得指定键,首先讲解用键名来声明,具体的方法声明如下面代码片段所示:

static function GetKey (name : String) : boolean; //声明静态的GetKey方法

下面用一些具体的代码片段来讲解用键名来声明GetKey方法,具体使用如下面的代码片段所示:

1 function Update () {        //声明Update方法

2  if (Input.GetKey ("up"))       //判断是否得到键名up

3   print ("up arrow key is held down");   //打印提示信息

4  if (Input.GetKey ("down"))      //判断是否得到键名down

5   print ("down arrow key is held down");  //打印提示信息

6 }

再次讲解一下用键码来获得指定的键,其一般的声明也是静态的,具体的方法声明如下面代码片段所示:

static function GetKey (key : KeyCode) : boolean; //声明静态的GetKey方法

下面用一些具体的代码片段来讲解用键码来声明GetKey方法,具体实现如下面的代码片段所示:

1 function Update () {       //声明Update方法

2  if (Input.GetKey (KeyCode.UpArrow))   //判断是否得到键码UpArrow

3   print ("up arrow key is held down");  //打印提示信息

4  if (Input.GetKey (KeyCode.DownArrow))  //判断是否得到键码DownArrow

5   print ("down arrow key is held down") //打印提示信息

6 }

7.GetKeyDown方法

GetKeyDown 方法的作用是如果用户通过键名而获得键值并在开始按下键时返回 true,由此来判定一些事件的进展,这个方法的声明一般都是静态的,而且还有两种声明方法,分别是通过键名和键码来获得指定键,首先讲解用键名来声明,具体的方法声明如下面代码片段所示:

static function GetKeyDown (name : String) : Boolean; //声明静态的GetKeyDown方法

下面用一些具体的代码片段来讲解用键名来声明GetKeyDown方法,具体使用如下面的代码片段所示:

1 function Update () {        //声明Update方法

2  if (Input.GetKeyDown ("space"))     //判断是否得到键名space

3   print ("space key was pressed");    //打印提示信息

4 }

再次讲解一下用键码来获得指定的键,其一般的声明也是静态的,具体的方法声明如下面代码片段所示:

static function GetKeyDown (key : KeyCode) : boolean; //声明静态的GetKeyDown方法

下面用一些具体的代码片段来讲解用键码来声明GetKeyDown方法,具体实现如下面的代码片段所示:

1 function Update () {        //声明Update方法

2  if (Input.GetKeyDown (KeyCode.Space))   //判断是否得到键码Space

3   print ("space key was pressed");    //打印提示信息

4 }

8.GetKeyUp方法

GetKeyUp方法的作用是如果用户通过键名而获得键的并在开始抬起键时返回true,由此来判定一些事件的进展,这个方法的声明一般都是静态的,而且还有两种声明方法,分别是通过键名和键码来获得指定键,首先讲解用键名来声明,具体的方法声明如下面代码片段所示:

static function GetKeyUp (name : String) : boolean ; //声明静态的GetKeyDown方法

下面用一些具体的代码片段来真正讲解用键名来声明GetKeyUp方法,具体实现如下面的代码片段所示:

1 function Update () {        //声明Update方法

2  if (Input.GetKeyUp ("space"))     //判断是否得到键名space

3   print ("space key was released");   //打印提示信息

4 }

再次讲解一下用键码来获得指定的键,其一般的声明也是静态的,具体的方法声明如下面代码片段所示:

static function GetKeyUp (key : KeyCode) : boolean; //声明静态的GetKeyDown方法

下面用一些具体的代码片段来讲解用键码来声明GetKeyUp方法,具体实现如下面的代码片段所示:

1 function Update () {      //声明Update方法

2  if (Input.GetKeyUp (KeyCode.Space))  //判断是否得到键码Space

3   print ("space key was released"); //打印提示信息

4 }

9.GetMouseButton方法

GetMouseButton方法的作用是返回指定的鼠标按钮是否被按下,由此来判定一些事件的进展,这个方法的声明一般都是静态的,具体的方法声明如下面代码片段所示:

static function GetMouseButton (button : int) : boolean;//声明静态的GetMouseButton方法

下面用一个简单的例子来讲解一下GetMouseButton方法及具体使用,首先是声明3个鼠标按钮,Left Button的键值为0,Right Button的键值为 1,Middle Button的键值为3,通过获得键值来执行相应的操作。具体实现如下面的代码片段所示:

1 function Update() {      //声明Update方法

2  if(Input.GetMouseButton(0))    //判断是否具有键值为0的鼠标按钮持有权

3   Debug.Log("Pressed left click."); //打印提示信息

4  if(Input.GetMouseButton(1))    //判断是否具有键值为1的鼠标按钮持有权

5   Debug.Log("Pressed right click."); //打印提示信息

6  if(Input.GetMouseButton(2))    //判断是否具有键值为2的鼠标按钮持有权

7   Debug.Log("Pressed middle click."); //打印提示信息

8 }

10.GetMouseButtonDown方法

GetMouseButtonDown方法的作用是若指定的鼠标按钮被按下则返回true,由此来判定一些事件的进展,这个方法的声明一般都是静态的,具体的方法声明如下所示:

static function GetMouseButtonDown (button : int) : boolean;//声明静态的GetMouseButtonDown方法

下面依然用上面的例子来对GetMouseButtonDown方法进行说明,即首先是声明3个鼠标按钮,Left Button的键值为0,Right Button的键值为 1,Middle Button的键值为3,通过获得键值来执行相应的操作。具体实现如下面的代码片段所示:

1 function Update() {      //声明Update方法

2  if(Input.GetMouseButtonDown(0))   //对鼠标按下键值为0的按钮事件进行判定

3   Debug.Log("Pressed left click."); //打印提示信息

4  if(Input.GetMouseButtonDown(1))   //对鼠标按下键值为0的按钮事件进行判定

5   Debug.Log("Pressed right click."); //打印提示信息

6  if(Input.GetMouseButtonDown(2))   //对鼠标按下键值为0的按钮事件进行判定

7   Debug.Log("Pressed middle click."); //打印提示信息

8 }

11.GetMouseButtonUp方法

GetMouseButtonUp方法的作用是若指定的鼠标按钮被抬起时则返回true,由此来判定一些事件的进展,这个方法的声明一般都是静态的,具体的方法声明如下所示:

static function GetMouseButtonUp (button : int) : boolean;//声明静态的GetMouseButtonUp方法

下面依然用上面的例子来对GetMouseButtonUp方法进行说明,即首先是声明3个鼠标按钮, Left Button的键值为0,Right Button的键值为1,Middle Button的键值为3,通过获得键值来执行相应的操作。具体实现如下面的代码片段所示:

1 function Update() {      //声明Update方法

2  if(Input.GetMouseButtonUp(0))   //对鼠标抬起键值为0的按钮事件进行判定

3   Debug.Log("Pressed left click."); //打印提示信息

4  if(Input.GetMouseButtonUp(1))   //对鼠标抬起键值为1的按钮事件进行判定

5   Debug.Log("Pressed right click."); //打印提示信息

6  if(Input.GetMouseButtonUp(2))   //对鼠标抬起键值为2的按钮事件进行判定

7   Debug.Log("Pressed middle click."); //打印提示信息

8 }

12.GetTouch方法

GetTouch方法的作用是返回当前触控事件的触控状态,这个方法的声明一般都是静态的,具体的方法声明如下所示:

static function GetTouch (index : int) : Touch; //声明静态的GetTouch方法

在游戏开发过程中还经常会遇到这样的触控问题,例如是子弹的生成与发射,当触控发射按钮就会生成一个子弹发射出去,这个在射击类游戏中是必不可少的环节,因此这样的触控问题也是必须解决的,这时就必须用到GetTouch方法,具体实现如下面的代码片段所示:

1 var particle : GameObject;     //声明一个子弹的游戏对象

2 function Update () {      //声明Update方法

3  for (var i = 0; i < Input.touchCount; ++i) {  //对触控点进行循环

4   if (Input.GetTouch(i).phase == TouchPhase.Began){//判断触控事件是否为刚开始触控

5    //创建一条垂直于屏幕触控点的射线ray

6    var ray = Camera.main.ScreenPointToRay (Input.GetTouch(i).position);

7    if (Physics.Raycast (ray)) {//是否触控到射线ray

8     //若触控到,则实例化子弹

9     Instantiate (particle, transform.position, transform.rotation);

10   } } } }