【问题标题】:Web Browser in Oculus Go VR application built with Unity使用 Unity 构建的 Oculus Go VR 应用程序中的 Web 浏览器
【发布时间】:2019-04-29 17:24:46
【问题描述】:

我目前正在尝试寻找一种在 VR 应用程序中使用网络浏览器的方法。基本上,目标是在面板中打开类似https://*.com 的页面,并使其可通过 oculus go 控制器滚动。

我已经对像 this 这样的插件进行了一些研究,但它们似乎都不适用于 oculus go。

【问题讨论】:

  • 我很确定那里什么都没有。我也花时间看。如果您不需要视频,可以制作一个 Android 插件来呈现 web 视图。如果你愿意,我可以发布一个教程链接。
  • @palebone 会很棒!
  • 这个线程有两个有用的链接,用于通过 github 项目和教程将 android 视图渲染到纹理:*.com/questions/12499396/…
  • 当我下周回到我的团队时,我会在 repo 上发布更新。
  • @sebbo- 你就是男人!感谢您的支持。我可能已经很接近解决问题了(至少在这个假设上),如果我得到答案,我会告诉你,这样你就可以取消赏金了。

标签: unity3d virtual-reality oculus oculusgo


【解决方案1】:

更新:我更新了repo 以支持视频,它是一个基于 GeckoView 浏览器引擎的功能齐全的 3D 浏览器。它依赖 Oculus 的 OVROverlay 将 Android 插件中生成的帧渲染到 Unity3D 纹理上。

This 是我创建的一个 repo,希望我们可以实现一个不错的游戏内浏览器。它有点错误/缓慢,但它可以工作(大部分时间)。

它使用一个 Java 插件,通过覆盖视图的 Draw 方法,将 Android WebView 渲染为 Bitmap,将其转换为 png 并将其传递给统一的 RawImage。有很多工作要做,所以请随时改进它!

使用方法:

在 repo 中,您可以找到需要导入到 Assets/Plugins/Android/ 和 BrowserView.csUnityThread.cs 的插件 (unitylibrary-debug.aar),您可以使用它们将 Android WebView 转换为纹理unity的RawImage可以显示。适当填写BrowserView.cs 的公共字段。确保在 Unity 的播放器设置中将 API 级别设置为 25。

代码示例

这里重写WebViewDraw方法来创建位图和PNG,并初始化你需要的变量:

public class BitmapWebView extends WebView{

    private void init(){
        stream = new ByteArrayOutputStream();
        array = new ReadData(new byte[]{});
        bm = Bitmap.createBitmap(outputWindowWidth,
             outputWindowHeight, Bitmap.Config.ARGB_8888);
        bmCanvas = new Canvas(bm);
   }


    @Override
    public void draw( Canvas ){
        // draw onto a new canvas  
        super.draw(bmCanvas);
        bm.compress(Bitmap.CompressFormat.PNG, 100, stream);

        array.Buffer = stream.toByteArray();
        UnityBitmapCallback.onFrameUpdate(array,
            bm.getWidth(),
            bm.getHeight(),
            canGoBack,
            canGoForward );
        stream.reset();

    }
}  
// you need this class to communicate properly with unity
public class ReadData {
    public byte[] Buffer;
    public ReadData(byte[] buffer) {
        Buffer=buffer;
    }
}

然后我们将 png 传递给一个统一的 RawImage。 这是 Unity 接收端:

// class used for the callback with the texture
class AndroidBitmapPluginCallback : AndroidJavaProxy
{
    public AndroidBitmapPluginCallback() : base("com.unityexport.ian.unitylibrary.PluginInterfaceBitmap") { }
    public BrowserView BrowserView;

    public void onFrameUpdate(AndroidJavaObject jo, int width, int height, bool canGoBack, bool canGoForward)
        {
        AndroidJavaObject bufferObject = jo.Get<AndroidJavaObject>("Buffer");
        byte[] bytes = AndroidJNIHelper.ConvertFromJNIArray<byte[]>(bufferObject.GetRawObject());
        if (bytes == null)
            return;
        if (BrowserView != null)
        {
            UnityThread.executeInUpdate(()=> BrowserView.SetTexture(bytes,width,height,canGoBack,canGoForward));
        }
        else
            Debug.Log("TestAndroidPlugin is not set");

    }
 }


public class BrowserView : MonoBehaviour {
// Browser view needs a RawImage component to display webpages


   void Start () {
        _imageTexture2D = new Texture2D(Screen.width, Screen.height, TextureFormat.ARGB32, false);
        _rawImage = gameObject.GetComponent<RawImage>();
        _rawImage.texture = _imageTexture2D;

        #if !UNITY_EDITOR && UNITY_ANDROID
        // Get your Java class and create a new instance
        var tempAjc = new AndroidJavaClass("YOUR_LIBRARY.YOUR_CLASS")
        _ajc = tempAjc.CallStatic<AndroidJavaObject>("CreateInstance"); 
        // send the callback object to java to get frame updates
        AndroidBitmapPluginCallback androidPluginCallback = new AndroidBitmapPluginCallback {BrowserView = this};
        _ajc.Call("SetUnityBitmapCallback", androidPluginCallback);
        #endif

    }
   // Android callback to change our browser view texture
    public void SetTexture( byte[] bytes, int width, int height, bool canGoBack, bool canGoForward)
    {

        if (width != _imageTexture2D.width || height != _imageTexture2D.height)
            _imageTexture2D = new Texture2D(width, height, TextureFormat.ARGB32, false);

        _imageTexture2D.LoadImage(bytes);
        _imageTexture2D.Apply();
        _rawImage.texture = _imageTexture2D;
    }
}

【讨论】:

    【解决方案2】:

    据我所知,最好的解决方案是this 3D browser plugin。它不像我尝试过的其他选项那样缓慢或错误,它只是通过在您的场景中放置一个您可以单击和滚动的预制件来工作。

    void CreateWebView(float width, float height, Vector3 position) {
        var prefab = WebViewPrefab.Instantiate(width, height);
        prefab.transform.position = position;
        prefab.transform.LookAt(Camera.main.transform);
        prefab.Initialized += (sender, args) => prefab.WebView.LoadUrl("https://*.com");
    }
    

    【讨论】:

    • 到目前为止,这似乎是最好的解决方案。
    最近更新 更多