1 前言

​ Input 是 Unity3D 中用于人机交互的工具类,用户可以调用其 GetKey、GetMousePosition、GetMouseButton、GetAxis、GetButton 等方法获取键盘和鼠标的状态信息,再通过这些状态信息控制游戏对象,从而实现人机交互。

1)键盘输入

// 按住按键
public static bool GetKey(KeyCode key)
// 按下按键
public static bool GetKeyDown(KeyCode key)
// 抬起按键
public static bool GetKeyUp(KeyCode key)

​ KeyCode 的取值有:

A~Z
F1~F15
// 键盘顶部的数字
Alpha0~Alpha9
Left、RightArrow、UpArrow、DownArrow
LeftCtrl、LeftShift、LeftAlt、LeftWindows、RightCtrl、RightShift、RightAlt、RightWindows
Tab、Space、Backspace、Return
// 加号、减号、星号、斜杠、反斜杠、左括号、右括号、小于号、大于号、等于号、上尖号
Plus、Minus、Asterisk、Slash、Backslash、LeftBracket、RightBracket、Less、Greater、Equals、Caret
// 逗号、点号、问号、分号、冒号、单引号、反引号、双引号、感叹号
Comma、Period、Question、Semicolon、Colon、Quote、BackQuote、DoubleQuote、Exclaim
// @符号、$符号、&符号、下划线
At、Dollar、Ampersand、Underscore
Insert、Delete、Home、End、PageUp、PageDown、Print
CapsLock、Numlock、ScrollLock
Keypad0~Keypad9、KeypadPeriod
KeypadPlus、KeypadMinus、KeypadMultiply、KeypadDivide
KeypadEquals、KeypadEnter
// 鼠标左键、鼠标右键、鼠标中间
Mouse0、Mouse1、Mouse2

2)鼠标输入

// 按住鼠标
public static bool GetMouseButton(int button)
// 按下鼠标
public static bool GetMouseButtonDown(int button)
// 抬起鼠标
public static bool GetMouseButtonUp(int button)
// 鼠标坐标
Vector3 position = Input.mousePosition

​ 说明:button 取值为 0、1、2,分别表示鼠标左键、右键、中键。

3)虚拟轴输入

​ 在【Edit→Project Settings→Input】中可以打开 InputManager 配置界面,用户可以在此配置虚拟轴信息。

// 按左右箭头或A、D键,hor在-1~1之间变化
float hor = Input.GetAxis("Horizontal");
// 按上下箭头或W、S键,hor在-1~1之间变化
float ver = Input.GetAxis("Vertical");
// 获取鼠标在水平方向上的移动
float mouseX = Input.GetAxis("Mouse X");
// 获取鼠标在竖直方向上的移动
float mouseY = Input.GetAxis("Mouse Y");
// 获取滚轮信息, 上滑为正, 下滑为负
float scroll = Input.GetAxis("Mouse ScrollWheel");

4)虚拟按键输入

​ InputManager 配置界面配置虚拟按键,如下:

// 按住虚拟按键
public static bool GetButton(string buttonName)
// 按下虚拟按键
public static bool GetButtonDown(string buttonName)
// 抬起虚拟按键
public static bool GetButtonUp(string buttonName)
// 按以上配置,按住Q键或鼠标左键返回true,表示开火了
bool fire = Input.GetButton("Fire");

5)鼠标回调方法

using UnityEngine;

public class MouseEventTest : MonoBehaviour {
private void OnMouseEnter() { // 鼠标进入碰撞体时回调
Debug.Log("OnMouseEnter");
} private void OnMouseOver() { // 鼠标悬浮在碰撞体上回调
Debug.Log("OnMouseOver");
} private void OnMouseExit() { // 鼠标离开碰撞体时回调
Debug.Log("OnMouseExit");
} private void OnMouseDown() { // 鼠标在碰撞体上按下了左键时回调
Debug.Log("OnMouseDown");
} private void OnMouseUp() { // 鼠标在碰撞体上按下了左键, 并且抬起时回调(此时不一定悬浮在碰撞体上)
Debug.Log("OnMouseUp");
} private void OnMouseUpAsButton() { // 鼠标按下和抬起都在同一个碰撞体上, 并且抬起了鼠标左键时回调
Debug.Log("OnMouseUpAsButton");
} private void OnMouseDrag() { // 鼠标在碰撞体上按下, 并拖拽时回调(拖拽过程中不一定悬浮在碰撞体上)
Debug.Log("OnMouseDrag");
}
}

