STYLY 開発者ブログ -STYLY Developer's Blog-

Unity・VR内でブラウザを利用するメモ

VR空間内でウェブブラウザを利用することのできるEMBEDDED BROWSERの利用メモです。
公式ドキュメントはこちらのReadmeZFBrowser Documentationを参照、

b1

EMBEDDED BROWSERアセットを利用することで、VR空間内で簡単にウェブサイトを利用することができます。後ろでChromiumブラウザが動作する仕組みで動作するため、WebGLコンテンツやYoutubeなどChromeで動作するウェブサイトであればそのままなんでも表示できます。

単なるウェブ表示用だけではなく、UI表示用パネルとしても利用価値大です。

また
・平面以外のオブジェクトに表示
・ウェブページ内のJavascriptからUnity上の関数を呼んだり
・Unity上の関数からウェブページ上の関数を呼んだり
できます。

利用方法は簡単で、ブラウザーPrefabをヒエラルキーに追加するだけです。URLを設定すれば実行時にウェブが表示されます

b2

実行時にはデバッグ用のボタンがInspectorに表示されるので便利です。

b3

ブラウザ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キャンバスにできて便利。

b4

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");

 

カテゴリー: Unity

HTC VIVEで一人称視点First Person Controllerを使う

HTC VIVE、ルームスケールで移動できて楽しいです。

ただ、コントローラーを使って一人称視点でゲームを作ろうとすると工夫が必要です。ルームスケール+一人称視点でのキャラクター操作は酔いやすいので注意が必要です。またUnityのStandard AssetのFirst Person Controllerはそのままではうまく動きません。

今回はHTC VIVEを用いて

  • X-Boxコントローラーおよびキーボードでの操作に対応
    VIVEのHMDで向いている先を中心にコントロール
  • VIVEコントローラーではトリガーを引くと視線の先に移動する

を実装します。(もっと適切な仕様もあるかも)

20160423_165716

1、まずはSteamVR Pluginをインポートします。(Unity5.4からVirtualReality SupportだけでVIVEの利用が可能になりましたがコントローラーが使えません。)

fpc1

2,UnityのStandard AssetのCharactersをインポートします。First Person Controllerが利用可能になります。

fpc2

3,インポートしたスタンダードアセットからRigidBodyFPSControllerをシーンに追加します。

fpc3

4,先ほど追加したRigidBodyFPSControllerの子オブジェクトとしてSteamVRの[CameraRig]をシーンに追加します。

fpc4

5,不要なカメラを削除します。シーンに初めからあるMainCameraとRigidBodyFPSController内のMainCameraを削除

インスペクタービューでRigidBodyFPSControllerのRigidbodyFirstPersonControllerスクリプトのCamに[CameraRig]内のカメラCamera(eye)を設定します。

 

fpc5

6,Unityのゲームビューでマウスによる誤動作防止のため、InspectorでRigidbodyFirstPersonControllerのMouseLookのSensitivityを0に設定しておきます。

fpc6

これで、XBOXコントローラーおよびキーボードを用いたFirst Person ControllerがVIVEで利用可能になりました。

 

7,では次にVIVEのコントローラーでも移動できるようにしましょう。今回は、トリガーを引くことで前方に移動するという機能を実装します。

(トラックパッドでの移動など誰か実装したら教えてください)

using UnityEngine;
using System.Collections;

public class vive_firstpersoncontroller : MonoBehaviour {


    SteamVR_TrackedObject trackedObj;
    public GameObject ViveCameraHead;
    public GameObject FPSController;
    public float speed = 3;

    void Awake()
    {
        trackedObj = GetComponent<SteamVR_TrackedObject>();
    }

    void Update()
    {
        var device = SteamVR_Controller.Input((int)trackedObj.index);

        //トリガーを浅く握る
        if (device.GetTouch(SteamVR_Controller.ButtonMask.Trigger))
        {
            //Debug.Log("GetTouch Trigger");
            float slowSpeedFactor = 0.5f;
            Vector3 moveDistance = ViveCameraHead.transform.TransformDirection(Vector3.forward);
            Vector3 moveDistance2 = new Vector3(moveDistance.x * Time.deltaTime * speed* slowSpeedFactor, 0, moveDistance.z * Time.deltaTime * speed* slowSpeedFactor);
            FPSController.transform.position += moveDistance2;
        }
        //トリガーを深く握る
        if (device.GetPress(SteamVR_Controller.ButtonMask.Trigger))
        {
            //Debug.Log("GetPress Trigger");
            Vector3 moveDistance = ViveCameraHead.transform.TransformDirection(Vector3.forward);
            Vector3 moveDistance2 = new Vector3(moveDistance.x * Time.deltaTime * speed, 0, moveDistance.z * Time.deltaTime * speed);
            FPSController.transform.position += moveDistance2;
        }


    }

}

上記コードをvive_firstpersoncontroller.csとして保存し、Controllerにアタッチします。

