WallpaperEngineの壁紙をUnityのWebGLで作るためのメモ

WallpaperEngineの壁紙をUnityで作成する場合、Windowsの実行形式(.exe)で出力すれば手軽に作成することができます。
しかし、Web形式(HTML)以外ではWallpaperEngineで壁紙を設定する際のプロパティを作成者で任意に作成できないため、ユーザにパラメータ変更を委ねたいときに面倒です。
UnityにはWebGLで出力する機能もあり、そちらをWallpaperEngineに使用する方法を調べたのですが、まとまった情報がなかったのでメモしておきます。

以下はUnity Ver 2017.1 で確認した内容です。

WebGLテンプレート

WallpaperEngineで表示した時に表示を最大化し、必要なJavascript外部ファイルを読み込むためHTMLのテンプレートを設定します。

参考: Unity – Manual: Using WebGL Templates

配置 : Assets > WebGLTemplates > (任意の名前) > index.html

<!DOCTYPE html>
<html lang="en-us">

  <head>
    <meta charset="utf-8">
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    <title>Unity WebGL Player | %UNITY_WEB_NAME%</title>
    <script src="PropertyScript.js"></script>
    <script src="%UNITY_WEBGL_LOADER_URL%"></script>
    <script>
      var gameInstance = UnityLoader.instantiate("gameContainer", "%UNITY_WEBGL_BUILD_URL%");
    </script>
    <style>
      body {
        overflow: hidden;
        margin: 0;
        padding: 0;
        background-color: black;
      }
    </style>
  </head>
  <body>
    <div id="gameContainer" style="width: 100%; height: 100%; position: absolute;"></div>
  </body>
</html>

Edit > Project Settings > Playerから追加したテンプレートを選択しておくこと。

WallpaperEngineで読み込むプロジェクトファイル

プロパティの値が定義されています。
プロパティ部分は、WallpaperEngineの作成ガイドにあるテンプレと同様です。

参考: Advanced: Web user customization

配置 : Assets > WebGLTemplates > (任意の名前) > project.json

{
    "file" : "index.html",
    "preview" : "prev.png",
    "general" : 
    {
        "properties" : 
        {
            "customcolor" : 
            {
                "text" : "User accent",
                "type" : "color",
                "value" : "0.2 0.8 1"
            },
            "schemecolor" : 
            {
                "text" : "Scheme color",
                "type" : "color",
                "value" : "0.7 0.2 0.1"
            },
            "custombool" : 
            {
                "text" : "User bool",
                "type" : "bool",
                "value" : false
            },
            "customint" :
            {
                "text" : "User slider",
                "type" : "slider",
                "value" : 50,
                "min" : 0,
                "max" : 100
            },
            "customcombo" :
            {
                "text" : "User combo",
                "type" : "combo",
                "value" : 1,
                "options" :
                [
                    {
                        "value" : 1,
                        "label" : "First"
                    },
                    {
                        "value" : 2,
                        "label" : "Second"
                    },
                    {
                        "value" : 3,
                        "label" : "Third"
                    }
                ]
            }
        }
    },
    "title" : "WebGL Template",
    "type" : "web"
}

プロパティを受け取るスクリプト

WallpaperEngineのプロパティはブラウザ?のJavascriptに用意した特定の関数が呼び出されることで受け渡しをするため、Unityのエディタとは別にスクリプトを用意します。
後述する「Javascript->C#」間の値の受け渡しの都合から、格納する値をINT型にしています。

参考: Advanced: Web user customization

配置 : Assets > WebGLTemplates > (任意の名前) > PropertyScript.js

