Unity中嵌入網頁插件Embedded Browser2.1.0

背景

最近剛換了工做,新公司不是作手遊的,一開始有點抵觸,總以爲不是作遊戲本身就是跨行了,認爲本身不對口,可是慢慢發如今這能夠學的東西面很廣,因此感受又到了打怪升級的時候了,老子就在這進階了。javascript

一進公司他們使用H5開發,作一款地形信息系統的軟件,基於Unity開發,可是全部頁面都是Js寫的,因此我第一件事要作的是實現Unity嵌入網頁,並實現交互。css

在這裏,領導說以前作過相似的即用的Embedded Browser2.1.0這個插件,讓我研究下作個簡單Demo。html

實現方案

使用插件Embedded Browser2.1.0實現unity與網頁交互java

具體步驟

1.Unity中導入插件node

2.新建Canvas,在Canvas下建立一GameObject,平鋪在Canvas上jquery

3.將網頁映射到GameObject上ajax

這一步須要給建立的BrowserGUI掛載插件腳本bootstrap

首先是Brower腳本,此腳本是設置嵌入網頁的URL以及一些幕布大小等參數,在這裏說下,有兩種嵌入方式c#

,1.能夠直接嵌入瀏覽器網頁2.能夠將html文件放入與Assets文件夾同級的BrowserAssets(必須一致,必須是這個文件夾,由於若放Assets下面,會自動默認爲代碼爲UnityScript而不是JavaScript),加載嵌入,這種方式相對快一些。瀏覽器

再一個就是掛載GUI Brower UI腳本,這腳本是構建UI的一個做用,請求的網頁會顯示出來是由於這個腳本,而且會自動添加上Raw Image組件

Unity經過插件與網頁的交互

1.Unity接收網頁操做作出響應

C#監聽代碼:

js代碼:

Tips:Unity接收網頁推送事件RegisterFunction(「MethodName」,CallBack);

即:網頁進行一系列操做,unity中監聽到並響應執行事件

2.Unity作出相應操做通知網頁並更新網頁顯示

案例:此爲unity方5秒倒計時,每輪計時結束時間重置,目標數+=3;通知網頁端並顯示的Demo

c# 代碼:

Js代碼:

Tips:網頁監聽Unity操做:browser.CallFunction("MethodName",params).Down();

 即:unity進行一系列操做,unity通知網頁自身變化並調用網頁更新函數

完整代碼

場景1:網頁點擊按鈕,Unity接收參數:

 c#:

  1 using System.Collections;
  2 using System.Collections.Generic;
  3 using UnityEngine;
  4 using UnityEngine.UI;
  5 using ZenFulcrum.EmbeddedBrowser;
  6 using UnityEngine.SceneManagement;
  7 /// <summary>
  8 /// Unity使用插件控制腳本
  9 /// </summary>
 10 public class DemoTexMgr : MonoBehaviour
 11 {
 12     /// <summary>
 13     /// 插件組件
 14     /// </summary>
 15     Browser browser;
 16     /// <summary>
 17     /// 監聽H5操做做出響應物體
 18     /// </summary>
 19     public Transform targetScle;
 20 
 21     /// <summary>
 22     /// 嵌入網頁地址
 23     /// </summary>
 24     string URL = "file:///C:/Users/lenovo/Desktop/工做/自測須要/測試Js腳本/TextTool.html";
 25     /// <summary>
 26     /// 目標位置(顯示同步到H5)
 27     /// </summary>
 28     private Vector3 targetPos;
 29     public Vector3 TargetPos { get; set; }
 30 
 31 
 32     private void Awake()
 33     {
 34         //獲取插件Browser組件(Unity方使用插件基礎一步)
 35         browser = transform.Find("BrowserGUI").GetComponent<Browser>();
 36     }
 37     void Start()
 38     {
 39         InitData();
 40     }
 41     public void Update()
 42     {
 43        
 44     }
 45     /// <summary>
 46     /// 初始化函數(初始化嵌入頁面)
 47     /// </summary>
 48     public void InitData()
 49     {
 50         //設置嵌入頁面網址
 51         browser.Url = URL;
 52         //插件前往函數
 53         browser.GoForward();
 54         //browser.gameObject.GetComponent<RawImage>().raycastTarget = false;
 55 
 56         //改變背景深度(透明度)
 57         browser.gameObject.GetComponent<RawImage>().color = new Color(browser.gameObject.GetComponent<RawImage>().color.r, browser.gameObject.GetComponent<RawImage>().color.b, browser.gameObject.GetComponent<RawImage>().color.g, 20);
 58        
 59         //插件中監聽函數,監聽H5操做(點擊縮小按鈕,Unity作出縮小響應)
 60         browser.RegisterFunction("displayDate", (JSONNode jk) =>
 61         {
 62             Debug.Log("yuanjun  Unity Get  H5     參數" + jk[0].AsJSON + "  參數  " + jk[1].AsJSON + "  " + jk[0].Value);
 63             targetScle.transform.localScale = new Vector3(0.8f, 0.8f, 0.8f);
 64         });
 65         browser.RegisterFunction("GetUniMethodty", (JSONNode jk) =>
 66         {
 67             targetScle.transform.localScale = new Vector3(float.Parse(jk[0].AsJSON), 0.8f, 0.8f);
 68             Debug.Log("yuanjun  Unity Get  H5  GetUniMethodty    參數1" + jk[0].AsJSON);
 69         });
 70 
 71     } 96     //退出按鈕
 97     public void OnClickQuitBtn()
 98     {
 99         Application.Quit();
100     }
101     public void ChangeBtn()
102     {
103         SceneManager.LoadScene(1);
104     }
105 }

