Unityでgree/unity-webviewを使ってLandscapeでWebViewを表示するときの注意点

UnityでWebViewを表示しようと思ってググるとgreeのこのプラグインがよく使われているので、試してみました。
gree/unity-webview · GitHub

ざっくりとサンプルを書くとこんな感じです。

using UnityEngine;
using System.Collections;

public class WebviewSample : MonoBehaviour {
  public string url;
  WebViewObject webViewObject;

  // Use this for initialization
  void Start () {
    webViewObject = (new GameObject("WebViewObject")).AddComponent<WebViewObject>();
    webViewObject.Init((msg) => {
      Debug.Log(msg);
    });
    webViewObject.LoadURL("http://google.com/");
    webViewObject.SetMargins(0, 0, 0, 100);
    webViewObject.SetVisibility(true);
  }

  // Update is called once per frame
  void Update () {

  }
}

あとは、AndroidManifest.xmlに以下を追加し、変更点を加える。

インターネットを使えるようにする。

<uses-permission android:name=”android.permission.INTERNET”/>

これをしないとWebView内のタッチがDOM側に通知されない。

<meta-data android:name=”unityplayer.ForwardNativeEventsToDalvik” android:value=”true” />

iOSでlandscape時に横幅いっぱいにWebViewが表示されない

この問題を修正したプルリクがあり、あれちゃんと対応されているなーと思っていたんですが、
Merge pull request #13 from endavid/fix/iOSLandscape · 3343201 · gree/unity-webview
どうもunity-webview.unitypackageがこのコードを含んだ状態になっていないようで、これをいくらimportしてもうまくいかなくてハマりました。

以下のふたつのファイルをimport後に上書きするとこの問題は解消されます。

  1. unity-webview/plugins/WebViewObject.cs at master · gree/unity-webview
  2. unity-webview/plugins/iOS/WebView.mm at master · gree/unity-webview

参考リンク

unity-webviewを使ってサイトを表示してみました!! 〜i-tai.net〜
Unity上でWebViewを表示する | 代打、俺
Unity で WebView を表示してみた。 | Lonely Mobiler

Unity4ゲームコーディング 本当にゲームが作れるスクリプトの書き方
浅野 祐一 荒川 巧也
SBクリエイティブ
売り上げランキング: 9,521

iOSのWebViewで外部リンクをネイティブブラウザで開く場合の注意点

以下のメソッド内で外部リンクかどうか判断し、外部リンクの場合はネイティブブラウザを開くようにできるのですが、iOSのWebViewはややこしいことにiframeのリクエスト時もここに入ってきてしまいます。

  - (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:  (NSURLRequest *)request navigationType:  (UIWebViewNavigationType)navigationType {-

これだと計測用のiframeのリクエストもこのメソッド内に入るので、外部URLだった場合にネイティブブラウザで開くという挙動を入れると、このiframeのリクエスト時にも反応してしまいます。

そこで方法としては、クリックした場合にのみ外部リンクかどうかを判断するようにするという方法があります。

シンプルなサンプルですが、以下のような雰囲気。

  NSString *absoluteUrl = request.URL.absoluteString;

  // 外部リンクをクリックした場合には、デバイスのデフォルトブラウザを起動する
  NSRange range = [absoluteUrl rangeOfString:@'domain'];
  if (range.location == NSNotFound) {
      if (navigationType == UIWebViewNavigationTypeLinkClicked) {
          [[UIApplication sharedApplication] openURL:request.URL];
          return NO;
      }
  }

そして、WebView側のコードに以下のようにクリックイベントをfireするコードで置き換えます。
もしもアンカーリンクなどをクリックする場合は以下のコードは不要ですが、何かしらJavaScriptでURLを作ってlocation.hrefに入れている場合には置き換えが必要になります。

  $("#hoge")[0].dispatchEvent(click());

  function click(){
    var event = document.createEvent("HTMLEvents");
    event.initEvent('click', true, false);
    return event;
  };

AndroidのWebViewはiframeなどはshouldOverrideUrlLoadingメソッドの中に入ってこないので、楽なのですが、
iOSは結構ややこしいですね。