Unity 如何在 iOS 新增键盘 KeyCode 响应事件

1.定位到文件UnityView+Keyboard.mm同如下路径:

2.打开该Objective-C脚本进行编辑,找到关键函数: createKeyboard:

- (void)createKeyboard
{
    // only English keyboard layout is supported
    NSString* baseLayout = @"1234567890-=qwertyuiop[]asdfghjkl;'\\`zxcvbnm,./!@#$%^&*()_+{}:\"|<>?~ \t\r\b\\";
    NSString* numpadLayout = @"1234567890-=*+/.\r";
    NSString* upperCaseLetters = @"QWERTYUIOPASDFGHJKLZXCVBNM";

    size_t sizeOfKeyboardCommands = baseLayout.length + numpadLayout.length + upperCaseLetters.length + 11;
    NSMutableArray* commands = [NSMutableArray arrayWithCapacity: sizeOfKeyboardCommands];

    void (^addKey)(NSString *keyName, UIKeyModifierFlags modifierFlags) = ^(NSString *keyName, UIKeyModifierFlags modifierFlags)
    {
        UIKeyCommand* command = [UIKeyCommand keyCommandWithInput: keyName modifierFlags: modifierFlags action: @selector(handleCommand:)];
#if UNITY_HAS_IOSSDK_15_0
        if (@available(iOS 15.0, tvOS 15.0, *))
            command.wantsPriorityOverSystemBehavior = YES;
#endif
        [commands addObject:command];
    };

    for (NSInteger i = 0; i < baseLayout.length; ++i)
    {
        NSString* input = [baseLayout substringWithRange: NSMakeRange(i, 1)];
        NSLog(@"%@ !!!",input);
        addKey(input, kNilOptions);
    }
    for (NSInteger i = 0; i < numpadLayout.length; ++i)
    {
        NSString* input = [numpadLayout substringWithRange: NSMakeRange(i, 1)];
        addKey(input, UIKeyModifierNumericPad);
    }
    for (NSInteger i = 0; i < upperCaseLetters.length; ++i)
    {
        NSString* input = [upperCaseLetters substringWithRange: NSMakeRange(i, 1)];
        addKey(input, UIKeyModifierShift);
    }

    // pageUp, pageDown
    addKey(@"UIKeyInputPageUp", kNilOptions);
    addKey(@"UIKeyInputPageDown", kNilOptions);

    // up, down, left, right, esc
    addKey(UIKeyInputUpArrow, kNilOptions);
    addKey(UIKeyInputDownArrow, kNilOptions);
    addKey(UIKeyInputLeftArrow, kNilOptions);
    addKey(UIKeyInputRightArrow, kNilOptions);
    addKey(UIKeyInputEscape, kNilOptions);

    // caps Lock, shift, control, option, command
    addKey(@"", UIKeyModifierAlphaShift);
    addKey(@"", UIKeyModifierShift);
    addKey(@"", UIKeyModifierControl);
    addKey(@"", UIKeyModifierAlternate);
    addKey(@"", UIKeyModifierCommand);

    keyboardCommands = commands.copy;
}

此函数由Unity定义,通过addKey函数负责初始化注册所有需要响应的按键.

   void (^addKey)(NSString *keyName, UIKeyModifierFlags modifierFlags) = ^(NSString *keyName, UIKeyModifierFlags modifierFlags)
    {
        UIKeyCommand* command = [UIKeyCommand keyCommandWithInput: keyName modifierFlags: modifierFlags action: @selector(handleCommand:)];
#if UNITY_HAS_IOSSDK_15_0
        if (@available(iOS 15.0, tvOS 15.0, *))
            command.wantsPriorityOverSystemBehavior = YES;
#endif
        [commands addObject:command];
    };

函数接受两个参数第一个是keyName表示接收的按键名称例如键盘上的a-z,第二个参数为UIKeyModifierFlags表示作为Modifier的按键种类如下:

  typedef   NS_OPTIONS(NSInteger, UIKeyModifierFlags) {
      UIKeyModifierAlphaShift     = 1 << 16,  // This bit indicates CapsLock
      UIKeyModifierShift          = 1 << 17,
      UIKeyModifierControl        = 1 << 18,
      UIKeyModifierAlternate      = 1 << 19,
      UIKeyModifierCommand        = 1 << 20,
      UIKeyModifierNumericPad     = 1 << 21,
  } API_AVAILABLE(ios(7.0));

使用时例如用户需要接收处理command a,需调用addKey(@"a", UIKeyModifierCommand); 针对于特殊按键对应的NSString存储于UIResponder.h中:

