Compartir tecnología

Unity WebGL incorpora páginas web front-end y se comunica

2024-07-12

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

1. Introducción

Recientemente, mientras trabajaba en un proyecto, encontré la necesidad de incrustar UnityWebGL en una página web, y UnityWebGL necesita responder al hacer clic en un botón en la página web.Saltar la nueva parte del proyecto directamente

2. Efecto final

webglResult.gif

3. Configuraciones básicas

  • Configure la plataforma de exportación en WebGL
    Imagen pegada 20240527102413
  • Verifique la configuración del reproductor -> Configuración de publicación Data Caching yDecompression Fallback El siguiente enlace es la explicación oficial.
    Data Caching En pocas palabras, los datos se almacenan en caché localmente y la próxima vez que los abras, podrás ingresar directamente al juego sin descargarlos.
    Decompression Fallback Si no se pueden analizar archivos gz, errores de configuración del servidor web, etc., debe marcar esta opción.
    Unity - Manual: Configuración del reproductor WebGL (unity3d.com)
    Imagen pegada 20240527102930

4. Escritura y exportación de código.

  • La escena está configurada de la siguiente manera (puedes crear escenas según tus propias necesidades)
    Imagen pegada 20240527110105
  • Parte del código (montar el código en el cubo creado)

Nota: El método debe ser público, de lo contrario no será accesible.

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
  • Exportar WebGL (solo espere a que se complete la exportación)
    Imagen pegada 20240527110452

Si desea explorar los archivos empaquetados localmente, debe descargarlos. Firefox浏览器 , la descarga requiere algunos parámetros de configuración específicos.Abrir webgl en Firefox_Abrir webgl en Firefox-CSDN Blog

5. Página web de muestra

Teniendo en cuenta que es posible que algunos amigos no sepan cómo escribir páginas web, el autor proporciona una plantilla de página web sencilla para que todos la prueben.

Instrucciones de uso: cree un nuevo archivo de texto, pegue el siguiente código en él, guárdelo y cambie el sufijo del archivo a.html
Imagen pegada 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. Incrustar WebGL

  • Cree una carpeta y coloque el WebGL empaquetado y las páginas web en la misma carpeta, como se muestra a continuación (este paso es principalmente para facilitar la administración, no es necesario que lo haga)
    Imagen pegada 20240527114742
  • Utilice el IDE para abrir la página web y busque la ubicación marcada por el cuadro rojo en el código siguiente.
    Imagen pegada 20240527114359
  • Reemplace el contenido de la etiqueta div con el siguiente código. Si su proyecto WebGL se ha implementado en el servidor, puede reemplazar el contenido de la etiqueta iframe con el siguiente código.src Simplemente cambie el enlace a la dirección del servidor. (Para obtener información sobre iframe, consulteMarco HTML (w3school.com.cn)) guardar y usarFirefox浏览器Abra una página web y los proyectos que se hayan implementado en el servidor se podrán abrir con cualquier navegador que admita 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

Imagen pegada 20240527115228
Imagen pegada 20240527115718

resultado de ejecución

7. La página web llama al método Unity

  • Encuentre la ubicación marcada por el cuadro rojo en el código a continuación
    Imagen pegada 20240527121614
  • Reemplace el contenido de la etiqueta del script con el siguiente código (el código es relativamente simple y tiene comentarios, así que no lo explicaré demasiado)

Aviso:methodName Debe ser coherente con el nombre del método en Unity; de lo contrario, no se encontrará el método.

    // 获取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

Imagen pegada 20240527122058

  • Después de completar los pasos anteriores, use el IDE para abrir la página web WebGL (archivo index.html en la imagen a continuación)
    Imagen pegada 20240527142351
  • Busque la etiqueta del script y busque el código para inicializar el cargador bajo esta etiqueta. Y agregue el código en el cuadro rojo.
    Imagen pegada 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
  • Crea el código para enviar mensajes a Unity. Aquí explicamos brevemente lo que se utiliza en el código.SendMessageMétodos Esto te permite llamar a métodos específicos en objetos del juego en tu escena de Unity desde código JavaScript.

Aviso:SendMessage El método tiene tres parámetros:
Nombre del objeto de destino: este es el nombre del objeto del juego en la escena. El método que desea llamar está definido en este objeto.
Nombre del método: este es el nombre del método que desea llamar; debe ser un método público en el script del objeto de destino.
Parámetros: estos son los parámetros que desea pasar al método. En SendMessage de Unity, este parámetro solo puede ser de tipo cadena. Si necesita pasar datos más complejos, es posible que necesite utilizar otros mecanismos.

   /**
       * 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. Fin

Bien, eso es todo por hoy ~
Si te resulta útil, puedes darle me gusta, seguirlo y recopilarlo. Si tienes alguna pregunta, nos vemos en el área de comentarios ~.
No es fácil ser original. Si reimprime, indique la fuente. Gracias a todos ~.