Last active
December 11, 2022 13:18
-
-
Save monry/8c20e41b144ff039956f8a44732169af to your computer and use it in GitHub Desktop.
Unity 2022.1 で Localization 1.4.2 を使っているプロジェクトを iOS ビルドした際に PostprocessBuild で AmbiguousMatchException が発生して、アプリ名とかのローカライズが行われない問題に対するワークアラウンド
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// VersionDefines を用いて「Localization v1.4.2 を用いていたら」的な Precompile Macro や、「Unity 2022.1.16f1 以上なら」みたいな条件を設定しても良いかも。 | |
#if UNITY_EDITOR_OSX && UNITY_IOS | |
using System.Diagnostics; | |
using System.IO; | |
using UnityEditor; | |
using UnityEditor.Compilation; | |
using UnityEngine.Localization.Settings; | |
using PackageInfo = UnityEditor.PackageManager.PackageInfo; | |
namespace Monry.Editor.Workaround | |
{ | |
[InitializeOnLoad] | |
public class FixLocalization | |
{ | |
private const string ChFlagsCommand = "/usr/bin/chflags"; | |
private const string LockFlagName = "uchg"; | |
private const string ReplacementSource = "s_PBXBuildFileDat.GetMethod(\"CreateFromFile\", BindingFlags.Static | BindingFlags.Public)"; | |
private const string ReplacementDestination = "s_PBXBuildFileDat.GetMethod(\"CreateFromFile\", new Type[] { typeof(string), typeof(bool), typeof(string)})"; | |
private const string EditorPrefsKey = "HasLocalizationWorkaroundRun"; | |
private readonly string _scriptFilePath; | |
static FixLocalization() | |
{ | |
EditorApplication.quitting -= UnlockPBXProjectExtensions; | |
EditorApplication.quitting += UnlockPBXProjectExtensions; | |
FixAndLockPBXProjectExtensions(); | |
} | |
private FixLocalization(string scriptFilePath) | |
{ | |
_scriptFilePath = scriptFilePath; | |
} | |
private static void FixAndLockPBXProjectExtensions() | |
{ | |
if (EditorPrefs.GetBool(EditorPrefsKey)) | |
{ | |
return; | |
} | |
EditorPrefs.SetBool(EditorPrefsKey, true); | |
var scriptFilePath = ResolveScriptFilePath(); | |
if (!File.Exists(scriptFilePath)) | |
{ | |
return; | |
} | |
new FixLocalization(scriptFilePath).Run(); | |
} | |
private static void UnlockPBXProjectExtensions() | |
{ | |
EditorPrefs.DeleteKey(EditorPrefsKey); | |
var scriptFilePath = ResolveScriptFilePath(); | |
if (!File.Exists(scriptFilePath)) | |
{ | |
return; | |
} | |
new FixLocalization(scriptFilePath).LockFile(false); | |
} | |
private static string ResolveScriptFilePath() | |
{ | |
var packageInfo = PackageInfo.FindForAssembly(typeof(LocalizationSettings).Assembly); | |
return $"Library/PackageCache/{packageInfo.packageId}/Editor/Platform/iOS/PBXProjectExtensions.cs"; | |
} | |
private void Run() | |
{ | |
LockFile(false); | |
ReplaceCode(); | |
LockFile(true); | |
CompilationPipeline.RequestScriptCompilation(); | |
} | |
private void ReplaceCode() | |
{ | |
var script = File.ReadAllText(_scriptFilePath); | |
script = script.Replace(ReplacementSource, ReplacementDestination); | |
File.WriteAllText(_scriptFilePath, script); | |
} | |
private void LockFile(bool lockFlag) | |
{ | |
var process = new Process(); | |
process.StartInfo = new ProcessStartInfo( | |
ChFlagsCommand, | |
$"{(lockFlag ? string.Empty : "no")}{LockFlagName} '{_scriptFilePath}'" | |
); | |
process.Start(); | |
process.WaitForExit(); | |
} | |
} | |
} | |
#endif |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
ちょっとした解説
[InitializeOnLoad]
BuildPipeline.BuildPlayer()
の前後で置換・ロック・アンロックを実行しても Localization のアセンブリがうまいことリロードされなかったため、[InitializeOnLoad]
で実行している。EditorApplication.quitting
でのアンロックビルドサーバなどでビルドしている場合、コードがロックされたままだと、プロジェクトの Clean (ディレクトリごと削除とか)に失敗するケースがありうるので、エディタが落とされる時にアンロックする。
EditorPrefs
置換・ロックに成功した際に EditorPrefs にフラグを立てて、フラグが立っている場合は何も処理させないことで、無限コンパイルが起きないようにする。
(スクリプトの置換が行われずとも、chflags によるファイル操作が行われた時点で差分ありと見なされて再コンパイル →
[InitializeOnLoad]
実行が発生してしまう。)謝辞
matatabi-ux さん のこちらのブログ記事がとても参考になりました。