VR空間内でウェブブラウザを利用することのできるEMBEDDED BROWSERの利用メモです。
公式ドキュメントはこちらのReadme、ZFBrowser Documentationを参照、
EMBEDDED BROWSERアセットを利用することで、VR空間内で簡単にウェブサイトを利用することができます。後ろでChromiumブラウザが動作する仕組みで動作するため、WebGLコンテンツやYoutubeなどChromeで動作するウェブサイトであればそのままなんでも表示できます。
単なるウェブ表示用だけではなく、UI表示用パネルとしても利用価値大です。
また
・平面以外のオブジェクトに表示
・ウェブページ内のJavascriptからUnity上の関数を呼んだり
・Unity上の関数からウェブページ上の関数を呼んだり
できます。
利用方法は簡単で、ブラウザーPrefabをヒエラルキーに追加するだけです。URLを設定すれば実行時にウェブが表示されます
実行時にはデバッグ用のボタンがInspectorに表示されるので便利です。
ブラウザPrefabは下記の4つが用意されています。
BrowserGUI
3D空間ではなく、2DのUIとして画面上にウェブを表示したい場合に利用します。
BrowserQuad
3D空間でウェブを表示する場合は通常こちらを利用します。
BrowserQuad (FPS UI)
マウス操作の代わりに視点でポインタを移動するスクリプトが入っています。
BrowserSphere
任意の形状のオブジェクトにウェブを表示する球体でのデモPrefabです。
スクリプトからブラウザの制御
スクリプトからブラウザの制御方法です。
using UnityEngine; using System.Collections; using ZenFulcrum.EmbeddedBrowser; public class buttonScript : MonoBehaviour { public void GotoURL() { var browserObj = GameObject.Find("BrowserQuad").GetComponent<Browser>(); browserObj.Url = "http://www.yahoo.co.jp/"; } }
指定のURLのページを表示
browserObj.Url = "http://www.yahoo.co.jp/";
指定の場所までページをスクロール
browserObj.EvalJS("window.scrollTo( 0, 1500 ) ;");
DOMへのアクセス(EvalJs経由で制御)
browserObj.EvalJS("document.body.style.background = 'red';");
HTMLを直接読み込み
browserObj.LoadHTML("<html><body><img src='http://psychic-vr-lab.com/web/etc/logo_portrait_squre_bg-transparent.png' width=100%></body></html>");
ちなみに、HTMLの背景はデフォルトでは透過状態になっています。透過pngをimgタグで表示した場合、下のように透けて表示されます。ウェブサーバー不要で、EMBEDDED BROWSERをHTMLを利用したUIキャンバスにできて便利。
Javascriptの関数を呼ぶ
//calls window.setPlayerStats("myPlayerName", 2, 4200, false) in the browser browserObj.CallFunction("setPlayerStats", "myPlayerName", 2, 4200, false);
Javascriptで関数が呼ばれた際にUnity内の関数が実行されるように登録
browserObj.RegisterFunction("confirmClicked", args => Debug.Log("Button clicked: " + args[0])); Then you can call it from your page: <!-- When this is clicked, Unity will log "Button clicked: button3" --> <button onclick="confirmClicked('button3')">Confirm Things</button>
Unityプロジェクト内のHTMLファイルへのアクセス
Assetsフォルダと同列に(下位フォルダではなく)、BrowserAssetsフォルダを作成
localGame://index.html
でBrowserAssets内のindex.htmlへアクセスできます。
ページ読み込み完了時に指定の関数を実行(Whenloadedはブラウザ内でユーザーがクリックした移動した遷移は取得不可)
public void Btn1() { var browserObj = GameObject.Find("BrowserQuad").GetComponent<Browser>(); browserObj.Url = "http://www.yahoo.co.jp/"; browserObj.WhenLoaded(loaded); } private void loaded() { Debug.Log("Page loaded"); }
ブラウザ内でユーザー遷移を補足して、RegisterFunctionを実行する方法
using UnityEngine; using System.Collections; using UnityEngine.UI; using ZenFulcrum.EmbeddedBrowser; using System; /** * A very simple controller for a Browser. * Call GoToURLInput() to go to the URL typed in urlInput */ [RequireComponent(typeof(Browser))] public class SimpleController : MonoBehaviour { private Browser browser; public InputField urlInput; public void Start() { browser = GetComponent<Browser>(); //ページ遷移時にコールバック関数を毎回登録するように指定 Action<JSONNode> act = delegate { RegisterCallbakFunctions(); }; browser.onLoad += act; } public void GoToURLInput() { browser.Url = urlInput.text; } /// <summary> /// コールバック関数の登録 /// </summary> void RegisterCallbakFunctions() { browser.RegisterFunction("confirmClicked", args => Debug.Log("Button clicked: " + args[0])); } }
便利な追加コード
EMBEDDED BROWSERに標準で用意されていないが便利なコードを作成したので共有
using UnityEngine; using System.Collections; /// <summary> /// https://psychic-vr-lab.com/blog/unity/unity%E3%83%BBvr%E5%86%85%E3%81%A7%E3%83%96%E3%83%A9%E3%82%A6%E3%82%B6%E3%82%92%E5%88%A9%E7%94%A8%E3%81%99%E3%82%8B%E3%83%A1%E3%83%A2/ /// </summary> public class ZFBrowserAdditionalCode { /// <summary> /// ZFBrowserのUserAgentを変更する関数 /// </summary> /// <param name="UA"></param> public static void setUserAgent(string UA) { //Copied from BrowserNative.cs var dirs = ZenFulcrum.EmbeddedBrowser.FileLocations.Dirs; int DebugPort = 9848; var debugPort = Debug.isDebugBuild ? DebugPort : 0; var settings = new ZenFulcrum.EmbeddedBrowser.BrowserNative.ZFBInitialSettings() { cefPath = dirs.resourcesPath, localePath = dirs.localesPath, subprocessFile = dirs.subprocessFile, //userAgent = UserAgent.GetUserAgent(), userAgent = UA, logFile = dirs.logFile, debugPort = debugPort, #if UNITY_EDITOR_WIN || UNITY_STANDALONE_WIN //CEF doesn't have the multithreaded loop implemented on 'cept Windows multiThreadedMessageLoop = 1, #else multiThreadedMessageLoop = 0, #endif }; ZenFulcrum.EmbeddedBrowser.BrowserNative.zfb_init(settings); } /// <summary> /// 表示中のウェブページにCSSを追加します。追加したCSSは即時適用されます。 /// </summary> /// <param name="browserObj"></param> /// <param name="CSS"></param> /// <example> /// ZFBrowserAdditionalCode.addStyleSheet(browserObj, "body{background-color:blue;};"); /// </example> public static void addStyleSheet(ZenFulcrum.EmbeddedBrowser.Browser browserObj, string CSS) { string JsString = @" var style = document.createElement('style'); style.setAttribute('type', 'text/css'); style.innerHTML = '%CSS%'; var head = document.getElementsByTagName('head')[0]; head.appendChild(style); "; JsString = JsString.Replace("%CSS%", CSS); Debug.Log(JsString); browserObj.EvalJS(JsString); } /// <summary> /// 表示中のウェブページに外部CSSの追加を行います。追加したCSSは即時適用されます。 /// </summary> /// <param name="browserObj"></param> /// <param name="CssURL"></param> /// <example> /// ZFBrowserAdditionalCode.addStyleSheetURL(browserObj, "http://xxxxxx.com/temp/test.css"); /// </example> public static void addStyleSheetURL(ZenFulcrum.EmbeddedBrowser.Browser browserObj, string CSS_URL) { string JsString = @" var link = document.createElement('link'); link.setAttribute('rel', 'stylesheet'); link.setAttribute('type', 'text/css'); link.setAttribute('href', '%CSS_URL%'); var head = document.getElementsByTagName('head')[0]; head.appendChild(link); "; JsString = JsString.Replace("%CSS_URL%", CSS_URL); browserObj.EvalJS(JsString); } /// <summary> /// 表示中のウェブページにJavascriptを文字列で渡して追加します。Javascriptの動的実行、関数の追加両方可能です。 /// </summary> /// <param name="browserObj"></param> /// <param name="Javascript"></param> /// <example> /// ZFBrowserAdditionalCode.addJavascript(browserObj, "alert(1);"); /// ZFBrowserAdditionalCode.addJavascript(browserObj, "function f(){alert(1);};"); //定義後の呼び出し方 browserObj.CallFunction("f"); /// </example> public static void addJavascript(ZenFulcrum.EmbeddedBrowser.Browser browserObj, string Javascript) { string JsString = @" var script = document.createElement('script'); script.innerHTML = '%Javascript%'; var head = document.getElementsByTagName('head')[0]; head.appendChild(script); "; JsString = JsString.Replace("%Javascript%", Javascript); browserObj.EvalJS(JsString); } /// <summary> /// 表示中のウェブページに外部JSファイルを読み込んで追加します。Javascriptの動的実行、関数の追加両方可能です。 /// </summary> /// <param name="browserObj"></param> /// <param name="JS_URL"></param> /// <example> /// ZFBrowserAdditionalCode.addJavascriptURL(browserObj, "http://xxxxxx.com/temp/test.js"); /// </example> public static void addJavascriptURL(ZenFulcrum.EmbeddedBrowser.Browser browserObj, string JS_URL) { string JsString = @" var script = document.createElement('script'); script.setAttribute('type', 'text/javascript'); script.setAttribute('src', '%JS_URL%'); var head = document.getElementsByTagName('head')[0]; head.appendChild(script); "; JsString = JsString.Replace("%JS_URL%", JS_URL); browserObj.EvalJS(JsString); } }
ユーザーエージェントの変更
呼び出し方(どこかで1回呼べば以降変更されます)
ZFBrowserAdditionalCode.setUserAgent("Mozilla/5.0 (iPod touch; CPU iPhone OS 7_0_2 like Mac OS X) AppleWebKit/537.51.1 (KHTML, like Gecko) Version/7.0 Mobile/11A501 Safari/9537.53"); var browserObj = GameObject.Find("BrowserQuad").GetComponent<ZenFulcrum.EmbeddedBrowser.Browser>(); browserObj.Url = "http://www.ugtop.com/spill.shtml";
CSSの動的変更
ZFBrowserAdditionalCode.addStyleSheet(browserObj, "body{background-color:blue;};");
外部CSSの動的追加
ZFBrowserAdditionalCode.addStyleSheetURL(browserObj, "http://xxxxxx.com/temp/test.css");
Jacascriptの動的実行・関数追加
ZFBrowserAdditionalCode.addJavascript(browserObj, "alert(1);"); ZFBrowserAdditionalCode.addJavascript(browserObj, "function f(){alert(1);};"); //定義後の呼び出し方 browserObj.CallFunction("f");
外部Javascriptの動的追加
ZFBrowserAdditionalCode.addJavascriptURL(browserObj, "http://xxxxxx.com/temp/test.js");