ISSUE-001
虚幻引擎文件路径错误
常见表现
加载进度卡住,加载过程中提示存储空间不足,加载过程中提示文件操作失败,加载过程中闪退,启动阶段黑屏。
相关源码
虚幻引擎 IOSPlatformFile.cpp
FString FIOSPlatformFile::ConvertToPlatformPath(const FString& Filename, bool bForWrite, bool bIsPublicWrite)
{
FString Result = Filename;
if (Result.StartsWith(TEXT("/var/")))
{
return Result;
}
if (bForWrite)
{
static FString PublicWritePathBase = FString([NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0]) + TEXT("/");
static FString PrivateWritePathBase = FString([NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES) objectAtIndex:0]) + TEXT("/");
return (bIsPublicWrite ? PublicWritePathBase : PrivateWritePathBase) + Result;
}
else
{
static FString ReadPathBase = FString([[NSBundle mainBundle] bundlePath]) + TEXT("/cookeddata/");
return ReadPathBase + Result.ToLower();
}
}
原因分析
虚幻引擎根据字符串是否以/var/开头,来判断字符串是否绝对路径,但macOS的绝对路径并不是以/var/开头的,因此导致各种问题。
iOS的绝对路径:/var/mobile/Containers/Data/Application/{GUID}/Documents
macOS的绝对路径:/Users/{USER}/Containers/{BUNDLE_ID}/Data/Documents
解决方法
文件链接法
BUNDLE_ID=com.companyname.appname
rm -r /Users/$USER/Library/Containers/$BUNDLE_ID/Data/Documents/Users/$USER/Library/Containers/$BUNDLE_ID/Data && ln -sf /Users/$USER/Library/Containers/$BUNDLE_ID/Data /Users/$USER/Library/Containers/$BUNDLE_ID/Data/Documents/Users/$USER/Library/Containers/$BUNDLE_ID/Data
rm -r /Users/$USER/Library/Containers/$BUNDLE_ID/Data/Library/Users/$USER/Library/Containers/$BUNDLE_ID/Data && ln -sf /Users/$USER/Library/Containers/$BUNDLE_ID/Data /Users/$USER/Library/Containers/$BUNDLE_ID/Data/Library/Users/$USER/Library/Containers/$BUNDLE_ID/Data
补丁法
修改常量字符串/var/为/User(保持字符串长度不变)
BUNDLE_ID=com.companyname.appname
BUNDLE_PATH=~/Library/Containers/io.playcover.PlayCover/Applications/$BUNDLE_ID.app
EXECUTABLE=$BUNDLE_PATH/$(/usr/libexec/PlistBuddy -c "Print :CFBundleExecutable" $BUNDLE_PATH/Info.plist)
perl -e 'open F, "+<:raw", $ARGV[0] or die $!; local $/; my $d = <F>; my $i = index($d, "\x2F\x00\x76\x00\x61\x00\x72\x00\x2F\x00\x00\x00"); exit 1 if $i < 0; seek F, $i, 0; print F "\x2F\x00\x55\x00\x73\x00\x65\x00\x72\x00\x00\x00"; close F;' $EXECUTABLE
codesign -fs- $EXECUTABLE --deep --preserve-metadata=entitlements