Android中system/bin/Input命令 -- Android12

这篇具有很好参考价值的文章主要介绍了Android中system/bin/Input命令 -- Android12。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

android12-release


1、Android12 Input命令更新

Android中system/bin/Input命令 -- Android12,Android,# InputMethodManagerService,Android,IMS,Input

ANdroid12之前可查看一下 IMS:injectInputEvent注入Input事件,Android12更新相关代码:
frameworks/base/services/core/java/com/android/server/input/InputManagerService.java
frameworks/base/services/core/java/com/android/server/input/InputShellCommand.java
frameworks/base/core/java/android/os/ShellCommand.java
frameworks/libs/modules-utils/java/com/android/modules/utils/BasicShellCommandHandler.java

emulator64_x86_64_arm64:/system/bin # input -d

Exception occurred while executing '-d':
java.lang.IllegalArgumentException: Argument expected after "-d"
        at com.android.modules.utils.BasicShellCommandHandler.getNextArgRequired(BasicShellCommandHandler.java:295)
        at com.android.server.input.InputShellCommand.getDisplayId(InputShellCommand.java:85)
        at com.android.server.input.InputShellCommand.onCommand(InputShellCommand.java:182)
        at com.android.modules.utils.BasicShellCommandHandler.exec(BasicShellCommandHandler.java:97)
        at android.os.ShellCommand.exec(ShellCommand.java:38)
        at com.android.server.input.InputManagerService.onShellCommand(InputManagerService.java:3478)
        at android.os.Binder.shellCommand(Binder.java:950)
        at android.os.Binder.onTransact(Binder.java:834)
        at android.hardware.input.IInputManager$Stub.onTransact(IInputManager.java:1125)
        at android.os.Binder.execTransactInternal(Binder.java:1184)
        at android.os.Binder.execTransact(Binder.java:1143)
255|emulator64_x86_64_arm64:/system/bin # input keyevent KEYCODE_VOLUME_UP

1.1 shell脚本

input脚本使用cmd bin执行,获取到Input服务Context.INPUT_SERVICE,通过IBinder::shellCommand(service, ......)最终调用的InputManagerService服务端onShellCommand方法
Android中system/bin/Input命令 -- Android12,Android,# InputMethodManagerService,Android,IMS,Input

frameworks/base/cmds/input/input

#!/system/bin/sh
cmd input "$@"

frameworks/native/cmds/cmd/cmd.cpp

