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其实用的是最多的

相关推荐
Frostnova丶7 小时前
LeetCode 190.颠倒二进制位
java·算法·leetcode
闻哥8 小时前
Redis事务详解
java·数据库·spring boot·redis·缓存·面试
hrhcode8 小时前
【Netty】五.ByteBuf内存管理深度剖析
java·后端·spring·springboot·netty
道亦无名8 小时前
aiPbMgrSendAck
java·网络·数据库
发现你走远了9 小时前
Windows 下手动安装java JDK 21 并配置环境变量(详细记录)
java·开发语言·windows
心 -9 小时前
java八股文DI
java
黎雁·泠崖9 小时前
Java常用类核心详解(一):Math 类超细讲解
java·开发语言
大尚来也9 小时前
跨平台全局键盘监听实战:基于 JNativeHook 在 Java 中捕获 Linux 键盘事件
java·linux
追随者永远是胜利者9 小时前
(LeetCode-Hot100)15. 三数之和
java·算法·leetcode·职场和发展·go
懒惰成性的10 小时前
12.Java的异常
java·开发语言