js腳本:

 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
  2 <html xmlns="http://www.w3.org/1999/xhtml">
  3 <head>
  4 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
  5 <title>相似於Jquery的JS下拉菜單</title>
  6 <style type="text/css">
  7 * { margin: 0; padding: 0; font-style: normal; font-family: 宋體; }
  8 body { text-align: center; font-size: 12px; background:url(1.jpg) center center; }
  9 #content { margin: 0 auto; width: 600px; }
 10 #content #nav { height: 32px; margin-top: 60px; background-color: #464749;FILTER: alpha(opacity=80); opacity: 0.8; -moz-opacity: 0.8;  }
 11 #content #nav ul { list-style: none; }
 12 #content #nav ul li { float: left; width: 100px; line-height: 32px; position: relative; }
 13 #nav div { width: 100px;FILTER: alpha(opacity=80); opacity: 0.8; -moz-opacity: 0.8; position:absolute; left:0px; top:32px; z-index:1; padding-bottom: 0px; float: left; height: 0; overflow: hidden; background-color: #fff;color:#000; }
 14 #content #nav li .a { text-decoration: none; color: #FFFFFF; line-height: 32px; display: block; border-right-width: 1px; border-right-style: solid; border-right-color: #393A3C; }
 15 #nav div a { text-decoration: none; color: #000; line-height: 26px; display: block; z-index:100; }
 16 #nav div a:hover { background-color: #ccc; }
 17 </style>
 18 </head>
 19 <body>
 20 <div id="content">
 21   <div id="nav">
 22     <ul id="supnav">
 23       <li><a href="#" class="a">物體變大</a>
 24         <div>
 25             <button onclick="GetUniMethodty(5)">變大</button>
 26         </div>
 27       </li>
 28       <li><a href="#" class="a">物體旋轉</a>
 29         <div> 
 30             <a href="#">物體旋轉</a> 
 31         </div>
 32       </li>
 33       <li><a href="#" class="a">物體縮小</a>
 34         <div> 
 35             <button onclick="displayDate(1,2)">縮小</button>
 36         </div>
 37       </li>
 38       <li><a href="#" class="a">導航菜單</a>
 39         <div> 
 40             <a href="#">導航菜單</a> 
 41         </div>
 42       </li>
 43       <li><a href="#" class="a">導航菜單</a>
 44         <div> 
 45             <a href="#">導航菜單</a> 
 46         </div>
 47       </li>
 48       <li><a href="#" class="a">導航菜單</a>
 49         <div> 
 50             <a href="#">導航菜單</a> 
 51          </div>
 52       </li>
 53     </ul>
 54   </div>
 55 </div>
 56 <script type="text/javascript">
 57     var supnav = document.getElementById("supnav");
 58     var nav = document.getElementById("nav");
 59     var btns = document.getElementsByTagName("li");
 60     var subnavs = nav.getElementsByTagName("div");
 61     var paddingbottom = 20;
 62     var defaultHeight = 0;
 63     function drop(obj, ivalue) {
 64         var a = obj.offsetHeight;
 65         var speed = (ivalue - obj.offsetHeight) / 8;
 66         a += Math.floor(speed);
 67         obj.style.height = a + "px";
 68     }
 69     window.onload = function() {
 70         for (var i = 0; i < btns.length; i++) {
 71             btns[i].index = i;
 72             btns[i].onmouseover = function() {
 73                 var osubnav = subnavs[this.index];
 74                 var sublinks = osubnav.getElementsByTagName("a");
 75                 if (osubnav.firstChild.tagName == undefined) {
 76                     var itarheight = parseInt(osubnav.childNodes[1].offsetHeight) * sublinks.length + paddingbottom;
 77                 } else {
 78                     var itarheight = parseInt(osubnav.firstChild.offsetHeight) * sublinks.length + paddingbottom;
 79                 }
 80                 clearInterval(this.itimer);
 81                 this.itimer = setInterval(function() {
 82                     drop(osubnav, itarheight);
 83                 },
 84                 30);
 85             }
 86             btns[i].onmouseout = function() {
 87                 var osubnav = subnavs[this.index];
 88                 clearInterval(this.itimer);
 89                 this.itimer = setInterval(function() {
 90                     drop(osubnav, defaultHeight);
 91                 },
 92                 30);
 93             }
 94         }
 95     }
 96 </script>
 97 
 98 
 99 <script>