Inspectorビューで
・VIVE Camera HeadにCameraを
・FPS ControllerにRigidBodyFPSControllerを
を設定します。

ここで要注意なのが

Unity5.3系ではCamera(head)
Unity5.4系ではCamera(eye)
を設定してください。

(Unity5.4では実行時にCamera(head)が消えるという謎仕様)

fpc7

パッケージダウンロード

上記をまとめたパッケージを用意しました。SteamVRを手動でインポートした後にパッケージのインポートを行ってください。(Unityスタンダードアセットは再配布OKとのことで下記パッケージに含めています)

RigidBodyFPSController_VIVE_5.3.unitypackage

RigidBodyFPSController_VIVE_5.4.unitypackage

 

カテゴリー: HTC VIVE, Unity

OptimusノートPCの15インチAlienwareでOculus Runtime0.8動作方法

OptimusノートPCの15インチAlienware(GTX765M搭載)にてOculus Runtime0.8を起動することに成功したのでメモ。

今まで、開発には
デスクトップPCにて
・Oculus Runtime 0.8+Unity5.3
または
・Oculus Runtime0.6.0.1+Unity5.1.1p4
で行っていたのですが、Unity5.3系で作成したアプリのデモがノートPCでできないので最近はデスクトップを持ち運んでいた。

alienware

一部の一部のOptimusノートでOCulusRuntime0.7が動作したという下記のページ参考にさせていただいたが私のマシンではうまく行かなかった。
Devel/OculusRift/OptimusノートでのDirectモード – cubic9.com

ところがひょんなことから試した手法でうまく行ったのでメモ。

私の持っているAlienwareには外部ディスプレイ用にHDMIポートとMini Displayポートが2つ用意されています。AlienwareのMini Displayポートに変換アダプタ経由でOculusを接続するだけでOculus Runtime 0.8がDK2を認識しました。

私はこちらのアダプタ経由でうまくいきました。
moshi mo-hdmi4k [Mini DisplayPort to HDMI Adapter (4K)]
100000001002684631_10204
外部HDMIポートはIntel HD Graphicsに接続されるが、Mini DisplayポートはGPUに接続される仕様のようだ。たぶん。

動作確認済みの環境
・Alienware15インチGTX765M搭載
・Unity5.3.3p2 64bit Virtual Reality Supportオン
・Oculus Runtime0.8
・Windows 8.1 64bit
・GeForce Game Ready Driver Version 364.51

これで私のAlienwareももう少し現役で行けそう。

Alienware以外にもOptimusマシンでHDMIポートと別にミニディスプレイポートがあるノートPCでは試してみる価値が有るかもしれません。

カテゴリー: Oculus, Unity

Unity5.3+Leapmotion orion 4.0.1のメモ

Unity5.3.3にLeapmotion Orionの設定でハマったのでメモです。

なんでPrefab追加するだけで動くようにしてくれてないんだろう。。。

LeapMotion_CoreAsset_Orion_Beta_4.0.1.unitypackage
をプロジェクトにインポート後、LMHeadMountedRigプレハブをシーンに追加します。LMHeadMountedRigにはカメラが入っているので、シーン上に元々あったMainCameraを削除しておきます。

orion1

LeapHandControllerに下記の4つを子として追加

  • CapsuleHand_L
  • CapsuleHand_R
  • RigidRoundHand_L
  • RigidRoundHand_R

orion2

LeapHandControllerのHandPoolスクリプトのModelCollectionのsizeを4に変更して
下記のように設定します。

orion3

CenterEyeAnchorにアタッチされているcameraの設定を変えないとSkyboxが表示されません。

orion4

これでOK

orion5

 

カテゴリー: Leap motion, Unity

Unity5.3でVuforia環境の忘備録

VuforiaをUnity5.3系で利用する場合のメモ

  • エディター上でプレビューする場合32ビット版Unityを利用する必要がある。
  • Unity32ビット版にAndroidやiOSビルド用のコンポーネントをインストールするのにハマったのでメモ。
  1. 64ビット版Unityのインストール
    パッチリリースのページから最新パッチ版をダウンロードします。
    Unityインストーラーをダウンロード-ダウンロード(Win)からWindows版64bitUnityのインストーラーを使ってインストール
  2. 32ビット版Unityのインストール
    個別にインストール(Windows)-Unity エディター(32ビット)
    からインストール。このインストールではエディターしかインストールされず、AndroidやiOSでのビルドができません。
  3. ビルド用コンポーネントを64bit版フォルダから32ビット版フォルダにコピー
    C:\Program Files\Unity\Editor\Data\PlaybackEngines
    から
    C:\Program Files (x86)\Unity\Editor\Data\PlaybackEngines
    にコピー

Unity

 

 

 

カテゴリー: Unity

HOME / Coporate Site/ Careers

© Copyright 2018 STYLY..