unity 内嵌H5界面需要用到Uniwebview 差件,百度搜索下就可以找到插件下载地址,这里就不提供了
Uniwebview 支持Android 、IOS。 PC平台下不显示,需要打包测试。
下面是封装好的动态加载外部网页类
using System;
using UnityEngine;
public class WebView : Singleton<WebView> {
public delegate void WebOnReceivedMessage(UniWebView webView, UniWebViewMessage message);
public WebOnReceivedMessage OnWebReceivedMessage;
#if !(UNITY_STANDALONE_OSX || UNITY_STANDALONE_WIN)
private UniWebView webView;
#endif
private Action onClose;
private void CreateWebView(Rect panelPosition,Action loadFinished = null) {
#if !(UNITY_STANDALONE_OSX || UNITY_STANDALONE_WIN)
if (this.webView == null) {
this.webView = this.gameObject.AddComponent<UniWebView>();
}
int top, left, bottom, right;
#if UNITY_ANDROID
left = (int)panelPosition.x;
top = (int)panelPosition.y;
bottom = (int)(Screen.height - panelPosition.height - top);
right = (int)(Screen.width - panelPosition.width - left) ;
#endif
#if UNITY_IOS
float ratio;
ratio = 1f / UniWebViewHelper.screenScale;
left = (int)(panelPosition.x * ratio);
top = (int)(panelPosition.y* ratio);
bottom = UniWebViewHelper.screenHeight - (int)((panelPosition.y+panelPosition.height)*ratio);
right = UniWebViewHelper.screenWidth - (int)((panelPosition.x + panelPosition.width) * ratio);
#endif
this.webView.insets = new UniWebViewEdgeInsets(top,left,bottom,right);
Color bgColor = Color.white;
bgColor.a = 0;
this.webView.SetBackgroundColor(bgColor);
this.webView.bouncesEnable = false;
this.webView.SetShowSpinnerWhenLoading(true);
if (loadFinished!=null) {
this.webView.OnLoadComplete += (UniWebView webView, bool success, string errorMessage) => {
this.webView.AddUrlScheme("http");
this.webView.AddUrlScheme("https");
loadFinished();
};
}
this.webView.OnWebViewShouldClose += (view) => {
return false;
};
this.webView.OnReceivedMessage += (webView, message) => {
OnWebReceivedMessage(webView, message);
UniWebviewTest.Instance.text.text = message.rawMessage;
Application.OpenURL(message.rawMessage);
};
#endif
}
public void Show(string url, Rect panelPosition, Action loadFinish = null,bool transition = false, Action onclosed = null) {
#if UNITY_EDITOR || UNITY_STANDALONE_WIN
if (loadFinish != null) {
loadFinish();
}
return;
#endif
#if !(UNITY_STANDALONE_OSX || UNITY_STANDALONE_WIN)
CreateWebView(panelPosition,loadFinish);
this.webView.Load(url);
this.webView.Show(true, transition ? UniWebViewTransitionEdge.Top : UniWebViewTransitionEdge.None, 0.3f);
this.onClose = onclosed;
#endif
}
public void Hide() {
#if !(UNITY_STANDALONE_OSX || UNITY_STANDALONE_WIN)
if (this.webView == null) {
return;
}
this.webView.Hide(true, UniWebViewTransitionEdge.None, 0.2f, () => {
CloseWebView();
});
#endif
}
private void CloseWebView() {
#if !(UNITY_STANDALONE_OSX || UNITY_STANDALONE_WIN)
if (this.webView == null) {
return;
}
this.webView.CleanCache();
DestroyImmediate(this.webView);
this.webView = null;
this.onClose.Invoke();
this.onClose = null;
#endif
}
}
Singleton单例
using UnityEngine;
public abstract class Singleton<T> : MonoBehaviour where T : MonoBehaviour {
private static T instance;
// ReSharper disable once StaticMemberInGenericType
private static readonly object Locker = new object();
// ReSharper disable once StaticMemberInGenericType
private static bool applicationIsQuitting;
public static T Instance {
get {
if (Singleton<T>.applicationIsQuitting) {
return null;
}
lock (Singleton<T>.Locker) {
if (Singleton<T>.instance == null) {
Singleton<T>.instance = Object.FindObjectOfType(typeof(T)) as T;
if (Object.FindObjectsOfType(typeof(T)).Length > 1) {
return Singleton<T>.instance;
}
if (Singleton<T>.instance == null) {
GameObject singleton = new GameObject();
Singleton<T>.instance = singleton.AddComponent<T>();
singleton.name = "(singleton) " + typeof(T);
Object.DontDestroyOnLoad(singleton);
} else {
}
}
return Singleton<T>.instance;
}
}
}
protected virtual void Awake() {
Singleton<T>.applicationIsQuitting = false;
}
protected virtual void OnDestroy() {
}
private void OnApplicationQuit() {
Singleton<T>.applicationIsQuitting = true;
}
}
测试类
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;
public class UniWebviewTest : MonoBehaviour {
private WebView webView;
public UnityEngine.UI.Text text;
public static UniWebviewTest Instance;
private string session_token = "45dbc533f2f47d9e693b621f0b2361a6";
private string id = "10000";
private void Awake() {
Instance = this;
}
// Use this for initialization
void Start () {
Rect rect = new UnityEngine.Rect(this.GetComponent<RectTransform>().position, this.GetComponent<RectTransform>().rect.size);
this.webView = Singleton<WebView>.Instance;
this.webView.OnWebReceivedMessage += ReceivedMessage;
this.webView.Show("http://192.168.18.57/pay.html",
rect,
() => { Debug.Log("H5"); });
}
private void ReceivedMessage(UniWebView webView, UniWebViewMessage message) {
text.text = webView.url + ":" + message.path ;
}
}
具体解析:
webView.AddUrlScheme()
是用来添加拦截链接 :// 前的部分,比如http://或者https://
如果h5里的按钮点击是访问上面两种开头的链接,则会被拦截,不进行访问
这时webView.OnReceivedMessage这个事件将会接收到拦截的url信息,也就是上面的message.rawMessage里
再通过Appliction.OpenUrl() 就可以在浏览器中打开想要访问的网站(PC,Android,IOS平台都可访问,亲测可用)
附:
Uniwebview 不能拦截动态获取的含有form表单的链接(与服务器交互获得的url 而且存在需要提交的表单),测试时是拦截不到,也可能是我了解不够的问题,你们如果能够测试通过,希望你们能给我留言,将不胜感激