この記事はUnity Advent Calendar 201916日目の記事です
はじめに
- 自動ビルドというとゲーム業界ではJenkinsを使うのが一般的だと思います
- かれこれ私も5年以上Jenkinsおじさんをやっています
- 今回はJenkinsでUnityビルドを作成する方法をご紹介します
- 今回はWindowsビルドを作成するまでを記事にしていますが、Androidビルドもほぼ同じ方法で実行可能です
- iOSの場合はXCodeプロジェクトを出力した後に、コマンドラインからXcodeを実行するシェルスクリプトを書く必要があります
Unity側の準備
コマンドラインからUnityを使う
- Unityはコマンドラインから、プロジェクト内の関数を実行することができます
- コマンドラインから関数を呼び出すには
Editor
フォルダ内にスクリプトを作成し、static
な関数を準備します
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class CommandLineTest
{
public static void TestFunction()
{
Debug.Log("Hello World!");
}
}
呼び出し方
/Applications/Unity/Hub/Editor/2019.3.0f1/Unity.app/Contents/MacOS/Unity \
-batchmode -quit -logFile log.txt \
-projectPath ~/UnityProjects/JenkinsTest \
-executeMethod CommandLineTest.TestFunction
実行結果
Hello World!
UnityEngine.DebugLogHandler:Internal_Log(LogType, LogOption, String, Object)
UnityEngine.DebugLogHandler:LogFormat(LogType, Object, String, Object[])
UnityEngine.Logger:Log(LogType, Object)
UnityEngine.Debug:Log(Object)
CommandLineTest:TestFunction() (at Assets/Editor/CommandLineTest.cs:12)
(Filename: Assets/Editor/CommandLineTest.cs Line: 12)
Debug.Log
の場合は上記のようにログファイルに実行結果が出力されます
コマンドの意味を説明していきます
/Applications/Unity/Hub/Editor/2019.3.0f1/Unity.app/Contents/MacOS/Unity \
-batchmode -quit -logFile log.txt \
-projectPath ~/UnityProjects/JenkinsTest \
-executeMethod CommandLineTest.TestFunction
Unityはバージョンごとにインストールされる場所が異なるので、それぞれの場所を指定してコマンドを実行します。
Windowsの場合はC:\Program Files\Unity\Editor\Unity.exe
のような形になります。
オプション | 意味 |
---|---|
-batchmode | コマンドラインで実行します。これをつけない場合はUnityEditorが開きます |
-quit | 実行終了後、自動的にUnityを閉じます |
-logFile | ログファイルの出力場所を設定します。設定しない場合、UnityEditorデフォルトの位置に出力されます。 |
-projectPath | プロジェクトのパスを設定します |
-executeMethod | 実行する関数名を設定します。 ClassName.MethodNameの形で指定しますが、クラスにnamespaceが付与されている場合は NameSpace.ClassName.MethodNameのようにnamespaceを頭につける必要があります。 |
引数でパラメータを渡す
このままでは関数を実行することしかできません。
パラメータを渡すにはSystem.Environment.GetCommandLineArgs
を使用します
先ほどの関数を以下のように書き換えてみて、同じコマンドを実行すると
public static void TestFunction()
{
string output = "";
var args = System.Environment.GetCommandLineArgs();
for(int i=0;i< args.Length;i++)
{
output += i + "->" + args[i] + "\n";
}
Debug.Log(output);
}
このような出力になります
配列の0番目がコマンド自体、それ以降が引数のようなシェルスクリプトと同じような感じになります。
0->/Applications/Unity/Hub/Editor/2019.3.0f1/Unity.app/Contents/MacOS/Unity
1->-batchmode
2->-quit
3->-logFile
4->log.txt
5->-projectPath
6->/Users/Name/UnityProjects/JenkinsTest
7->-executeMethod
8->CommandLineTest.TestFunction
GetCommandLineArgs()
はstring[]
として引数を返すので
string
以外の型を使用したい場合は、自前でパースする必要があります。
新しい関数を作って引数を受け取れるようにした例が下記のコードです。
-option
の形でオプションを受け取って、その次に入っているのがオプションのパラメータという作りになっています。
public static void ArgumentTest()
{
string message = "";
int number = -1;
var args = System.Environment.GetCommandLineArgs();
for(int i=0;i<args.Length;i++)
{
switch(args[i])
{
case "-message":
message = args[i + 1];
break;
case "-number":
number = int.Parse(args[i + 1]);
break;
default:
break;
}
}
Debug.Log("Message is " + message + " Number is " + number);
}
以下のコマンドで実行します
/Applications/Unity/Hub/Editor/2019.3.0f1/Unity.app/Contents/MacOS/Unity \
-batchmode -quit -logFile log.txt \
-projectPath ~/UnityProjects/JenkinsTest \
-executeMethod CommandLineTest.ArgumentTest \
-message hello -number 123
実行結果は以下のようになります。
message
にはhelloが入り、number
には123を入力することができました。
Message is hello Number is 123
UnityEngine.DebugLogHandler:Internal_Log(LogType, LogOption, String, Object)
UnityEngine.DebugLogHandler:LogFormat(LogType, Object, String, Object[])
UnityEngine.Logger:Log(LogType, Object)
UnityEngine.Debug:Log(Object)
CommandLineTest:ArgumentTest() (at Assets/Editor/CommandLineTest.cs:39)
(Filename: Assets/Editor/CommandLineTest.cs Line: 39)
ビルド用関数を作る
- コマンドラインからUnityを実行できるようになったら、次はビルドできるよう準備をします
- 通常、ビルドするときはFile→Build Settings→Buildとするのが一般的です
- UnityではC#のスクリプト上からもビルドを実行することができ、様々なパラメータを動的に設定することができます
- BuildPipeline.BuildPlayer
public static void Build()
{
var output = "";
bool isDevelopment = false;
var args = System.Environment.GetCommandLineArgs();
for (int i = 0; i < args.Length; i++)
{
switch (args[i])
{
case "-outputPath":
output = args[i + 1]; //出力先の設定
break;
case "-development":
isDevelopment = true; //Developmentビルドにする
break;
default:
break;
}
}
var option = new BuildPlayerOptions();
option.locationPathName = output;
if(isDevelopment)
{
//optionsはビットフラグなので、|で追加していくことができる
option.options = BuildOptions.Development | BuildOptions.AllowDebugging;
}
option.target = BuildTarget.StandaloneWindows64; //ビルドターゲットを設定. 今回はWin64
var result = BuildPipeline.BuildPlayer(option);
if(result.summary.result == UnityEditor.Build.Reporting.BuildResult.Succeeded)
{
Debug.Log("BUILD SUCCESS");
}
else
{
Debug.LogError("BUILD FAILED");
}
}
/Applications/Unity/Hub/Editor/2019.3.0f1/Unity.app/Contents/MacOS/Unity \
-batchmode -quit -logFile log.txt \
-projectPath ~/UnityProjects/JenkinsTest \
-executeMethod CommandLineTest.Build \
-outputPath ~/UnityProjects/Build/test.exe \
-development
とコマンドを叩けば、~/UnityProjects/Build/test.exe
の場所にdevelopmentビルドが完成します
Jenkinsの準備
- 最後にJenkins側の設定です
- Jenkinsのインストールについては下記の記事を参照してください
プラグインの設定
Jenkinsの管理
→プラグインの管理
から
Unity3d pulgin
をインストールします
プラグインのインストールができたらUnityのパスを設定します。
Jenkinsの管理
→Global Tool Configuration
から
Unity3d
のUnity3d追加
ボタンを押し、パスを設定します
ここではバージョンごとに異なったパスを設定することができます
MacとWindowsでパスの設定の仕方が異なるので、ご注意ください。
JenkinsがMacの場合
JenkinsがWindowsの場合
Jobの設定
新規ジョブ作成
からJob名を設定し、フリースタイル・プロジェクトのビルド
でJobを作成します
ビルド手順の追加からInvoke Unity3d Editor
を選択します
ここで使うUnityを指定し、Editor command line arguments
にビルドで使用するコマンドを入れます
この中では環境変数を使用することが可能です
私がJenkinsでよく使う環境変数を下の表にまとめました。
環境変数 | 意味 |
---|---|
BUILD_NUMBER | ビルド番号 |
JOB_NAME | Jobの名前 |
BUILD_TAG |
jenkins-${JOB_NAME}-${BUILD_NUMBER} という形になるので成果物の名前で使うとわかりやすい |
WORKSPACE | ワークスペースの絶対パス |
GIT_COMMIT | ビルド時のgitのハッシュ値 |
環境変数を使うときは${WORKSPACE}
のように使うとエラーが少ないです
設定が終わったら保存
を押して、ビルドの実行
をすればビルドが作成されます。
あとはビルドのパラメータ化
を使って、ビルドごとにパラメータを与えたり
SCMをポーリング
機能を使ってデイリービルドを作成したりすることが可能です。
おわりに
- 駆け足でしたがJenkinsでUnityビルドを作成する方法を紹介しました
- ビルドだけでなく、アセットバンドルビルドやテストに応用することも可能です
- Jenkinsには様々なプラグインが用意されているので、そちらと組み合わせることで効率的な開発を行うことができます
- それでは良きUnity&Jenkinsライフを!