首页 最新 热门 推荐

  • 首页
  • 最新
  • 热门
  • 推荐

Unity新版输入系统InputSystem

  • 25-02-16 11:40
  • 3026
  • 12113
blog.csdn.net

InputSystem

  • 一、InputSystem简介
  • 二、教程
    • Lesson1-InputSystem的导入
    • Lesson2-键盘输入
    • Lesson3-鼠标输入
    • Lesson4-触屏输入
    • Lesson5-手柄输入
    • Lesson6-其他输入
    • Lesson7-InputAction
    • Lesson8-输入配置文件
    • Lesson9-输入配置文件生成C#代码
    • Lesson10-PlayerInput组件
    • Lesson11_Player Input行为执行模式

一、InputSystem简介

InputSystem是Unity提供的更好的一种输入系统,相对的Unity的老输入系统是InputManager。现在大部分公司都是使用新版的输入系统。老系统和新系统的区别在于:老系统需要我们自己去写代码,来检测按键的输入。但是新输入系统我们不需要再写代码来检测按键输入了。我们在新的输入系统中,只需要写关于按键之后的逻辑部分的代码。

二、教程

Lesson1-InputSystem的导入

在使用新版输入系统InputSystem之前,我们需要先导入它:Window–Packge Manager。将左上角选为Unity Registty模式,之后在右上角搜索框搜索InputSystem,点击Install即可。注意:安装后会重启Unity。
在这里插入图片描述
在安装完成之后,可以在File–Build Setting–Player Setting–Other–Active Input Handing 中选择使用哪一种输入系统,可以同时启用新老两种输入系统。主意:在重新选择后会重启Unity。并且如果只启用新输入系统,再使用老输入系统的话,Unity会报错,所以可以选择Both将两种输入系统都启用。
在这里插入图片描述

Lesson2-键盘输入

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.InputSystem;

public class Lesson2 : MonoBehaviour
{
    Keyboard keyboard;
    
    void Start()
    {
        #region 知识点一 获取当前键盘设备(需要引用命名空间)
        //新输入系统 提供了对应的输入设备类 帮助我们对某一种设备输入进行检测
        //注意后面不能new 要去.current 代表获得我们当前激活使用的键盘
        keyboard = Keyboard.current;
        #endregion

        #region 知识点二 判断键盘的单个按键 按下 抬起 长按
        //通过键盘类对象 点出 单个按键 来获取
        //按下
        if (keyboard.aKey.wasPressedThisFrame)
        {

        }
        //抬起
        if (keyboard.sKey.wasReleasedThisFrame)
        {

        }
        //长按
        if (keyboard.spaceKey.isPressed)
        {

        }
        #endregion

        #region 知识点三 得到键盘的哪个键按下
        //通过给keyboard对象中的 文本输入事件 添加委托函数
        //可以得到键盘按下的是哪一个字符
        //方法的参数是一个char char就是按下的字符
        keyboard.onTextInput += (c) =>
        {
            print("键盘按下的是" + c + "键");
        };

        #endregion

        #region 知识点四 任意键按下监听
        //可以处理 任意键 按下 抬起 长按 相关的逻辑
        if (keyboard.anyKey.wasPressedThisFrame)
        {

        }
        //.wasPressedThisFrame
        //.wasReleasedThisFrame
        //.isPressed
        #endregion
    }