100 function displayDate(a,b){
101  alert("DisPlayData  " +a );
102 return a+b;
103 }
104 </script>
105 
106 <script>
107 function GetUniMethodty(s){
108        alert("Data Come " +s);
109    return s;
110 }
111 </script>
112 
113 
114 <script>
115 function myFunction(){
116     alert("Welcome " +  "Harry Potter ");
117 }
118 </script>
119 
120 </body>
121 </html>
View Code

 場景2:Unity中Cube移動位置,網頁上位置信息更新

c#:

  1 using System.Collections;
  2 using System.Collections.Generic;
  3 using UnityEngine;
  4 using UnityEngine.UI;
  5 using ZenFulcrum.EmbeddedBrowser;
  6 using UnityEngine.SceneManagement;
  7 public class DemoTesxMgrOne : MonoBehaviour
  8 {
  9     /// <summary>
 10     /// 插件組件
 11     /// </summary>
 12     Browser browser;
 13     /// <summary>
 14     /// 監聽H5操做做出響應物體
 15     /// </summary>
 16     public Transform targetScle;
 17 
 18     /// <summary>
 19     /// 嵌入網頁地址
 20     /// </summary>
 21     string URL = "file:///C:/Users/lenovo/Desktop/工做/自測須要/測試Js腳本/demo.html";
 22     /// <summary>
 23     /// 目標位置(顯示同步到H5)
 24     /// </summary>
 25     public delegate void del(Vector3 v);
 26     public del _del;
 27     public Vector3 oldv;
 28     private Vector3 targetPos;
 29     public Vector3 TargetPos {
 30         get {
 31             return targetPos;
 32             }
 33         set
 34         {
 35             targetPos = value;
 36             if (oldv!=targetPos)
 37             {
 38                 _del(targetPos);
 39                 oldv=targetPos;
 40             }
 41         } }
 42 
 43     public int TextValue = 0;
 44     public float timer = 5;
 45 
 46     private void Awake()
 47     {
 48         //獲取插件Browser組件(Unity方使用插件基礎一步)
 49         browser = transform.Find("BrowserGUI").GetComponent<Browser>();
 50         _del += calH5;
 51        // oldv = targetScle.transform.localPosition;
 52     }
 53     void Start()
 54     {
 55         InitData();
 56     }
 57     public void Update()
 58     {
 59         TargetPos = targetScle.transform.localPosition;
 60             //if (timer > 0)
 61             //{
 62             //    timer -= Time.deltaTime;
 63             //}
 64             //else
 65             //{
 66             //    TextValue += 3;
 67             //    timer = 5;
 68             //    browser.CallFunction("selall", TextValue).Done();
 69             //}
 70 
 71     }
 72     public void calH5(Vector3 v)
 73     {
 74         browser.CallFunction("selall", v.ToString()).Done();
 75     }
 76     /// <summary>
 77     /// 初始化函數(初始化嵌入頁面)
 78     /// </summary>
 79     public void InitData()
 80     {
 81         //設置嵌入頁面網址
 82         browser.Url = URL;
 83         //插件前往函數
 84         browser.GoForward();
 85         //browser.gameObject.GetComponent<RawImage>().raycastTarget = false;
 86 
 87         //改變背景深度(透明度)
 88         browser.gameObject.GetComponent<RawImage>().color = new Color(browser.gameObject.GetComponent<RawImage>().color.r, browser.gameObject.GetComponent<RawImage>().color.b, browser.gameObject.GetComponent<RawImage>().color.g, 20);
 89 
 90         //插件中監聽函數,監聽H5操做(點擊縮小按鈕,Unity作出縮小響應)
 91         //browser.RegisterFunction("displayDate", (JSONNode jk) =>
 92         //{
 93         //    Debug.Log("yuanjun  Unity Get  H5     參數" + jk[0].AsJSON + "  參數  " + jk[1].AsJSON + "  " + jk[0].Value);
 94         //    targetScle.transform.localScale = new Vector3(0.8f, 0.8f, 0.8f);
 95         //});
 96         //browser.RegisterFunction("GetUniMethodty", (JSONNode jk) =>
 97         //{
 98         //    targetScle.transform.localScale = new Vector3(float.Parse(jk[0].AsJSON), 0.8f, 0.8f);
 99         //    Debug.Log("yuanjun  Unity Get  H5  GetUniMethodty    參數1" + jk[0].AsJSON);
100         //});
101 
102     }
103 
104     //unity調試
105     public void OnClickJsData()
106     {//調用頁面中任何可用的js(自上而下)
107      // browser.EvalJS("displayDate(7,5)").Then(Result =>
108      //   { Debug.Log(Result.Value); }
109      //).Done();
110      // //查詢頁面中的數據,能夠查看返回值(測試多返回值時好像只返回最後一個值)
111      //browser.CallFunction("displayDate", 1, 2).Then(Result =>
112      //{
113      //    Debug.Log(" displayDate   " + Result.Value);
114      //});
115 
116        // browser.CallFunction("selall", 100).Done();
117 
118     }
119  
120     //退出按鈕
121     public void OnClickQuitBtn()
122     {
123         Application.Quit();
124     }
125     public void ChangeBtn()
126     {
127         SceneManager.LoadScene(0);
128     }
129 }

 js:

