8.InputAction输入操作

  1. 8.InputAction类
    1. 8.1 知识点
      1. InputAction是什么?
        1. 比如创建移动和开火两个输入动作
        2. 把脚本挂载到空对象上,可以在inspector窗口编辑InputAction
        3. InputAction的缺点是不会显示变量名。可以添加一个头特性进行区分。
      2. InputAction参数相关
        1. 点击齿轮
          1. Actions 输入动作设置 设置检测哪些输入
            1. Action Type:动作类型
            2. Control Type:控制类型
          2. Interactions 相互作用设置 用于特殊输入,比如长按、多次点击等等 当满足条件时才会触发这个行为(设置长按时间、点击次数等等)
            1. 3个事件
            2. 相互作用设置参数
          3. Processors 值处理加工设置 对得到的值进行处理加工 就是输入设备的值传过来后进行二次处理
        2. 点击+号
          1. Add Binding 添加新的输入绑定(单按键输入)比如鼠标左右键按下
          2. Add Positive\Negative Binding Or Add 1D Axis Composite 添加1D轴组合(类似Input中的水平竖直热键,返回-1~1之间的一个值)
            1. 条下的参数
            2. 双击1DAxis的参数
            3. 双击下面的条可以选择监听的按键 比如下面 按S代表-1 W代表1
            4. 代码开启1D轴后 可以在Update中实时打印选择按下的值
          3. Add Up\Down\Left\Right Composite Or Add 2D Vector Composite 添加2D向量组合(类似将Input中的水平竖直热键组合在一起,得到的Vector中的x,y分别表示两个轴)
            1. 条下的参数
            2. 点击2DVector的参数
            3. 双击点击下方条选择监听的按键 比如键盘的上下左右键
            4. 代码开启2D轴后 可以在Update中实时打印选择按下的值
          4. Add Up\Down\Left\Right\Forward\Backward Composite 添加3D向量组合
          5. Add Button With One Modifier Composite 添加带有一个复合修改器的按钮(可以理解为双组合键, 比如Ctrl+C、Ctrl+V)
            1. 条下参数
          6. Add Button With Two Modifier Composite 添加带有两个复合修改器的按钮(可以理解为三组合键,比如Ctrl+K+U)
            1. 条下参数
        3. 创建一种输入后
      3. InputAction的使用
        1. 启用输入检测
        2. 操作监听相关
          1. 开始操作
          2. 真正触发
          3. 结束操作
        3. 关键参数 CallbackContext
      4. 特殊输入设置
        1. 注意Interactions
        2. 点击按钮或手动找到InputSystem默认值的设置
        3. 可以点击创建InputSystem默认值的设置文件按钮,会创建出设置文件,可以修改设置文件的值
        4. Input System Package设置
          1. UpdateMode:更新模式
            1. Process Events In Dynamic Update:在动态更新中处理事件
            2. Process Events In Fixed Update:在固定更新中处理事件
            3. Process Events Manually:手动处理事件
          2. Background Behavior:后台行为
            1. Reset And Disable Non Background Devices:重置和禁用非后台设备
            2. Reset And Disable All Devices:重置和禁用所有设备
            3. Ignore Focus:忽略焦点
          3. Filter Noise on .current:过滤当前设备的噪音
          4. Compensate Orientation:定向补偿
          5. Default Deadzone Min:默认死区最小值
          6. Default Deadzone Max:默认死区最大值
          7. Default Button Press Point:默认按钮按下点
          8. Button Release Threshold:按钮释放阈值
          9. Default Tap TIme:默认点击时间
          10. Default Slow Tap Time:默认慢速点击时间
          11. Default Hold Time:默认保持时间
          12. Tap Radius:点击半径
          13. MultTap Delay TIme:多次点击延迟时间
          14. Supported Devices:支持的设备
          15. Motion Usage:动作使用
          16. Description:描述
          17. Play Mode Input Behavior:播放模式输入行为
            1. Pointers And Keyboards Respect Game View Focus:指针和键盘遵守游戏视图焦点
            2. All Devices Respect Game View Focus:所有设备都遵守游戏视图焦点
            3. All Device Input Always Goes To Game View:所有设备输入始终进入游戏视图
    2. 8.2 知识点代码
    3. 8.3 练习题
      1. 使用InputAction类,为一个3D对象制作通过鼠标键盘控制其移动、跳跃、开火的逻辑(移动跳跃 利用物理系统刚体加力)
        1. 创建一个平面和一个球体 球体改颜色 添加刚体
        2. 创建脚本挂载到小球上。创建移动、跳跃、开火InputAction。添加分组特性。
        3. 创建刚体变量 Start中得到小球的刚体
        4. 给移动控制关联wasd和上下左右, 启用移动控制输入,创建存储移动方向的变量 Start中启用移动控制输入,Update中读取移动输入的值,将读取的y和z进行转换后给球体添加力
        5. 给跳跃添加空格按键监听,启用跳跃控制输入,Start中给跳跃事件的触发事件添加监听,让物体施加向上的力(利用物理系统刚体加力)
        6. 点击发子弹要做成鼠标当前位置的获取和射线检测
        7. 创建子弹预制体,添加子弹脚本让子弹一直往前飞,两秒后销毁
        8. 给开火事件添加左按键,启用开火控制输入,声明一个公共游戏对象bullet,用于存储子弹的预制体,外部关联。Start中给开火事件的触发事件添加监听,把鼠标位置转成射线得到方向向量,生成子弹设置初始旋转
    4. 8.4 练习题代码
      1. Lesson08_练习题
      2. Bullet

