Unity3D关于InputSystem的简单使用(二)

本文详细介绍了如何在Unity3D中使用InputSystem进行游戏输入处理,包括创建Input脚本、实现接口、注册回调函数、处理InputAction的各个阶段,以及如何在角色移动场景中应用这些概念。通过示例代码展示了如何监听键盘输入并触发角色移动的事件,从而实现角色的动态移动控制。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Unity3D关于InputSystem的简单使用(一)

前面提到了关于InputSystem的简单配置 接下来用C#代码的形式用到下面这个接口

public interface IGamePlayActions
{
    void OnMove(InputAction.CallbackContext context);//这里的方法是你添加的具体的Input Action
}

创建Input脚本 并做成ScriptableObject(加不加都行) 并继承接口

并实现抽象接口

//这里的InputMove 指的是你刚才Generate的C#类名
public class PlayerMove : MonoBehaviour, InputMove.IGamePlayActions
{
    public void OnMove(InputAction.CallbackContext context)
    {
        throw new System.NotImplementedException();
    }
}

获取生成类的引用 并实例化

   private InputMove inputActions;
    private void OnEnable()
    {
        inputActions = new InputMove();
        //登记回调函数 这样每次添加新的动作表 在这里登记回调函数
        inputActions.GamePlay.SetCallbacks(this);
    }
    public void DisableAllInputs()
    {
        inputActions.GamePlay.Disable();//禁用动作表
    }
    public void EnableGamePlayInput()
    {
        inputActions.GamePlay.Enable();//启用动作表
    }
    public void OnMove(InputAction.CallbackContext context)
    {
        throw new System.NotImplementedException();
    }

前面我们提到 输入动作是由输入信号触发的事件
声明一个事件onMove

 private event UnityAction<Vector2> onMove = delegate { };
 //因为需要接收的是来自键盘的输入 是一个二维向量 需要添加一个v2的参数

在OnMove函数中调用这个事件:

public void OnMove(InputAction.CallbackContext context)
{
    if (context.phase == InputActionPhase.Performed)//相当于Input.GetKey()
    {
        //传入输入动作读取到的二维向量的值 将其作为参数 
        //当按下按键的时候 调用onmove方法 同时将读取到的二维向量值作为参数
        onMove.Invoke(context.ReadValue<Vector2>());
    }
    if (context.phase == InputActionPhase.Canceled)
    {
        onStopMove.Invoke();
    }
}

关于InputAction

简单了解下

Class InputAction

这个类表示的是一种响应动作逻辑,可以绑定到多个物理输入上,这些绑定的物理输入和得到的输入值将影响同一个 InputAction 对象。该类只代表一种动作“逻辑”而不代表任何物理输入。

每个动作逻辑在每一时刻都有现在的状态阶段(Phase),通过 Enum InputActionPhase 表示,有五种阶段。分别为:Canceled, Disabled, Performed, Started, Waiting。在 Start, Performed, Canceled 阶段会分别触发三个对应的 C# 事件
(类型为eventAction<InputAction.CallbackContext>)。

每次动作逻辑被触发时,可以通过ReadValue()成员来获取本次触发的具体值。

Waiting,Started, Performed,Canceled, Disabled,

Waiting:在动作表启用 且没有输入信号传入
Started:按下按键的那一帧 相当于Input.GetKeyDown()
Performed:输入动作已执行 包含了按下按键和按住按键的两个阶段 相当于Input.Getkey()
Cancel:相当于松开按键的时候 相当于Input.GetKeyUp()

这样 当键盘实现输入后 将具体的vector2的参数传入到事件中 调用事件的函数

在具体的事件函数中写对应的移动代码 就可以实现角色的移动。

参考代码:

[CreateAssetMenu(menuName = "Input")]
public class Input : ScriptableObject, InputSystems.IGamePlayActions
{
    public event UnityAction<Vector2> onMove = delegate { };
    public event UnityAction onStopMove = delegate { };
    private InputSystems inputActions;
    private void OnEnable()
    {
        inputActions = new InputSystems();
        inputActions.GamePlay.SetCallbacks(this);
    }
    private void OnDisable()
    {
        DisableAllInputs();
    }
    public void DisableAllInputs()
    {
        inputActions.GamePlay.Disable();
    }
    public void EnableGamePlayInput()
    {
        inputActions.GamePlay.Enable();
        Cursor.visible = false;
        Cursor.lockState = CursorLockMode.None;
    }
    public void OnMove(InputAction.CallbackContext context)
    {
        if (context.phase == InputActionPhase.Performed)//相当于Input.GetKey()
        {
            //传入输入动作读取到的二维向量的值 将其作为参数 
            //当按下按键的时候 调用onmove方法 同时将读取到的二维向量值作为参数
            onMove.Invoke(context.ReadValue<Vector2>());
        }
        if (context.phase == InputActionPhase.Canceled)
        {
            onStopMove.Invoke();
        }
    }
public class Player : MonoBehaviour
{
    public float moveSpeed = 6f;
    [SerializeField] private Input playerInput;
    [SerializeField] private new Rigidbody2D rigidbody2D;
    [SerializeField] private float acceleTime = 3f;
    [SerializeField] private float deAcceleTime = 3f;
    Coroutine coroutine;
    private void OnEnable()
    {
        //事件处理程序  Player订阅 Input的onMove和onStopMove事件
        playerInput.onMove += Move;
        playerInput.onStopMove += StopMove;
    }
    private void OnDisable()
    {
        playerInput.onMove -= Move;
        playerInput.onStopMove -= StopMove;
    }
    private void Awake()
    {
        rigidbody2D = GetComponent<Rigidbody2D>();
    }
    private void Start()
    {
        playerInput.EnableGamePlayInput();//操作玩家角色时 GamePlay动作表激活 
    }
    private void StopMove()
    {
        if (coroutine != null)
            StopCoroutine(coroutine);//每次按键调用 暂停上一次的协程
        coroutine = StartCoroutine(MoveCoroutine(deAcceleTime, Vector2.zero));
    }

    private void Move(Vector2 moveInput)
    {
        if (coroutine != null)
            StopCoroutine(coroutine);
        coroutine = StartCoroutine(MoveCoroutine(acceleTime, moveInput.normalized * moveSpeed));
    }
    IEnumerator MoveCoroutine(float time, Vector2 moveVelocity)
    {
        float t = 0f;
        while (t < time)
        {
            t += Time.deltaTime / time;
            rigidbody2D.velocity = Vector2.Lerp(rigidbody2D.velocity, moveVelocity, t / time);
            yield return null;
        }
    }
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值