LoginSignup
30

More than 5 years have passed since last update.

fastlane で Unity のビルドと配布を自動化する

Last updated at Posted at 2016-04-05

はじめに

普通の Unity プロジェクトの開発中は、以下のサイクルが何度も繰り返されることと思います。

  1. iOS 用の buildNumber をインクリメント
  2. iOS 用の Xcode プロジェクト書き出し
  3. iOS 用 ipa 作成
  4. ipa を fabric の beta で配布
  5. Android 用の bundleVersionCode をインクリメント
  6. Android 用 apk 書き出し
  7. apk を fabric の beta で配布
  8. slack で開発チームに報告

面倒ですね。fastlane でラクしましょう。

この記事は fastlane で Unity のビルドを行う部分を中心に書いていますので、fastlane の基本的な部分はこちらの記事などをどうぞ。

HOW?

1. ビルドスクリプトの準備

Assets/Editor 以下に、こんな感じでビルド用のスクリプトを配置します。

AppBuilder.cs
using UnityEditor;
using UnityEngine;

public class AppBuilder{

    [MenuItem ("Build/Android向けビルド")]
    static void buildForAndroid(){
        bumpBuildNumberForAndroid ();
        string errorMessage = BuildPipeline.BuildPlayer(GetAllScenePaths (), "/Users/plasticstraw/Desktop/game.apk", BuildTarget.Android, BuildOptions.None);
        if( !string.IsNullOrEmpty( errorMessage ) )
            Debug.LogError( "[Error!] " + errorMessage );
        else
            Debug.Log( "[Success!]" );
    }

    [MenuItem ("Build/iOS向けビルド")]
    static void buildForIOS(){
        bumpBuildNumberForIOS ();
        // 出力パス。絶対パスで指定すること。また、最後にスラッシュを入れないこと。PostBuildProcess に渡る path が通常ビルドと異なってしまい、思わぬバグを引き起こすことがあります。
        string path = "/Users/plasticstraw/Desktop/game";
        string errorMessage = BuildPipeline.BuildPlayer(GetAllScenePaths(), path, BuildTarget.iOS, BuildOptions.Il2CPP);
        if( !string.IsNullOrEmpty( errorMessage ) )
            Debug.LogError( "[Error!] " + errorMessage );
        else
            Debug.Log( "[Success!]" );
    }

    static void bumpBuildNumberForIOS(){
        string str = PlayerSettings.iOS.buildNumber;
        int num = int.Parse (str);
        num++;
        PlayerSettings.iOS.buildNumber = num + "";
    }

    static void bumpBuildNumberForAndroid(){
        PlayerSettings.Android.bundleVersionCode += 1;
    }

    static string[] GetAllScenePaths(){
        string[] scenes = new string[EditorBuildSettings.scenes.Length];
        for( int i = 0; i < EditorBuildSettings.scenes.Length ; i++ ) {
            scenes[i] = EditorBuildSettings.scenes[i].path;
        }
        return scenes;
    }
}

Unity のメニューに「Build 」が追加されているので、そこからそれぞれのビルド処理が期待通りに動くかテストできます。

2. Fastfile を記述

Unity には、コマンドラインから任意のスクリプトを実行する機能が備わっています。
fastlane を使って、上記で作成したビルドスクリプトを呼んでやることでビルドを自動化できます。

Fastfile
desc "ビルドして Beta で配布します。"
lane :beta do
    buildForIOS
    buildForAndroid
    distributeByCrashlytics
    slack(
        default_payloads: [],
        message: "<!channel>: Beta で配布したよ",
    )
end

desc "iOS用ビルド"
lane :buildForIOS do
    path = File.expand_path(File.dirname(__FILE__)) +"/../"
    sh("/Applications/Unity/Unity.app/Contents/MacOS/Unity -batchmode -quit -logFile ./build.log -projectPath '#{path}' -buildTarget ios -executeMethod AppBuilder.buildForIOS")
    gym(
        project: "/Users/plasticstraw/Desktop/game/Unity-iPhone.xcodeproj",
    )
end

desc "android用ビルド"
lane :buildForAndroid do
    path = File.expand_path(File.dirname(__FILE__)) +"/../"
    sh("/Applications/Unity/Unity.app/Contents/MacOS/Unity -batchmode -quit -logFile ./build.log -projectPath '#{path}' -buildTarget android -executeMethod AppBuilder.buildForAndroid")
end

desc "配布"
lane :distributeByCrashlytics do
    # ios
    crashlytics(
        groups: 'team'
    )

    # android
    crashlytics(
        apk_path: "/Users/plasticstraw/Desktop/game.apk",
        groups: 'team'
        ipa_path: false, # デフォルトでiOSの値が入っており、apk_pathを指定しても正常に動作しないので値を削除
        crashlytics_path: false, # デフォルトでiOSの値が入っており、android向けだと正常に動作しないため、値を削除してfastlaneに任せる
    )
end

3.実行

あとはターミナルから $ fastlane beta 一発で、もろもろビルドしてもろもろ配布してくれます。おめでとうございます。

これを実行するためには Unity で該当のプロジェクトを開いている状態ではダメで、かつビルドで贅沢にCPUを食われるため、CIに組み込むなり、別のマシンでリポジトリをクローンしてから実行するなりがオススメです。

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
30