工作需求,在项目里做一个网页浏览器,记录一下功能。
最终效果:浏览器的基本功能都实现了,输入网址跳转网页,倒退前进,刷新
预制体结构(一开始只是做一个多媒体播放功能所以叫MediumScreen):
用的插件是3DWebView,对比了很多浏览器插件,还是这个最好用,在VR项目里的支持最好。文档也比较清晰,Demo非常全面,使用也很方便,当然了,价格也最贵。。。
插件官网:
这个插件是要分平台购买的,因为我们的目标设备Oculus和Pico都是Android系统,我们只需要用Android和Windows两个包就行了,Windows用来调试,把两个包直接导入Unity,会有一个Vuplex文件夹,最有用的是这个Resources和Demo,直接看Demo就行了。对几种实现浏览器的方式都有对应的场景,代码也都有,学起来很方便。
上面预制体里的CanvasWebViewPrefab,就在这个Resources文件夹里,直接拖到自己的预制体里按需要设置一下分辨率和对应平台的支持就能用,非常方便。
以下是我的设置:
我这里基本没改他原来的预制体,只把
这个预制体的位置往下缩进了50,留给功能区域。
这里面对应设置的解释都是直接点 View documentation 就能跳转到相应文档了,非常方便(需要科学上网)。
我的代码:
功能基本都是在Demo的代码里还有文档里扒下来的,我这里因为有UI方面开关之类的需求,有一些方法用来传递参数之类的是不用太关注的,被我删除了,主要关注几个按钮的功能,还有开关浏览器的功能实现。
using System.Timers;
using TMPro;
using UnityEngine;
using UnityEngine.UI;
using Vuplex.WebView;
public class MediumScreen : MonoBehaviour
{
public CanvasWebViewPrefab canvasWebViewPrefab;
[SerializeField]
private TMP_InputField website;//网址输入框
[SerializeField]
private Button openBtn;//跳转网址
[SerializeField]
private Button backBtn;//返回
[SerializeField]
private Button forwardBtn;//前进
[SerializeField]
private Button closeBtn;//关闭
[SerializeField]
private Button reloadBtn;//重载
private string mediumUrl = "";
Timer _buttonRefreshTimer = new Timer();//定义一个计时器
private void Awake()
{
#if UNITY_ANDROID && !UNITY_EDITOR
//这个API是关闭打包Android后网页自动按照移动设备显示,比例就不对了
Web.SetUserAgent(false);
#endif
}
async void Start()
{
await canvasWebViewPrefab.WaitUntilInitialized();//初始化后才能使用
website.text = canvasWebViewPrefab.InitialUrl;
canvasWebViewPrefab.WebView.UrlChanged += MainWebView_UrlChanged;
OnRegist();
// Set up a timer to allow the state of the back / forward buttons to be
// refreshed one second after a URL change occurs.
_buttonRefreshTimer.AutoReset = false;
_buttonRefreshTimer.Interval = 1000;
_buttonRefreshTimer.Elapsed += ButtonRefreshTimer_Elapsed;
}
void ButtonRefreshTimer_Elapsed(object sender, ElapsedEventArgs eventArgs)
{
// Get the main webview's back / forward state and then
// to the controls UI to update its buttons' state.
Vuplex.WebView.Internal.Dispatcher.RunOnMainThread(async () =>
{
var canGBack = await canvasWebViewPrefab.WebView.CanGoBack();
var canGoForward = await canvasWebViewPrefab.WebView.CanGoForward();
backBtn.interactable = canGBack;
forwardBtn.interactable = canGoForward;
});
}
void MainWebView_UrlChanged(object sender, UrlChangedEventArgs eventArgs)
{
_buttonRefreshTimer.Start();
}
private void CloseMediumScreen()
{
Destroy(canvasWebViewPrefab.gameObject);
}
/// <summary>
/// 打开输入的网址
/// </summary>
/// <param name="url"></param>
private void ClickToSetMediumUrl(string url)
{
mediumUrl = url;
OnSetScreenState(true);
}
/// <summary>
/// 打开浏览器
/// </summary>
private void OnSetScreenState(bool isScreenOpen)
{
var tempUrl = isScreenOpen ? mediumUrl : "about:blank";
if (isScreenOpen && !string.IsNullOrEmpty(tempUrl))
{
OnRegist();
website.text = tempUrl;
canvasWebViewPrefab.WebView.LoadUrl(tempUrl);
canvasWebViewPrefab.WebView.UrlChanged += MainWebView_UrlChanged;
}
}
private void OnRegist()
{
openBtn.onClick.AddListener(() => ClickToSetMediumUrl(website.text));
backBtn.onClick.AddListener(() => { canvasWebViewPrefab.WebView.GoBack(); });
forwardBtn.onClick.AddListener(() => { canvasWebViewPrefab.WebView.GoForward(); });
closeBtn.onClick.AddListener(CloseMediumScreen);
reloadBtn.onClick.AddListener(() => { canvasWebViewPrefab.WebView.Reload(); });
}
private void OnDestroy()
{
openBtn.onClick.RemoveAllListeners();
backBtn.onClick.RemoveAllListeners();
closeBtn.onClick.RemoveAllListeners();
reloadBtn.onClick.RemoveAllListeners();
forwardBtn.onClick.RemoveAllListeners();
_buttonRefreshTimer.Close();
}
}
因篇幅问题不能全部显示,请点此查看更多更全内容