// These are pre-defined constants for use with the input property of UIKeyCommand objects.
UIKIT_EXTERN NSString *const UIKeyInputUpArrow         API_AVAILABLE(ios(7.0));
UIKIT_EXTERN NSString *const UIKeyInputDownArrow       API_AVAILABLE(ios(7.0));
UIKIT_EXTERN NSString *const UIKeyInputLeftArrow       API_AVAILABLE(ios(7.0));
UIKIT_EXTERN NSString *const UIKeyInputRightArrow      API_AVAILABLE(ios(7.0));
UIKIT_EXTERN NSString *const UIKeyInputEscape          API_AVAILABLE(ios(7.0));
UIKIT_EXTERN NSString *const UIKeyInputPageUp          API_AVAILABLE(ios(8.0));
UIKIT_EXTERN NSString *const UIKeyInputPageDown        API_AVAILABLE(ios(8.0));
UIKIT_EXTERN NSString *const UIKeyInputHome            API_AVAILABLE(ios(13.4), tvos(13.4)) API_UNAVAILABLE(watchos);
UIKIT_EXTERN NSString *const UIKeyInputEnd             API_AVAILABLE(ios(13.4), tvos(13.4)) API_UNAVAILABLE(watchos);
UIKIT_EXTERN NSString *const UIKeyInputF1              API_AVAILABLE(ios(13.4), tvos(13.4)) API_UNAVAILABLE(watchos);
UIKIT_EXTERN NSString *const UIKeyInputF1              API_AVAILABLE(ios(13.4), tvos(13.4)) API_UNAVAILABLE(watchos);
UIKIT_EXTERN NSString *const UIKeyInputF2              API_AVAILABLE(ios(13.4), tvos(13.4)) API_UNAVAILABLE(watchos);
UIKIT_EXTERN NSString *const UIKeyInputF3              API_AVAILABLE(ios(13.4), tvos(13.4)) API_UNAVAILABLE(watchos);
UIKIT_EXTERN NSString *const UIKeyInputF4              API_AVAILABLE(ios(13.4), tvos(13.4)) API_UNAVAILABLE(watchos);
UIKIT_EXTERN NSString *const UIKeyInputF5              API_AVAILABLE(ios(13.4), tvos(13.4)) API_UNAVAILABLE(watchos);
UIKIT_EXTERN NSString *const UIKeyInputF6              API_AVAILABLE(ios(13.4), tvos(13.4)) API_UNAVAILABLE(watchos);
UIKIT_EXTERN NSString *const UIKeyInputF7              API_AVAILABLE(ios(13.4), tvos(13.4)) API_UNAVAILABLE(watchos);
UIKIT_EXTERN NSString *const UIKeyInputF8              API_AVAILABLE(ios(13.4), tvos(13.4)) API_UNAVAILABLE(watchos);
UIKIT_EXTERN NSString *const UIKeyInputF9              API_AVAILABLE(ios(13.4), tvos(13.4)) API_UNAVAILABLE(watchos);
UIKIT_EXTERN NSString *const UIKeyInputF10             API_AVAILABLE(ios(13.4), tvos(13.4)) API_UNAVAILABLE(watchos);
UIKIT_EXTERN NSString *const UIKeyInputF11             API_AVAILABLE(ios(13.4), tvos(13.4)) API_UNAVAILABLE(watchos);
UIKIT_EXTERN NSString *const UIKeyInputF12             API_AVAILABLE(ios(13.4), tvos(13.4)) API_UNAVAILABLE(watchos);
UIKIT_EXTERN NSString *const UIKeyInputDelete          API_AVAILABLE(ios(15.0), tvos(15.0)) API_UNAVAILABLE(watchos);