1 <body>
 2 <!-- 我記得複選框不是這樣寫的? 那個是 下拉選擇框 -->
 3 <input type="checkbox" id="cb1" onclick="fun0()"/>全選/全不選
 4 </br>
 5 <input type="checkbox" name="love">籃球<br/>
 6 <input type="checkbox" name="love">足球<br/>
 7 <input type="checkbox" name="love">排球<br/>
 8 <input type="checkbox" name="love">冰球<br/>
 9  
10 <input type="button" value="全選" onclick="selall()"/>
11 <input type="button" value="全不選" onclick="selno()"/>
12 <input type="button" value="反選" onclick="selother()"/>
13 <script type="text/javascript">
14 function fun0(){
15 var cb = document.getElementById("cb1");
16 if(cb.checked==true){
17 selall();
18 }else{
19 selno();
20 }
21 }
22 function selall(a){
23 alert(a);
24 var nodes = document.getElementsByName("love");
25 for(var i = 0; i < nodes.length; i++){ //遍歷節點
26 var node1 = nodes[i];
27 node1.checked = true; //把節點的checked屬性設置爲 true
28 }
29 }
30 function selno(){
31 var nodes = document.getElementsByName("love");
32 for(var j = 0; j < nodes.length; j++){ //遍歷節點
33 //var node2 = nodes[j];
34 //node2.checked = false;
35 nodes[j].checked = false; //把節點的checked屬性設置爲 false
36 }
37 }
38 </script>
39 </body>
View Code

 Tips:注意以上有很多冗餘代碼,爲何用兩個場景兩個網頁測試,歸根結底是由於我不懂Js,我想要的事件一個沒法知足還不會擴展,因此,重點看方法不看代碼。

我也只是跑通了,裏面還有不少方法函數,我這裏只是先實現了互通,理解可能不許確或者不對,熱烈歡迎指出並交流。

 

最近:最近在作demo時,具體遇到了這麼幾點:

1.上面在嵌入網頁時須要掛在GUI Brower UI腳本,可是在我作demo時發現,這個腳本在這個版本還能夠用,可是已被編輯爲過期[Obsolete("Use PointerUIGUI and CursorRendererOS instead.")],應用PointerUIGUI腳本替代。

2.

