unity transform_Unity 操作检测的各种实现#1电脑端

写在前面

之前开了个坑,现在来填了。操作判断是个大问题,今天就来总结Unity里面常用的操作检测。根据我们开发的应用类型,可分为电脑和手机应用,因此在不同的平台上操作方式可以分为两大类:

  1. 电脑端
    1. 键盘按键控制
    2. 鼠标点击控制
  2. 手机端
    1. 触屏控制
    2. 手势控制
    3. 重力控制
    4. 陀螺仪控制

本文的限制:1 Unity也支持需要用到手柄或VR头盔的应用平台,但在这些平台上也只不过是对上述操作控制进行变种设计而已,这里就不展开说了。2 既然涉及到检测,就一定有对应的移动和转向等命令,命令的实现有很多种方法。如果讲到相关例子,并不代表最佳用法。

正文

绝大多数的输入判断,都需要用到Input类,而Keycode类则用来表示键盘上的按键

Unity - Scripting API: Input​docs.unity3d.com
e997994d5c768f52c1fd1c50229d412f.png
Unity - Scripting API: KeyCode​docs.unity3d.com
e997994d5c768f52c1fd1c50229d412f.png

1 按键输入

与按键相关的方法有两个,一是GetKey(),另一个是GetAxis()

GetKey()例子:

If (Input.GetKey(KeyCode.A))
{
    Debug.Log("A pressed");
}

GetKey()方法检测的是这个按键是否被一直按住,GetKeyDown()检测按键被按下,GetKeyU()检测按键抬起。举个例子,一个推箱子游戏,每次按下一次按键才会向前推进,那么你就可以使用GetKeyDown。但是像一些即时战略的游戏则需要用到GetKey,玩家按住按键,自己的角色就会一直往前跑。

GetAxis()例子:

float v = verticalSpeed * Input.GetAxis("Horizontal");
float h = horizontalSpeed * Input.GetAxis("Vertical");
transform.Rotate(v, h, 0);

你可以去Project Settings -> Input中自定义自己的按键,比如你可以把空格键叫作Fire,使用Input.GetButton("Fire")检测Space按键。

9f56e5a406b556927dc512fddfaea770.png

2 鼠标点击输入

检测哪个鼠标按键被按下,可以使用Input.GetMouseButtonDown()方法,当传入值为0时,检测鼠标左键。当传入值为1时,检测鼠标右键。当传入值为2时,检测鼠标中键。

If (nput.GetMouseButtonDown(0))
{
     Debug.Log("Primary Mouse Button Pressed"); 
}

当然你的手有没有按下去,这个好说,但是游戏里面,游戏界面上的鼠标到底有否按到东西呢?或者其他可以用鼠标实现的想法,例如枪有否打中人呢?这些需要使用到光线投射(Raycast)的物理概念来解释。在物理层面,如果我们给定一个光源和一个方向,那么光线就会一直向前跑(假设它在真空中),最后到达一个妨碍它继续前进的物体表面。

在Unity中,这个物体表面表现为一个带有碰撞体(Collider)信息的物体。如果发出的射线有穿过任意一个碰撞体,则回传碰撞体的资讯,其中包括该物件的名称、世界坐标等。如下图

b6cf6939e8a58aa7128cd850b51db3da.png
Raycast 示意图
Unity - Scripting API: Physics.Raycast​docs.unity3d.com
e997994d5c768f52c1fd1c50229d412f.png

要取得鼠标点击的位置,可以用Input.position。我们的Main Camera可以作为起点来创建一条Ray(射线),把摄像机到点击位置的的向量,当作射线方向。根据这条射线,参考上图,判断是否碰到碰撞体。当然,Input类返回的点击位置不能直接使用,需用Camera.main.ScreenPointToRay()方法将其转成可用参数

Camera.main其实就等同于GameObject.FindGameObjectWithTag("Main Camera").GetComponent<Camera>(); 这一句。很长对伐!你每次用Camera.main都会调用这么长一串东西哟!
Camera cam = Camera.main;
Ray ray = cam.ScreenPointToRay(Input.position); // 这是起点产生的Ray
RaycastHit hit; // 这是用来检测碰撞的Ray,如果有则存入hit内
if (Physics.Raycast(ray, out hit))
{
    Debug.Log(hit.transform.name); // 输出点击物体名称
}

Raycast小技巧:

Raycast还可以传入Layermask来过滤一些你不感兴趣的碰撞事件,

Layermask layermask;
if (Physics.Raycast(ray, out hit,layermask))
{
    Debug.Log(hit.transform.name); // 输出点击物体名称
}

没带有你所设定Layer的物件都会被这条Raycast无视,是不是非常惨。

d0017f5c803505896457aff9aa394ea6.png

电脑端完,热身完了,接下来会继续填坑的 ...

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值