8.InputAction类


8.1 知识点

InputAction是什么?

  • 顾名思义,InputAction是InputSystem帮助我们封装的输入动作类。
  • 它的主要作用是不需要我们通过写代码的形式来处理输入,而是直接在Inspector窗口编辑想要处理的输入类型。当输入触发时,我们只需要把精力花在输入触发后的逻辑处理上。
  • 我们在想要用于处理输入动作的类中,申明对应的InputAction类型的成员变量(注意:需要引用命名空间UnityEngine.InputSystem)。

比如创建移动和开火两个输入动作

把脚本挂载到空对象上,可以在inspector窗口编辑InputAction

InputAction的缺点是不会显示变量名。可以添加一个头特性进行区分。

[Header("move Binding")]
public InputAction move;
[Header("axis 1D Axis")]
public InputAction axis;

InputAction参数相关

点击齿轮

Actions 输入动作设置 设置检测哪些输入
Action Type:动作类型

  • Value:值类型,主要用于状态连续更改的输入,例如鼠标的移动,手柄的遥感。如果有多个设备绑定这个Action,只会发送其中一个设备(最受控制的)的输入。比如多个手柄只会检测主手柄的输入。
  • Button:按钮类型,用于每次按下时触发的Action
  • Pass Through:直通类型,和Value一样,区别在于如果有多个设备绑定这个Action,会发送所有设备的输入。比如多个手柄都会响应他的输入组。
Control Type:控制类型

  • 在这里选择对应的类型,之后在选择对应设备按键相关属性时。会根据你选择内容的不同,筛选对应内容。这上面显示的内容就是各设备属性的返回值类型。当你选择他们后,非选择的类型将不会在之后的按键设置中出现、很多内容我们基本用不到。相当于是在这里筛选输入设备。
  • Any 任何值
  • Analog 模拟值,浮点数
  • Axis 一维轴浮点数,例如:摇杆输入返回值
  • Bone 骨骼
  • Digital 数字
  • Double 浮点
  • Dpad 4向按钮,例如:摇杆上的D-pad
  • Eyes VR相关数值
  • Integer 整数
  • Quaternion 四元数
  • Stick 摇杆相关
  • Touch 触屏相关
  • Vector2 2维向量
  • Vector3 3维向量
  • 比如控制类型选择了Vector2,那么在点击加号添加绑定,点击选择号设备后,只能选择返回Vector2变量类型的输入设备,比如手柄摇杆,鼠标位置等,因为进行了筛选。假如选择了按钮类型,那么只能选择按钮返回值的输入设备,比如鼠标左键,手柄按键等。



