javascript - 使用 Firebase JS SDK 将 Unity WebGL 表单发布到 Cloud Firestore

标签 javascript firebase unity3d google-cloud-firestore unity-webgl

我的目标是在 Unity 中构建一个具有特定表单的 WebGL 游戏,并在提交该表单后将数据发布到 Firebase 存储解决方案之一。看完this article ,我很清楚我需要使用 Cloud Firestore 而不是实时数据库。好消息是,截至 2020 年 3 月,one of the team members wrote ,

we released Firebase Unity SDK 6.12.0 which includes an alpha release of Firestore.


问题是,Firebase 的 Unity SDK 不适用于 WebGL 构建,对于经历过这种思考过程的人来说,可以使用 Firebase JS SDK (垃圾邮件警报)。从查看 release notes ,可以看到 Firebase JS SDK 支持 Firestore,因此这具备了快速解决方案的所有条件。
所以,我去了 Firebase 控制台,创建了一个项目,一个使用 Firebase JS SDK 的 Web 应用程序,这个过程给出了以下代码作为输出
<!-- The core Firebase JS SDK is always required and must be listed first -->
<script src="https://www.gstatic.com/firebasejs/7.17.1/firebase-app.js"></script>

<!-- TODO: Add SDKs for Firebase products that you want to use
     https://firebase.google.com/docs/web/setup#available-libraries -->
<script src="https://www.gstatic.com/firebasejs/7.17.1/firebase-analytics.js"></script>

<script>
  // Your web app's Firebase configuration
  var firebaseConfig = {
    apiKey: "",
    authDomain: "",
    databaseURL: "",
    projectId: "",
    storageBucket: "",
    messagingSenderId: "",
    appId: "",
    measurementId: ""
  };
  // Initialize Firebase
  firebase.initializeApp(firebaseConfig);
  firebase.analytics();
</script>
留言说

Copy and paste these scripts into the bottom of your tag, but before you use any Firebase services


除此之外,这是how to Call JavaScript functions from Unity scripts这是一个Cloud Firestore JS Sample App .
鉴于此信息,如何创建表单?

最佳答案

