Berbagi teknologi

Unity WebGL menyematkan halaman web front-end dan berkomunikasi

2024-07-12

한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina

1. Perkenalan

Baru-baru ini, ketika mengerjakan sebuah proyek, saya mengalami kebutuhan untuk menyematkan UnityWebGL ke dalam halaman web, dan UnityWebGL perlu merespons ketika mengklik tombol di halaman web.Lewati bagian proyek baru secara langsung

2. Efek akhir

webglResult.gif

3. Pengaturan dasar

  • Atur platform ekspor ke WebGL
    Gambar yang ditempel 20240527102413
  • Periksa Pengaturan Pemain -> Pengaturan Penerbitan Data Caching DanDecompression Fallback Tautan di bawah ini adalah penjelasan resminya.
    Data Caching Sederhananya, data di-cache secara lokal dan saat Anda membukanya lagi, Anda dapat langsung masuk ke dalam game tanpa mengunduh.
    Decompression Fallback Jika ada ketidakmampuan untuk mengurai file gz, kesalahan konfigurasi server web, dll., Anda perlu mencentang opsi ini.
    Unity - Manual: Pengaturan Pemutar WebGL (unity3d.com)
    Gambar yang ditempel 20240527102930

4. Penulisan dan ekspor kode

  • Adegan diatur sebagai berikut (Anda dapat membuat adegan sesuai kebutuhan Anda sendiri)
    Gambar yang ditempel 20240527110105
  • Bagian kode (pasang kode pada Cube yang dibuat)

Catatan: Metode ini harus bersifat publik jika tidak maka metode tersebut tidak dapat diakses

using System;  
using System.Text;  
using UnityEngine;  
using UnityEngine.UI;  
  
public class CubeRotate : MonoBehaviour  
{  
    public Text tx;  
  
