Unityを使っていてWeb画面を表示したい場合は、greeさんが公開しているunity-webviewを使用することが多いと思いますが、この処理はネイティブのWebViewをUnityのビューの上に乗っけて表示を行う仕組みなので、Unityの表示の常に上に表示されてしまいます。
そこで、Unityの中で優先を混ぜられるようにします。
サンプルプロジェクトはこちら
https://bitbucket.org/HoshiyamaTakaaki/pixelreadstest
まずベースとなる処理はこちらのページにまとめられています。
ここではWebViewの表示をOpenGLESのテクスチャとして使用しています。
WebViewのレンダリング先を自前で用意したGLSurfaceに切り替えてやり、OpenGLESテクスチャに書き込みます。
この処理を応用して、このテクスチャをUnity側に持って来れば良いわけです。
Unityにはネイティブ側で作成したテクスチャを持ってくる機構がありますが、スレッドが違うせいかうまく参照ができません。
またGLSurfaceで使用するテクスチャはGL_TEXTURE_2Dではなく、GL_TEXTURE_EXTERNAL_OESで生成を行うため、シェーダーもsamplerExternalOESを使用する必要があります。
UnityではsamplerExternalOESが使用できないので、このあたりも工夫が必要です。
今回はネイティブ側でReadPixelsを行なってピクセル情報をUnity側へ渡してやって、Unity側でテクスチャを生成します。
このため処理負荷が結構高いです。
private void Start()
{
var texture2D = new Texture2D(texWidth / 2, texHeight / 2, TextureFormat.ARGB32, false);
m_WebView = GameObject.Find("RenderCanvas/WebView").GetComponent<RawImage>();
m_WebView.texture = texture2D;
var rt = m_WebView.GetComponent<RectTransform>();
rt.sizeDelta = new Vector2(texWidth * aspect, texHeight * aspect);
rt.localPosition = new Vector3(posX, posY, 0);
}
private void Update()
{
var data = GetWebTexturePixel();
if (data != null)
{
var tex = (Texture2D)m_WebView.texture;
tex.LoadRawTextureData(data);
tex.Apply();
}
}
ネイティブ側でキャプチャしたピクセル情報をGetWebTexturePixel()
で取得して、あらかじめ作っておいたテクスチャにLoadRawTextureData()
で流し込みます。
LoadRawTextureDataは重そうな感じがしますが、意外とサクサク動きます。
ReadPixelsが重すぎるせいでそう感じるだけかもしれませんが。
texture2Dとして使用できるので、モデルのテクスチャとしても利用が可能です。
ただしタッチ入力は本来のWebViewの表示範囲内で行われるため、平面表示以外の場合は操作が破綻します。
また表示の優先は変更できても、入力は必ずWebView側が勝ちます。
WebView上にuGUIのボタンなどを置いても反応しませんので注意が必要です。
そのような場合はWebViewの表示を一時的にOFFにすることで、Unity側のUIが反応するようになります。
ただし今度はWebView側の操作ができなくなります。
(表示は最後にレンダリングした状態を保持しますのでそれほど違和感はないかも)
GLSurfaceのテクスチャをそのまま流用できればパフォーマンスが上がると思うのですが。
スレッド間でOpenGLESのコンテキストを共有できれば何とかなるのかもしれませんが、うまい方法が今の所見つかっていません。