Unity WebGL 可编辑配置文件
Unity WebGL editable configuration file
如何让Unity WebGL项目读取一种配置文件(任何格式),在Unity工作区"Build"后可编辑。
下面是Build目录的示例,里面有打包后的文件
用例是让此 WebGL 项目使用的后端 API 在托管服务器上 可配置 ,这样当 player/user浏览它,它知道在哪里连接到后端 API.
我目前可以探索的最接近的部分是实现自定义 Javascript browser scripting。任何建议或任何现有的 API 都可以从 Unity 使用吗?
针对此问题选择的解决方案的更新。使用了Javascript browser scripting方法。
总共要创建 3 个文件:
WebConfigurationManager.cs
- 将其放在资产文件夹中。此文件是 C# 代码的主要入口,它决定从何处获取 Web 配置,或者通过来自另一个 C# 的默认值 class (使用统一编辑器时) ,或使用浏览器脚本方法检索 (同时通过浏览器浏览分发版本).
WebConfigurationManager.jslib
- 将其放在与
WebConfigurationManager.cs
相同的文件夹中。此文件为javascript代码,由浏览器加载。
web-config.json
- 您的 JSON 配置。 Web 配置文件可以托管在任何地方,下面的示例放置在分发构建文件夹的根目录下,您必须知道在哪里加载文件,例如
https://<website>/web-config.json
.
// WebConfigurationManager.cs
using System;
using UnityEngine;
using System.Runtime.InteropServices;
using AOT;
public class ConfigurationManager : MonoBehaviour
{
#if UNITY_WEBGL && !UNITY_EDITOR
// Load the web-config.json from the browser, and result will be passed via EnvironmentConfigurationCallback
public delegate void EnvironmentConfigurationCallback(System.IntPtr ptr);
[DllImport("__Internal")]
private static extern void GetEnvironmentConfiguration(EnvironmentConfigurationCallback callback);
void Start()
{
GetEnvironmentConfiguration(Callback);
}
[MonoPInvokeCallback(typeof(EnvironmentConfigurationCallback))]
public static void Callback(System.IntPtr ptr)
{
string value = Marshal.PtrToStringAuto(ptr);
try
{
var webConfig = JsonUtility.FromJson<MainConfig>(value);
// webConfig contains the value loaded from web-config.json. MainConfig is the data model class of your configuration.
}
catch (Exception e)
{
Debug.LogError($"Failed to read configuration. {e.Message}");
}
}
#else
void Start()
{
GetEnvironmentConfiguration();
}
private void GetEnvironmentConfiguration()
{
// do nothing on unity editor other than triggering the initialized event
// mock the configuration for the use of Unity editor
var testConfig = JsonUtility.FromJson<MainConfig>("{\n" +
" \"apiEndpoint\": \"ws://1.1.1.1:30080/events\",\n" +
" \"updateInterval\": 5\n" +
"}");
Debug.Log(testConfig.apiEndpoint);
Debug.Log(testConfig.updateInterval);
}
#endif
}
// WebConfigurationManager.jslib
mergeInto(LibraryManager.library, {
GetEnvironmentConfiguration: function (obj) {
function getPtrFromString(str) {
var buffer = _malloc(lengthBytesUTF8(str) + 1);
writeStringToMemory(str, buffer);
return buffer;
}
var request = new XMLHttpRequest();
// load the web-config.json via web request
request.open("GET", "./web-config.json", true);
request.onreadystatechange = function () {
if (request.readyState === 4 && request.status === 200) {
var buffer = getPtrFromString(request.responseText);
Runtime.dynCall('vi', obj, [buffer]);
}
};
request.send();
}
});
如何让Unity WebGL项目读取一种配置文件(任何格式),在Unity工作区"Build"后可编辑。
下面是Build目录的示例,里面有打包后的文件
用例是让此 WebGL 项目使用的后端 API 在托管服务器上 可配置 ,这样当 player/user浏览它,它知道在哪里连接到后端 API.
我目前可以探索的最接近的部分是实现自定义 Javascript browser scripting。任何建议或任何现有的 API 都可以从 Unity 使用吗?
针对此问题选择的解决方案的更新。使用了Javascript browser scripting方法。
总共要创建 3 个文件:
WebConfigurationManager.cs
- 将其放在资产文件夹中。此文件是 C# 代码的主要入口,它决定从何处获取 Web 配置,或者通过来自另一个 C# 的默认值 class (使用统一编辑器时) ,或使用浏览器脚本方法检索 (同时通过浏览器浏览分发版本).
WebConfigurationManager.jslib
- 将其放在与
WebConfigurationManager.cs
相同的文件夹中。此文件为javascript代码,由浏览器加载。
- 将其放在与
web-config.json
- 您的 JSON 配置。 Web 配置文件可以托管在任何地方,下面的示例放置在分发构建文件夹的根目录下,您必须知道在哪里加载文件,例如
https://<website>/web-config.json
.
- 您的 JSON 配置。 Web 配置文件可以托管在任何地方,下面的示例放置在分发构建文件夹的根目录下,您必须知道在哪里加载文件,例如
// WebConfigurationManager.cs
using System;
using UnityEngine;
using System.Runtime.InteropServices;
using AOT;
public class ConfigurationManager : MonoBehaviour
{
#if UNITY_WEBGL && !UNITY_EDITOR
// Load the web-config.json from the browser, and result will be passed via EnvironmentConfigurationCallback
public delegate void EnvironmentConfigurationCallback(System.IntPtr ptr);
[DllImport("__Internal")]
private static extern void GetEnvironmentConfiguration(EnvironmentConfigurationCallback callback);
void Start()
{
GetEnvironmentConfiguration(Callback);
}
[MonoPInvokeCallback(typeof(EnvironmentConfigurationCallback))]
public static void Callback(System.IntPtr ptr)
{
string value = Marshal.PtrToStringAuto(ptr);
try
{
var webConfig = JsonUtility.FromJson<MainConfig>(value);
// webConfig contains the value loaded from web-config.json. MainConfig is the data model class of your configuration.
}
catch (Exception e)
{
Debug.LogError($"Failed to read configuration. {e.Message}");
}
}
#else
void Start()
{
GetEnvironmentConfiguration();
}
private void GetEnvironmentConfiguration()
{
// do nothing on unity editor other than triggering the initialized event
// mock the configuration for the use of Unity editor
var testConfig = JsonUtility.FromJson<MainConfig>("{\n" +
" \"apiEndpoint\": \"ws://1.1.1.1:30080/events\",\n" +
" \"updateInterval\": 5\n" +
"}");
Debug.Log(testConfig.apiEndpoint);
Debug.Log(testConfig.updateInterval);
}
#endif
}
// WebConfigurationManager.jslib
mergeInto(LibraryManager.library, {
GetEnvironmentConfiguration: function (obj) {
function getPtrFromString(str) {
var buffer = _malloc(lengthBytesUTF8(str) + 1);
writeStringToMemory(str, buffer);
return buffer;
}
var request = new XMLHttpRequest();
// load the web-config.json via web request
request.open("GET", "./web-config.json", true);
request.onreadystatechange = function () {
if (request.readyState === 4 && request.status === 200) {
var buffer = getPtrFromString(request.responseText);
Runtime.dynCall('vi', obj, [buffer]);
}
};
request.send();
}
});