​ 说明:MouseEventTest 挂在需要触发鼠标事件的对象上,并且该对象有碰撞体组件,2D UI 需要添加 BoxCollider2D 组件。

2 应用

​ 本节将实现坦克对战游戏。

1)实现需求

  • 绘制2个坦克,一个表示己方,一个表示敌方;
  • 用户可以通过上下箭头按键控制己方坦克前后移动,通过左右箭头按键控制己方坦克左右移动或左右转向;
  • 用户可以通过鼠标左键发射炮弹;
  • 敌方坦克可以自动转向瞄准己方坦克,但是有延时,转向先快后慢,延时插值系数为 0.6;
  • 敌方坦克瞄准己方坦克后(允许有5°误差),自动开炮,开炮间隔需要大于1秒。

2)创建游戏对象

​ 游戏对象的 Transform 组件参数如下:

name type position Rotation scale Color/Texture
MyTank Empty (0, 0.25, -5) (0, 0, 0) (1, 1, 1) ——
Button Cube (0, 0, 0) (0, 0, 0) (2, 0.5, 2) #228439FF
Top Cube (0, 0.5, 0) (0, 0, 0) (1, 0.5, 1) #228439FF
Gun Cylinder (0, 0, 1.5) (90, 0, 0) (0.2, 1, 0.4) #228439FF
FirePoint Empty (0, 1.15, 0) (0, 0, 0) (1, 1, 1) ——
MyBullet Sphere (0, 0, -2) (0, 0, 0) (0.2, 0.2, 0.2) #82EA4FFF
Plane Plane (0, 0, 0) (0, 0, 0) (10, 10, 10) GrassRockyAlbedo
EnemyTank Empty (0, 0.25, 5) (0, 180, 0) (1, 1, 1) 15D3F9FF
EnemyBullet Sphere (0, 0, 2) (0, 0, 0) (0.2, 0.2, 0.2) #4C55F8FF

​ 说明: EnemyTank 由 MyTank复制而来,只是修改了它自己及其子对象的颜色属性;EnemyBullet 由 MyBullet 复制而来,然后修改了颜色属性;将 MyBullet 和 EnemyBullet 拖拽至 Assets 窗口的 Resources/Prefabs 目录下,生成预设体(prefab),再删除 Hierarchy 窗口下 MyBullet 和 EnemyBullet 对象。

​ 游戏对象的层级结构如下:

​ 游戏界面如下:

3)脚本组件

​ MyTank.cs

using UnityEngine;

public class MyTank : MonoBehaviour {
private Transform firePoint; // 开火点
private GameObject bulletPrefab; // 炮弹预设体 void Start() {
firePoint = transform.Find("Top/Gun/FirePoint");
bulletPrefab = (GameObject) Resources.Load("Prefabs/MyBullet");
Debug.Log(bulletPrefab);
} void Update () {
float hor = Input.GetAxis("Horizontal");
float ver = Input.GetAxis("Vertical");
move(hor, ver);
if (Input.GetMouseButtonDown(0)) { // 开炮
GameObject bullet = Instantiate(bulletPrefab, firePoint.position, Quaternion.identity); // 通过预设体创建炮弹
bullet.GetComponent<Bullet>().setMoveDir(transform.forward); // 设置炮弹飞出方向
}
} private void move(float hor, float ver) {
// 移动方案一:上下箭头控制前后移动,左右箭头控制左右移动
// transform.Translate(hor * Time.deltaTime * 3, 0, ver * Time.deltaTime * 3); // 移动方案二:上下箭头控制前后移动,左右箭头控制左右拐弯
transform.Translate(0, 0, ver * Time.deltaTime * 3);
transform.Rotate(Vector3.up * hor * Time.deltaTime * 120f);
}
}