Interactions 相互作用设置 用于特殊输入,比如长按、多次点击等等 当满足条件时才会触发这个行为(设置长按时间、点击次数等等)
3个事件
  • 之后通过代码添加监听事件
  • 开始started:比如鼠标点击 一点击就触发了时间
  • 触发performed:比如长按 长按1秒后就触发该事件
  • 结束canceled:比如长按 但是只长按了0.5秒就松开了 结束该事件
相互作用设置参数

  • Hold 长按
    • 适用于需要输入设备保持一段时间的操作。当按钮按下会触发started,若在松开按钮前,按住时间大于等于Hold Time则会触发performed(时间一到就触发),否则触发canceled。
    • 比如设置长按一秒 才会触发performed事件
  • Tap 点击
    • 和Hold相反,需要在一段时间内按下松开来触发。当按钮按下会触发started,若在Max Tap Duriation时间内(小于)松开按钮,触发performed,否则触发canceled。
      • 其实就是按下抬起
      • 比如要在0.2秒内按下抬起 才算做一次点击 执行performed事件
  • SlowTap 缓慢点击
    • 类似Hold,但是它在按住时间大于等于Max Tap Duriation的时候,并不会立刻触发performed,而是会在松开的时候才触发performed
    • 比如当前按下时间要大于0.6秒后,松开鼠标,才会触发performed事件
  • MultiTap 多次点击
    • 用作于多次点击,例如双击或者三连击。Tap Count为点击次数,Max Tap Spacing为每次点击之间的间隔(默认值为 2 * Max Tap Duration)。Max Tap Duration为每次点击的持续时间,即按下和松开按钮的这段时间。当每次点击时间小于Max Tap Duration,且点击间隔时间小于Max Tap Spacing,点击Tap Count次,触发performed。
    • 比如 双击时间要小于0.75秒才算双击 0.2秒内点击松开才算点击
  • Press 按下
    • 可以实现类似按钮的操作
    • Trigger Behavior 触发行为
      • Press Only:按下的时候触发started和performed。不触发canceled
      • Release Only:按下的时候触发started,松开的时候触发performed
      • Press And Release:按下的时候触发started和performed,松开的时候会再次触发started和performed。不触发canceled
  • Press Point:在Input System中,每个按钮都有对应的浮点值,例如普通的按钮,将会在0(未按下)和1(按下)之间。因此我们可以利用这个值(Press Point)来进行区分,当大于等于这个值则认为按钮按下了。
Processors 值处理加工设置 对得到的值进行处理加工 就是输入设备的值传过来后进行二次处理

  • Clamp 将输入值钳制到[min..max]范围。
  • Invert 反转控件中的值(即,将值乘以-1)。
  • Invert Vector 2 反转控件中的值(即,将值乘以-1)。如果invertX为真,则反转矢量的x轴;如果invertY为真,则反转矢量的y轴。
  • Invert Vector 3 反转控件中的值(即,将值乘以-1)。如果反转x为真,则反转矢量的x轴;如果反转y为真,则反转y轴;如果反转z为真,则反转z轴。
  • Normalize 如果最小值>=零,则将[min..max]范围内的输入值规格化为无符号规格化形式[0..1],如果最小值<零,则将输入值规格化为有符号规格化形式[-1..1]。
  • Normalize Vector 2 将输入向量规格化为单位长度(1)。
  • Normalize Vector 3 将输入向量规格化为单位长度(1)
  • Scale 将所有输入值乘以系数。
  • Scale Vector 2 将所有输入值沿x轴乘以x,沿y轴乘以y。
  • Scale Vector 3 将所有输入值沿x轴乘以x,沿y轴乘以y,沿z轴乘以z。
  • 死区:死区可以理解为最小最大范围的扩大取值。比如摇杆在0-0.125的时候都认为是0,0.925以上都认为是1。可以解决轻微摇动会产生输入和最大摇动都没拉满的问题。
  • Axis Deadzone axis死区处理器缩放控件的值,使绝对值小于最小值的任何值为0,绝对值大于最大值的任何值为1或-1。许多控件没有精确的静止点(也就是说,当控件位于中心时,它们并不总是精确报告0)。在死区处理器上使用最小值可避免此类控件的无意输入。此外,当轴一直移动时,某些控件不一致地报告其最大值。在死区处理器上使用最大值可确保在这种情况下始终获得最大值。
  • Stick Deadzone 摇杆死区处理器缩放Vector2控件(如摇杆)的值,以便任何幅值小于最小值的输入向量都将得到(0,0),而任何幅值大于最大值的输入向量都将规格化为长度1。许多控件没有精确的静止点(也就是说,当控件位于中心时,它们并不总是精确地报告0,0)。在死区处理器上使用最小值可避免此类控件的无意输入。此外,当轴一直移动时,某些控件不一致地报告其最大值。在死区处理器上使用最大值可确保在这种情况下始终获得最大值。