此文档以F1-F12按键添加为例:使用addKey(UIKeyInputF4, kNilOptions);

    addKey(UIKeyInputF1, kNilOptions);
    addKey(UIKeyInputF2, kNilOptions);
    addKey(UIKeyInputF3, kNilOptions);
    addKey(UIKeyInputF4, kNilOptions);
  1. 注册好按键后还需要在handleCommand函数中进行响应处理:

    • (void)handleCommand:(UIKeyCommand )command
      {
      NSString
      input = command.input;
      UIKeyModifierFlags modifierFlags = command.modifierFlags;

      char inputChar = ([input length] > 0) ? [input characterAtIndex: 0] : 0;
      int code = (int)inputChar; // ASCII code
      UnitySendKeyboardCommand(command);

      if (![self isValidCodeForButton: code])
      {
      code = 0;
      }

      if ((modifierFlags & UIKeyModifierAlphaShift) != 0)
      code = UnityStringToKey("caps lock");
      if ((modifierFlags & UIKeyModifierShift) != 0)
      code = UnityStringToKey("left shift");
      if ((modifierFlags & UIKeyModifierControl) != 0)
      code = UnityStringToKey("left ctrl");
      if ((modifierFlags & UIKeyModifierAlternate) != 0)
      code = UnityStringToKey("left alt");
      if ((modifierFlags & UIKeyModifierCommand) != 0)
      code = UnityStringToKey("left cmd");

      if ((modifierFlags & UIKeyModifierNumericPad) != 0)
      {
      switch (inputChar)
      {
      case '0':
      code = UnityStringToKey("[0]");
      break;
      case '1':
      code = UnityStringToKey("[1]");
      break;
      case '2':
      code = UnityStringToKey("[2]");
      break;
      case '3':
      code = UnityStringToKey("[3]");
      break;
      case '4':
      code = UnityStringToKey("[4]");
      break;
      case '5':
      code = UnityStringToKey("[5]");
      break;
      case '6':
      code = UnityStringToKey("[6]");
      break;
      case '7':
      code = UnityStringToKey("[7]");
      break;
      case '8':
      code = UnityStringToKey("[8]");
      break;
      case '9':
      code = UnityStringToKey("[9]");
      break;
      case '-':
      code = UnityStringToKey("[-]");
      break;
      case '=':
      code = UnityStringToKey("equals");
      break;
      case '':
      code = UnityStringToKey("[
      ]");
      break;
      case '+':
      code = UnityStringToKey("[+]");
      break;
      case '/':
      code = UnityStringToKey("[/]");
      break;
      case '.':
      code = UnityStringToKey("[.]");
      break;
      case '\r':
      code = UnityStringToKey("enter");
      break;
      default:
      break;
      }
      }

      if (input == UIKeyInputUpArrow)
      code = UnityStringToKey("up");
      else if (input == UIKeyInputDownArrow)
      code = UnityStringToKey("down");
      else if (input == UIKeyInputRightArrow)
      code = UnityStringToKey("right");
      else if (input == UIKeyInputLeftArrow)
      code = UnityStringToKey("left");
      else if (input == UIKeyInputEscape)
      code = UnityStringToKey("escape");
      else if ([input isEqualToString: @"UIKeyInputPageUp"])
      code = UnityStringToKey("page up");
      else if ([input isEqualToString: @"UIKeyInputPageDown"])
      code = UnityStringToKey("page down");

      KeyMap::iterator item = GetKeyMap().find(code);
      if (item == GetKeyMap().end())
      {
      // New key is down, register it and its time
      UnitySetKeyboardKeyState(code, true);
      GetKeyMap()[code] = GetTimeInSeconds();
      }
      else
      {
      // Still holding the key, update its time
      item->second = GetTimeInSeconds();
      }
      }

函数中input表示createKeyboard函数注册对应的keyName,modifierFlags表示注册时传入的modifierFlags.函数中的Code对应Unity的KeyCodeEnum:

using System;

namespace UnityEngine
{
    // Key codes returned by Event.keyCode. These map directly to a physical key on the keyboard.
    public enum KeyCode
    {
        // Not assigned (never returned as the result of a keystroke)
        None = 0,
        // The backspace key
        Backspace       = 8,
        // The forward delete key
        Delete      = 127,
        // The tab key
        Tab     = 9,
        // The Clear key
        Clear       = 12,
        // Return key
        Return      = 13,
        // Pause on PC machines
        Pause       = 19,
        // Escape key
        Escape      = 27,
        // Space key
        Space       = 32,

        // Numeric keypad 0
        Keypad0     = 256,
        // Numeric keypad 1
        Keypad1     = 257,

前添加判断并给code进行赋值即可,F1-F12对应282-294以此为例代码如下:

   if (input == UIKeyInputF1)
        code = 282;
    else if (input == UIKeyInputF2)
        code = 283;
    else if (input == UIKeyInputF3)
        code = 284;
复制代码
  1. 测试结果如下:
相关推荐
向宇it10 小时前
【从零开始入门unity游戏开发之——C#篇23】C#面向对象继承——`as`类型转化和`is`类型检查、向上转型和向下转型、里氏替换原则(LSP)
java·开发语言·unity·c#·游戏引擎·里氏替换原则
BangRaJun14 小时前
LNCollectionView-替换幂率流体
算法·ios·设计
刘小哈哈哈14 小时前
iOS 多个输入框弹出键盘处理
macos·ios·cocoa
靴子学长14 小时前
iOS + watchOS Tourism App(含源码可简单复现)
mysql·ios·swiftui
Cool-浩18 小时前
Unity 开发Apple Vision Pro空间锚点应用Spatial Anchor
unity·游戏引擎·apple vision pro·空间锚点·spatial anchor·visionpro开发
吴梓穆20 小时前
unity 最小后监听键盘输入
unity
一个程序员(●—●)20 小时前
四元数旋转+四元数和向量相乘+音频相关
unity·游戏引擎
一如初夏丿20 小时前
xcode15 报错 does not contain ‘libarclite‘
ios·xcode
YY-nb21 小时前
Apple Vision Pro 开发教程:通过 TestFlight 把开发的程序安装到其他的设备上测试
unity·apple vision pro
Ke-Di21 小时前
Unity-URP设置单独渲染UI相机
ui·unity