    void Update()
    {
        //在update中测试
        if (keyboard.aKey.wasPressedThisFrame)
        {
            print("a键按下");
        }
        if (keyboard.sKey.wasReleasedThisFrame)
        {
            print("s键抬起");
        }
        if (keyboard.spaceKey.isPressed)
        {
            print("空格键长按中");
        }
        if (keyboard.anyKey.wasPressedThisFrame)
        {
            print("任意键按下");
        }
           
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81

Lesson3-鼠标输入

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.InputSystem;

public class Lesson3 : MonoBehaviour
{
    // Start is called before the first frame update
    void Start()
    {
        #region 知识点一 获取当前鼠标设备(需要引用命名空间)
        //和前面的键盘一样 要先获取我们使用的鼠标
        Mouse mouse = Mouse.current;
        #endregion

        #region 知识点二 鼠标各个键位 按下 抬起 长按
        //鼠标左键
        //mouse.leftButton;
        //鼠标右键
        //mouse.rightButton;
        //鼠标中键
        //mouse.middleButton;
        //鼠标侧键(前后)
        //mouse.forwardButton;
        //mouse.backButton;


        if (mouse.leftButton.wasPressedThisFrame)
        {
            
        }

        if (mouse.leftButton.wasReleasedThisFrame)
        {

        }

        if (mouse.leftButton.isPressed)
        {

        }

        #endregion

        #region 知识点三 鼠标位置相关
        //获取鼠标当前位置
        //注意这个position是Mouse封装了的 如果要得到具体位置的值 需要.ReadValue();
        mouse.position.ReadValue();

        //获得鼠标这一帧 和上一帧的偏移量
        mouse.delta.ReadValue();

        //获得鼠标滚轮的值(方向向量)
        mouse.scroll.ReadValue();
        #endregion
    }

    // Update is called once per frame
    void Update()
    {
        if (Mouse.current.leftButton.wasPressedThisFrame)
        {
            print("左键按下");
        }

        if (Mouse.current.leftButton.wasReleasedThisFrame)
        {
            print("左键抬起");
        }

        if (Mouse.current.rightButton.isPressed)
        {
            print("右键长按");
        }

        if (Mouse.current.forwardButton.isPressed)
        {
            print("前侧键长按");
        }

        //print(Mouse.current.position.ReadValue());

        //print(Mouse.current.delta.ReadValue());

        print(Mouse.current.scroll.ReadValue());
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87

Lesson4-触屏输入

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.InputSystem.Controls;
using UnityEngine.InputSystem;

public class Lesson4 : MonoBehaviour
{
    // Start is called before the first frame update
    void Start()
    {
        #region 知识点一 获取当前触屏设备
        Touchscreen ts = Touchscreen.current;
        //由于触屏相关都是在移动平台或提供触屏的设备上使用
        //所以在使用时最好做一次判空
        if (ts == null)
            return;
        #endregion

        #region 知识点二 得到触屏手指信息
        //得到触屏手指数量
        print(ts.touches.Count);
        //得到单个触屏手指
        print(ts.touches[0]);
        //得到所有触屏手指
        foreach (var t in ts.touches)
        {

        }
        #endregion

        #region 知识点三 手指按下 抬起 长按 点击
        //获取指定索引手指
        print(ts.touches[0]);
        //要判断是否抬起等等 要先获得这根手指的信息
        TouchControl tc = ts.touches[0];
        //按下 抬起
        if (tc.press.wasPressedThisFrame)
        {

        }
        if (tc.press.wasReleasedThisFrame)
        {

        }
        //长按
        if (tc.press.isPressed)
        {

        }

        //点击手势
        if (tc.tap.isPressed)
        {

        }

        //连续点击次数
        print(tc.tapCount);

        #endregion

        #region 知识点四 手指位置等相关信息
        //位置
        print(tc.position.ReadValue());
        //第一次接触时位置
        print(tc.startPosition.ReadValue());
        //接触区域大小
        print(tc.radius.ReadValue());
        //和上一帧的偏移位置
        print(tc.delta.ReadValue());

        //得到当前手指的 状态(阶段)
        UnityEngine.InputSystem.TouchPhase tp = tc.phase.ReadValue();
        switch (tp)
        {
            //无状态
            case UnityEngine.InputSystem.TouchPhase.None:
                break;
            //手指开始接触屏幕
            case UnityEngine.InputSystem.TouchPhase.Began:
                break;
            //手指开始在屏幕上移动
            case UnityEngine.InputSystem.TouchPhase.Moved:
                break;
            //手指结束移动
            case UnityEngine.InputSystem.TouchPhase.Ended:
                break;
            //手指取消移动
            case UnityEngine.InputSystem.TouchPhase.Canceled:
                break;
            //静止 手指没动了
            case UnityEngine.InputSystem.TouchPhase.Stationary:
                break;
            default:
                break;
        }
        #endregion
    }

    // Update is called once per frame
    void Update()
    {
        
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106

Lesson5-手柄输入

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.InputSystem;

public class Lesson5 : MonoBehaviour
{
    // Start is called before the first frame update
    void Start()
    {
        #region 知识点一 获取当前手柄
        Gamepad gp = Gamepad.current;
        //判断是否得到手柄
        if(gp == null)
        {
            return;
        }
        #endregion

        #region 知识点二 手柄摇杆
        //摇杆方向
        //左摇杆
        print(gp.leftStick.ReadValue());
        //右摇杆
        print(gp.rightStick.ReadValue());

        //摇杆按下 抬起 长按
        //左摇杆
        if (gp.leftStickButton.wasPressedThisFrame)
        {

        }
        if (gp.leftStickButton.wasReleasedThisFrame)
        {

        }
        if (gp.leftStickButton.isPressed)
        {

        }
        //右摇杆

        #endregion

        #region 知识点三 手柄方向键
        //对应手柄上4个方向键 上下左右
        //gamePad.dpad.left
        //gamePad.dpad.right
        //gamePad.dpad.up
        //gamePad.dpad.down
        //按下 抬起 长按
        if (gp.dpad.left.wasPressedThisFrame)
        {

        }
        if (gp.dpad.left.wasReleasedThisFrame)
        {

        }
        if (gp.dpad.left.isPressed)
        {

        }
        #endregion

        #region 知识点四 手柄右侧按键
        //通用
        //东西南北

        //Y、△
        //北方(上方) gp.buttonNorth

        //A、X
        //南方(下方) gp.buttonSouth

        //X、□
        //西方(左方) gp.buttonWest

        //B、○
        //东方(右方) gp.buttonEast

        //它们的按下抬起长按和上面一致
        //wasPressedThisFrame
        //wasReleasedThisFrame
        //isPressed



        //不建议这样使用 因为不同手柄的名称都是不一样的 而上面的东西南北是通用的
        //手柄右侧按钮 x ○ △ □ A B Y 
        //○
        //gamePad.circleButton
        //△
        //gamePad.triangleButton
        //□
        //gamePad.squareButton
        //X
        //gamePad.crossButton
        //x
        //gamePad.xButton
        //a
        //gamePad.aButton
        //b
        //gamePad.bButton
        //Y
        //gamePad.yButton
        #endregion

        #region 知识点五 手柄中央按键
        //中央键
        //gp.startButton;
        //gp.selectButton;

        //wasPressedThisFrame
        //wasReleasedThisFrame
        //isPressed

        #endregion

        #region 知识点六 手柄肩部按键
        //左上右上 肩部键位
        //左右前方肩部键
        //gp.leftShoulder;
        //gp.rightShoulder;

        //左右后方触发键(油门键)
        //gamePad.leftTrigger
        //gamePad.rightTrigger

        //wasPressedThisFrame
        //wasReleasedThisFrame
        //isPressed

        #endregion
    }

    // Update is called once per frame
    void Update()
    {
        
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142

Lesson6-其他输入

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Lesson6 : MonoBehaviour
{
    // Start is called before the first frame update
    void Start()
    {
        #region 知识点一 新输入系统中的输入设备类
        //常用的
        //Keyboard—键盘
        //Mouse—鼠标
        //Touchscreen—触屏
        //Gamepad—手柄

        //其它
        //Joystick—摇杆
        //Pen—电子笔

        //Sensor(传感器)
        //https://docs.unity3d.com/Packages/[email protected]/manual/Sensors.html#accelerometer
        //Gyroscope—陀螺仪
        //GravitySensor—重力传感器
        //加速传感器
        //光照传感器
        //等等
        #endregion

        #region 知识点二 关于没有细讲的设备
        //对于我们没有细讲的设备
        //平时在开发中不是特别常用
        //如果想要学习他们的使用
        //最直接的方式就是看官方的文档
        //或者直接进到类的内部查看具体成员
        //通过查看变量名和方法名即可了解使用方式

        //UnityEngine.InputSystem.Gyroscope g = UnityEngine.InputSystem.Gyroscope.current;
        //g.angularVelocity.ReadValue()
        #endregion

        #region 知识点三 注意事项
        //新输入系统的设计初衷就是想提升开发者的开发效率
        //我们不提倡写代码来处理输入逻辑
        //之后我们学了配置文件相关知识后
        //都是通过配置文件来设置监听(监视窃听)的输入事件类型
        //我们只需要把工作重心放在输入触发后的逻辑处理

        //所以我们目前讲解的知识都是为了之后最准备
        //实际开发中使用较少
        #endregion
    }

    // Update is called once per frame
    void Update()
    {
        
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59

Lesson7-InputAction

在之前我们都需要通过手动写代码的形式来绑定监听哪个键输入了,现在我们可以使用InputAction,直接在界面上来绑定监听哪个键输入了。在界面上确定了监听哪个键之后。我们只需要在代码中去处理,按键触发后的逻辑就行了。
  • 1
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.InputSystem;
using static UnityEngine.InputSystem.Controls.AxisControl;

public class Lesson7 : MonoBehaviour
{
    //声明一些InputAction
    [Header("单个按钮")]
    public InputAction move;

    [Header("1D轴")]
    public InputAction axis;

    [Header("2D轴")]
    public InputAction vector2D;

    [Header("3D轴")]
    public InputAction vector3D;

    [Header("双键组合")]
    public InputAction one;

    [Header("三键组合")]
    public InputAction two;

    void Start()
    {
        #region 知识点一 InputAction是什么?
        //顾名思义,InputAction是InputSystem帮助我们封装的输入动作类
        //它的主要作用,是不需要我们通过写代码的形式来处理输入
        //而是直接在Inspector窗口编辑想要处理的输入类型
        //当输入触发时,我们只需要把精力花在输入触发后的逻辑处理上

        //我们在想要用于处理输入动作的类中 
        //申明对应的InputAction类型的成员变量(注意:需要引用命名空间UnityEngine.InputSystem)
        //之后就可以在Unity的Inspector窗口上面来编辑它们了
        #endregion

        #region 知识点二 InputAction参数相关
        //接下来我们讲解Inspector窗口上的参数
        //参数分为三部分

        #region 按钮一:齿轮

        #region Action:输入动作设置
        //Action Type:动作类型(就是选择是要得到设备的返回值 还是 得到按钮是否按下)
        //Value:值类型 主要用于状态连续更改的输入,例如鼠标的移动,手柄的遥感。如果有多个设备绑定这个 Action,只会发送其中一个设备(最受控制的)的输入
        //Button:按钮类型 用于每次按下时触发的 Action
        //Pass Through:直通类型 和 Value 一样,区别在于如果有多个设备绑定这个 Action,会发送所有设备的输入

        //Control Type:控制类型(就是进行一次返回值筛选 选出你要得到的值是什么 例如只需要得到vector2)
        //Any	任何值	
        //Integer	整数
        //Axis	一维轴浮点数,例如:摇杆输入返回值	
        //Quaternion	四元数
        //Bone	骨骼	
        //Stick	摇杆相关
        //Digital	数字	
        //Touch	触屏相关
        //Dpad	4 向按钮,例如:摇杆上的 D-pad	
        //Vector2	2 维向量
        //Eyes	VR 相关数值	
        //Vector3	3 维向量

        //在这里选择对应的类型,之后在选择对应设备按键相关属性时,
        //会根据你选择内容的不同,筛选对应内容这上面显示的内容就是各设备属性的返回值类型
        //当你选择他们后,非选择的类型将不会在之后的按键设置中出现
        //很多内容我们基本用不到,相当于是在这里筛选输入设备
        #endregion

        #region Interactions:相互作用设置 
        //用于特殊输入,比如长按、多次点击等等,当满足条件时才会触发这个行为(设置长按时间、点击次数等等)
        //默认关联了以下 3 个输入事件,我们可以通过代码为事件添加监听逻辑:
        //开始:Started
        //触发:Performed
        //结束:Canceled

        //1.Hold:长按。
        //适用于需要输入设备保持一段时间的操作。
        //当按钮按下会触发 Started。
        //若在松开按钮前,按住时间大于等于 Hold Time 则会触发 Performed(时间一到就触发)
        //否则触发 Canceled。
        //Press Point:在 Input System 中,每个按钮都有对应的浮点值,例如普通的按钮,将会在 0(未按下)和 1(按下)之间。
        //因此我们可以利用这个值(Press Point)来进行区分,当大于等于这个值则认为按钮按下了。

        //2.Tap:单击
        //和 Hold 相反,需要在一段时间内按下松开来触发。
        //当按钮按下会触发 Started
        //若在 Max Tap Duriation 时间内(小于)松开按钮,触发 Performed
        //否则触发 Canceled。

        //3.SlowTap:长按并松开。
        //类似 Hold,但是它在按住时间大于等于 Max Tap Duriation 的时候,并不会立刻触发 Performed,而是会在松开的时候才触发 Performed

        //4.MultiTap:连击。
        //用作于多次点击,例如双击或者三连击。
        //Tap Count:点击次数
        //Max Tap Spacing:每次点击之间的间隔(默认值为 2 * Max Tap Duration)
        //Max Tap Duration:每次点击的持续时间,即按下和松开按钮的这段时间。
        //当每次点击时间小于 Max Tap Duration,且点击间隔时间小于 Max Tap Spacing,点击 Tap Count 次,触发 Performed。

        //5.Press:按下
        //可以实现类似按钮的操作
        //Press Only:按下的时候触发 Started和 Performed。不触发 Canceled
        //Release Only:按下的时候触发 Started,松开的时候触发 Performed
        //Press And Release:按下的时候触发 Started和 Performed,松开的时候会再次触发 Started和 Performed。不触发 Canceled
        //PressPoint:在InputSystem中 每个按钮都有对应的默认值 例如普通按钮 将会在0(未按下)和1(按下)之间 我们可以利用这个值来区分
        //当大于这个值 则被认为按下(有些按钮有浅按和全按的区分 可以利用它来区分)
        #endregion

        #region Processors:值处理加工设置
        // 对得到的值进行处理加工
        //1.Clamp:将输入值钳制到[min,max] 范围。

        //2.Invert:反转控件中的值(即,将值乘以 - 1)。

        //3.Invert Vector 2:反转控件中的值(即,将值乘以 - 1)。
        //如果 invertX 为真,则反转矢量的 x 轴
        //如果 invertY 为真,则反转矢量的 y 轴。

        //4.Invert Vector 3:反转控件中的值(即,将值乘以 - 1)。
        //如果反转 x 为真,则反转矢量的 x 轴
        //如果反转 y 为真,则反转 y 轴
        //如果反转 z 为真,则反转 z 轴

        //5.Normalize:
        //如果最小值 >= 0,则将[min,max] 范围内的输入值规格化为无符号规格化形式[0,1]
        //如果最小值 < 0,则将输入值规格化为有符号规格化形式[-1,1]。

        //6.Normalize Vector 2:将输入向量规格化为单位长度(1)。

        //7.Normalize Vector 3:将输入向量规格化为单位长度(1)

        //8.Scale:将所有输入值乘以系数。

        //9.Scale Vector 2:将所有输入值沿 x 轴乘以 x,沿 y 轴乘以 y。

        //10.Scale Vector 3:将所有输入值沿 x 轴乘以 x,沿 y 轴乘以 y,沿 z 轴乘以 z。

        //11.Axis Deadzone:axis 死区处理器缩放控件的值,使绝对值小于最小值的任何值为 0,绝对值大于最大值的任何值为 1 或 - 1。
        //许多控件没有精确的静止点(也就是说,当控件位于中心时,它们并不总是精确报告 0)。
        //在死区处理器上使用最小值可避免此类控件的无意输入。
        //此外,当轴一直移动时,某些控件不一致地报告其最大值。在死区处理器上使用最大值可确保在这种情况下始终获得最大值。

        //12.Stick Deadzone:摇杆死区处理器缩放 Vector2 控件(如摇杆)的值,
        //以便任何幅值小于最小值的输入向量都将得到(0,0),而任何幅值大于最大值的输入向量都将规格化为长度 1。
        //许多控件没有精确的静止点(也就是说,当控件位于中心时,它们并不总是精确地报告(0,0)。
        //在死区处理器上使用最小值可避免此类控件的无意输入。此外,当轴一直移动时,某些控件不一致地报告其最大值。
        //在死区处理器上使用最大值可确保在这种情况下始终获得最大值。

        #endregion

        #endregion

        #region 按钮二:加号
        //1.Add Binding
        //添加新的输入绑定(单按键输入)

        //2.Add Positive \ Negative Binding 或者 Add 1D Axis Composite
        //添加 1D 轴组合(类似 Input 中的水平竖直热键,返回 - 1 ~1 之间的一个值)

        //3.Add Up \ Down \ Left \ Right Composite 或者 Add 2D Vector Composite
        //添加 2D 向量组合(类似将 Input 中的水平竖直热键组合在一起,得到的 Vector 中的 x,y 分别表示两个轴)

        //4.Add Up \ Down \ Left \ Right \ Forward \ Backward Composite
        //添加 3D 向量组合

        //5.Add Button With One Modifier Composite
        //添加带有一个复合修改器的按钮(可以理解为双组合键, 比如 Ctrl +C、Ctrl + V)

        //6.Add Button With Two Modifier Composite
        //添加带有两个复合修改器的按钮(可以理解为三组合键,比如 Ctrl+K + U)

        #endregion

        #region 按钮三:减号

        #endregion

        #endregion

        #region 知识点三 InputAction的使用
        //第一点:想要使用这个InputAction的话 必须先启用输入检测
        move.Enable();

        //第二点:操作监听相关 它有三个事件
        //1.开始状态
        move.started += TestFunc;
        //2.真正触发
        move.performed += (context) =>
        {
            //第三点:关键参数 CallbackContext 我们可以通过context来得到很多信息
            //1.当前动作的状态
            print(context.phase); //没有启用:Disabled //等待:Waiting //开始:Started //触发:Performed //结束:Canceled

            //2.当前动作的名字(其实这里的action就是一个属性 它会返回我们上面声明的InputAction,也就是move这个对象)
            print(context.action.name);

            //3.控件信息(哪一个键)
            print(context.control.name);

            //4.获取值
            print(context.ReadValue<Vector2>());

            //5.持续时间
            print(context.duration);

            //6.开始时间
            print(context.startTime);

            print("触发事件调用");
        };

        //3.结束状态
        move.canceled += (callback) =>
        {
            print("结束事件调用");
        };


        

        axis.Enable();
        vector2D.Enable();
        vector3D.Enable();
        one.Enable();
        two.Enable();

        axis.started += (callback) =>
        {
            print(callback.ReadValue<Vector2>());
        };
        one.started += (callback) =>
        {
            print("双组合键触发");
        };
        two.started += (callback) =>
        {
            print("三键组合触发");
        };
        #endregion

        #region 知识点四 特殊输入设置
        //1.Input System 基础设置(一些默认值设置)
        //2.设置特殊输入规则
        #endregion
    }
    public void TestFunc(InputAction.CallbackContext callbackContext)
    {
        print("开始事件调用");
    }
    
    void Update()
    {
        //因为axis是得到-1到1之间的数 一般用于2D控制人物 所以我们不太需要启用它的三个事件
        //而是直接通过声明的InputAction 也就是axis对象 axis.ReadValue()来得到返回值就行了
        //不需要启用事件 然后在使用事件中的参数context来获取值

        //print(axis.ReadValue());
        //print(vector2D.ReadValue());
        print(vector3D.ReadValue<Vector3>());
    }
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • 165
  • 166
  • 167
  • 168
  • 169
  • 170
  • 171
  • 172
  • 173
  • 174
  • 175
  • 176
  • 177
  • 178
  • 179
  • 180
  • 181
  • 182
  • 183
  • 184
  • 185
  • 186
  • 187
  • 188
  • 189
  • 190
  • 191
  • 192
  • 193
  • 194
  • 195
  • 196
  • 197
  • 198
  • 199
  • 200
  • 201
  • 202
  • 203
  • 204
  • 205
  • 206
  • 207
  • 208
  • 209
  • 210
  • 211
  • 212
  • 213
  • 214
  • 215
  • 216
  • 217
  • 218
  • 219
  • 220
  • 221
  • 222
  • 223
  • 224
  • 225
  • 226
  • 227
  • 228
  • 229
  • 230
  • 231
  • 232
  • 233
  • 234
  • 235
  • 236
  • 237
  • 238
  • 239
  • 240
  • 241
  • 242
  • 243
  • 244
  • 245
  • 246
  • 247
  • 248
  • 249
  • 250
  • 251
  • 252
  • 253
  • 254
  • 255
  • 256
  • 257
  • 258
  • 259
  • 260
  • 261
  • 262
  • 263
  • 264
  • 265
  • 266
  • 267

Lesson8-输入配置文件

在上一节课中,我们需要在代码中自己声明InputAction对象,虽然可以在界面中直接绑定按钮监听,从而不需要写代码了。但是我们还是需要自己在代码中去声明它。在这节课我们学习输入配置文件-InputActions之后,我们也不需要在代码中去声明InputAction对象了,我们可以直接在面板新建立一个InputActions,它是InputAction的集合,里面可以包含n个InputAction。更加的方便。
  • 1
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Lesson8 : MonoBehaviour
{
    // Start is called before the first frame update
    void Start()
    {
        #region 知识点一 什么是输入配置文件?
        //输入系统中提供了一种输入配置文件
        //你可以理解它是InputAction的集合
        //可以在一个文件中编辑多个InputAction的信息

        //里面记录了想要处理的行为和动作(也就是InputAction的相关信息)
        //我们可以在其中自己定义 InputAction(比如:开火、移动、旋转等)
        //然后为这个InputAction关联对应的输入动作

        //之后将该配置文件和PlayerInput进行关联
        //PlayerInput会自动帮助我们解析该文件
        //当触发这些InputAction输入动作时会以分发事件的形式通知我们执行行为
        #endregion

        #region 知识点二 编辑输入配置文件
        //1.在Project窗口右键Create创建InputActions配置文件
        //2.双击创建出的文件
        //3.进行配置
        #endregion

        #region 知识点三 配置窗口参数相关

        #endregion
    }

    // Update is called once per frame
    void Update()
    {
        
    }
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41

Lesson9-输入配置文件生成C#代码

在上节课我们学习了如何声明InputActions,这节课我们来学习如何使用这个InputAction的集合,也就是InputActions。
  • 1
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Lesson9 : MonoBehaviour
{
    Lesson9Input input;
    // Start is called before the first frame update
    void Start()
    {
        #region 知识点一 根据配置文件生成C#脚本
        //1.选择InputActions文件
        //2.在Inspector窗口设置生成路径,类名,命名空间
        //3.应用后生成C#脚本
        #endregion

        #region 知识点二 使用C#代码进行监听
        //我们为InputActions生成了对应的C#脚本 接下来的使用和InputAction的使用类似

        //1.创建生成的脚本类对象
        input = new Lesson9Input();
        //2.激活输入
        input.Enable();
        //3.事件监听
        //因为InputActions中有多套动作行为
        //所以先使用声明的类对象.出来是使用的哪套输入动作
        //再.出来 要使用的是哪个动作行为
        //再.出来三个事件进行使用
        input.Action1.Fire.performed += (callback) =>
        {
            print("开火了");
        };
        input.Action2.Space.performed += (callback) =>
        {
            print("跳跃了");
        };
        
        #endregion
    }

    // Update is called once per frame
    void Update()
    {
        print(input.Action1.Move.ReadValue<Vector2>());
    }
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47

Lesson10-PlayerInput组件

上节课我们学习了如何使用InputActions,它需要我们去生成C#脚本文件,然后声明脚本类对象去使用。这样做实际很麻烦,所以我们学习PlayerInput组件,进一步的简化使用。只要将需要操控的对象身上挂载PlayerInput组件,然后将InputActions和组件上的actions关联,这样我们使用InputActions的时候,就不需要再去为它声明C#脚本了。而是通过PlayerInput组件上的Behavior去使用它上面声明的InputAction。
  • 1
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Lesson10 : MonoBehaviour
{
    // Start is called before the first frame update
    void Start()
    {
        #region 知识点一 PlayerInput是什么?
        //PlayerInput是InputSystem提供的
        //专门用于接受玩家输入来处理自定义逻辑的组件

        //主要工作原理
        //1.配置输入文件(InputActions文件)
        //2.通过PlayerInput关联配置文件,它会自动解析该配置文件
        //3.关联对应的响应函数,处理对应逻辑

        //好处:
        //不需要自己进行相关输入的逻辑书写
        //通过配置文件即可配置想要监听的对应行为
        //让我们专注于输入事件触发后的逻辑处理
        #endregion

        #region 知识点二 添加PlayerInput组件
        //选择任意对象(一般为一个玩家对象)
        //为其添加PlayerInput组件
        #endregion

        #region 知识点三 PlayerInput参数相关
        //1.Actions:选择一套InputActions和玩家关联。
        //       Default Scheme:默认启用哪一个设备(键盘鼠标或者手柄之类的)
        //       Auto - Switch:允许自动切换设备
        //       Default Map:默认启用哪一个Map

        //2.UI Input Module:关联UI的EventSystem(需要使用UI来控制行为的时候,例如使用UI制作的虚拟摇杆控制人物移动等等)

        //3.Camera:关联摄像机,当需要分屏设置时才会修改它 Behavior:如何通知游戏对象执行逻辑

        //4.Behavior:
        //        Send Message:将逻辑脚本挂载在PlayerInput挂载的对象上 这样就可以通过Send Message通知执行对应函数
        //        Broadcast Message:将逻辑脚本挂载在PlayerInput挂载的对象上 或者挂载在子对象上 这样就可以通过Broadcast Message通知执行对应函数
        //        Invoke UnityEvent Actions:通过拖曳脚本关联函数 指明想要执行的函数
        //        Invoke CSharp Events:通过C#事件监听处理对应的逻辑 通过获取PlayerInput进行事件监听
        #endregion
    }

    // Update is called once per frame
    void Update()
    {
        
    }
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54

Lesson11_Player Input行为执行模式

再上一节课我们初步认识了PlayerInput这个组件,也了解了上面的参数的含义。这节课我们就来仔细的学习,如何使用PlayerInput来使用InputActions,而不是通过声明C#脚本的形式来使用它。
  • 1
using System.Collections;
using System.Collections.Generic;
using UnityEditor.Timeline.Actions;
using UnityEngine;
using UnityEngine.InputSystem;

public class Lesson11 : MonoBehaviour
{
    //使用第四种代码添加的形式 应该先得到PlayerInput这个组件
    PlayerInput input;

    void Start()
    {
        //建议使用第三和第四种 效率更高 因为不用去查找

        #region 知识点一 Send Messages
        //在自定义脚本中
        //申明名为 "On+行为名" 的函数
        //没有参数 或者 参数类型为InputValue
        //将该自定义脚本挂载到PlayerInput依附的对象上
        //当触发对应输入时 会自动调用函数

        //并且还有默认的3个和设备相关的函数可以调用
        //设备注册(当控制器从设备丢失中恢复并再次运行时会触发):OnDeviceRegained(PlayerInput input)
        //设备丢失(玩家失去了分配给它的设备之一,例如,当无线设备耗尽电池时):OnDeviceLost(PlayerInput input)
        //控制器切换:OnControlsChanged(PlayerInput input)
        #endregion

        #region 知识点二 Broadcast Messages	
        //基本和SendMessage规则一致
        //唯一的区别是,自定义脚本不仅可以挂载在PlayerInput依附的对象上
        //还可以挂载在其子对象下
        #endregion

        #region 知识点三 Invoke Unity Events
        //该模式可以让我们在Inspector窗口上通过拖拽的形式关联响应函数
        //它的好处是看起来更加清晰 而且不需要像上面一样 必须要将脚本挂载在PlayerInput依附的对象上(或子对象上)
        //但是注意:响应函数的参数类型 需要改为 InputAction.CallbackContext
        #endregion

        #region 知识点四 Invoke C Sharp Events
        //1.获取PlayerInput组件
        input = GetComponent<PlayerInput>();
        //2.获取对应事件进行委托函数添加
        input.onControlsChanged += OnControlsChanged;
        input.onDeviceLost += OnDeviceLost;
        input.onDeviceRegained += OnDeviceRegained;
        //不管触发了什么都会调用该函数 所以要通过传入的参数来具体判断触发了哪一种
        input.onActionTriggered += onActionTrigger;
        //3.当触发输入时会自动触发事件调用对应函数

        #endregion

        #region 知识点五 关键参数InputValue和InputAction.CallbackContext
        //InputValue
        //是否按下

        //得到具体返回值

        #endregion
    }

    void Update()
    {
        //第四种方式可以直接这样使用 来控制移动
        print(input.currentActionMap["Move"].ReadValue<Vector2>());
    }

    #region Send Messages / Broadcast Messages	
    public void OnMove(InputValue value)
    {
        print("Move");
    }
    public void OnLook(InputValue value)
    {
        print("Look");
    }
    public void OnFire(InputValue value)
    {
        print("Fire");
    }
    public void OnDeviceRegained(PlayerInput input)
    {
        print("设备注册");
    }
    public void OnDeviceLost(PlayerInput input)
    {
        print("设备丢失");
    }
    public void OnControlsChanged(PlayerInput input)
    {
        print("设备切换");
    }
    #endregion

    #region Invoke Unity Events
    public void PlayerMove(InputAction.CallbackContext context)
    {
        print("人物移动");
    }
    public void PlayerFire(InputAction.CallbackContext context)
    {
        print("人物开火");
    }
    public void PlayerLook(InputAction.CallbackContext context)
    {
        print("人物Look");
    }
    #endregion

    #region Invoke C Sharp Events
    public void onActionTrigger(InputAction.CallbackContext context)
    {
        switch (context.action.name)
        {
            case "Move":
                print(context.ReadValue<Vector2>());
                break;
            case "Fire":
                if (context.phase == InputActionPhase.Performed)
                    print("开火了");
                break;
            case "Look":
                print(context.ReadValue<Vector2>());
                break;
        }
    }
    #endregion
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
注:本文转载自blog.csdn.net的遇到困难先睡大觉的文章"https://blog.csdn.net/weixin_52402845/article/details/143126137"。版权归原作者所有,此博客不拥有其著作权,亦不承担相应法律责任。如有侵权,请联系我们删除。
复制链接
复制链接
相关推荐
发表评论
登录后才能发表评论和回复 注册

/ 登录

评论记录:

未查询到任何数据!
回复评论:

分类栏目

后端 (14832) 前端 (14280) 移动开发 (3760) 编程语言 (3851) Java (3904) Python (3298) 人工智能 (10119) AIGC (2810) 大数据 (3499) 数据库 (3945) 数据结构与算法 (3757) 音视频 (2669) 云原生 (3145) 云平台 (2965) 前沿技术 (2993) 开源 (2160) 小程序 (2860) 运维 (2533) 服务器 (2698) 操作系统 (2325) 硬件开发 (2492) 嵌入式 (2955) 微软技术 (2769) 软件工程 (2056) 测试 (2865) 网络空间安全 (2948) 网络与通信 (2797) 用户体验设计 (2592) 学习和成长 (2593) 搜索 (2744) 开发工具 (7108) 游戏 (2829) HarmonyOS (2935) 区块链 (2782) 数学 (3112) 3C硬件 (2759) 资讯 (2909) Android (4709) iOS (1850) 代码人生 (3043) 阅读 (2841)

热门文章

134
游戏
关于我们 隐私政策 免责声明 联系我们
Copyright © 2020-2025 蚁人论坛 (iYenn.com) All Rights Reserved.
Scroll to Top