点击+号

  • 比如添加了鼠标左键点击事件,并开启了代码,点击会进入逻辑

  • 点击一下后

  • 可以关联添加多个被监听的点击设备,比如下面按下1也会执行

Add Binding 添加新的输入绑定(单按键输入)比如鼠标左右键按下
Add Positive\Negative Binding Or Add 1D Axis Composite 添加1D轴组合(类似Input中的水平竖直热键,返回-1~1之间的一个值)
条下的参数

  • Negative:负面按键,例如 0~-1
  • Positive:正向按键,例如 0~1
双击1DAxis的参数

  • Composite Type:复合类型 一般不修改
  • MinValue:最小值
  • MaxValue:最大值
  • Which Side Wins:哪一方获胜(当同时按下时如何处理 比如同时按下前进后退ws时 看ws谁获胜 可能打平)
    • Neither:双方没有优先权,返回MinValue和MaxValue的中间值
    • Positive:正面优先,返回maxValue
    • Negative:负面优先,返回minValue
双击下面的条可以选择监听的按键 比如下面 按S代表-1 W代表1

代码开启1D轴后 可以在Update中实时打印选择按下的值
axis.Enable();
void Update()
{
    print(axis.ReadValue<float>());
}

如下图 因为选择了Neither 0代表不按或者ws一起按 -1代表s 1代表w

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

  • Up:上 ( 0 , 1 )
  • Down:下 ( 0 , -1 )
  • Left:左 ( -1 , 0 )
  • Right:右 ( 1 , 0 )
点击2DVector的参数

  • Composite Type:复合类型
  • Mode:处理模式
    • Analog:模拟值,浮点值
    • Digital Normalized:单位化向量
    • Digital:未单位化的向量
双击点击下方条选择监听的按键 比如键盘的上下左右键

代码开启2D轴后 可以在Update中实时打印选择按下的值
vector2D.Enable();
void Update()
{
    print(vector2D.ReadValue<Vector2>());
}

Add Up\Down\Left\Right\Forward\Backward Composite 添加3D向量组合
  • 3D和2D类似 无非是多了一维的参数 要关联多两个键
Add Button With One Modifier Composite 添加带有一个复合修改器的按钮(可以理解为双组合键, 比如Ctrl+C、Ctrl+V)
条下参数

  • Modifier:复合输入内容
  • Button:输入内容
  • 举例:复制按键Ctrl+C
  • Ctrl为Modifier
  • C为Button
btnOne.Enable();
btnOne.performed += (context) =>
{
    print("组合键触发");
};

Add Button With Two Modifier Composite 添加带有两个复合修改器的按钮(可以理解为三组合键,比如Ctrl+K+U)
  • 和单组合键类似