​ 说明:MyTank.cs 脚本组件挂载在 MyTank 游戏对象上。

​ EnemyTank.cs

using UnityEngine;

public class EnemyTank : MonoBehaviour {
private Transform target; // 目标
private Transform top; // 炮头
private Transform firePoint; // 开火点
private GameObject bulletPrefab; // 炮弹预设体
private float fireInternal = 0; // 开炮间隔 void Start () {
target = GameObject.Find("MyTank/Top").transform;
top = transform.Find("Top");
firePoint = transform.Find("Top/Gun/FirePoint");
bulletPrefab = (GameObject) Resources.Load("Prefabs/EnemyBullet");
} void Update () {
Quaternion dir = Quaternion.LookRotation(target.position - top.position);
top.rotation = Quaternion.Lerp(top.rotation, dir, Time.deltaTime * 0.6f); // 敌军转向己方
float angle = Vector3.Angle(target.position - top.position, top.forward);
if (angle < 5 && fireInternal > 1) {
GameObject bullet = Instantiate(bulletPrefab, firePoint.position, Quaternion.identity); // 通过预设体创建炮弹
bullet.GetComponent<Bullet>().setMoveDir(top.forward); // 设置炮弹飞出方向
fireInternal = 0;
}
fireInternal += Time.deltaTime;
}
}

​ 说明:EnemyTank.cs 脚本组件挂载在 EnemyTank 游戏对象上。

​ Bullet.cs

using UnityEngine;

public class Bullet : MonoBehaviour {
private Vector3 moveDir; // 炮弹飞出方向 void Start () {
Destroy(gameObject, 2); // 2秒后自动销毁
} void Update () {
if (moveDir != null) {
transform.Translate(moveDir * Time.deltaTime * 6);
}
} public void setMoveDir(Vector3 dir) {
moveDir = dir;
}
}

​ 说明:Bullet.cs 脚本组件挂载在 MyBullet 和 EnemyBullet 预设体上。

4)运行效果

​ 左右箭头按键控制己方坦克左右移动

​ 左右箭头按键控制己方坦克左右转向

​ 声明:本文转自【Unity3D】人机交互Input

