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

问题描述 投票:0回答:1

我的目标是在 Unity 中构建一个具有特定形式的 WebGL 游戏,并在提交时将表单将数据发布到其中一个 Firebase 存储解决方案中。阅读这篇文章后,我很清楚我需要使用 Cloud Firestore 而不是实时数据库。好消息是,截至 2020 年 3 月,一位团队成员写道,

我们发布了 Firebase Unity SDK 6.12.0,其中包括一个 alpha 版本 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>

留言说

将这些脚本复制并粘贴到标签底部,但是 在您使用任何 Firebase 服务之前

除此之外,这是 如何从 Unity 脚本调用 JavaScript 函数,这是一个 Cloud Firestore JS 示例应用程序

根据这些信息,如何创建表格?

javascript firebase unity3d google-cloud-platform google-cloud-firestore
1个回答
2
投票

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

  • 字符串
  • 数字
  • 来自用户的文字

在您的 Firestore 控制台中,创建一个集合并为其命名(例如 formDataTree),提供一个自动 ID 并添加字段

  • strVal
  • intVal
  • 网络价值

然后,我会将这些脚本放在您的 WebGL 模板中 head 标签的底部。因此,在 Assets 中创建一个名为 WebGLTemplates 的文件夹,以及一个名为 New Template(或任何您喜欢的名称)的文件夹,并在其中添加一个 index.html

根据文档,这个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>

然后,在播放器设置下,选择该模板。

然后在模板的正文中,有一个隐藏可见性的表单。包括游戏中的内容以及您想要在浏览器中填写的任何输入:

<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 等意味着它将在检查页面或查看页面源时显示为。然而,正如提到的,分享这些信息是可以的。

然后,在您的Assets文件夹中,创建一个Plugins文件夹并向其中添加一个

.jslib
文件,例如名为form.jslib的实例,它具有显示表单的功能,并将游戏数据放入表单的隐藏输入。

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,因为这就是您收到该错误的原因.

最后,在 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'));
  },
});

目前无法测试,因此请注意拼写错误或其他语法错误。

© www.soinside.com 2019 - 2024. All rights reserved.