条下参数

  • Modifier:复合输入内容
  • Button:输入内容
  • 举例:复制按键Ctrl+K+U
  • Ctrl为Modifier1
  • K为Modifier2
  • U为Button

创建一种输入后

  • 比如值创建一个单键输入 会出现一个条 双击选择输入设备


  • Path:从哪个控件接受输入

    • Usages:常用用法
    • GamePad:游戏手柄
    • Joystick:操纵杆
    • Keyboard:键盘
    • Mouse:鼠标
    • Pen:笔
    • Pointer:指针
    • Sensor:传感器
    • TouchScreen:触屏
    • Tracked Device:履带装置
    • XR Controller:XR 控制器
    • XR HMD:XR 头戴显示器
    • Other:其它

InputAction的使用

启用输入检测

  • move.Enable();

操作监听相关

开始操作
move.started += StartedTestFun;

private void StartedTestFun(InputAction.CallbackContext context)
{
    print("开始事件调用");
}
真正触发
move.performed += (context) =>
{
    print("触发事件调用");
};
结束操作
move.canceled += (context) =>
{
    print("结束事件调用");
};

关键参数 CallbackContext

//真正触发
move.performed += (context) =>
{
    print("触发事件调用");

    //当前状态
    //没有启用 Disabled
    //等待 Waiting
    //开始 Started
    //触发 Performed
    //结束 Canceled
    //context.phase
    print("当前状态"+context.phase);

    //动作行为信息 
    print("动作行为信息" + context.action.name);

    //控件(设备)信息
    print("控件(设备)信息" + context.control.name);

    //获取值
    //context.ReadValue<float>

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

    //开始时间
    print("开始时间"+context.startTime);
};

特殊输入设置

注意Interactions

  • 可以点击上方Move条的齿轮 设置的为整个Move的所有关联设备 要长按五秒才能触发performed事件
  • 也可以点击下方条 专门只为右键设置长按五秒才能触发performed事件

点击按钮或手动找到InputSystem默认值的设置

可以点击创建InputSystem默认值的设置文件按钮,会创建出设置文件,可以修改设置文件的值



Input System Package设置

UpdateMode:更新模式

Process Events In Dynamic Update:在动态更新中处理事件
Process Events In Fixed Update:在固定更新中处理事件
Process Events Manually:手动处理事件
Background Behavior:后台行为

Reset And Disable Non Background Devices:重置和禁用非后台设备
Reset And Disable All Devices:重置和禁用所有设备
Ignore Focus:忽略焦点
Filter Noise on .current:过滤当前设备的噪音
Compensate Orientation:定向补偿
Default Deadzone Min:默认死区最小值
Default Deadzone Max:默认死区最大值
Default Button Press Point:默认按钮按下点
Button Release Threshold:按钮释放阈值
Default Tap TIme:默认点击时间
Default Slow Tap Time:默认慢速点击时间
Default Hold Time:默认保持时间
Tap Radius:点击半径
MultTap Delay TIme:多次点击延迟时间
Supported Devices:支持的设备
  • 如果希望输入系统支持其可以识别的所有输入设备,请将支持的设备保留为空。
  • 但是,如果您只对某一组设备感兴趣,那么在此处添加它们将缩小编辑器中显示的范围,并避免从与项目无关的设备获取输入。
  • 在此处添加设备时,任何未被分类为受支持的设备都将显示在输入调试器的“不受支持的设备”下
Motion Usage:动作使用
Description:描述
Play Mode Input Behavior:播放模式输入行为

Pointers And Keyboards Respect Game View Focus:指针和键盘遵守游戏视图焦点
All Devices Respect Game View Focus:所有设备都遵守游戏视图焦点
All Device Input Always Goes To Game View:所有设备输入始终进入游戏视图

8.2 知识点代码

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

public class Lesson08_InputAction类 : MonoBehaviour
{
    [Header("move Binding")]
    public InputAction move;
    [Header("axis 1D Axis")]
    public InputAction axis;
    [Header("2D Vector")]
    public InputAction vector2D;
    [Header("3D Vector")]
    public InputAction vector3D;

