我的目标是在 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 并添加字段
然后,我会将这些脚本放在 WebGL template 中的 head 标签的底部。 .因此,在 Assets 中创建一个名为 的文件夹WebGL模板 , 和一个名为 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 等意味着它会在检查页面或查看页面源时显示。然而,作为 mentioned here ,可以分享这些信息。然后,在您的 Assets 文件夹中,创建一个 插件 文件夹并添加一个
.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 停用为 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/