😶‍🌫️

【Unity】macOS版でのWebGLビルドに失敗する

2023/03/20に公開

はじめに

macOS版UnityでWebGL版ビルドに失敗する問題について、(おそらくの)原因と解消方法をまとめました。

実行環境

Unity: 2020.3.32f1
macOS: macOS 12.3以降

ビルド失敗の概要

WebGLビルドを実行しようとした際、以下のようなエラー文が表示されてビルドに失敗します。
(エラー原文ではなく、同様のエラーについてのUnity Answersから引用。改行は記事執筆者による)

System.ComponentModel.Win32Exception (2): No such file or directory
  at System.Diagnostics.Process.ForkAndExecProcess(String filename, String[] argv, String[] envp, String cwd, Boolean redirectStdin, Boolean redirectStdout, Boolean redirectStderr, Boolean setCredentials, UInt32 userId, UInt32 groupId, UInt32[] groups, Int32& stdinFd, Int32& stdoutFd, Int32& stderrFd, Boolean usesTerminal, Boolean throwOnNoExec)
  at System.Diagnostics.Process.StartCore(ProcessStartInfo startInfo)
  at System.Diagnostics.Process.Start()
  at Unity.IL2CPP.Shell.SetupAndStart(ExecuteContext context, Boolean asyncMode) in /Users/bokken/build/output/unity/il2cpp/Unity.IL2CPP.Shell/Shell.cs:line 423
  at Unity.IL2CPP.Shell.ExecuteAsync(ExecuteArgs executeArgs, IExecuteController controller, Boolean asyncMode) in /Users/bokken/build/output/unity/il2cpp/Unity.IL2CPP.Shell/Shell.cs:line 299
  at Unity.IL2CPP.Shell.Execute(ExecuteArgs executeArgs, IExecuteController controller) in /Users/bokken/build/output/unity/il2cpp/Unity.IL2CPP.Shell/Shell.cs:line 355
  at Unity.IL2CPP.Building.CppProgramBuilder.ProvideObjectFile(IntermediateObjectFileCompilationData data) in /Users/bokken/build/output/unity/il2cpp/Unity.IL2CPP.Building/CppProgramBuilder.cs:line 334
  at Unity.IL2CPP.Building.ParallelFor.<>c__DisplayClass1_0`2.<Execute>b__0(Object o) in /Users/bokken/build/output/unity/il2cpp/Unity.IL2CPP.Building/ParallelFor.cs:line 78

下記のような理由でエラーが出るようです。

エラー解消のためにできること

A. バージョン2020.3.40f1以降へのバージョンアップ

2020.3.40f1では、WebGLビルド用モジュールにPython 2.7と対応したツールチェーンがバンドルされているため、バージョンアップすると解消されるとの公式回答がありました。(2021以降へのバージョンアップでもOKだそう)
ただし、このエラーが出た人が全員バージョンアップで直っているわけではないようです。

B. Pythonをインストールし、環境変数を設定し直すコードを追加する

B-0. PCにPythonがインストールされていないことを確認する

ターミナルを起動し、以下のコマンドを実行します。

$ python --version

Pythonがインストールされていない場合

以下のように表示されます。

$ python --version
zsh: command not found: python

Pythonがインストールされている場合

以下(など)のように表示されます。

$ python --version
Python 3.10.5

先述の通り、WebGLビルドモジュールはPython 2.7に依存するため、「Python 2.7がインストールされていない」場合はインストールを行います。

B-1. Python 2.7をインストールする

公式サイトのインストーラから「macOS 64-bit installer」を選択し、Python 2.7をインストールします。
再度$ python --versionのコマンドをターミナルに入力し、Python 2.7.18(など)と表示されたらインストール完了です。

Homebrewを使ったインストール方法について

Homebrewを使ったインストール方法もあり、Pythonで開発を行う際にはこちらが推奨のようです。Homebrewで提供されるPythonは自動的に新しいバージョンに更新されるため、バージョンを切り替えて使用するにはpyenvというツールを使えばいいそうですが、今回は公式サイトのインストーラで事足りたので私(の生徒さん)は試していません。

B-2. 環境変数を設定し直すコードを追加する

新規スクリプトPreBuildProcessing.csを作成し、以下のコードを貼り付けます。
(/Library/Frameworks/Python.framework/Versions/2.7/bin/pythonの部分は、Pythonをインストールしたパスに書き換えます。)

#if UNITY_EDITOR
using UnityEditor;
using UnityEditor.Build;
using UnityEditor.Build.Reporting;
using UnityEngine;
 
public class PreBuildProcessing : IPreprocessBuildWithReport
{
    public int callbackOrder => 1;
    public void OnPreprocessBuild(BuildReport report)
    {
        System.Environment.SetEnvironmentVariable("EMSDK_PYTHON", "/Library/Frameworks/Python.framework/Versions/2.7/bin/python");
    }
}
#endif

これは先程インストールしたPython 2.7のパスをEMSDK_PYTHONというシステム環境変数に設定するコードなのですが、ApplicationsにあるPythonのパスを指定するよう書き換えるとうまく動作しないです。これは、ApplicationsにあるPythonはインタプリタ(ソースコードを直接実行するプログラム)そのものではないから(だそう)です。Unity Answersに投稿されている通り、インタプリタへのパスを通す必要があるらしいです。

Python2.7がインストールされていれば、ターミナルで以下のコマンドを実行するとPythonインタプリタのパスが取得できます。

$ which python

B-3. 作成したスクリプトを所定の場所に置いてビルド

作成したPreBuildProcessing.csですが、Assetsフォルダ直下に置いてビルドするとうまくいったと言っている人と、Assets>Editorに格納してうまくいったと言っている人がどちらもいるようです。プリプロセッサで囲んであるのでAssetsフォルダ直下で構わないと思われますが、解消されない場合はEditorフォルダを作成し、そこにPreBuildProcessing.csを置いてみてください。

おわりに

忘れがちですが、最終的にWebGLなりPC用なりでビルドしたいプログラムの場合はコードを書く前や、一段落ついたタイミングでビルドできるかどうかを確認しておくのが良さそうです。バージョンアップが致命的で(ある可能性が)ないプログラムであれば、Unity自体のバージョンを上げるのが一番楽だったな…と思っています。

参考

Discussion