    void Update()  
    {        
	    transform.Rotate(Vector3.up * Time.deltaTime * 30, Space.World);  
    }  
    public void SetTextInfo(string info)  
    {        byte[] bytes = Convert.FromBase64String(info);  
        var decodedMessage = Encoding.UTF8.GetString(bytes);  
        Debug.Log($"收到消息:{info}----{decodedMessage}");  
        tx.text = decodedMessage;  
    }  
    public void AddScale()  
    {        
	    transform.localScale += Vector3.one * 0.1f;  
    }  
    public void SubtractScale()  
    {        
	    transform.localScale -= Vector3.one * 0.1f;  
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • Ekspor WebGL (tunggu saja hingga ekspor selesai)
    Gambar yang ditempel 20240527110452

Jika Anda ingin menelusuri file yang dikemas secara lokal, Anda perlu mendownloadnya. Firefox浏览器 , pengunduhan memerlukan beberapa parameter konfigurasi tertentu.Buka webgl di Firefox_Buka webgl di Blog Firefox-CSDN

5. Contoh halaman web

Mengingat beberapa teman mungkin tidak tahu cara menulis halaman web, penulis menyediakan templat halaman web sederhana untuk diuji semua orang.

Petunjuk penggunaan: Buat file teks baru, tempelkan kode berikut ke dalamnya, simpan dan ubah akhiran file menjadi.html
Gambar yang ditempel 20240527114133

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Simple Web Page</title>
    <style>
      body {
        margin: 0;
        padding: 0;
        font-family: Arial, sans-serif;
      }
      .header {
        background-color: #333;
        color: white;
        padding: 10px;
        text-align: center;
      }
      .nav {
        background-color: #ddd;
        padding: 10px;
        text-align: center;
      }
      .nav-button {
        background-color: #ddd;
        border: none;
        color: #333;
        padding: 10px 15px;
        text-align: center;
        text-decoration: none;
        display: inline-block;
        font-size: 16px;
        margin: 4px 2px;
        cursor: pointer;
        border-radius: 4px; /* 圆角边框 */
      }
      .nav-button:hover {
        background-color: #ccc;
      }
      .nav a {
        color: #333;
        text-decoration: none;
        margin-right: 10px;
      }
      .container {
        display: flex;
        justify-content: space-between;
        padding: 20px;
      }
      .sidebar,
      .main {
        padding: 20px;
        height: 550px;
        overflow: hidden;
      }
      .sidebar {
        background-color: #f0f0f0;
        flex: 0 0 380px; /* Fixed width for sidebar */
      }
      .main {
        background-color: #e0e0e0;
        flex: 0 0 960px; /* Fixed width for main content */
      }
      .sidebar-left {
        margin-right: 20px; /* Adjust the margin for the left sidebar */
      }
      .sidebar-right {
        margin-left: 20px; /* Adjust the margin for the right sidebar */
      }
      .footer {
        background-color: #333;
        color: white;
        text-align: center;
        padding: 10px;
        position: fixed;
        bottom: 0;
        width: 100%;
      }
    </style>
  </head>
  <body>
    <div class="header">
      <h1>My Simple Web Page</h1>
    </div>

    <div class="nav">
      <button id="enlargeButton" class="nav-button">放大</button>
      <button id="shrinkButton" class="nav-button">缩小</button>
      <button id="infoButton" class="nav-button">设置信息</button>
    </div>

    <div class="container">
      <div class="sidebar sidebar-left">
        <h2>Left Sidebar</h2>
        <p>
          This is the left sidebar area. It typically contains additional
          information or links.
        </p>
      </div>
      <div class="main">
        WebGL网页
      </div>
      <div class="sidebar sidebar-right">
        <h2>Right Sidebar</h2>
        <p>
          This is the right sidebar area. It typically contains additional
          information or links.
        </p>
      </div>
    </div>

    <div class="footer">
      <p>Footer - Copyright &copy; 2024</p>
    </div>
  </body>

  <script>
    // JS 代码
  </script>
</html>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120

6. Sematkan WebGL

  • Buat folder dan letakkan paket WebGL dan halaman web di folder yang sama, seperti yang ditunjukkan di bawah ini (langkah ini terutama untuk memudahkan pengelolaan, Anda tidak perlu melakukan ini)
    Gambar yang ditempel 20240527114742
  • Gunakan IDE untuk membuka halaman web dan temukan lokasi yang ditandai dengan kotak merah pada kode di bawah ini.
    Gambar yang ditempel 20240527114359
  • Ganti konten di tag div dengan kode berikut. Jika proyek WebGL Anda telah disebarkan di server, Anda dapat mengganti konten di tag iframe dengan kode berikut.src Ubah saja tautan ke alamat server. (Untuk informasi tentang iframe, silakan merujuk keBingkai HTML (w3school.com.cn)) simpan dan gunakanFirefox浏览器Buka halaman web, dan proyek yang telah diterapkan di server dapat dibuka dengan browser apa pun yang mendukung WebGL.
<iframe
          id="webgl"
          style="
            position: relative;
            width: 100%;
            height: 100%;
            border: medium none;
          "
          src="../UnWeb/webgl/index.html"
        ></iframe>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

Gambar yang ditempel 20240527115228
Gambar yang ditempel 20240527115718

hasil berjalan

7. Halaman web memanggil metode Unity

  • Temukan lokasi yang ditandai dengan kotak merah pada kode di bawah ini
    Gambar yang ditempel 20240527121614
  • Ganti isi tag script dengan kode berikut (kodenya relatif sederhana dan ada komentarnya, jadi saya tidak akan menjelaskannya terlalu banyak)

Melihat:methodName Itu harus konsisten dengan nama metode di Unity, jika tidak, metode tersebut tidak akan ditemukan.

    // 获取DOM中id为"webgl"的iframe元素
    var unWebGL = document.getElementById("webgl");
    // 获取放大按钮
    var enlargeButton = document.getElementById("enlargeButton");
    // 获取缩小按钮
    var shrinkButton = document.getElementById("shrinkButton");
    // 获取信息按钮
    var infoButton = document.getElementById("infoButton");

    /**
     * Action函数用于向iframe内的WebGL应用发送指令。
     * @param {string} methodName - 要调用的方法名
     * @param {string} message - 要传递的消息(可选)
     */
    function Action(methodName, message) {
      // 获取嵌套的iframe元素
      var iframeB = document.getElementById("webgl");
      // 调用iframe内容窗口的ReceiveJSMethod方法,传递方法名和消息
      iframeB.contentWindow.ReceiveJSMethod(methodName, message);
    }

    // 为放大按钮添加点击事件监听器
    enlargeButton.addEventListener("click", function () {
      // 当按钮被点击时,调用Action函数,通知WebGL应用增大缩放
      Action("AddScale");
      // 可以在这里执行其他操作
    });

    // 为缩小按钮添加点击事件监听器
    shrinkButton.addEventListener("click", function () {
      // 当按钮被点击时,调用Action函数,通知WebGL应用减小缩放
      Action("SubtractScale");
    });

    // 为信息按钮添加点击事件监听器
    infoButton.addEventListener("click", function () {
      // 当按钮被点击时,调用Action函数,通知WebGL应用显示信息
      Action("SetTextInfo", "这是一条测试消息");
    });
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39

Gambar yang ditempel 20240527122058

  • Setelah menyelesaikan langkah di atas, gunakan IDE untuk membuka halaman web WebGL (file index.html pada gambar di bawah)
    Gambar yang ditempel 20240527142351
  • Temukan tag skrip dan temukan kode untuk menginisialisasi pemuat di bawah tag ini. Dan tambahkan kode di kotak merah.
    Gambar yang ditempel 20240527143058
var unityIns = null;
      script.src = loaderUrl;
      script.onload = () => {
        createUnityInstance(canvas, config, (progress) => {
          progressBarFull.style.width = 100 * progress + "%";
        })
          .then((unityInstance) => {
            unityIns = unityInstance;
            loadingBar.style.display = "none";
            fullscreenButton.onclick = () => {
              unityInstance.SetFullscreen(1);
            };
          })
          .catch((message) => {
            alert(message);
          });
      };
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • Buat kode untuk mengirim pesan ke Unity. Berikut kami jelaskan secara singkat apa yang digunakan dalam kode tersebut.SendMessageMetode Ini memungkinkan Anda memanggil metode tertentu pada objek game di adegan Unity Anda dari kode JavaScript.

Melihat:SendMessage Metode ini memiliki tiga parameter:
Nama objek target: Ini adalah nama objek permainan dalam adegan. Metode yang ingin Anda panggil ditentukan pada objek ini.
Nama Metode: Ini adalah nama metode yang ingin Anda panggil, ini harus berupa metode publik dalam skrip pada objek target.
Parameter: Ini adalah parameter yang ingin Anda sampaikan ke metode. Di SendMessage Unity, parameter ini hanya bisa bertipe string. Jika Anda perlu meneruskan data yang lebih kompleks, Anda mungkin perlu menggunakan mekanisme lain.

   /**
       * ReceiveJSMethod 函数用于接收来自网页的指令和消息,并将它们传递给 Unity 中的对象。
       * @param {string} methodName - 要调用的 Unity 对象的方法名
       * @param {string} message - 要传递给 Unity 对象的消息(可选)
       */
      function ReceiveJSMethod(methodName, message) {
        // 在控制台输出接收到的methodName和message,用于调试
        console.log(methodName, message);

        // 检查methodName是否不为null
        if (methodName != null) {
          // 如果message也不为null,则进行处理
          if (message != null) {
            // 将文本消息转换为base64编码
            var base64Str = btoa(
              encodeURIComponent(message).replace(
                /%([0-9A-F]{2})/g,
                function (match, p1) {
                  // 将百分比编码的序列转换回原始字符
                  return String.fromCharCode("0x" + p1);
                }
              )
            );
            // 使用Unity引擎的SendMessage方法,将methodName和base64编码的消息发送给名为"Cube"的Unity对象
            unityIns.SendMessage("Cube", methodName, base64Str);
          } else {
            // 如果没有message,只发送methodName给名为"Cube"的Unity对象
            unityIns.SendMessage("Cube", methodName);
          }
        }
      }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31

8. Akhir

Oke, itu saja untuk hari ini~
Jika bermanfaat bagi Anda, Anda dapat menyukai, mengikuti, dan mengumpulkannya. Jika Anda memiliki pertanyaan, sampai jumpa di area komentar~
Tidak mudah untuk menjadi orisinal. Jika Anda mencetak ulang, harap sebutkan sumbernya~