int cmdMain(const std::vector<std::string_view>& argv, TextOutput& outputLog, TextOutput& errorLog,
            int in, int out, int err, RunMode runMode) {
    sp<ProcessState> proc = ProcessState::self();
    proc->startThreadPool();

#if DEBUG
    ALOGD("cmd: starting");
#endif
    sp<IServiceManager> sm = defaultServiceManager();
    if (runMode == RunMode::kStandalone) {
        fflush(stdout);
    }
    if (sm == nullptr) {
        ALOGW("Unable to get default service manager!");
        errorLog << "cmd: Unable to get default service manager!" << endl;
        return 20;
    }

    int argc = argv.size();

    if (argc == 0) {
        errorLog << "cmd: No service specified; use -l to list all running services. Use -w to start and wait for a service." << endl;
        return 20;
    }

    if ((argc == 1) && (argv[0] == "-l")) {
        Vector<String16> services = sm->listServices();
        services.sort(sort_func);
        outputLog << "Currently running services:" << endl;

        for (size_t i=0; i<services.size(); i++) {
            sp<IBinder> service = sm->checkService(services[i]);
            if (service != nullptr) {
                outputLog << "  " << services[i] << endl;
            }
        }
        return 0;
    }

    bool waitForService = ((argc > 1) && (argv[0] == "-w"));
    int serviceIdx = (waitForService) ? 1 : 0;
    const auto cmd = argv[serviceIdx];

    Vector<String16> args;
    String16 serviceName = String16(cmd.data(), cmd.size());
    for (int i = serviceIdx + 1; i < argc; i++) {
        args.add(String16(argv[i].data(), argv[i].size()));
    }
    sp<IBinder> service;
    if(waitForService) {
        service = sm->waitForService(serviceName);
    } else {
        service = sm->checkService(serviceName);
    }

    if (service == nullptr) {
        if (runMode == RunMode::kStandalone) {
            ALOGW("Can't find service %.*s", static_cast<int>(cmd.size()), cmd.data());
        }
        errorLog << "cmd: Can't find service: " << cmd << endl;
        return 20;
    }

    sp<MyShellCallback> cb = new MyShellCallback(errorLog);
    sp<MyResultReceiver> result = new MyResultReceiver();

#if DEBUG
    ALOGD("cmd: Invoking %.*s in=%d, out=%d, err=%d",
          static_cast<int>(cmd.size()), cmd.data(), in, out, err);
#endif

    // TODO: block until a result is returned to MyResultReceiver.
    status_t error = IBinder::shellCommand(service, in, out, err, args, cb, result);
    if (error < 0) {
        const char* errstr;
        switch (error) {
            case BAD_TYPE: errstr = "Bad type"; break;
            case FAILED_TRANSACTION: errstr = "Failed transaction"; break;
            case FDS_NOT_ALLOWED: errstr = "File descriptors not allowed"; break;
            case UNEXPECTED_NULL: errstr = "Unexpected null"; break;
            default: errstr = strerror(-error); break;
        }
        if (runMode == RunMode::kStandalone) {
            ALOGW("Failure calling service %.*s: %s (%d)", static_cast<int>(cmd.size()), cmd.data(),
                  errstr, -error);
        }
        outputLog << "cmd: Failure calling service " << cmd << ": " << errstr << " (" << (-error)
                  << ")" << endl;
        return error;
    }

    cb->mActive = false;
    status_t res = result->waitForResult();
#if DEBUG
    ALOGD("result=%d", (int)res);
#endif
    return res;
}

1.2 InputShellCommand#onCommand 命令解析

frameworks/base/services/core/java/com/android/server/input/InputShellCommand.java
frameworks/base/core/java/android/os/ShellCommand.java
frameworks/libs/modules-utils/java/com/android/modules/utils/BasicShellCommandHandler.java

  • "text"runText(inputSource, displayId);
  • "keyevent"runKeyEvent(inputSource, displayId);
  • "tap"runTap(inputSource, displayId);
  • "swipe"runSwipe(inputSource, displayId);
  • "draganddrop"runDragAndDrop(inputSource, displayId);
  • "press"runPress(inputSource, displayId);
  • "roll"runRoll(inputSource, displayId);
  • "motionevent"runMotionEvent(inputSource, displayId);
  • "keycombination"runKeyCombination(inputSource, displayId);
  • handleDefaultCommands(arg);
@Override
public final int onCommand(String cmd) {
    String arg = cmd;
    int inputSource = InputDevice.SOURCE_UNKNOWN;
    // Get source (optional).
    if (SOURCES.containsKey(arg)) {
        inputSource = SOURCES.get(arg);
        arg = getNextArgRequired();
    }

    // Get displayId (optional).
    int displayId = INVALID_DISPLAY;
    if ("-d".equals(arg)) {
        displayId = getDisplayId();
        arg = getNextArgRequired();
    }

    try {
        if ("text".equals(arg)) {
            runText(inputSource, displayId);
        } else if ("keyevent".equals(arg)) {
            runKeyEvent(inputSource, displayId);
        } else if ("tap".equals(arg)) {
            runTap(inputSource, displayId);
        } else if ("swipe".equals(arg)) {
            runSwipe(inputSource, displayId);
        } else if ("draganddrop".equals(arg)) {
            runDragAndDrop(inputSource, displayId);
        } else if ("press".equals(arg)) {
            runPress(inputSource, displayId);
        } else if ("roll".equals(arg)) {
            runRoll(inputSource, displayId);
        }  else if ("motionevent".equals(arg)) {
            runMotionEvent(inputSource, displayId);
        } else if ("keycombination".equals(arg)) {
            runKeyCombination(inputSource, displayId);
        } else {
            handleDefaultCommands(arg);
        }
    } catch (NumberFormatException ex) {
        throw new IllegalArgumentException(INVALID_ARGUMENTS + arg);
    }
    return 0;
}