【Unity3D】人机交互Input的更多相关文章

  1. 【转】Unity3D的输入(Input)——键盘和鼠标

    http://blog.csdn.net/lingyun_blog/article/details/41451565 Unity3D使用input类控制用户的输入,输入包括了用户键盘,鼠标,触摸,重力 ...

  2. 【Unity3D基础】让物体动起来②--UGUI鼠标点击逐帧移动

    背景 上一篇通过鼠标移动的代码很简单,所以看的人也不多,但是还是要感谢“武装三藏”在博客园给出的评论和支持,希望他也能看到第二篇,其实可以很简单,而且是精灵自控制,关键是代码少是我喜欢的方式,也再次印 ...

  3. Unity3d监听手机暂停与退出事件

    做移动互联网类型的开放,很多情况得考虑移动设备的暂停与退出时,做某些数据操作或UI. 1,退出事件,Unity3d,InPut就包含了: Input.GetKey(KeyCode.Escape) .  ...

  4. Unity学习之路——主要类

    学习https://blog.csdn.net/VRunSoftYanlz/article/details/78881752 1.Component类gameObject:组件附加的游戏对象.组件总是 ...

  5. [Unity3D]做个小Demo学习Input.touches

    [Unity3D]做个小Demo学习Input.touches 学不如做,下面用一个简单的Demo展示的Input.touches各项字段,有图有真相. 本项目已发布到Github,地址在(https ...

  6. 【Unity3D基础教程】给初学者看的Unity教程(一):GameObject,Compoent,Time,Input,Physics

    作者:王选易,出处:http://www.cnblogs.com/neverdie/  欢迎转载,也请保留这段声明.如果你喜欢这篇文章,请点推荐.谢谢! Unity3D重要模块的类图 最近刚刚完成了一 ...

  7. Unity3D 中鼠标按下时OnMouseDown()、Input.GetMouseButtonDown()和EventType.MouseDown的响应验证

    初学unity3D,对于其中的事件响应不是很清楚,于是写了下面的代码来验证: 1.新建.cs文件,名为testMouse.cs: using UnityEngine; using System.Col ...

  8. Unity3D for VR 学习(3): 暴风魔镜PC Input小改造–自己动手、丰衣足食

    在做手游的时候,80%时间是在PC调试的,例如业务逻辑.AI算法.核心玩法等. 拿到魔镜提供的demo,晕了,必须得安装到Android机器上,才能调试,究其原因,有三: 需要用到手机陀螺仪 需要用到 ...

  9. 【python系统学习05】input函数——实现人机交互

    input函数 目录 input用途 语法 示例 参数 返回值 返回值数据类型转换 容错处理 动手吧 input用途 实现人机交互: 1.你提出问题打印在屏幕上, 2.运行程序的人再输入回答. 3.按 ...

  10. [原]Unity3D深入浅出 - 常用类的成员变量和成员函数(Tranform、Time、Random、Mathf、Input)

    Transform的成员变量 Transform的成员函数 Time类,获取和时间相关的信息,可用来计算帧速率,调整时间流逝的速度等. Random类,可用来生成随机数,随机点和旋转. Mathf类提 ...

随机推荐

  1. 配置Maven项目时无法找到依赖

    1.问题 在配置pom.xml文件时,关于plugin插件配置时,遭遇许多类似 未找到插件 'maven-clean-plugin:3.1.0' 未找到插件 'org.apache.maven.plu ...

  2. Laravel - Eloquent 更新数据

    public function ormUpdate()     {         # 1.通过模型更新数据        /*  $student = Student::find(14);      ...

  3. C++11 同步与互斥

    C++11 同步与互斥 0. C++11的线程 #include <thread> 面向对象的接口 RAII(资源获取即初始化)机制,当线程对象被销毁时,会自动执行析构函数,如果线程仍然在 ...

  4. Go-错误-error

  5. Go-强制类型转换-T(x)

    类型转换 T(x) 具有相同的底层类型 数字类型之间可以互相转换(int系 uint系 float系),较大数转换成较小数会损失精度 字符串与切片之间的转换 string <==> []r ...

  6. 使用requests爬虫遇到的一个奇葩的问题:UnicodeEncodeError: 'latin-1' codec can't encode character

    每一位成功的程序员,背后也许都站着无数的秃头的男人--为其提供各种开发工具&代码库,当然也包括-- 各种玄学bug-- 玄学的开端 最近在用Python做一个爬虫项目的时候遇到一个很奇怪的问题 ...

  7. 【特别的骚气】asp.net core运行时注入服务,实现类库热插拔

    引言 很久之前在群里有看到说asp.net core能不能在运行时注入程序,当时并没有太在意,刚才在某个群里又看到有人再问,core能不能在运行时注入服务,闲来无事,我就研究了一下,其实也比较简单,在 ...

  8. [转帖]SQL SERVER中什么情况会导致索引查找变成索引扫描

    https://www.cnblogs.com/kerrycode/p/4806236.html SQL Server 中什么情况会导致其执行计划从索引查找(Index Seek)变成索引扫描(Ind ...

  9. [转帖]linux将大目录等分切割成多个小目录

    https://www.jianshu.com/p/6f9e6743a1dc 需求:有一个目录存放了数十万个文件,现在需要将这个目录上传,如果整个目录上传,中间因为某些故障断开连接了,可能又要从头开始 ...

  10. [转帖]shell脚本字符串截取的8种方法

    https://www.cnblogs.com/zwgblog/p/6031256.html 假设有变量 var=http://www.aaa.com/123.htm. 1. # 号截取,删除左边字符 ...