Partage de technologie

Unity WebGL intègre des pages Web frontales et communique

2024-07-12

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

1. Introduction

Récemment, lorsque je travaillais sur un projet, j'ai rencontré le besoin d'intégrer UnityWebGL dans une page Web, et UnityWebGL doit répondre lorsque vous cliquez sur un bouton de la page Web.Passer directement la nouvelle partie du projet

2. Effet final

webglRésultat.gif

3. Paramètres de base

  • Définir la plateforme d'exportation sur WebGL
    Image collée 20240527102413
  • Vérifiez les paramètres du lecteur -> Paramètres de publication Data Caching etDecompression Fallback Le lien ci-dessous est l'explication officielle.
    Data Caching Pour faire simple, les données sont mises en cache localement et la prochaine fois que vous l'ouvrirez, vous pourrez directement accéder au jeu sans téléchargement.
    Decompression Fallback S'il est impossible d'analyser les fichiers gz, si des erreurs de configuration du serveur Web, etc., vous devez cocher cette option.
    Unity - Manuel : Paramètres du lecteur WebGL (unity3d.com)
    Image collée 20240527102930

4. Écriture et exportation de code

  • La scène est configurée comme suit (vous pouvez créer des scènes selon vos propres besoins)
    Image collée 20240527110105
  • Partie code (monter le code sur le Cube créé)

Remarque : La méthode doit être publique sinon elle ne sera pas accessible

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
  • Exporter WebGL (attendez simplement la fin de l'exportation)
    Image collée 20240527110452

Si vous souhaitez parcourir les fichiers packagés localement, vous devez les télécharger. Firefox浏览器 , le téléchargement nécessite certains paramètres de configuration spécifiques.Ouvrir webgl dans Firefox_Ouvrir webgl dans Firefox-CSDN Blog

5. Exemple de page Web

Étant donné que certains amis ne savent peut-être pas comment rédiger des pages Web, l'auteur propose un modèle de page Web simple que tout le monde peut tester.

Mode d'emploi : Créez un nouveau fichier texte, collez-y le code suivant, enregistrez-le et modifiez le suffixe du fichier en.html
Image collée 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. Intégrer WebGL

  • Créez un dossier et placez le WebGL et les pages Web packagés dans le même dossier, comme indiqué ci-dessous (cette étape est principalement destinée à faciliter la gestion, vous n'avez pas besoin de le faire)
    Image collée 20240527114742
  • Utilisez l'EDI pour ouvrir la page Web et recherchez l'emplacement marqué par la case rouge dans le code ci-dessous.
    Image collée 20240527114359
  • Remplacez le contenu de la balise div par le code suivant. Si votre projet WebGL a été déployé sur le serveur, vous pouvez remplacer le contenu de la balise iframe par le code suivant.src Changez simplement le lien vers l’adresse du serveur. (Pour plus d'informations sur l'iframe, veuillez vous référer àCadre HTML (w3school.com.cn)) enregistrer et utiliserFirefox浏览器Ouvrez une page Web et les projets déployés sur le serveur peuvent être ouverts avec n'importe quel navigateur prenant en charge 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

Image collée 20240527115228
Image collée 20240527115718

résultat en cours d'exécution

7. La page Web appelle la méthode Unity

  • Trouvez l'emplacement marqué par la case rouge dans le code ci-dessous
    Image collée 20240527121614
  • Remplacez le contenu de la balise script par le code suivant (le code est relativement simple et comporte des commentaires, donc je ne vais pas trop l'expliquer)

Avis:methodName Il doit être cohérent avec le nom de la méthode dans Unity, sinon la méthode ne sera pas trouvée.

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

Image collée 20240527122058

  • Après avoir terminé les étapes ci-dessus, utilisez l'IDE pour ouvrir la page Web WebGL (fichier index.html dans l'image ci-dessous)
    Image collée 20240527142351
  • Recherchez la balise de script et recherchez le code pour initialiser le chargeur sous cette balise. Et ajoutez le code dans la case rouge.
    Image collée 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
  • Créez le code pour envoyer des messages à Unity. Ici, nous expliquons brièvement ce qui est utilisé dans le code.SendMessageMéthodes Cela vous permet d'appeler des méthodes spécifiques sur des objets de jeu dans votre scène Unity à partir du code JavaScript.

Avis:SendMessage La méthode comporte trois paramètres :
Nom de l'objet cible : C'est le nom de l'objet du jeu dans la scène. La méthode que vous souhaitez appeler est définie sur cet objet.
Nom de la méthode : il s'agit du nom de la méthode que vous souhaitez appeler, il doit s'agir d'une méthode publique dans le script sur l'objet cible.
Paramètres : ce sont les paramètres que vous souhaitez transmettre à la méthode. Dans SendMessage de Unity, ce paramètre ne peut être que de type chaîne. Si vous devez transmettre des données plus complexes, vous devrez peut-être utiliser d'autres mécanismes.

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

Ok, c'est tout pour aujourd'hui~
Si cela vous est utile, vous pouvez l'aimer, le suivre et le récupérer. Si vous avez des questions, rendez-vous dans la zone de commentaires~.
Ce n'est pas facile d'être original. Si vous réimprimez, veuillez indiquer la source. Merci à tous~.