2、Input相关命令参数

2.1 text

input text c 输入键盘字符,injectInputEvent注入KeyEvent事件

Android中system/bin/Input命令 -- Android12,Android,# InputMethodManagerService,Android,IMS,Input

private void sendText(int source, final String text, int displayId) {
    final StringBuilder buff = new StringBuilder(text);
    boolean escapeFlag = false;
    for (int i = 0; i < buff.length(); i++) {
        if (escapeFlag) {
            escapeFlag = false;
            if (buff.charAt(i) == 's') {
                buff.setCharAt(i, ' ');
                buff.deleteCharAt(--i);
            }
        }
        if (buff.charAt(i) == '%') {
            escapeFlag = true;
        }
    }

    final char[] chars = buff.toString().toCharArray();
    final KeyCharacterMap kcm = KeyCharacterMap.load(KeyCharacterMap.VIRTUAL_KEYBOARD);
    final KeyEvent[] events = kcm.getEvents(chars);
    for (int i = 0; i < events.length; i++) {
        KeyEvent e = events[i];
        if (source != e.getSource()) {
            e.setSource(source);
        }
        e.setDisplayId(displayId);
        injectKeyEvent(e);
    }
}

2.2 keyevent

input keyevent KEYCODE_VOLUME_UP KeyEvent中对应的KEYCODE_*事件,injectInputEvent注入KeyEvent事件
Android中system/bin/Input命令 -- Android12,Android,# InputMethodManagerService,Android,IMS,Input

Android中system/bin/Input命令 -- Android12,Android,# InputMethodManagerService,Android,IMS,Input

private void runKeyEvent(int inputSource, int displayId) {
    String arg = getNextArgRequired();
    final boolean longpress = "--longpress".equals(arg);
    if (longpress) {
        arg = getNextArgRequired();
    } else {
        final boolean doubleTap = "--doubletap".equals(arg);
        if (doubleTap) {
            arg = getNextArgRequired();
            final int keycode = KeyEvent.keyCodeFromString(arg);
            sendKeyDoubleTap(inputSource, keycode, displayId);
            return;
        }
    }

    do {
        final int keycode = KeyEvent.keyCodeFromString(arg);
        sendKeyEvent(inputSource, keycode, longpress, displayId);
    } while ((arg = getNextArg()) != null);
}

private void sendKeyEvent(int inputSource, int keyCode, boolean longpress, int displayId) {
    final long now = SystemClock.uptimeMillis();

    KeyEvent event = new KeyEvent(now, now, KeyEvent.ACTION_DOWN, keyCode, 0 /* repeatCount */,
            0 /*metaState*/, KeyCharacterMap.VIRTUAL_KEYBOARD, 0 /*scancode*/, 0 /*flags*/,
            inputSource);
    event.setDisplayId(displayId);

    injectKeyEvent(event);
    if (longpress) {
        // Some long press behavior would check the event time, we set a new event time here.
        final long nextEventTime = now + ViewConfiguration.getGlobalActionKeyTimeout();
        injectKeyEvent(KeyEvent.changeTimeRepeat(event, nextEventTime, 1 /* repeatCount */,
                KeyEvent.FLAG_LONG_PRESS));
    }
    injectKeyEvent(KeyEvent.changeAction(event, KeyEvent.ACTION_UP));
}

2.3 tap

input tap 1000 2000 坐标点(x, y)的MotionEvent点解事件,injectInputEvent注入MotionEvent事件

Android中system/bin/Input命令 -- Android12,Android,# InputMethodManagerService,Android,IMS,Input

private void runTap(int inputSource, int displayId) {
    inputSource = getSource(inputSource, InputDevice.SOURCE_TOUCHSCREEN);
    sendTap(inputSource, Float.parseFloat(getNextArgRequired()),
            Float.parseFloat(getNextArgRequired()), displayId);
}