假设您想要一个接收输入的表单

  • 字符串
  • 号码
  • 来自用户的文字

  • 在您的 Firestore 控制台中,创建一个集合并为其命名(如 formDataTree ),提供一个 autoID 并添加字段
  • 字符串
  • 整数
  • 网络验证

  • Cloud Firestore create collection
    然后,我会将这些脚本放在 WebGL template 中的 head 标签的底部。 .因此,在 Assets 中创建一个名为 的文件夹WebGL模板 , 和一个名为 New Template (或任何你想要的名字) 的文件夹并添加一个 index.html 那里。
    New WebGL Template in Unity
    根据文档,这个 index.html 应该类似于
    <!DOCTYPE html>
    <html lang="en-us">
    
      <head>
        <meta charset="utf-8">
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
        <title>Unity WebGL Player | %UNITY_WEB_NAME%</title>
        <script src="%UNITY_WEBGL_LOADER_URL%"></script>
        <script>
        var unityInstance = UnityLoader.instantiate("unityContainer", "%UNITY_WEBGL_BUILD_URL%");
        </script>
      </head>
      
      <body>
        <div id="unityContainer" style="width: %UNITY_WIDTH%px; height: %UNITY_HEIGHT%px; margin: auto"></div>
      </body>
      
    </html>
    
    所以,有了这些新信息,它会是这样的
    <!DOCTYPE html>
    <html lang="en-us">
    
      <head>
        <meta charset="utf-8">
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
        <title>Unity WebGL Player | %UNITY_WEB_NAME%</title>
        <script src="%UNITY_WEBGL_LOADER_URL%"></script>
        <script>
            var unityInstance = UnityLoader.instantiate("unityContainer", "%UNITY_WEBGL_BUILD_URL%");
        </script>
        <!-- The core Firebase JS SDK is always required and must be listed first -->
        <script src="https://www.gstatic.com/firebasejs/7.17.1/firebase-app.js"></script>
    
        <!-- TODO: Add SDKs for Firebase products that you want to use
             https://firebase.google.com/docs/web/setup#available-libraries -->
        <script src="https://www.gstatic.com/firebasejs/7.17.1/firebase-analytics.js"></script>
    
        <script>
          // Your web app's Firebase configuration
          var firebaseConfig = {
            apiKey: "",
            authDomain: "",
            databaseURL: "",
            projectId: "",
            storageBucket: "",
            messagingSenderId: "",
            appId: "",
            measurementId: ""
          };
          // Initialize Firebase
          firebase.initializeApp(firebaseConfig);
          firebase.analytics();
        </script>
      </head>
      
      <body>
        <div id="unityContainer" style="width: %UNITY_WIDTH%px; height: %UNITY_HEIGHT%px; margin: auto"></div>
      </body>
      
    </html>
    
    然后,在播放器设置下,选择该模板。
    Player WebGL Template
    然后在模板的正文中,有一个隐藏可见性的表单。包括游戏中的内容以及您想要在浏览器中填写的任何输入:
    <form id="webForm" style="visibility:hidden;">
        <input type="hidden" id="stringInput" name="stringInput">
        <input type="hidden" id="intInput" name="intInput">
        <label for="webInput">web input</label><input type="text" id="webInput" name="webInput">
        <button type="submit">Submit</button>
    </form>
    
    然后在 Firebase 脚本和表单下方,为页面上的表单添加一个提交监听器,将其提交到 Firestore(基于 this answer):
    myForm.addEventListener('submit', function(evt) {
      evt.preventDefault(); //Prevent the default form submit action
    
      var strVal = myForm.stringInput.value;
      var intVal = myForm.intInput.value;
      var webVal = intInput.webInput.value;
    
      var formData = {
        "strVal" : strVal,
        "intVal" : intVal,
        "webVal" : webVal
      };
    
      firebase.database().ref('/formDataTree').push( formData ); // Adds the new form data to the list under formDataTree node
    });
    
    总而言之, index.html 应该是这样的
    <!DOCTYPE html>
    <html lang="en-us">
      <head>
        <meta charset="utf-8">
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
        <title>Change Mapping | %UNITY_WEB_NAME%</title>
        <script src="%UNITY_WEBGL_LOADER_URL%"></script>
        <script>
            var unityInstance = UnityLoader.instantiate("unityContainer", "%UNITY_WEBGL_BUILD_URL%");
        </script>
        
        <!-- The core Firebase JS SDK is always required and must be listed first -->
        <script src="https://www.gstatic.com/firebasejs/7.17.1/firebase-app.js"></script>
    
        <!-- TODO: Add SDKs for Firebase products that you want to use
             https://firebase.google.com/docs/web/setup#available-libraries -->
        <script src="https://www.gstatic.com/firebasejs/7.17.1/firebase-analytics.js"></script>
    
        <script>
          // Your web app's Firebase configuration
          var firebaseConfig = {
            apiKey: "",
            authDomain: "",
            databaseURL: "",
            projectId: "",
            storageBucket: "",
            messagingSenderId: "",
            appId: "",
            measurementId: ""
          };
          // Initialize Firebase
          firebase.initializeApp(firebaseConfig);
          firebase.analytics();
        </script>
      </head>
      <body>
        <div style="height:20px; width: %UNITY_WIDTH%px; background: green;" onclick="unityInstance.SetFullscreen(1)"><b>Click here to make it full screen.</b></div>
        <div id="unityContainer" style="width: %UNITY_WIDTH%px; height: %UNITY_HEIGHT%px; margin: auto"></div>
        <form id="webForm" style="visibility:hidden;">
            <input type="hidden" id="stringInput" name="stringInput">
            <input type="hidden" id="intInput" name="intInput">
            <label for="webInput">web input</label><input type="text" id="webInput" name="webInput">
            <button type="submit">Submit</button>
        </form>
        <script>
            var myForm = document.getElementById("webForm");
            myForm.addEventListener('submit', function(evt) {
              evt.preventDefault(); //Prevent the default form submit action
    
              var strVal = myForm.stringInput.value;
              var intVal = myForm.intInput.value;
              var webVal = intInput.webInput.value;
    
              var formData = {
                "strVal" : strVal,
                "intVal" : intVal,
                "webVal" : webVal
              };
    
              firebase.database().ref('/formDataTree').push( formData ); // Adds the new form data to the list under formDataTree node
            });
        </script>
      </body>
    </html>
    
    在模板中使用 apiKey、authDomain 等意味着它会在检查页面或查看页面源时显示。然而,作为 mentioned here ,可以分享这些信息。
    然后,在您的 Assets 文件夹中,创建一个 插件 文件夹并添加一个.jslib文件,对于名为 的实例form.jslib ,它具有显示表单的功能,并将游戏数据放入表单的隐藏输入中。
    Plugins in Asset
    mergeInto(LibraryManager.library, {
      ShowWebForm: function (importantString, importantInt) {
        var myForm = document.getElementById("webForm");
    
        myForm.stringInput.value = Pointer_stringify(importantString);
        myForm.intInput.value = importantInt;
    
        myForm.style.visibility="visible"
       
      },
    });
    
    到此为止的步骤之后,如果您进入控制台 net::ERR_BLOCKED_BY_CLIENT ,只需将该站点的 AdBlocker 停用为 that's why you get that error .
    最后,在 Unity 中,声明该函数并在适当时调用它。因此,考虑到您有一个新创建的场景(因此它只有主摄像机和定向光),您可以在新场景中调用的一些代码中调用该方法。它是一种静态方法,因此只要您可以找到参数所需的数据,您就可以从任何地方调用它。
    [DllImport("__Internal")]
    private static extern void ShowWebForm(string importantString, int importantInt);
    
    public void Start()
    {
        // Suppose we want to send the version of unity the app is running on 
        // and the unix timestamp at start
        string unityVersion = Application.unityVersion;
    
        System.DateTime epochStart = new System.DateTime(1970, 1, 1, 0, 0, 0,  
                System.DateTimeKind.Utc);
        int cur_time = (int)(System.DateTime.UtcNow - epochStart).TotalSeconds;
    
        ShowWebForm(unityVersion, cur_time);
    }
    
    或者,如果您不想让用户在浏览器中填写内容,您可以让表单不可见,而不是将其设置为可见,而是发送一个提交事件:
    mergeInto(LibraryManager.library, {
      ShowWebForm: function (importantString, importantInt) {
        var myForm = document.getElementById("webForm");
    
        myForm.stringInput.value = Pointer_stringify(importantString);
        myForm.intInput.value = importantInt;
        myForm.webInput.value = "some other value from the game could go here";
    
        myForm.dispatchEvent(new Event('submit'));
      },
    });
    
    目前无法测试,因此请注意拼写错误或其他语法错误。

    关于javascript - 使用 Firebase JS SDK 将 Unity WebGL 表单发布到 Cloud Firestore,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63274431/

    相关文章:

    javascript - 如何在nodejs中重复执行

    javascript - Node Javascript 的这一行条件有什么问题?

    javascript - 无法使用 Canvas 读取 null 的属性 'getContext'

    c# - 更改启动屏幕/启动屏幕颜色和图像

    javascript - Jquery自动播放和自动播放下一首歌曲

    firebase - 如何让 firestore 在写入时创建嵌套对象作为子集合?

    Android: "Cannot Resolve symbol ' addValueEventListener'"在 Firebase 中

    android - 负载和通知如何在 Firestore 消息传递中工作

    c# - Unity,将立方体贴图保存为一个圆形图像

    c# - 当一切看起来都很好时,有条件的不起作用