Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

ISSUE-024

Unity KeyboardDelegate初始化报错

常见表现

启动闪退。

通过终端运行游戏,日志显示“[KeyboardDelegate Initialize] called after creating keyboard”。

相关源码

Unity引擎 Keyboard.mm

@implementation KeyboardDelegate

+ (void)Initialize
{
    NSAssert(_keyboard == nil, @"[KeyboardDelegate Initialize] called after creating keyboard");
    if (!_keyboard)
        _keyboard = [[KeyboardDelegate alloc] init];
}

+ (KeyboardDelegate*)Instance
{
    if (!_keyboard)
        _keyboard = [[KeyboardDelegate alloc] init];

    return _keyboard;
}

@end

原因分析

游戏先调用了[KeyboardDelegate Instance],后调用[KeyboardDelegate Initialize],触发断言失败。

解决方法

方法一: 使用PlayCover Nightly版,右键游戏图标 - 设置 - 杂项设置,启用“ignoreUnityKeyboardInitializationError”选项。

方法二: 通过补丁屏蔽+[KeyboardDelegate Initialize]

BUNDLE_ID=com.companyname.appname
EXECUTABLE=~/Library/Containers/io.playcover.PlayCover/Applications/$BUNDLE_ID.app/Frameworks/UnityFramework.framework/UnityFramework
FUNC_ADDR=$(otool -oV $EXECUTABLE | awk '/KeyboardDelegate/{found=1} found && /Initialize/{f=1} f && /imp/{print $2; exit}')
printf '\xC0\x03\x5F\xD6' | dd of=$EXECUTABLE bs=1 seek=$(($FUNC_ADDR)) conv=notrunc
codesign -fs- $EXECUTABLE