    [Header("Button With One")]
    public InputAction btnOne;


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

        //我们在想要用于处理输入动作的类中 
        //申明对应的InputAction类型的成员变量(注意:需要引用命名空间UnityEngine.InputSystem)
        #endregion

        #region 知识点二 InputAction参数相关

        #endregion

        #region 知识点三 InputAction的使用

        //1.启用输入检测
        move.Enable();

        //2.操作监听相关

        //开始操作
        move.started += StartedTestFun;

        //真正触发
        move.performed += (context) =>
        {
            print("触发事件调用");

            //当前状态
            //没有启用 Disabled
            //等待 Waiting
            //开始 Started
            //触发 Performed
            //结束 Canceled
            //context.phase
            print("当前状态"+context.phase);

            //动作行为信息 
            print("动作行为信息" + context.action.name);

            //控件(设备)信息
            print("控件(设备)信息" + context.control.name);

            //获取值
            //context.ReadValue<float>

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

            //开始时间
            print("开始时间"+context.startTime);
        };

        //结束操作
        move.canceled += (context) =>
        {
            print("结束事件调用");
        };

        //3.关键参数 CallbackContext
        //当前状态

        //动作行为信息 

        //控件信息

        //获取值

        //持续时间

        //开始时间


        axis.Enable();


        vector2D.Enable();

        vector3D.Enable();

        btnOne.Enable();
        btnOne.performed += (context) =>
        {
            print("组合键触发");
        };

        #endregion

