我目前正在尝试找到一种在 VR 应用程序中使用 Web 浏览器的方法。基本上,目标是在面板中打开类似https://stackoverflow.com的页面,并使其可通过 oculus go 控制器滚动。
我已经对插件进行了一些研究以实现这样的效果,但它们似乎都不适用于 oculus go。
我目前正在尝试找到一种在 VR 应用程序中使用 Web 浏览器的方法。基本上,目标是在面板中打开类似https://stackoverflow.com的页面,并使其可通过 oculus go 控制器滚动。
我已经对插件进行了一些研究以实现这样的效果,但它们似乎都不适用于 oculus go。
更新:我更新了repo以支持视频,它是一个基于 GeckoView 浏览器引擎的功能齐全的 3D 浏览器。它依靠OVROverlay
Oculus 将 Android 插件中生成的帧渲染到 Unity3D 纹理上。
这是我做的一个 repo,希望我们可以实现一个不错的游戏内浏览器。这有点错误/缓慢,但它可以工作(大部分时间)。
它使用 Java 插件,通过覆盖视图的方法将 Android 渲染WebView
为 a ,将其转换为 png 并将其传递给 unity 。有很多工作要做,所以请随时改进它!Bitmap
Draw
RawImage
在 repo 中,您可以找到unitylibrary-debug.aar
需要导入到 Assets/Plugins/Android/ 的插件 ( ) BrowserView.cs
,UnityThread.cs
您可以使用它来将 Android 转换为WebView
UnityRawImage
可以显示的纹理。适当填写BrowserView.cs
的公共字段。确保在 Unity 的播放器设置中将 API 级别设置为 25。
这里覆盖WebView
'Draw
方法来创建位图和 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 传递给 unity 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;
}
}
据我所知,最好的解决方案是这个 3D 浏览器插件。它不像我尝试过的其他选项那样缓慢或错误,它只是通过在您的场景中放置一个预制件来工作,您可以单击和滚动。
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://stackoverflow.com");
}