[Unity] PostProcessでビルド後に処理を差し込む

  • 21
    Like
  • 0
    Comment
More than 1 year has passed since last update.

Unityではゲームを作る以外にも色々なところで自作のスクリプトを差し込むことができます。
今回はPostProcessについて書いておこうと思います。


Post Processは「あと処理」を意味する英単語です。
つまり、Unityでビルドを行ったのち、あと処理を差し込むことができます。
利用例としては自作のプラグインを作っている場合に、その設定ファイルを書き出したり、あるいはUnityが書き出したファイルに置換処理を入れたり、といったことが可能になります。

ルール

  1. /Assets/Editor以下に置く。(Editor Scriptとして認識させればOK)
  2. public staticなメソッドに[PostProcessBuild(N)]属性を付与。
    1. (N)は実行順序

例) ドキュメントには以下のように記載があります。

post-process
// C# example:
using UnityEngine;
using UnityEditor;
using UnityEditor.Callbacks;

public class MyBuildPostprocessor {
    [PostProcessBuildAttribute(1)]
    public static void OnPostprocessBuild(BuildTarget target, string pathToBuiltProject) {
        Debug.Log( pathToBuiltProject );
        }
}

ドキュメントではPostProcessBuildAttributeとなっていますが、PostProcessBuildでも大丈夫でした。違いはちょっと分かってません;

ファイルを書き換えるサンプル

試しに、Unityが書きだしたUnityAppController.mmを書き換えるサンプルを示します。
OpenGLESOpenGLESHogeに置換するものです。
意味がないどころか動かなくなりますが、サンプルということでw

PostProcess-replace-sample
using UnityEngine;
using UnityEditor;
using UnityEditor.Callbacks;
using System.Collections;
using System.IO;

public class PostProcessTest {

    [PostProcessBuild (100)]
    public static void OnPostProcessBuild(BuildTarget target, string path) {
        #if UNITY_5_0
        if (target == BuildTarget.iOS) {
        #else
        if (target == BuildTarget.iPhone) {
        #endif
            RewriteObjCFiles(path);
        }
    }

    /// <summary>
    /// Rewrites the Objective-C files.
    /// </summary>
    /// <param name="path">File path.</param>
    private static void RewriteObjCFiles(string path) {
        string filePath = System.IO.Path.Combine(path, "Classes/UnityAppController.mm");
        if (File.Exists(filePath)) {
            ReplaceStringInFile(filePath, "OpenGLES", "OpenGLESHoge");
        }
    }

    /// <summary>
    /// Replaces the string in the file.
    /// </summary>
    /// <param name="file">File path</param>
    /// <param name="target">Target string</param>
    /// <param name="replaceText">Replace text</param>
    private static void ReplaceStringInFile(string file, string target, string replaceText) {
        if (!File.Exists(file)) {
            return;
        }

        // 置換後のテキスト
        string processedContents = "";

        using (StreamReader stream = new StreamReader(file)) {
            while (stream.Peek() >= 0) {
                string line = stream.ReadLine();
                processedContents += line.Replace(target, replaceText) + "\n";
            }
        }

        // 既存ファイルを削除し、置換後のテキストで新規作成
        File.Delete(file);

        using (StreamWriter stream = File.CreateText(file)) {
            stream.Write(processedContents);
        }
    }
}

こんな感じで簡単に置換を行うことができます。
ちなみにOnPostProcessBuildはそれっぽい名前になっていますが、任意のメソッド名で大丈夫です。
(が、分かりやすさのために上記のような名称にしておいたほうがいいでしょう)

あとは普通にビルドするとビルド後に上記のスクリプトが実行され、該当箇所が置換されて書き出されるようになります。