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-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