private void sendTap(int inputSource, float x, float y, int displayId) {
    final long now = SystemClock.uptimeMillis();
    injectMotionEvent(inputSource, MotionEvent.ACTION_DOWN, now, now, x, y, 1.0f,
            displayId);
    injectMotionEvent(inputSource, MotionEvent.ACTION_UP, now, now, x, y, 0.0f, displayId);
}

2.4 swipe

input swipe 1000 2000 100 200 从坐标点(x1, y1)滑动到坐标点(x2, y2)的MotionEvent事件,injectInputEvent注入MotionEvent事件

Android中system/bin/Input命令 -- Android12,Android,# InputMethodManagerService,Android,IMS,Input

private void runSwipe(int inputSource, int displayId) {
    inputSource = getSource(inputSource, InputDevice.SOURCE_TOUCHSCREEN);
    sendSwipe(inputSource, displayId, false);
}

private void sendSwipe(int inputSource, int displayId, boolean isDragDrop) {
    // Parse two points and duration.
    final float x1 = Float.parseFloat(getNextArgRequired());
    final float y1 = Float.parseFloat(getNextArgRequired());
    final float x2 = Float.parseFloat(getNextArgRequired());
    final float y2 = Float.parseFloat(getNextArgRequired());
    String durationArg = getNextArg();
    int duration = durationArg != null ? Integer.parseInt(durationArg) : -1;
    if (duration < 0) {
        duration = 300;
    }

    final long down = SystemClock.uptimeMillis();
    injectMotionEvent(inputSource, MotionEvent.ACTION_DOWN, down, down, x1, y1, 1.0f,
            displayId);
    if (isDragDrop) {
        // long press until drag start.
        try {
            Thread.sleep(ViewConfiguration.getLongPressTimeout());
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
    }
    long now = SystemClock.uptimeMillis();
    final long endTime = down + duration;
    while (now < endTime) {
        final long elapsedTime = now - down;
        final float alpha = (float) elapsedTime / duration;
        injectMotionEvent(inputSource, MotionEvent.ACTION_MOVE, down, now,
                lerp(x1, x2, alpha), lerp(y1, y2, alpha), 1.0f, displayId);
        now = SystemClock.uptimeMillis();
    }
    injectMotionEvent(inputSource, MotionEvent.ACTION_UP, down, now, x2, y2, 0.0f,
            displayId);
}

2.5 draganddrop

input draganddrop 1000 2000 100 200 与参数swipe 不同的是isDragDrop=true从坐标点(x1, y1)拖拽到坐标点(x2, y2)的MotionEvent事件,injectInputEvent注入MotionEvent事件

private void sendSwipe(int inputSource, int displayId, boolean isDragDrop) {
    // Parse two points and duration.
    final float x1 = Float.parseFloat(getNextArgRequired());
    final float y1 = Float.parseFloat(getNextArgRequired());
    final float x2 = Float.parseFloat(getNextArgRequired());
    final float y2 = Float.parseFloat(getNextArgRequired());
    String durationArg = getNextArg();
    int duration = durationArg != null ? Integer.parseInt(durationArg) : -1;
    if (duration < 0) {
        duration = 300;
    }

    final long down = SystemClock.uptimeMillis();
    injectMotionEvent(inputSource, MotionEvent.ACTION_DOWN, down, down, x1, y1, 1.0f,
            displayId);
    if (isDragDrop) {
        // long press until drag start.
        try {
            Thread.sleep(ViewConfiguration.getLongPressTimeout());
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
    }
    long now = SystemClock.uptimeMillis();
    final long endTime = down + duration;
    while (now < endTime) {
        final long elapsedTime = now - down;
        final float alpha = (float) elapsedTime / duration;
        injectMotionEvent(inputSource, MotionEvent.ACTION_MOVE, down, now,
                lerp(x1, x2, alpha), lerp(y1, y2, alpha), 1.0f, displayId);
        now = SystemClock.uptimeMillis();
    }
    injectMotionEvent(inputSource, MotionEvent.ACTION_UP, down, now, x2, y2, 0.0f,
            displayId);
}

private void runDragAndDrop(int inputSource, int displayId) {
    inputSource = getSource(inputSource, InputDevice.SOURCE_TOUCHSCREEN);
    sendSwipe(inputSource, displayId, true);
}

2.6 press

input press 与参数tap不同的是规定固定在(0,0)的SOURCE_TRACKBALL事件,injectInputEvent注入MotionEvent事件

private void sendTap(int inputSource, float x, float y, int displayId) {
    final long now = SystemClock.uptimeMillis();
    injectMotionEvent(inputSource, MotionEvent.ACTION_DOWN, now, now, x, y, 1.0f,
            displayId);
    injectMotionEvent(inputSource, MotionEvent.ACTION_UP, now, now, x, y, 0.0f, displayId);
}

private void runPress(int inputSource, int displayId) {
    inputSource = getSource(inputSource, InputDevice.SOURCE_TRACKBALL);
    sendTap(inputSource, 0.0f, 0.0f, displayId);
}

2.7 roll

input roll 1000 2000 就是MotionEvent.ACTION_MOVE事件,injectInputEvent注入MotionEvent事件

Android中system/bin/Input命令 -- Android12,Android,# InputMethodManagerService,Android,IMS,Input

private void runRoll(int inputSource, int displayId) {
    inputSource = getSource(inputSource, InputDevice.SOURCE_TRACKBALL);
    sendMove(inputSource, Float.parseFloat(getNextArgRequired()),
            Float.parseFloat(getNextArgRequired()), displayId);
}

/**
 * Sends a simple zero-pressure move event.
 *
 * @param inputSource the InputDevice.SOURCE_* sending the input event
 * @param dx change in x coordinate due to move
 * @param dy change in y coordinate due to move
 */
private void sendMove(int inputSource, float dx, float dy, int displayId) {
    final long now = SystemClock.uptimeMillis();
    injectMotionEvent(inputSource, MotionEvent.ACTION_MOVE, now, now, dx, dy, 0.0f,
            displayId);
}

2.8 motionevent

input motionevent DOWN 1000 2000/input motionevent UP 1000 2000 就是MotionEvent各种事件,injectInputEvent注入MotionEvent事件

Android中system/bin/Input命令 -- Android12,Android,# InputMethodManagerService,Android,IMS,Input

private int getAction() {
    String actionString = getNextArgRequired();
    switch (actionString.toUpperCase()) {
        case "DOWN":
            return MotionEvent.ACTION_DOWN;
        case "UP":
            return MotionEvent.ACTION_UP;
        case "MOVE":
            return MotionEvent.ACTION_MOVE;
        case "CANCEL":
            return MotionEvent.ACTION_CANCEL;
        default:
            throw new IllegalArgumentException("Unknown action: " + actionString);
    }
}

private void runMotionEvent(int inputSource, int displayId) {
    inputSource = getSource(inputSource, InputDevice.SOURCE_TOUCHSCREEN);
    int action = getAction();
    float x = 0, y = 0;
    if (action == MotionEvent.ACTION_DOWN
            || action == MotionEvent.ACTION_MOVE
            || action == MotionEvent.ACTION_UP) {
        x = Float.parseFloat(getNextArgRequired());
        y = Float.parseFloat(getNextArgRequired());
    } else {
        // For ACTION_CANCEL, the positions are optional
        String xString = getNextArg();
        String yString = getNextArg();
        if (xString != null && yString != null) {
            x = Float.parseFloat(xString);
            y = Float.parseFloat(yString);
        }
    }

    sendMotionEvent(inputSource, action, x, y, displayId);
}

private void sendMotionEvent(int inputSource, int action, float x, float y,
        int displayId) {
    float pressure = NO_PRESSURE;

    if (action == MotionEvent.ACTION_DOWN || action == MotionEvent.ACTION_MOVE) {
        pressure = DEFAULT_PRESSURE;
    }

    final long now = SystemClock.uptimeMillis();
    injectMotionEvent(inputSource, action, now, now, x, y, pressure, displayId);
}

2.9 keycombination

input keycombination KEYCODE_POWER KEYCODE_VOLUME_DOWN KeyEvent的组合按键,injectInputEvent连续注入KeyEvent事件

Android中system/bin/Input命令 -- Android12,Android,# InputMethodManagerService,Android,IMS,Input

private void runKeyCombination(int inputSource, int displayId) {
    String arg = getNextArgRequired();
    ArrayList<Integer> keyCodes = new ArrayList<>();

    while (arg != null) {
        final int keyCode = KeyEvent.keyCodeFromString(arg);
        if (keyCode == KeyEvent.KEYCODE_UNKNOWN) {
            throw new IllegalArgumentException("Unknown keycode: " + arg);
        }
        keyCodes.add(keyCode);
        arg = getNextArg();
    }

    // At least 2 keys.
    if (keyCodes.size() < 2) {
        throw new IllegalArgumentException("keycombination requires at least 2 keycodes");
    }

    sendKeyCombination(inputSource, keyCodes, displayId);
}

private void injectKeyEventAsync(KeyEvent event) {
    InputManager.getInstance().injectInputEvent(event,
            InputManager.INJECT_INPUT_EVENT_MODE_ASYNC);
}

private void sendKeyCombination(int inputSource, ArrayList<Integer> keyCodes, int displayId) {
    final long now = SystemClock.uptimeMillis();
    final int count = keyCodes.size();
    final KeyEvent[] events = new KeyEvent[count];
    for (int i = 0; i < count; i++) {
        final KeyEvent event = new KeyEvent(now, now, KeyEvent.ACTION_DOWN, keyCodes.get(i), 0,
                0 /*metaState*/, KeyCharacterMap.VIRTUAL_KEYBOARD, 0 /*scancode*/, 0 /*flags*/,
                inputSource);
        event.setDisplayId(displayId);
        events[i] = event;
    }

    for (KeyEvent event: events) {
        // Use async inject so interceptKeyBeforeQueueing or interceptKeyBeforeDispatching could
        // handle keys.
        injectKeyEventAsync(event);
    }

    try {
        Thread.sleep(ViewConfiguration.getTapTimeout());
    } catch (InterruptedException e) {
        e.printStackTrace();
    }

    for (KeyEvent event: events) {
        injectKeyEventAsync(KeyEvent.changeAction(event, KeyEvent.ACTION_UP));
    }
}

2.10 默认handleDefaultCommands(arg)

  • dump
    Android中system/bin/Input命令 -- Android12,Android,# InputMethodManagerService,Android,IMS,InputAndroid中system/bin/Input命令 -- Android12,Android,# InputMethodManagerService,Android,IMS,Input

  • help
    Android中system/bin/Input命令 -- Android12,Android,# InputMethodManagerService,Android,IMS,InputAndroid中system/bin/Input命令 -- Android12,Android,# InputMethodManagerService,Android,IMS,Input

  • "Unknown command: " 不识别
    Android中system/bin/Input命令 -- Android12,Android,# InputMethodManagerService,Android,IMS,Input文章来源地址https://www.toymoban.com/news/detail-547238.html

到了这里,关于Android中system/bin/Input命令 -- Android12的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【Unity_Input System】Input System新输入系统(三)——在游戏中更换按键绑定

    Binding只由一个部分组成,一般绑定单个按键或者摇杆 CompositeBinding由两个以上部分组成,一般是用于将多个按键组成虚拟轴 更换按键绑定时,Binding和Composite Binding需要分别处理,对Composite Binding需要循环各个部分进行修改。 可以用InputBinding.isComposite来判断是否是Composite Bind

    2024年02月04日
    浏览(50)
  • 潇洒郎: 小白一次性成功——红米 Note 12 5G Android12 系统13.0.16/14.0.9 小米红米手机解BL锁+ROOT-刷面具—官方ROM下载-线刷降级—解锁system系统分区

    下载工具 申请解锁小米手机 (miui.com) 驱动安装进入Fastboot模式后,会自动识别已连接, 否则显示未连接

    2024年01月25日
    浏览(116)
  • Unity新(Input System)老(Input Manager)输入系统代码对比

    以下介绍都是基于Unity2022版本 一、键盘操作 当w键按下时 当w键抬起时 当w键按着时 二、鼠标操作 获取鼠标位置 获取鼠标滚轮 获取鼠标左键按下 获取鼠标右键抬起 获取鼠标中间按着

    2024年02月16日
    浏览(46)
  • Unity 3D Input System的使用

    Input System是Unity新推出的输入系统,可以用作以前Input Manager的更具扩展性和可自定义性的替代方案。这里我将使用Unity 3D的Input System来实现一个FPS第一人称的游戏场景。 演示效果如下: 新建一个Unity 3D项目,在Asset Store里面下载StarterAssets - FirstPerson,然后在Package Manager里面导

    2024年02月20日
    浏览(34)
  • Unity 新版输入系统(Input System)

    官方教程 注意 新的输入法系统需要 Unity 2019.4+ 和 .NET 4 运行时。它不适用于 .NET 3.5 的项目。 教程版本:Unity 2021.3.26 导航栏 - Window - Package Manager 选择 Unity Registry 在列表中找到 Input System 点击 Install 安装 点击 Yes 启用新版 Input System 等待Unity重新启动 Unity 默认会同时启用旧版和

    2024年04月23日
    浏览(47)
  • /system/bin/sh: ./xxx: can‘t execute: Permission denied

    adb shell在Android emulator下运行可执行文件时,报错: 以为是权限问题,执行 su 进入root权限,然后执行 chmod 777 文件名 修改权限。重新运行可执行文件,还是报同样的错。 最后发现是可执行文件存放的路径问题,有些路径放可执行文件是执行不了的,不知道是为什么。 最后把

    2024年02月16日
    浏览(48)
  • 第五十二章 Unity Input System 新输入系统

    新输入系统InputSystem是2019年Unity新推出的插件。请注意,Unity默认使用旧的Input Manager,新的Input System处于未启用状态。当你安装Input System组件时,Unity会询问你是否启用新的输入系统。如果你选择Yes,Unity会启用新的并禁用旧的,之后编辑器将重新启动。具体的操作是,打开包

    2024年02月07日
    浏览(39)
  • 【Unity学习笔记】New Input System 部分源码和测试用例补充

    转载请注明出处:🔗https://blog.csdn.net/weixin_44013533/article/details/135630016 作者:CSDN@|Ringleader| 主要参考: Unity官方Input System手册与API 【Unity学习笔记】Unity TestRunner使用 NewIputSystem主体内容请参见:【Unity学习笔记】第十二 · New Input System 及其系统结构 和 源码浅析 注:本文使用的

    2024年01月22日
    浏览(40)
  • Unity New Input System 及其系统结构和源码浅析【Unity学习笔记·第十二】

    转载请注明出处:🔗https://blog.csdn.net/weixin_44013533/article/details/132534422 作者:CSDN@|Ringleader| 主要参考: 官方文档:Unity官方Input System手册与API 官方测试用例:Unity-Technologies/InputSystem 如果c#的委托和事件不了解,参考我这篇:【C#学习笔记】委托与事件 (从观察者模式看C#的委

    2024年01月25日
    浏览(52)
  • Unity VR:XR Interaction Toolkit 输入系统(Input System):获取手柄的输入

    输入系统是 VR 应用中非常重要的一部分。我们通常需要获取 VR 手柄上某个按键的输入,然后将其作用到应用中,比如按下手柄的 Grip 键进行抓取。在我的其他 Unity XR Interaction Toolkit 的开发教程里,已经有介绍如何去获取手柄的输入。那么这篇教程我将做一个总结,将相关的

    2024年02月12日
    浏览(42)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包