var WALLPAPER_ENGIN_PROPERTY = WALLPAPER_ENGIN_PROPERTY || {};
window.wallpaperPropertyListener = {
    applyUserProperties: function(properties) {
        // Read scheme color
        if (properties.schemecolor) {
            WALLPAPER_ENGIN_PROPERTY.schemecolor = PropertyColorToInt(properties.schemecolor.value);
        }

        // Read custom color
        if (properties.customcolor) {
            WALLPAPER_ENGIN_PROPERTY.customcolor = PropertyColorToInt(properties.customcolor.value);
        }

        // Read custom boolean
        if (properties.custombool) {
            WALLPAPER_ENGIN_PROPERTY.custombool = PropertyBoolToInt(properties.custombool.value);
        }

        // Read custom slider
        if (properties.customint) {
            WALLPAPER_ENGIN_PROPERTY.customint = properties.customint.value;
        }

        // Read custom combo box
        if (properties.customcombo) {
            WALLPAPER_ENGIN_PROPERTY.customcombo = properties.customcombo.value;
        }

        function PropertyColorToInt(colorValue){
            var Colors = colorValue.split(' ');
            colorInt = Math.ceil(Colors[0] * 255) * 1000 * 1000;
            colorInt += Math.ceil(Colors[1] * 255) * 1000;
            colorInt += Math.ceil(Colors[2] * 255);
            return colorInt;
        }

        function PropertyBoolToInt(boolValue){
            return Number(boolValue);
        }
    }
};

WebGLからブラウザのJavascript関数を呼び出すプラグイン

WebGLからブラウザのJavascriptの関数を呼び出せるよう、プラグインとしてスクリプトファイルを作成します。

参考: Unity – マニュアル: WebGL: ブラウザのスクリプトと通信を行う

配置 : Assets > Plugins > WebGL > PropertyPlugin.jslib

var PropertyPlugin = {
    GetSchemeColor: function()
    {
        return WALLPAPER_ENGIN_PROPERTY.schemecolor;
    },
    GetCustomColor: function()
    {
        return WALLPAPER_ENGIN_PROPERTY.customcolor;
    },
    GetCustomBool: function()
    {
        return WALLPAPER_ENGIN_PROPERTY.custombool;
    },
    GetCustomInt: function()
    {
        return WALLPAPER_ENGIN_PROPERTY.customint;
    },
    GetCustomCombo: function()
    {
        return WALLPAPER_ENGIN_PROPERTY.customcombo;
    }
};

mergeInto(LibraryManager.library, PropertyPlugin);

WebGLからブラウザのJavascript関数を呼び出すスクリプト

Asset内の任意の場所に保存し、適当なオブジェクトでコンポーネントとして呼び出し。
マニュアルにINT型とString型を呼び出す方法しかなかったため、全てINTでやり取りしています。
以下の例ではUI>Textオブジェクトにプロパティで取得した値を反映しています。

参考: Unity – マニュアル: WebGL: ブラウザのスクリプトと通信を行う

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using System.Runtime.InteropServices;
using System;

public class PropertyTestScript : MonoBehaviour {
    public Text[] TextObj;

    [DllImport("__Internal")]
    private static extern int GetSchemeColor();

    [DllImport("__Internal")]
    private static extern int GetCustomColor();

    [DllImport("__Internal")]
    private static extern int GetCustomBool();

    [DllImport("__Internal")]
    private static extern int GetCustomInt();

    [DllImport("__Internal")]
    private static extern int GetCustomCombo();

    private static Color SchemecolorIntToColor(int schemecolorInt)
    {
        int red = schemecolorInt / 1000 / 1000;
        int green = schemecolorInt / 1000 % 1000;
        int blue = schemecolorInt % 1000;
        return rgb(red, green, blue);
    }

    private static Color rgb(int red, int green, int blue)
    {
        return new Color(red / 255f, green / 255f, blue / 255f);
    }

    private static bool SchemeboolIntToBool(int schemeboolInt)
    {
        return Convert.ToBoolean(schemeboolInt);
    }

    void Start () {
    }

    void Update () {
        TextObj[0].color = SchemecolorIntToColor(GetSchemeColor());
        TextObj[1].color = SchemecolorIntToColor(GetCustomColor());
        TextObj[2].text = "GetCustomBool : " + SchemeboolIntToBool(GetCustomBool()).ToString();
        TextObj[3].text = "GetCustomInt : " + GetCustomInt().ToString();
        TextObj[4].text = "GetCustomCombo : " + GetCustomCombo().ToString();
    }
}

コメント