Unity的InputSystem常见问题和疑惑解答

一、获取InputAction的几种方式

假设我们现在已经配置好了一个最简单的InputAction,如图1

【图1】

方法1.声明public InputActionAsset对象,通过脚本挂上去

代码如下:

csharp 复制代码
public class test1 : MonoBehaviour
{
    public InputActionAsset ass;

    private void Start()
    {
        InputActionMap map = ass.FindActionMap("map1");
        InputAction ac = map.FindAction("KM");
        ac.Enable();    //注意必须要调用Enable!

        ac.started += St;
        ac.performed += Perf;
        ac.canceled += Cancel;
    }

    private void St(CallbackContext context)
    {
        Debug.Log("Start");
    }

    private void Perf(CallbackContext context)
    {
        Debug.Log("Perform");
    }

    private void Cancel(CallbackContext context)
    {
        Debug.Log("Cancel");
    }
}

方法2.通过生成代码的方式获取

Aseets中勾选Generate C# Class,然后Apply,就会生成一个类,之后可以直接用这个类,代码如下

csharp 复制代码
public class test1 : MonoBehaviour
{
    Ac1 ac1; //使用前要先new一个对象
    private void Start()
    {
        ac1 = new Ac1();
        ac1.Enable();  //注意必须要调用Enable!
        InputAction ac = ac1.map1.KM;

        ac.started += St;
        ac.performed += Perf;
        ac.canceled += Cancel;
    }

    private void St(CallbackContext context)
    {
        Debug.Log("Start");
    }

    private void Perf(CallbackContext context)
    {
        Debug.Log("Perform");
    }

    private void Cancel(CallbackContext context)
    {
        Debug.Log("Cancel");
    }
}

关于这里为什么要将ac1放在外面声明,而不是在Start中声明对象,我测试发现,如果放在Start中声明,Ac1析构函数会被提前调用,导致报错

方法3.通过InputActionReference挂上去

csharp 复制代码
public class test1 : MonoBehaviour
{
    public InputActionReference acRef;
    private void Start()
    {
        InputAction ac = acRef.action;
        ac.Enable();  //注意必须要调用Enable!

        ac.started += St;
        ac.performed += Perf;
        ac.canceled += Cancel;
    }

    private void St(CallbackContext context)
    {
        Debug.Log("Start");
    }

    private void Perf(CallbackContext context)
    {
        Debug.Log("Perform");
    }

    private void Cancel(CallbackContext context)
    {
        Debug.Log("Cancel");
    }
}

把Assets里的某个Action拖上去就行了

总结这三种方法的区别:

方法1其实很少用到,因为他是通过字符串查找的,性能就不如其他两种方法,并且如果配置改了名字,那字符串也得跟着改

方法2和方法3的最大区别,就是对象实例的数量问题

方法2虽然需要new一个对象,但是其实全局只应该有一个map,在使用action时,其实所有地方用的都是一个action。如果另外一个地方再new了对象,并且调用Enable时,就会报错

方法3每次拖拽一个进去,都是一个新的实例,这就不会相互影响,并且他可以只考虑这个Action的逻辑,写代码时不用看到其他的Action。所以方法3其实用的是最多的

相关推荐
向上的车轮7 小时前
为什么.NET(C#)转 Java 开发时常常在“吐槽”Java:checked exception
java·c#·.net
Dragon Wu7 小时前
Spring Security Oauth2.1 授权码模式实现前后端分离的方案
java·spring boot·后端·spring cloud·springboot·springcloud
跳动的梦想家h7 小时前
环境配置 + AI 提效双管齐下
java·vue.js·spring
坚持就完事了7 小时前
Java中的集合
java·开发语言
wjhx8 小时前
QT中对蓝牙权限的申请,整理一下
java·数据库·qt
YCY^v^8 小时前
JeecgBoot 项目运行指南
java·学习
人间打气筒(Ada)8 小时前
jenkins基于Pipeline发布项目
java·pipeline·jenkins·流水线·ci·cd·cicd
爬山算法8 小时前
Hibernate(88)如何在负载测试中使用Hibernate?
java·后端·hibernate
自不量力的A同学8 小时前
Solon AI v3.9 正式发布:全能 Skill 爆发
java·网络·人工智能
万岳科技系统开发8 小时前
食堂采购系统源码库存扣减算法与并发控制实现详解
java·前端·数据库·算法