【Unity3D】人机交互Input
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的更多相关文章
- 【转】Unity3D的输入(Input)——键盘和鼠标
http://blog.csdn.net/lingyun_blog/article/details/41451565 Unity3D使用input类控制用户的输入,输入包括了用户键盘,鼠标,触摸,重力 ...
- 【Unity3D基础】让物体动起来②--UGUI鼠标点击逐帧移动
背景 上一篇通过鼠标移动的代码很简单,所以看的人也不多,但是还是要感谢“武装三藏”在博客园给出的评论和支持,希望他也能看到第二篇,其实可以很简单,而且是精灵自控制,关键是代码少是我喜欢的方式,也再次印 ...
- Unity3d监听手机暂停与退出事件
做移动互联网类型的开放,很多情况得考虑移动设备的暂停与退出时,做某些数据操作或UI. 1,退出事件,Unity3d,InPut就包含了: Input.GetKey(KeyCode.Escape) . ...
- Unity学习之路——主要类
学习https://blog.csdn.net/VRunSoftYanlz/article/details/78881752 1.Component类gameObject:组件附加的游戏对象.组件总是 ...
- [Unity3D]做个小Demo学习Input.touches
[Unity3D]做个小Demo学习Input.touches 学不如做,下面用一个简单的Demo展示的Input.touches各项字段,有图有真相. 本项目已发布到Github,地址在(https ...
- 【Unity3D基础教程】给初学者看的Unity教程(一):GameObject,Compoent,Time,Input,Physics
作者:王选易,出处:http://www.cnblogs.com/neverdie/ 欢迎转载,也请保留这段声明.如果你喜欢这篇文章,请点推荐.谢谢! Unity3D重要模块的类图 最近刚刚完成了一 ...
- Unity3D 中鼠标按下时OnMouseDown()、Input.GetMouseButtonDown()和EventType.MouseDown的响应验证
初学unity3D,对于其中的事件响应不是很清楚,于是写了下面的代码来验证: 1.新建.cs文件,名为testMouse.cs: using UnityEngine; using System.Col ...
- Unity3D for VR 学习(3): 暴风魔镜PC Input小改造–自己动手、丰衣足食
在做手游的时候,80%时间是在PC调试的,例如业务逻辑.AI算法.核心玩法等. 拿到魔镜提供的demo,晕了,必须得安装到Android机器上,才能调试,究其原因,有三: 需要用到手机陀螺仪 需要用到 ...
- 【python系统学习05】input函数——实现人机交互
input函数 目录 input用途 语法 示例 参数 返回值 返回值数据类型转换 容错处理 动手吧 input用途 实现人机交互: 1.你提出问题打印在屏幕上, 2.运行程序的人再输入回答. 3.按 ...
- [原]Unity3D深入浅出 - 常用类的成员变量和成员函数(Tranform、Time、Random、Mathf、Input)
Transform的成员变量 Transform的成员函数 Time类,获取和时间相关的信息,可用来计算帧速率,调整时间流逝的速度等. Random类,可用来生成随机数,随机点和旋转. Mathf类提 ...
随机推荐
- Pycharm配置git
原文链接:https://www.jianshu.com/p/ae92970d2062 1.下载Gitee插件 同样在设置页面,选中 Plugins,并搜索 Gitee安装. 安装后,重启一下Pych ...
- 日常测试进行beans比较的简单方法
日常测试进行beans比较的简单方法 摘要 想每天把有变化的bean抓取出来有新增的beans时能够及时进行分析和介入 保证beans 都是符合规范的. 方式和方法 开启actuator 打开bean ...
- 基于eBPF的微服务网络安全(Cilium 1)
基于eBPF的微服务网络安全 翻译自:Network security for microservices with eBPF 一些开源的kubernetes工具已经开始使用eBPF,这些工具大多数与 ...
- pytest单元测试基本使用
一.pytest安装 pip install pytest:安装 pip install pytest==version:指定版本安装 pytest --version:查看版本 pip instal ...
- forEach在项目中的使用
forEach 会改变原始数组 被forEach循环的数组不能够为空 forEach会改变原始数组 value是内容 index是索引 array是你写的数组. foeEach内部是异步的哈 功能描述 ...
- 【JS 逆向百例】房天下登录接口参数逆向
声明 本文章中所有内容仅供学习交流,严禁用于商业用途和非法用途,否则由此产生的一切后果均与作者无关,若有侵权,请联系我立即删除! 逆向目标 目标:房天下账号密码登录 主页:https://passpo ...
- 【JS 逆向百例】网洛者反爬练习平台第二题:JJEncode 加密
关注微信公众号:K哥爬虫,持续分享爬虫进阶.JS/安卓逆向等技术干货! 声明 本文章中所有内容仅供学习交流,抓包内容.敏感网址.数据接口均已做脱敏处理,严禁用于商业用途和非法用途,否则由此产生的一切后 ...
- MeshFilter mesh vs sharedMesh
MeshFilter有两个属性mesh和sharedMesh,从官方文档和实际使用来说说这两者的区别 MeshFilter文档 Unity的MeshFilter文档:https://docs.unit ...
- 基于中文金融知识的 LLaMA 系微调模型的智能问答系统:LLaMA大模型训练微调推理等详细教学
基于中文金融知识的 LLaMA 系微调模型的智能问答系统:LLaMA大模型训练微调推理等详细教学 基于 LLaMA 系基模型经过中文金融知识指令精调/指令微调(Instruct-tuning) 的微调 ...
- 样本数量不平衡问题方案(Focal Loss & Circle Loss)
1.Focal Loss focal loss是最初由何恺明提出的,最初用于图像领域解决数据不平衡造成的模型性能问题.本文试图从交叉熵损失函数出发,分析数据不平衡问题,focal loss与交叉熵损失 ...