1.10 从0开始学习Unity游戏开发--接收用户输入

在1.8章节里面,我们详细介绍了Unity里面开发游戏逻辑的一个比较重要的概念,就是组件(MonoBehaviour),只要你的逻辑需要关联上GameObject,那么基本上都是从组件来开始编写逻辑。

有了这个前提之后,我们回顾一下最开始讲解游戏逻辑的几个大块:

  1. 接收用户输入
  2. 处理逻辑
  3. 渲染画面

那么本篇我们将会讲解如何完成第一步,也就是接收用户输入的这个逻辑。

原生输入

如果本职工作是windows上原生开发,那么对windows上如果要处理用户输入就比较熟悉,其实就是处理windows消息,MSDN的官方文档在这里Using Messages and Message Queues - Win32 apps | Microsoft LearnThe following code examples demonstrate how to perform the following tasks associated with Windows messages and message queues.https://learn.microsoft.com/en-us/windows/win32/winmsg/using-messages-and-message-queues

如果把里面关键点拿出来就是

while (PeekMessage(&msg, hwnd,  0, 0, PM_REMOVE)) 
{ 
    switch(msg.message) 
    { 
        case WM_LBUTTONDOWN: 
            // 处理鼠标左键按下
            break;
        case WM_RBUTTONDOWN: 
            // 处理鼠标右键按下
            break;
        case WM_KEYDOWN: 
            // 处理键盘按键按下
            break;
    } 
} 

可以看到就是一个循环,然后每次从消息队列里面取一个消息来获取当前用户输入状态。

其他的框架或者系统也有可能将其封装成一个事件回调函数,但是处理起来也还是差不多的。

Unity用户输入

Unity因为要跨平台,上一章里面也讲了你只要安装好了对应平台的支持包,那基本上Unity希望你不太需要改你的普通逻辑代码就能直接编译跑在对应平台上。

所以肯定也不可能让你自己用原生代码写了再搞进去,太麻烦,那么Unity封装了这样一个用户输入库,叫Input。官方文档在这里:

Unity - Scripting API: Inputhttps://docs.unity3d.com/ScriptReference/Input.html

官方文档也给了个简单的例子:

using UnityEngine;
using System.Collections;

public class ExampleClass : MonoBehaviour
{
    public void Update()
    {
        if (Input.GetButtonDown("Fire1"))
        {
            Debug.Log(Input.mousePosition);
        }
    }
}

看起来是不是很类似,也是循环(Update函数是每帧都调用一次,可以理解为某种形式上的循环)中不停的处理消息(Input类给你获取当前消息里面有没有输入内容)。

好像挺简单的,但是等着,这个GetButtonDown的参数为啥是Fire1?难道不应该是鼠标左键之类的名字吗?

有的有的,且看这个函数:

Unity - Scripting API: Input.GetMouseButtonDownhttps://docs.unity3d.com/ScriptReference/Input.GetMouseButtonDown.html

using UnityEngine;
using System.Collections;

// Detects clicks from the mouse and prints a message
// depending on the click detected.

public class ExampleClass : MonoBehaviour
{
    void Update()
    {
        if (Input.GetMouseButtonDown(0))
            Debug.Log("Pressed primary button.");

        if (Input.GetMouseButtonDown(1))
            Debug.Log("Pressed secondary button.");

        if (Input.GetMouseButtonDown(2))
            Debug.Log("Pressed middle click.");
    }
}

可以看到这个0,1,2分别对应了鼠标上的三个主要按键。

那么回到上面,为啥Unity提供了一个Fire1这样一个奇怪的按键名字呢?

道理也还是跟跨平台类似,如果你的游戏只发布在PC端,而且只支持键鼠操作,那确实直接响应键盘鼠标事件是最直接的,但是游戏这个东西,很多时候是可以用手柄玩的!那么手柄上可没有什么鼠标左键这样的按键,都是ABXY或者XO方块三角,这样的按键。

当然你也可以说我再接入对应平台的接口不就好了?确实是如此,但是这样的话,上面这个代码是不是每个平台都得写一遍。

比如人物移动在键盘上是wasd四个键,但是在手柄上就是摇杆,用的接口和名字可能都不同。

所以Unity为了方便你写一套逻辑代码支持各种输入设备适配,做了这样一个封装,你要做的就是将具体的输入设备的按键名字翻译成对应的逻辑名字,比如你按下鼠标左键是开火,那么你可以为开火(Fire1)通过配置来映射到物理设备输入上,具体来说就是在Unity的顶部菜单,找到Edit->ProjectSettings,可以看到这里有一个InputManager:

可以看到右侧就能看到Axes列表里面有一个Fire1,这里我们就可以配置它对应按键映射,这里初见其实还是比较难理解的。

首先Unity将所有按键都理解为一种可以正向或者反向按的按键,就跟手柄上摇杆类似,摇杆如果左摇是负向,那右摇就是正向,对应上面说的Negative Button和Positive Button。

Alt就是Alternative的意思,意味着是备选,可以看大Fire1这个输入,正向输入的首选是左Ctrl,备选才是鼠标按键0。

而且我也要吐槽一下,这里居然都是输入框,不是可以搜索的下拉列表,这随便写就容易写错,具体有哪些可以用的,可以参考官方文档的Mapping virtual axes to controls这个节:

Unity - Manual: Input Managerhttps://docs.unity3d.com/Manual/class-InputManager.html

Unity官方可能也是意识到这个设计比较挫,所以提供了新一代的输入管理系统:

Input System | Input System | 1.5.1https://docs.unity3d.com/Packages/[email protected]/manual/index.html

光看这个展示截图就好理解太多了

但是缺点就是这个包不是Unity自带的,需要手动安装,并且代码也有所不同,为了减少教程的复杂度,这个我们就按下不表,后面仍然使用Unity内置的Input来做输入处理讲解。

下一章

好了,既然我们已经理解了输入操作怎么处理,那么我们可以小试牛刀,将场景里面唯一的摄像机移动移动位置,毕竟我们学了这么久,游戏画面还是一尘不变,起码要动一动视角吧。

这么做需要我们新建一个组件,并操作场景里面游戏物体的Transform组件的属性,这里面涉及了如何从一个物体引用另外一个物体,由于内容比较多,所以放到下一个章节单独再讲。

猜你喜欢

转载自blog.csdn.net/z175269158/article/details/129832370
今日推荐