js代碼:

 

  1 <!doctype html>
  2 <html lang="en">
  3   <head>
  4     <!-- Required meta tags -->
  5     <meta charset="utf-8">
  6     <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
  7 
  8     <!-- Bootstrap CSS -->
  9     <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
 10 
 11     <title>Ventilation UI</title>
 12 
 13     <style>
 14         html {
 15             height: 100%;
 16         }
 17 
 18         body
 19         {
 20             font-family: Monospace;
 21             font-weight: bold;
 22             background-color: #ccccff00;
 23             margin: 0px;
 24             height: 100%;
 25             overflow: hidden;
 26         }
 27     </style>
 28 
 29   </head>
 30   <body>
 31       <!-- Optional JavaScript -->
 32       <!-- jQuery first, then Popper.js, then Bootstrap JS -->
 33       <script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
 34       <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js" integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1" crossorigin="anonymous"></script>
 35       <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous"></script>
 36 
 37       <div class="container">
 38           <div class="btn-toolbar " role="toolbar" aria-label="Toolbar">
 39               <div class="btn-group mr-2" role="group" aria-label="First Group">
 40                   <button id="createLaneway" type="button" class="btn btn-success">新建</button>
 41                   <button id="editLaneway" type="button" class="btn btn-success">編輯</button>
 42                   <button id="drawAirDuct" type="button" class="btn btn-success">繪製</button>
 43                   <button id="drawAirDoor" type="button" class="btn btn-success">繪製</button>
 44                   <button id="drawLine" type="button" class="btn btn-success">畫線</button>
 45                   <button id="drawFace" type="button" class="btn btn-success">畫面</button>
 46               </div>
 47               <div class="btn-group mr-2" role="group" aria-label="Second Group">
 48                   <button type="button" class="btn btn-success">平移</button>
 49                   <button type="button" class="btn btn-success">旋轉</button>
 50                   <button type="button" class="btn btn-success">縮放</button>
 51               </div>
 52               <div class="btn-group" role="group" aria-label="Fourth group">
 53                   <button id="undo" type="button" class="btn btn-success">撤銷</button>
 54                   <button id="redo" type="button" class="btn btn-success">重作</button>
 55                   <button id="none" type="button" class="btn btn-success">退出編輯</button>
 56                   <button id="exit" type="button" class="btn btn-success">退出程序</button>
 57               </div>
 58           </div>
 59       </div>
 60 
 61       <script>
 62           $('#createLaneway').on('click', function () { onCreateLane(); });
 63           $('#editLaneway').on('click', function () { onEditLane(); });
 64           $('#drawAirDuct').on('click', function () { onDrawDuct(); });
 65           $('#drawAirDoor').on('click', function () { onDrawDoor(); });
 66           $('#drawLine').on('click', function () { onDrawLine(); });
 67           $('#drawFace').on('click', function () { onDrawFace(); });
 68           $('#undo').on('click', function () { onUndo(); });
 69           $('#redo').on('click', function () { onRedo(); });
 70           $('#none').on('click', function () { onExitEdit(); });
 71           $('#exit').on('click', function () { onExit(); });
 72 
 73 
 74           
 75           function onCreateLane(e) {
 76 
 77               console.log('新建');
 78 
 79           }
 80 
 81           
 82           function onEditLane(e) {
 83 
 84               console.log('編輯');
 85 
 86           }
 87 
 88         
 89           function onDrawDuct(e) {
 90 
 91               console.log('繪製');
 92 
 93           }
 94 
 95           
 96           function onDrawDoor(e) {
 97 
 98               console.log('繪製');
 99 
100           }
101 
102           // 畫線事件響應
103           function onDrawLine(e) {
104 
105               console.log('畫線');
106 
107           }
108 
109           // 畫面事件響應
110           function onDrawFace(e) {
111 
112               console.log('畫面');
113 
114           }
115 
116           // 撤銷事件響應
117           function onUndo(e) {
118 
119               console.log('撤銷');
120 
121           }
122 
123           // 重作事件響應
124           function onRedo(e) {
125 
126               console.log('重作');
127 
128           }
129 
130           function onExitEdit() {
131               console.log('退出編輯');
132           }
133 
134           function onExit() {
135               console.log('退出');
136           }
137 
138           //加載結束
139           function loadEnd() {
140               console.log("Load end");
141           }
142 
143           window.onload = function () { loadEnd(); }
144 
145       </script>
146 
147   </body>
148 </html>
View Code

 

這種註冊按鈕的方式,按着我以前說的那中監聽方式會監聽不到,

如:  $('#createLaneway').on('click', function () { onCreateLaneway(); });這句註冊按鈕代碼,若是寫成  $('#createLaneway').on('click',  onCreateLaneway() );就會監聽不到,因此外面套了個function () { },就能夠了。

3.好比你要加載完H5頁面再執行邏輯,browser.WhenLoaded(StartApp());使用browser.WhenLoaded()函數,裏面傳Action參數,在裏面能夠處理寫加載完頁面後你想處理的事件。

4.請求地址能夠在最後面寫:browser.WhenReady(SetRequestURL());使用browser.WhenReady()這個函數,裏面傳Action參數,在裏面寫請求地址。如:

1   private Action SetRequestURL()
2         {
3             return delegate ()
4             {
5                 // 設置Url地址
6                 browser.Url = "localGame://index.html";
7             };
8         }
View Code
相關文章
相關標籤/搜索