        #region 知识点四 特殊输入设置
        //1.Input System 基础设置(一些默认值设置)
        //2.设置特殊输入规则
        #endregion
    }

    #region 知识点三 InputAction的使用

    private void StartedTestFun(InputAction.CallbackContext context)
    {
        print("开始事件调用");
    }

    #endregion

    void Update()
    {
        //print(axis.ReadValue<float>());

        //print(vector2D.ReadValue<Vector2>());

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

8.3 练习题

使用InputAction类,为一个3D对象制作通过鼠标键盘控制其移动、跳跃、开火的逻辑(移动跳跃 利用物理系统刚体加力)

创建一个平面和一个球体 球体改颜色 添加刚体

创建脚本挂载到小球上。创建移动、跳跃、开火InputAction。添加分组特性。

[Header("移动控制")]
public InputAction move;
[Header("跳跃控制")]
public InputAction jump;
[Header("开火控制")]
public InputAction fire;

创建刚体变量 Start中得到小球的刚体

private Rigidbody body; // 刚体组件,用于实现物体的运动
void Start()
{
    body = this.GetComponent<Rigidbody>(); // 获取当前游戏对象的刚体组件
}

给移动控制关联wasd和上下左右, 启用移动控制输入,创建存储移动方向的变量 Start中启用移动控制输入,Update中读取移动输入的值,将读取的y和z进行转换后给球体添加力

private Vector3 dir; // 存储移动方向的向量
move.Enable(); // 启用移动控制输入
void Update()
{
    dir = move.ReadValue<Vector2>(); // 读取移动输入的值,即鼠标或键盘的输入
    dir.z = dir.y; // 将移动向量的y值赋给z值,因为我们只需要在水平方向上移动
    dir.y = 0; // 将移动向量的y值设为0,保证物体不会上下移动
    body.AddForce(dir); // 通过刚体组件给物体施加力,实现移动
}

给跳跃添加空格按键监听,启用跳跃控制输入,Start中给跳跃事件的触发事件添加监听,让物体施加向上的力(利用物理系统刚体加力)

jump.Enable(); // 启用跳跃控制输入
jump.performed += (context) =>
{
    // 跳跃逻辑,给物体施加向上的力(利用物理系统刚体加力)
    body.AddForce(Vector3.up * 200);
};

点击发子弹要做成鼠标当前位置的获取和射线检测

创建子弹预制体,添加子弹脚本让子弹一直往前飞,两秒后销毁

public class Bullet : MonoBehaviour
{    
    void Start()
    {
        Destroy(this.gameObject, 2);
    }
    
    void Update()
    {
        this.transform.Translate(Vector3.forward * 20 * Time.deltaTime);
    }
}

给开火事件添加左按键,启用开火控制输入,声明一个公共游戏对象bullet,用于存储子弹的预制体,外部关联。Start中给开火事件的触发事件添加监听,把鼠标位置转成射线得到方向向量,生成子弹设置初始旋转

// 声明一个公共游戏对象bullet,用于存储子弹的预制体
public GameObject bullet;
fire.Enable(); // 启用开火控制输入
fire.performed += (context) =>
{
    // 开火逻辑,通过鼠标位置的射线检测确定子弹飞出去的方向
    RaycastHit info;
    if (Physics.Raycast(Camera.main.ScreenPointToRay(Mouse.current.position.ReadValue()), out info))
    {
        // 得到子弹飞出去的向量
        Vector3 point = info.point;
        //让y轴和小球y相等 否则可能会在地下发射
        point.y = this.transform.position.y;
        //得到子弹向量
        Vector3 dir = point - this.transform.position;
        // 创建子弹实例并飞出去
        Instantiate(bullet, this.transform.position, Quaternion.LookRotation(dir));
    }
};

8.4 练习题代码

Lesson08_练习题

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

public class Lesson08_练习题 : MonoBehaviour
{
    //使用InputAction类
    //为一个3D对象制作通过鼠标键盘控制其
    //移动、跳跃、开火的逻辑(移动跳跃 利用物理系统刚体加力)



    // 声明一个公共游戏对象bullet,用于存储子弹的预制体
    public GameObject bullet;

    [Header("移动控制")]
    public InputAction move;
    [Header("跳跃控制")]
    public InputAction jump;
    [Header("开火控制")]
    public InputAction fire;

    private Rigidbody body; // 刚体组件,用于实现物体的运动
    private Vector3 dir; // 存储移动方向的向量

    void Start()
    {
        body = this.GetComponent<Rigidbody>(); // 获取当前游戏对象的刚体组件

        move.Enable(); // 启用移动控制输入

        jump.Enable(); // 启用跳跃控制输入

        fire.Enable(); // 启用开火控制输入

        jump.performed += (context) =>
        {
            // 跳跃逻辑,给物体施加向上的力(利用物理系统刚体加力)
            body.AddForce(Vector3.up * 200);
        };

        fire.performed += (context) =>
        {
            // 开火逻辑,通过鼠标位置的射线检测确定子弹飞出去的方向
            RaycastHit info;
            if (Physics.Raycast(Camera.main.ScreenPointToRay(Mouse.current.position.ReadValue()), out info))
            {
                // 得到子弹飞出去的向量
                Vector3 point = info.point;
                //让y轴和小球y相等 否则可能会在地下发射
                point.y = this.transform.position.y;
                //得到子弹向量
                Vector3 dir = point - this.transform.position;
                // 创建子弹实例并飞出去
                Instantiate(bullet, this.transform.position, Quaternion.LookRotation(dir));
            }
        };
    }

    void Update()
    {
        dir = move.ReadValue<Vector2>(); // 读取移动输入的值,即鼠标或键盘的输入
        dir.z = dir.y; // 将移动向量的y值赋给z值,因为我们只需要在水平方向上移动
        dir.y = 0; // 将移动向量的y值设为0,保证物体不会上下移动
        body.AddForce(dir); // 通过刚体组件给物体施加力,实现移动
    }
}

Bullet

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

public class Bullet : MonoBehaviour
{    
    void Start()
    {
        Destroy(this.gameObject, 2);
    }
 
    void Update()
    {
        this.transform.Translate(Vector3.forward * 20 * Time.deltaTime);
    }
}


转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 785293209@qq.com

×

喜欢就点赞,疼爱就打赏