Auto-publish.

This commit is contained in:
nebulaliu 2025-06-19 15:41:14 +08:00
parent 207766f6db
commit 53fb63dd14
230 changed files with 10093 additions and 4640 deletions

View File

@ -6,7 +6,7 @@ Removed - 删除功能/接口
Fixed - 修复问题
Others - 其他
-->
## v0.1.26 【普通更新
## v0.1.26 【预发布
### Feature
* 普通:增加禁止多点触控的配置
### Fixed

Binary file not shown.

View File

@ -0,0 +1,82 @@
fileFormatVersion: 2
guid: be799b1631d688242995c11c94a5b318
PluginImporter:
externalObjects: {}
serializedVersion: 2
iconMap: {}
executionOrder: {}
defineConstraints: []
isPreloaded: 0
isOverridable: 1
isExplicitlyReferenced: 0
validateReferences: 1
platformData:
- first:
: Any
second:
enabled: 0
settings:
Exclude Android: 1
Exclude Editor: 0
Exclude Linux64: 1
Exclude OSXUniversal: 1
Exclude WebGL: 1
Exclude Win: 1
Exclude Win64: 1
Exclude WindowsStoreApps: 1
- first:
Android: Android
second:
enabled: 0
settings:
CPU: ARMv7
- first:
Any:
second:
enabled: 0
settings: {}
- first:
Editor: Editor
second:
enabled: 1
settings:
CPU: x86_64
DefaultValueInitialized: true
OS: Windows
- first:
Standalone: Linux64
second:
enabled: 0
settings:
CPU: AnyCPU
- first:
Standalone: OSXUniversal
second:
enabled: 0
settings:
CPU: None
- first:
Standalone: Win
second:
enabled: 0
settings:
CPU: x86
- first:
Standalone: Win64
second:
enabled: 0
settings:
CPU: x86_64
- first:
Windows Store Apps: WindowsStoreApps
second:
enabled: 0
settings:
CPU: AnyCPU
DontProcess: false
PlaceholderPath:
SDK: AnySDK
ScriptingBackend: AnyScriptingBackend
userData:
assetBundleName:
assetBundleVariant:

View File

@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: a3d25085461954ccf96b870bbabd2d51
guid: 5c4133172957c4ff58904dc589712f66
folderAsset: yes
DefaultImporter:
externalObjects: {}

View File

@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: 72db98ce23892438085944429a2f0f1e
guid: 688f385fb02274584bc0da25fc717541
DefaultImporter:
externalObjects: {}
userData:

View File

@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: 0786375919a5f4b39a2842d398bab691
guid: 7f21f78b4cc234191b76cd464483218a
TextScriptImporter:
externalObjects: {}
userData:

View File

@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: e49d6d9d90710412390e04f36c283269
guid: e2d1865a2511c490fade16ba4a1cb98d
folderAsset: yes
DefaultImporter:
externalObjects: {}

View File

@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: a687be9fecc0c4635a0198f4c84c5a7a
guid: 87afef55b8ecb4102a02702ac98a8c08
TextScriptImporter:
externalObjects: {}
userData:

View File

@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: 59195b600f5474a34ab0de959545786a
guid: 15b1d1d2687c240e79f3326305a8e34d
DefaultImporter:
externalObjects: {}
userData:

View File

@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: 945d329c042b5422590297f9a668573b
guid: f2f9e284d496f4f0da239b534fc0962e
DefaultImporter:
externalObjects: {}
userData:

View File

@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: 5c728f27cb29c4a7ab957bec87aee79b
guid: c36b18db4fca44e7999111a49563794c
DefaultImporter:
externalObjects: {}
userData:

View File

@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: e116238b593ee4f118e080fc2e1be1d0
guid: 18049f8d0a7b340e089d8f6a56329852
TextScriptImporter:
externalObjects: {}
userData:

View File

@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: 95f171f78f3854726ba37852e7da8ace
guid: 717be45d5d44c471e96a22dbcd2aaddd
TextScriptImporter:
externalObjects: {}
userData:

8
Editor/Playable.meta Normal file
View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: b9ade20e13f604b10b5328d9cbdeafbe
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,138 @@
using System;
using System.IO;
using UnityEditor;
using UnityEngine;
namespace WeChatWASM
{
public class WXPlayableConvertCore
{
static WXPlayableConvertCore() { }
public static WXPlayableEditorScriptObject config => UnityUtil.GetPlayableEditorConf();
public static WXConvertCore.WXExportError DoExport(bool buildWebGL = true)
{
WXConvertCore.isPlayableBuild = true;
// var preCheckResult = WXConvertCore.PreCheck();
// if (preCheckResult != WXConvertCore.WXExportError.SUCCEED)
// {
// WXConvertCore.isPlayableBuild = false;
// return preCheckResult;
// }
// WXConvertCore.PreInit();
var exportResult = WXConvertCore.DoExport();
WXConvertCore.isPlayableBuild = false;
return exportResult;
}
public static WXEditorScriptObject GetFakeScriptObject()
{
return SetDefaultProperties(ConvertPlayableConfigToCommon(config));
}
public static WXEditorScriptObject ConvertPlayableConfigToCommon(
WXPlayableEditorScriptObject source,
WXEditorScriptObject target = null)
{
// 创建或使用现有的目标实例
var newTarget = target ?? ScriptableObject.CreateInstance<WXEditorScriptObject>();
// 使用序列化方式深度拷贝公共字段
var so = new SerializedObject(newTarget);
// 遍历源对象的所有字段
var sourceType = source.GetType();
foreach (var sourceField in sourceType.GetFields(
System.Reflection.BindingFlags.Public |
System.Reflection.BindingFlags.Instance |
System.Reflection.BindingFlags.NonPublic))
{
// 跳过readonly字段
if (sourceField.IsInitOnly) continue;
// 查找目标对象中的对应字段
var targetField = typeof(WXEditorScriptObject).GetField(
sourceField.Name,
System.Reflection.BindingFlags.Public |
System.Reflection.BindingFlags.Instance |
System.Reflection.BindingFlags.NonPublic);
// if (targetField != null && !targetField.FieldType.IsValueType && !targetField.FieldType.IsEnum)
// {
// // // 复制字段值
// // var value = sourceField.GetValue(source);
// // targetField.SetValue(newTarget, value);
// // 递归复制子对象属性
// var subObj = targetField.GetValue(newTarget) ?? Activator.CreateInstance(targetField.FieldType);
// CopySubObjectProperties(value, subObj);
// targetField.SetValue(newTarget, subObj);
// }
// if (targetField != null &&
// (targetField.FieldType.IsAssignableFrom(sourceField.FieldType) ||
// (targetField.FieldType.IsValueType && sourceField.FieldType.IsValueType &&
// targetField.FieldType == sourceField.FieldType)))
// {
// 复制字段值
var value = sourceField.GetValue(source);
// 特殊处理嵌套对象类型的字段
if (value != null && !targetField.FieldType.IsValueType && !targetField.FieldType.IsEnum)
{
// 递归复制子对象属性
var subObj = targetField.GetValue(newTarget) ?? Activator.CreateInstance(targetField.FieldType);
CopySubObjectProperties(value, subObj);
targetField.SetValue(newTarget, subObj);
}
else
{
targetField.SetValue(newTarget, value);
}
// }
}
// 应用修改到序列化对象
so.ApplyModifiedProperties();
return newTarget;
}
private static void CopySubObjectProperties(object source, object target)
{
var sourceType = source.GetType();
var targetType = target.GetType();
foreach (var sourceField in sourceType.GetFields(
System.Reflection.BindingFlags.Public |
System.Reflection.BindingFlags.Instance |
System.Reflection.BindingFlags.NonPublic))
{
if (sourceField.IsInitOnly) continue;
var targetField = targetType.GetField(
sourceField.Name,
System.Reflection.BindingFlags.Public |
System.Reflection.BindingFlags.Instance |
System.Reflection.BindingFlags.NonPublic);
if (targetField != null &&
(targetField.FieldType.IsAssignableFrom(sourceField.FieldType) ||
(targetField.FieldType.IsValueType && sourceField.FieldType.IsValueType &&
targetField.FieldType == sourceField.FieldType)))
{
var value = sourceField.GetValue(source);
targetField.SetValue(target, value);
}
}
}
public static WXEditorScriptObject SetDefaultProperties(WXEditorScriptObject target)
{
target.ProjectConf.CDN = "";
target.ProjectConf.assetLoadType = 1;
target.ProjectConf.compressDataPackage = true;
target.CompileOptions.showMonitorSuggestModal = false;
return target;
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: ad34d0bbab40b445689701c63f86cf16
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,363 @@
using System;
using System.Collections.Generic;
using System.IO;
using UnityEditor;
using UnityEngine;
namespace WeChatWASM
{
[InitializeOnLoad]
public class WXPlayableSettingsHelperInterface
{
public static WXPlayableSettingsHelper helper = new WXPlayableSettingsHelper();
}
public class WXPlayableSettingsHelper
{
public static string projectRootPath;
private static WXPlayableEditorScriptObject config;
private static bool m_EnablePerfTool = false;
private static string _dstCache;
public static bool UseIL2CPP
{
get
{
#if TUANJIE_2022_3_OR_NEWER
return PlayerSettings.GetScriptingBackend(BuildTargetGroup.WeixinMiniGame) == ScriptingImplementation.IL2CPP;
#else
return true;
#endif
}
}
public WXPlayableSettingsHelper()
{
projectRootPath = System.IO.Path.GetFullPath(Application.dataPath + "/../");
_dstCache = "";
}
public void OnFocus()
{
loadData();
}
public void OnLostFocus()
{
saveData();
}
public void OnDisable()
{
EditorUtility.SetDirty(config);
}
private Vector2 scrollRoot;
private bool foldBaseInfo = true;
private bool foldDebugOptions = true;
public void OnSettingsGUI(EditorWindow window)
{
scrollRoot = EditorGUILayout.BeginScrollView(scrollRoot);
GUIStyle linkStyle = new GUIStyle(GUI.skin.label);
linkStyle.normal.textColor = Color.yellow;
linkStyle.hover.textColor = Color.yellow;
linkStyle.stretchWidth = false;
linkStyle.alignment = TextAnchor.UpperLeft;
linkStyle.wordWrap = true;
foldBaseInfo = EditorGUILayout.Foldout(foldBaseInfo, "基本信息");
if (foldBaseInfo)
{
EditorGUILayout.BeginVertical("frameBox", GUILayout.ExpandWidth(true));
this.formInput("appid", "小游戏试玩AppID");
this.formInput("projectName", "小游戏试玩项目名");
this.formIntPopup("orientation", "游戏方向", new[] { "Portrait", "Landscape" }, new[] { 0, 1, 2, 3 });
this.formInput("memorySize", "UnityHeap预留内存(?)", "单位MB预分配内存值超休闲游戏256/中轻度496/重度游戏768需预估游戏最大UnityHeap值以防止内存自动扩容带来的峰值尖刺。预估方法请查看GIT文档《优化Unity WebGL的内存》");
GUILayout.BeginHorizontal();
string targetDst = "dst";
if (!formInputData.ContainsKey(targetDst))
{
formInputData[targetDst] = "";
}
EditorGUILayout.LabelField(string.Empty, GUILayout.Width(10));
GUILayout.Label(new GUIContent("导出路径(?)", "支持输入相对于项目根目录的相对路径wxbuild"), GUILayout.Width(140));
formInputData[targetDst] = GUILayout.TextField(formInputData[targetDst], GUILayout.MaxWidth(EditorGUIUtility.currentViewWidth - 270));
if (GUILayout.Button(new GUIContent("打开"), GUILayout.Width(40)))
{
if (!formInputData[targetDst].Trim().Equals(string.Empty))
{
EditorUtility.RevealInFinder(GetAbsolutePath(formInputData[targetDst]));
}
GUIUtility.ExitGUI();
}
if (GUILayout.Button(new GUIContent("选择"), GUILayout.Width(40)))
{
var dstPath = EditorUtility.SaveFolderPanel("选择你的游戏导出目录", string.Empty, string.Empty);
if (dstPath != string.Empty)
{
formInputData[targetDst] = dstPath;
this.saveData();
}
GUIUtility.ExitGUI();
}
GUILayout.EndHorizontal();
EditorGUILayout.EndVertical();
}
foldDebugOptions = EditorGUILayout.Foldout(foldDebugOptions, "调试编译选项");
if (foldDebugOptions)
{
EditorGUILayout.BeginVertical("frameBox", GUILayout.ExpandWidth(true));
this.formCheckbox("developBuild", "Development Build", "", false, null, OnDevelopmentBuildToggleChanged);
this.formCheckbox("il2CppOptimizeSize", "Il2Cpp Optimize Size(?)", "对应于Il2CppCodeGeneration选项勾选时使用OptimizeSize(默认推荐)生成代码小15%左右取消勾选则使用OptimizeSpeed。游戏中大量泛型集合的高频访问建议OptimizeSpeed在使用HybridCLR等第三方组件时只能用OptimizeSpeed。(Dotnet Runtime模式下该选项无效)", !UseIL2CPP);
this.formCheckbox("profilingFuncs", "Profiling Funcs");
this.formCheckbox("webgl2", "WebGL2.0(beta)");
EditorGUILayout.EndVertical();
}
EditorGUILayout.EndScrollView();
}
public void OnBuildButtonGUI(EditorWindow window)
{
GUIStyle linkStyle = new GUIStyle(GUI.skin.label);
linkStyle.normal.textColor = Color.yellow;
linkStyle.hover.textColor = Color.yellow;
linkStyle.stretchWidth = false;
linkStyle.alignment = TextAnchor.UpperLeft;
linkStyle.wordWrap = true;
EditorGUILayout.BeginHorizontal();
EditorGUILayout.LabelField(string.Empty, GUILayout.MinWidth(10));
if (GUILayout.Button(new GUIContent("生成并转换"), GUILayout.Width(100), GUILayout.Height(25)))
{
this.saveData();
if (WXPlayableConvertCore.DoExport() == WXConvertCore.WXExportError.SUCCEED)
{
window.ShowNotification(new GUIContent("转换完成"));
}
GUIUtility.ExitGUI();
}
EditorGUILayout.EndHorizontal();
}
private void OnDevelopmentBuildToggleChanged(bool InNewValue)
{
// 针对non-dev build取消性能分析工具的集成
if (!InNewValue)
{
this.setData("enablePerfAnalysis", false);
}
}
private string SDKFilePath;
private void loadData()
{
SDKFilePath = Path.Combine(UnityUtil.GetWxSDKRootPath(), "Runtime", "wechat-playable-default", "unity-sdk", "index.js");
config = UnityUtil.GetPlayableEditorConf();
_dstCache = config.ProjectConf.DST;
this.setData("projectName", config.ProjectConf.projectName);
this.setData("appid", config.ProjectConf.Appid);
this.setData("orientation", (int)config.ProjectConf.Orientation);
this.setData("dst", _dstCache);
this.setData("developBuild", config.CompileOptions.DevelopBuild);
this.setData("il2CppOptimizeSize", config.CompileOptions.Il2CppOptimizeSize);
this.setData("profilingFuncs", config.CompileOptions.profilingFuncs);
this.setData("webgl2", config.CompileOptions.Webgl2);
this.setData("customNodePath", config.CompileOptions.CustomNodePath);
this.setData("memorySize", config.ProjectConf.MemorySize.ToString());
}
private void saveData()
{
config.ProjectConf.projectName = this.getDataInput("projectName");
config.ProjectConf.Appid = this.getDataInput("appid");
config.ProjectConf.Orientation = (WXScreenOritation)this.getDataPop("orientation");
_dstCache = this.getDataInput("dst");
config.ProjectConf.DST = GetAbsolutePath(_dstCache);
config.CompileOptions.DevelopBuild = this.getDataCheckbox("developBuild");
config.CompileOptions.Il2CppOptimizeSize = this.getDataCheckbox("il2CppOptimizeSize");
config.CompileOptions.profilingFuncs = this.getDataCheckbox("profilingFuncs");
config.CompileOptions.CustomNodePath = this.getDataInput("customNodePath");
config.CompileOptions.Webgl2 = this.getDataCheckbox("webgl2");
config.ProjectConf.MemorySize = int.Parse(this.getDataInput("memorySize"));
}
private Dictionary<string, string> formInputData = new Dictionary<string, string>();
private Dictionary<string, int> formIntPopupData = new Dictionary<string, int>();
private Dictionary<string, bool> formCheckboxData = new Dictionary<string, bool>();
private string getDataInput(string target)
{
if (this.formInputData.ContainsKey(target))
return this.formInputData[target];
return "";
}
private int getDataPop(string target)
{
if (this.formIntPopupData.ContainsKey(target))
return this.formIntPopupData[target];
return 0;
}
private bool getDataCheckbox(string target)
{
if (this.formCheckboxData.ContainsKey(target))
return this.formCheckboxData[target];
return false;
}
private void formCheckbox(string target, string label, string help = null, bool disable = false, Action<bool> setting = null, Action<bool> onValueChanged = null)
{
if (!formCheckboxData.ContainsKey(target))
{
formCheckboxData[target] = false;
}
GUILayout.BeginHorizontal();
EditorGUILayout.LabelField(string.Empty, GUILayout.Width(10));
if (help == null)
{
GUILayout.Label(label, GUILayout.Width(140));
}
else
{
GUILayout.Label(new GUIContent(label, help), GUILayout.Width(140));
}
EditorGUI.BeginDisabledGroup(disable);
// Toggle the checkbox value based on the disable condition
bool newValue = EditorGUILayout.Toggle(disable ? false : formCheckboxData[target]);
// Update the checkbox data if the value has changed and invoke the onValueChanged action
if (newValue != formCheckboxData[target])
{
formCheckboxData[target] = newValue;
onValueChanged?.Invoke(newValue);
}
if (setting != null)
{
EditorGUILayout.LabelField("", GUILayout.Width(10));
// 配置按钮
if (GUILayout.Button(new GUIContent("设置"), GUILayout.Width(40), GUILayout.Height(18)))
{
setting?.Invoke(true);
}
EditorGUILayout.LabelField("", GUILayout.MinWidth(10));
}
EditorGUI.EndDisabledGroup();
if (setting == null)
EditorGUILayout.LabelField(string.Empty);
GUILayout.EndHorizontal();
}
private void setData(string target, string value)
{
if (formInputData.ContainsKey(target))
{
formInputData[target] = value;
}
else
{
formInputData.Add(target, value);
}
}
private void setData(string target, bool value)
{
if (formCheckboxData.ContainsKey(target))
{
formCheckboxData[target] = value;
}
else
{
formCheckboxData.Add(target, value);
}
}
private void setData(string target, int value)
{
if (formIntPopupData.ContainsKey(target))
{
formIntPopupData[target] = value;
}
else
{
formIntPopupData.Add(target, value);
}
}
private void formInput(string target, string label, string help = null)
{
if (!formInputData.ContainsKey(target))
{
formInputData[target] = "";
}
GUILayout.BeginHorizontal();
EditorGUILayout.LabelField(string.Empty, GUILayout.Width(10));
if (help == null)
{
GUILayout.Label(label, GUILayout.Width(140));
}
else
{
GUILayout.Label(new GUIContent(label, help), GUILayout.Width(140));
}
formInputData[target] = GUILayout.TextField(formInputData[target], GUILayout.MaxWidth(EditorGUIUtility.currentViewWidth - 195));
GUILayout.EndHorizontal();
}
private void formIntPopup(string target, string label, string[] options, int[] values)
{
if (!formIntPopupData.ContainsKey(target))
{
formIntPopupData[target] = 0;
}
GUILayout.BeginHorizontal();
EditorGUILayout.LabelField(string.Empty, GUILayout.Width(10));
GUILayout.Label(label, GUILayout.Width(140));
formIntPopupData[target] = EditorGUILayout.IntPopup(formIntPopupData[target], options, values, GUILayout.MaxWidth(EditorGUIUtility.currentViewWidth - 195));
GUILayout.EndHorizontal();
}
public static bool IsAbsolutePath(string path)
{
// 检查是否为空或空白
if (string.IsNullOrWhiteSpace(path))
{
return false;
}
// 在 Windows 上,检查驱动器字母或网络路径
if (Application.platform == RuntimePlatform.WindowsEditor && Path.IsPathRooted(path))
{
return true;
}
// 在 Unix/Linux 和 macOS 上,检查是否以 '/' 开头
if (Application.platform == RuntimePlatform.OSXEditor && path.StartsWith("/"))
{
return true;
}
return false; // 否则为相对路径
}
public static string GetAbsolutePath(string path)
{
if (IsAbsolutePath(path))
{
return path;
}
return Path.Combine(projectRootPath, path);
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 1cc549c674e5b4efe964933831f56e80
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,46 @@
using UnityEngine;
using UnityEditor;
using static WeChatWASM.WXConvertCore;
namespace WeChatWASM
{
public class WXPlayableWin : EditorWindow
{
[MenuItem("微信小游戏 / 转换小游戏试玩", false, 2)]
public static void Open()
{
var win = GetWindow(typeof(WXPlayableWin), false, "微信小游戏试玩转换工具面板");
win.minSize = new Vector2(350, 400);
win.position = new Rect(200, 200, 600, 300);
win.Show();
}
// 向前兼容,请使用 WXConvertCore.cs
public static WXExportError DoExport(bool buildWebGL = true)
{
return WXPlayableConvertCore.DoExport(buildWebGL);
}
public void OnFocus()
{
WXPlayableSettingsHelperInterface.helper.OnFocus();
}
public void OnLostFocus()
{
WXPlayableSettingsHelperInterface.helper.OnLostFocus();
}
public void OnDisable()
{
WXPlayableSettingsHelperInterface.helper.OnDisable();
}
public void OnGUI()
{
WXPlayableSettingsHelperInterface.helper.OnSettingsGUI(this);
WXPlayableSettingsHelperInterface.helper.OnBuildButtonGUI(this);
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: f37c59ed5d1a64bf59ac4657b5fd2cd8
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -71,7 +71,9 @@ namespace WeChatWASM
BUILD_WEBGL_FAILED = 2,
}
public static WXEditorScriptObject config => UnityUtil.GetEditorConf();
public static WXEditorScriptObject config => isPlayableBuild ? WXPlayableConvertCore.GetFakeScriptObject() : UnityUtil.GetEditorConf();
public static string defaultTemplateDir => isPlayableBuild ? "playable-default" : "wechat-default";
public static string webglDir = "webgl"; // 导出的webgl目录
public static string miniGameDir = "minigame"; // 生成小游戏的目录
public static string audioDir = "Assets"; // 音频资源目录
@ -80,6 +82,10 @@ namespace WeChatWASM
public static string codeMd5 = string.Empty;
public static string dataMd5 = string.Empty;
public static string defaultImgSrc = "Assets/WX-WASM-SDK-V2/Runtime/wechat-default/images/background.jpg";
/// <summary>
/// 是否在构建试玩,构建开始前修改值,构建结束后恢复值
/// </summary>
public static bool isPlayableBuild = false;
private static bool lastBrotliType = false;
public static bool UseIL2CPP
@ -93,37 +99,66 @@ namespace WeChatWASM
#endif
}
}
// 可以调用这个来集成
public static WXExportError DoExport(bool buildWebGL = true)
// public static void SetPlayableEnabled(bool enabled)
// {
// isPlayableBuild = enabled;
// }
/// <summary>
/// 导出前的初始配置
/// 小游戏模式和试玩模式都会使用这个函数,如果要在这个函数加新方法,建议都以不兼容试玩模式看待
/// </summary>
public static void PreInit()
{
LifeCycleEvent.Init();
Emit(LifeCycle.beforeExport);
if (!CheckSDK())
{
Debug.LogError("若游戏曾使用旧版本微信SDK需删除 Assets/WX-WASM-SDK 文件夹后再导入最新工具包。");
return WXExportError.BUILD_WEBGL_FAILED;
}
if (!CheckBuildTemplate())
{
Debug.LogError("因构建模板检查失败终止导出。");
return WXExportError.BUILD_WEBGL_FAILED;
}
if (CheckInvalidPerfIntegration())
{
Debug.LogError("性能分析工具只能用于Development Build, 终止导出! ");
return WXExportError.BUILD_WEBGL_FAILED;
}
CheckBuildTarget();
Init();
ProcessWxPerfBinaries();
// 可能有顺序要求?如果没要求,可挪到此函数外
if (!isPlayableBuild) {
ProcessWxPerfBinaries();
}
MakeEnvForLuaAdaptor();
// JSLib
SettingWXTextureMinJSLib();
UpdateGraphicAPI();
EditorUtility.SetDirty(config);
AssetDatabase.SaveAssets();
}
public static WXExportError PreCheck()
{
if (!CheckSDK())
{
Debug.LogError("若游戏曾使用旧版本微信SDK需删除 Assets/WX-WASM-SDK 文件夹后再导入最新工具包。");
return WXExportError.BUILD_WEBGL_FAILED;
}
if (!isPlayableBuild && !CheckBuildTemplate())
{
Debug.LogError("因构建模板检查失败终止导出。");
return WXExportError.BUILD_WEBGL_FAILED;
}
if (!isPlayableBuild && CheckInvalidPerfIntegration())
{
Debug.LogError("性能分析工具只能用于Development Build, 终止导出!");
return WXExportError.BUILD_WEBGL_FAILED;
}
dynamic config = isPlayableBuild ? UnityUtil.GetPlayableEditorConf() : UnityUtil.GetEditorConf();
if (config.ProjectConf.DST == string.Empty)
{
Debug.LogError("请先配置游戏导出路径");
return WXExportError.BUILD_WEBGL_FAILED;
}
return WXExportError.SUCCEED;
}
// 可以调用这个来集成
public static WXExportError DoExport(bool buildWebGL = true)
{
LifeCycleEvent.Init();
Emit(LifeCycle.beforeExport);
var preCheckResult = PreCheck();
if (preCheckResult != WXExportError.SUCCEED)
{
return preCheckResult;
}
PreInit();
// 记录上次导出的brotliType
{
@ -141,12 +176,6 @@ namespace WeChatWASM
}
}
if (config.ProjectConf.DST == string.Empty)
{
Debug.LogError("请先配置游戏导出路径");
return WXExportError.BUILD_WEBGL_FAILED;
}
else
{
// 仅删除StreamingAssets目录
if (config.CompileOptions.DeleteStreamingAssets)
@ -566,7 +595,7 @@ namespace WeChatWASM
private static bool CheckBuildTemplate()
{
string[] res = BuildTemplate.CheckCustomCoverBaseConflict(
Path.Combine(UnityUtil.GetWxSDKRootPath(), "Runtime", "wechat-default"),
Path.Combine(UnityUtil.GetWxSDKRootPath(), "Runtime", defaultTemplateDir),
Path.Combine(Application.dataPath, "WX-WASM-SDK-V2", "Editor", "template"),
new string[] { @"\.(js|ts|json)$" }
);
@ -801,7 +830,12 @@ namespace WeChatWASM
PlayerSettings.WeixinMiniGame.emscriptenArgs = string.Empty;
if (WXExtEnvDef.GETDEF("UNITY_2021_2_OR_NEWER"))
{
PlayerSettings.WeixinMiniGame.emscriptenArgs += " -s EXPORTED_FUNCTIONS=_main,_sbrk,_emscripten_stack_get_base,_emscripten_stack_get_end -s ERROR_ON_UNDEFINED_SYMBOLS=0";
PlayerSettings.WeixinMiniGame.emscriptenArgs += " -s EXPORTED_FUNCTIONS=_main,_sbrk,_emscripten_stack_get_base,_emscripten_stack_get_end";
if (config.CompileOptions.enablePerfAnalysis)
{
PlayerSettings.WeixinMiniGame.emscriptenArgs += ",_WxPerfFrameIntervalCallback";
}
PlayerSettings.WeixinMiniGame.emscriptenArgs += " -s ERROR_ON_UNDEFINED_SYMBOLS=0";
}
#else
@ -809,6 +843,10 @@ namespace WeChatWASM
if (WXExtEnvDef.GETDEF("UNITY_2021_2_OR_NEWER"))
{
PlayerSettings.WebGL.emscriptenArgs += " -s EXPORTED_FUNCTIONS=_sbrk,_emscripten_stack_get_base,_emscripten_stack_get_end";
if (config.CompileOptions.enablePerfAnalysis)
{
PlayerSettings.WebGL.emscriptenArgs += ",_WxPerfFrameIntervalCallback";
}
#if UNITY_2021_2_5
PlayerSettings.WebGL.emscriptenArgs += ",_main";
#endif
@ -1156,7 +1194,9 @@ namespace WeChatWASM
public static void convertDataPackageJS()
{
checkNeedRmovePackageParallelPreload();
if (!isPlayableBuild) {
checkNeedRmovePackageParallelPreload();
}
var loadDataFromCdn = config.ProjectConf.assetLoadType == 0;
Rule[] rules =
@ -1275,9 +1315,10 @@ namespace WeChatWASM
RemoveOldAssetPackage(Path.Combine(config.ProjectConf.DST, webglDir));
RemoveOldAssetPackage(Path.Combine(config.ProjectConf.DST, webglDir + "-min"));
var buildTemplate = new BuildTemplate(
Path.Combine(UnityUtil.GetWxSDKRootPath(), "Runtime", "wechat-default"),
Path.Combine(UnityUtil.GetWxSDKRootPath(), "Runtime", defaultTemplateDir),
Path.Combine(Application.dataPath, "WX-WASM-SDK-V2", "Editor", "template"),
Path.Combine(config.ProjectConf.DST, miniGameDir)
Path.Combine(config.ProjectConf.DST, miniGameDir),
true
);
buildTemplate.start();
// FIX: 2021.2版本生成symbol有bug导出时生成symbol报错有symbol才copy
@ -1285,12 +1326,15 @@ namespace WeChatWASM
if (File.Exists(symbolPath))
{
File.Copy(symbolPath, Path.Combine(config.ProjectConf.DST, miniGameDir, "webgl.wasm.symbols.unityweb"), true);
// gen symbols.br
Brotlib("webgl.wasm.symbols.unityweb.br", symbolPath, Path.Combine(config.ProjectConf.DST, miniGameDir, "webgl.wasm.symbols.unityweb.br"));
}
var info = new FileInfo(dataPath);
dataFileSize = info.Length.ToString();
UnityEngine.Debug.LogFormat("[Converter] that to genarate md5 and copy files ended");
if (config.ProjectConf.Appid == "wx7c792ca878775717") // 快适配小游戏示例
// 若APPID为快适配小游戏示例则插入预览盒子
if (config.ProjectConf.Appid == "wx7c792ca878775717")
{
InsertPreviewCode();
}
@ -1399,14 +1443,9 @@ namespace WeChatWASM
" } else {\n" +
" this._send = GameGlobal.Module.SendMessage;\n" +
" }",
},
new Rule()
{
old = "3.5.1", // project.config.json 转换插件 hardcode
newStr = "latest",
}
};
string[] files = { "game.js", "game.json", "unity-sdk/module-helper.js", "project.config.json" };
string[] files = { "game.js", "game.json", "unity-sdk/module-helper.js" };
ReplaceFileContent(files, rules);
Debug.LogWarning("[WeChat Preview] InsertPreviewCode End");
}
@ -1508,7 +1547,8 @@ namespace WeChatWASM
writer.PrettyPrint = true;
// 将 game.json 里面关系链相关的配置删除
if (!config.SDKOptions.UseFriendRelation)
// 试玩 game.json 中不含其他配置
if (!config.SDKOptions.UseFriendRelation && gameJson.ContainsKey("openDataContext") && gameJson.ContainsKey("plugins"))
{
gameJson.Remove("openDataContext");
gameJson["plugins"].Remove("Layout");
@ -1519,7 +1559,7 @@ namespace WeChatWASM
Directory.Delete(openDataDir, true);
}
if (!config.SDKOptions.UseMiniGameChat)
if (!config.SDKOptions.UseMiniGameChat && gameJson.ContainsKey("plugins"))
{
gameJson["plugins"].Remove("MiniGameChat");
UnityEngine.Debug.Log(gameJson["plugins"]);
@ -1606,17 +1646,19 @@ namespace WeChatWASM
{
dst = Path.Combine(config.ProjectConf.DST, miniGameDir);
}
string content = File.ReadAllText(Path.Combine(UnityUtil.GetWxSDKRootPath(), "Runtime", "wechat-default", "unity-sdk", "index.js"), Encoding.UTF8);
string content = File.ReadAllText(Path.Combine(UnityUtil.GetWxSDKRootPath(), "Runtime", defaultTemplateDir, "unity-sdk", "index.js"), Encoding.UTF8);
content = content.Replace("$unityVersion$", Application.unityVersion);
File.WriteAllText(Path.Combine(dst, "unity-sdk", "index.js"), content, Encoding.UTF8);
// content = File.ReadAllText(Path.Combine(Application.dataPath, "WX-WASM-SDK-V2", "Runtime", "wechat-default", "unity-sdk", "storage.js"), Encoding.UTF8);
content = File.ReadAllText(Path.Combine(UnityUtil.GetWxSDKRootPath(), "Runtime", "wechat-default", "unity-sdk", "storage.js"), Encoding.UTF8);
var PreLoadKeys = config.PlayerPrefsKeys.Count > 0 ? JsonMapper.ToJson(config.PlayerPrefsKeys) : "[]";
content = content.Replace("'$PreLoadKeys'", PreLoadKeys);
File.WriteAllText(Path.Combine(dst, "unity-sdk", "storage.js"), content, Encoding.UTF8);
if (!isPlayableBuild) {
content = File.ReadAllText(Path.Combine(UnityUtil.GetWxSDKRootPath(), "Runtime", defaultTemplateDir, "unity-sdk", "storage.js"), Encoding.UTF8);
var PreLoadKeys = config.PlayerPrefsKeys.Count > 0 ? JsonMapper.ToJson(config.PlayerPrefsKeys) : "[]";
content = content.Replace("'$PreLoadKeys'", PreLoadKeys);
File.WriteAllText(Path.Combine(dst, "unity-sdk", "storage.js"), content, Encoding.UTF8);
}
// 修改纹理dxt
// content = File.ReadAllText(Path.Combine(Application.dataPath, "WX-WASM-SDK-V2", "Runtime", "wechat-default", "unity-sdk", "texture.js"), Encoding.UTF8);
content = File.ReadAllText(Path.Combine(UnityUtil.GetWxSDKRootPath(), "Runtime", "wechat-default", "unity-sdk", "texture.js"), Encoding.UTF8);
content = File.ReadAllText(Path.Combine(UnityUtil.GetWxSDKRootPath(), "Runtime", defaultTemplateDir, "unity-sdk", "texture.js"), Encoding.UTF8);
File.WriteAllText(Path.Combine(dst, "unity-sdk", "texture.js"), content, Encoding.UTF8);
}
@ -1833,14 +1875,15 @@ namespace WeChatWASM
UnityEngine.Debug.LogFormat("[Converter] Starting to modify configs");
var PRELOAD_LIST = GetPreloadList(config.ProjectConf.preloadFiles);
var imgSrc = HandleLoadingImage();
// 试玩不存在封面图
var imgSrc = isPlayableBuild ? "" : HandleLoadingImage();
var bundlePathIdentifierStr = GetArrayString(config.ProjectConf.bundlePathIdentifier);
var excludeFileExtensionsStr = GetArrayString(config.ProjectConf.bundleExcludeExtensions);
var screenOrientation = new List<string>() { "portrait", "landscape", "landscapeLeft", "landscapeRight" }[(int)config.ProjectConf.Orientation];
var customUnicodeRange = GetCustomUnicodeRange(config.FontOptions.CustomUnicode);
// 试玩不支持系统字体
var customUnicodeRange = isPlayableBuild ? "[]" : GetCustomUnicodeRange(config.FontOptions.CustomUnicode);
Debug.Log("[Converter] customUnicodeRange: " + customUnicodeRange);
var boolConfigInfo = GenerateBootInfo();
@ -1913,6 +1956,9 @@ namespace WeChatWASM
List<Rule> replaceList = new List<Rule>(replaceArrayList);
List<string> files = new List<string> { "game.js", "game.json", "project.config.json", "unity-namespace.js", "check-version.js", "unity-sdk/font/index.js" };
if (isPlayableBuild) {
files = new List<string> { "game.js", "game.json", "project.config.json", "unity-namespace.js", "check-version.js" };
}
if (WXRuntimeExtEnvDef.IsPreviewing)
{

View File

@ -2,7 +2,7 @@ namespace WeChatWASM
{
public class WXPluginVersion
{
public static string pluginVersion = "202505120809"; // 这一行不要改他,导出的时候会自动替换
public static string pluginVersion = "202506190740"; // 这一行不要改他,导出的时候会自动替换
}
public class WXPluginConf

Binary file not shown.

View File

@ -9,12 +9,17 @@
构建模板工具类
</summary>
</member>
<member name="F:WeChatWASM.BuildTemplate.ignoreUserTemplate">
<summary>
是否忽略用户自定义模板
</summary>
</member>
<member name="F:WeChatWASM.BuildTemplate.IgnoreRules">
<summary>
复制覆盖时不参与覆盖的正则表达式,可在 beforeCoverTemplate前动态修改
</summary>
</member>
<member name="M:WeChatWASM.BuildTemplate.CheckCustomCoverBaseConflict(System.String,System.String,System.String[])">
<member name="M:WeChatWASM.BuildTemplate.CheckCustomCoverBaseConflict(System.String,System.String,System.String[],System.Boolean)">
<summary>
防止自定义模板对覆盖基础模板有覆盖在新版本更新后有代码冲突需要做此检查
</summary>
@ -289,7 +294,7 @@
<member name="T:WeChatWASM.UnityUtil">
工具函数
</member>
<member name="M:WeChatWASM.UnityUtil.WxSDKEnvInit">
<member name="M:WeChatWASM.UnityUtil.WxSDKEnvInit(System.Boolean)">
<summary>
微信SDK环境初始化
</summary>
@ -758,5 +763,61 @@
字体配置
</summary>
</member>
<member name="F:WeChatWASM.WXPlayableProjectConf.projectName">
<summary>
试玩项目名
</summary>
</member>
<member name="F:WeChatWASM.WXPlayableProjectConf.Appid">
<summary>
试玩 appid
</summary>
</member>
<member name="F:WeChatWASM.WXPlayableProjectConf.DST">
<summary>
导出路径(绝对路径)
</summary>
</member>
<member name="F:WeChatWASM.WXPlayableProjectConf.MemorySize">
<summary>
游戏内存大小(MB)
</summary>
</member>
<member name="F:WeChatWASM.WXPlayableProjectConf.Orientation">
<summary>
游戏方向
</summary>
</member>
<member name="F:WeChatWASM.WXPlayableProjectConf.IOSDevicePixelRatio">
<summary>
IOS限制固定的分辨率以减少内存但是会降低游戏画面品质
注意不要随意修改默认值为00表示不限制
</summary>
</member>
<member name="F:WeChatWASM.PlayableCompileOptions.DevelopBuild">
<summary>
Development Build
</summary>
</member>
<member name="F:WeChatWASM.PlayableCompileOptions.Il2CppOptimizeSize">
<summary>
Il2CppCodeGeneration.OptimizeSize
</summary>
</member>
<member name="F:WeChatWASM.PlayableCompileOptions.profilingFuncs">
<summary>
Profiling Funcs
</summary>
</member>
<member name="F:WeChatWASM.PlayableCompileOptions.Webgl2">
<summary>
WebGL2.0
</summary>
</member>
<member name="F:WeChatWASM.PlayableCompileOptions.CustomNodePath">
<summary>
CustomNodePath
</summary>
</member>
</members>
</doc>

View File

@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: 69a894eefcf7a97830ad465e4668424b
guid: 9af1b953c27faa9e9cbba73925185e2f
DefaultImporter:
externalObjects: {}
userData:

View File

@ -0,0 +1,5 @@
mergeInto(LibraryManager.library, {
JSStartGameDataMonitor: function() {
GameGlobal.manager.startGameDataMonitor();
}
});

View File

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 63a9d4fa9c3846e3704029822b94973f
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -28,6 +28,22 @@ mergeInto(LibraryManager.library, {
GameGlobal.unityNamespace.ProfileWebgl.stopRecord();
}
},
JSProfilerUploadBinary: function(dataPtr, bufSize, namePtr, dirPtr, id, inStartFrameIdx, inEndFrameIdx) {
//if (GameGlobal && GameGlobal.manager && GameGlobal.manager.profiler) {
const name = UTF8ToString(namePtr);
const dir = UTF8ToString(dirPtr);
const content = HEAPU8.slice(dataPtr, dataPtr+bufSize);
GameGlobal.manager.profiler.uploadBinary({
'data': content,
'len': bufSize,
'fileName': name,
'uploadDir': dir,
'id': id,
'startFrameIndex': inStartFrameIdx,
'endFrameIndex': inEndFrameIdx
});
//}
},
JSProfilerUploadString: function(dataPtr, bufSize, namePtr, dirPtr, id, inStartFrameIdx, inEndFrameIdx) {
//if (GameGlobal && GameGlobal.manager && GameGlobal.manager.profiler) {
const name = UTF8ToString(namePtr);
@ -106,5 +122,12 @@ mergeInto(LibraryManager.library, {
stringToUTF8(GameGlobal.unityNamespace.convertPluginVersion, stringOnWasmHeap, lengthBytes);
return stringOnWasmHeap;
},
JSProfilerCanvasToFilepathSync: function(savePath) {
if (GameGlobal && GameGlobal.unityNamespace && GameGlobal.unityNamespace.ProfileWebgl && GameGlobal.unityNamespace.ProfileWebgl.stopRecord) {
const savePathJSStr = UTF8ToString(savePath);
GameGlobal.manager.profiler.canvasToFilepathSync(savePathJSStr);
}
}
});

Binary file not shown.

View File

@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: f0cbdcf50f6d52cea758f1ea825443c0
guid: ffcf22f69c45d4919a04626e60e86c20
PluginImporter:
externalObjects: {}
serializedVersion: 2
@ -7,68 +7,21 @@ PluginImporter:
executionOrder: {}
defineConstraints: []
isPreloaded: 0
isOverridable: 1
isOverridable: 0
isExplicitlyReferenced: 0
validateReferences: 1
platformData:
- first:
: Any
second:
enabled: 0
settings:
Exclude Editor: 0
Exclude Linux64: 1
Exclude OSXUniversal: 1
Exclude WebGL: 0
Exclude Win: 1
Exclude Win64: 1
- first:
Any:
second:
enabled: 0
enabled: 1
settings: {}
- first:
Editor: Editor
second:
enabled: 1
enabled: 0
settings:
CPU: AnyCPU
DefaultValueInitialized: true
OS: AnyOS
- first:
Standalone: Linux64
second:
enabled: 0
settings:
CPU: None
- first:
Standalone: OSXUniversal
second:
enabled: 0
settings:
CPU: None
- first:
Standalone: Win
second:
enabled: 0
settings:
CPU: None
- first:
Standalone: Win64
second:
enabled: 0
settings:
CPU: None
- first:
WebGL: WebGL
second:
enabled: 1
settings: {}
- first:
WeixinMiniGame: WeixinMiniGame
second:
enabled: 1
settings: {}
- first:
Windows Store Apps: WindowsStoreApps
second:

View File

@ -1,7 +1,7 @@
fileFormatVersion: 2
guid: 8ea3a597042b1e09596b698c5fcfd06b
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
guid: 94249136b4b39434dbb3ae3f5b41f47b
TextScriptImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

File diff suppressed because it is too large Load Diff

View File

@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: e804d8e7fcbdd8120297b31d43cba494
guid: c27f53d8c1fa5d4727053751650aac98
DefaultImporter:
externalObjects: {}
userData:

Binary file not shown.

File diff suppressed because it is too large Load Diff

View File

@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: f1ac621062d513597aaf96b982e6d32a
guid: 1aa8d6fc1d69228aafca53b646494d5e
DefaultImporter:
externalObjects: {}
userData:

Binary file not shown.

Binary file not shown.

View File

@ -648,6 +648,7 @@ namespace WeChatWASM
/// ## 注意事项
/// - 基础库 v2.10.4 开始支持获取群工具小程序启动信息
/// - 基础库 v2.17.3 开始支持获取群聊小程序消息卡片、群待办小程序启动信息
/// - 基础库 v3.7.8 支持获取单聊群启动信息,获取的群(含单聊)唯一标识,可用于[聊天工具模式](https://developers.weixin.qq.com/minigame/dev/api/chattool/wx.openChatTool.html)。
/// **示例代码**
/// ```js
/// wx.getGroupEnterInfo({
@ -667,7 +668,10 @@ namespace WeChatWASM
/// 获取得到的开放数据为以下 json 结构(其中 opengid 为当前群的唯一标识):
/// ```json
/// {
/// "opengid": "OPENGID"
/// "opengid": "OPENGID", // 多聊群下返回的群唯一标识
/// "open_single_roomid": "", // 单聊群下返回的群唯一标识
/// "group_openid": "", // 用户在当前群的唯一标识
/// "chat_type": 3, // 聊天室类型
/// }
/// ```
/// **Tips**
@ -1400,7 +1404,7 @@ namespace WeChatWASM
/// <summary>
/// [wx.openCustomerServiceConversation(Object object)](https://developers.weixin.qq.com/minigame/dev/api/open-api/customer-message/wx.openCustomerServiceConversation.html)
/// 需要基础库: `2.0.3`
/// 进入客服会话。要求在用户发生过至少一次 touch 事件后才能调用。后台接入方式与小程序一致,详见 [客服消息接入](#)
/// 进入客服会话。要求在用户发生过至少一次 touch 事件后才能调用。后台接入方式与小程序一致,详见 [客服消息接入](https://developers.weixin.qq.com/minigame/dev/guide/open-ability/customer-message/customer-message.html)
/// **注意事项**
/// - 在客服会话内点击小程序消息卡片进入小程序时,不能通过 wx.onShow 或 wx.getEnterOptionsSync 等接口获取启动路径和参数,而是应该通过 wx.openCustomerServiceConversation 接口的 success 回调获取启动路径和参数
/// </summary>
@ -2150,9 +2154,6 @@ namespace WeChatWASM
/// [wx.showShareImageMenu(Object object)](https://developers.weixin.qq.com/minigame/dev/api/share/wx.showShareImageMenu.html)
/// 需要基础库: `2.14.3`
/// 打开分享图片弹窗,可以将图片发送给朋友、收藏或下载
/// **Bug & Tip**
/// 1. `tip`: `needShowEntrance`分享的图片消息是否要带小程序入口,支持申明类目:商家自营、电商平台、餐饮服务(餐饮服务场所/餐饮服务管理企业、点餐平台、外卖平台)、旅游服务(住宿服务、景区服务、OTA、旅游管理单位)、生活服务(家政服务、丽人服务、宠物(非医院类)、婚庆服务、洗浴保健、休闲娱乐、百货/超市/便利店、开锁服务、营业性演出票务、其他宠物健康服务、洗浴保健平台、共享服务、跑腿、寄存、求职/招聘)
/// 2. `tip`: `needShowEntrance`小游戏所有类目都支持
/// </summary>
public static void ShowShareImageMenu(ShowShareImageMenuOption callback)
{
@ -4035,6 +4036,32 @@ namespace WeChatWASM
return WXSDKManagerHandler.Instance.GetLogManager(option);
}
/// <summary>
/// [[PageManager](https://developers.weixin.qq.com/minigame/dev/api/open-api/openlink/PageManager.html) wx.createPageManager()](https://developers.weixin.qq.com/minigame/dev/api/open-api/openlink/wx.createPageManager.html)
/// 需要基础库: `3.6.7`
/// 小游戏开放页面管理器用于启动微信内置的各种小游戏活动、功能页面。具体OPENLINK值由不同的能力渠道获得。
/// **示例代码**
/// ```js
/// const pageManager = wx.createPageManager();
/// pageManager.load({
/// openlink: 'xxxxxxx-xxxxxx', // 由不同渠道获得的OPENLINK值
/// }).then((res) => {
/// // 加载成功res 可能携带不同活动、功能返回的特殊回包信息(具体请参阅渠道说明)
/// console.log(res);
/// // 加载成功后按需显示
/// pageManager.show();
/// }).catch((err) => {
/// // 加载失败,请查阅 err 给出的错误信息
/// console.error(err);
/// })
/// ```
/// </summary>
/// <returns></returns>
public static WXPageManager CreatePageManager()
{
return WXSDKManagerHandler.Instance.CreatePageManager();
}
/// <summary>
/// [[RealtimeLogManager](https://developers.weixin.qq.com/minigame/dev/api/base/debug/RealtimeLogManager.html) wx.getRealtimeLogManager()](https://developers.weixin.qq.com/minigame/dev/api/base/debug/wx.getRealtimeLogManager.html)
/// 需要基础库: `2.14.4`

View File

@ -1117,6 +1117,16 @@ namespace WeChatWASM
{
WXSDKManagerHandler.Instance.ReserveChannelsLive(option);
}
#region
/// <summary>
/// 通知试玩结束
/// </summary>
/// <param name="option"></param>
public static void NotifyMiniProgramPlayableStatus(NotifyMiniProgramPlayableStatusOption option)
{
WXSDKManagerHandler.Instance.NotifyMiniProgramPlayableStatus(option);
}
#endregion
}
}
#endif

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 260b24feb18b7455485a7bd2ed1d0a07
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,164 @@
/* eslint-disable no-multi-assign */
/* eslint-disable @typescript-eslint/naming-convention */
const { version, SDKVersion } = wx.getAppBaseInfo ? wx.getAppBaseInfo() : wx.getSystemInfoSync();
const { platform, system } = wx.getDeviceInfo ? wx.getDeviceInfo() : wx.getSystemInfoSync();
const accountInfo = wx.getAccountInfoSync();
const envVersion = accountInfo?.miniProgram?.envVersion;
function compareVersion(v1, v2) {
if (!v1 || !v2) {
return false;
}
return (v1
.split('.')
.map(v => v.padStart(2, '0'))
.join('')
>= v2
.split('.')
.map(v => v.padStart(2, '0'))
.join(''));
}
export const isDebug = false;
export const isPc = platform === 'windows' || platform === 'mac';
export const isIOS = platform === 'ios';
export const isAndroid = platform === 'android';
export const isDevtools = platform === 'devtools';
export const isMobile = !isPc && !isDevtools;
export const isDevelop = envVersion === 'develop';
// 是否禁止**开通了高性能模式**的小游戏在不支持的iOS设备上回退成普通模式回退可能导致无法正常体验游戏
// @ts-ignore
const disableHighPerformanceFallback = $DISABLE_HIGHPERFORMANCE_FALLBACK && isIOS;
// 是否iOS高性能模式
export const isH5Renderer = GameGlobal.isIOSHighPerformanceMode;
// 操作系统版本号
const systemVersionArr = system ? system.split(' ') : [];
const systemVersion = systemVersionArr.length ? systemVersionArr[systemVersionArr.length - 1] : '';
// pc微信版本号不一致需要>=3.3
const isPcWeChatVersionValid = compareVersion(version, '3.3');
// 支持unity小游戏需要试玩基础库>=2.0.10
const isLibVersionValid = compareVersion(SDKVersion, '2.0.10');
// 如果是iOS高性能模式基础库需要>=2.0.10
const isH5LibVersionValid = compareVersion(SDKVersion, '2.0.10');
// 压缩纹理需要iOS系统版本>=14.0,检测到不支持压缩纹理时会提示升级系统
const isIOSH5SystemVersionValid = compareVersion(systemVersion, '14.0');
// iOS系统版本>=15支持webgl2高性能模式+无此系统要求
const isIOSWebgl2SystemVersionValid = compareVersion(systemVersion, '15.0') || GameGlobal.isIOSHighPerformanceModePlus;
// Android客户端版本>=8.0.19支持webgl2
const isAndroidWebGL2ClientVersionValid = compareVersion(version, '8.0.19');
// 是否用了webgl2
const isWebgl2 = () => GameGlobal.managerConfig.contextConfig.contextType === 2;
// 是否支持BufferURL
export const isSupportBufferURL = !isPc
&& (isH5Renderer
? compareVersion(SDKVersion, '2.0.10') && compareVersion(version, '8.0.30')
: typeof wx.createBufferURL === 'function');
// 安卓innerAudio支持playbackRate
export const isSupportPlayBackRate = !isAndroid || compareVersion(version, '8.0.23');
// IOS innerAudio支持复用时再次触发onCanplay
export const isSupportCacheAudio = !isIOS || compareVersion(version, '8.0.31');
// // 安卓旧客户端版本innerAudio偶现会导致闪退大于等于8.0.38才使用innerAudio减少内存
export const isSupportInnerAudio = compareVersion(version, '8.0.38');
// 检查是否支持brotli压缩pc基础库>=2.29.2,真机基础库>=2.21.1
// @ts-ignore
const isPcBrotliInvalid = isPc && !compareVersion(SDKVersion, $LOAD_DATA_FROM_SUBPACKAGE ? '2.29.2' : '2.32.3');
const isMobileBrotliInvalid = isMobile && !compareVersion(SDKVersion, '2.0.10');
// @ts-ignore
const isBrotliInvalid = $COMPRESS_DATA_PACKAGE && (isPcBrotliInvalid || isMobileBrotliInvalid);
// iOS系统版本>=17.5时,小游戏退后台会导致异常
export const isIOS175 = compareVersion(systemVersion, '17.5') && isH5Renderer;
// 试玩无开放数据域
export const isSupportSharedCanvasMode = false;
// 是否能以iOS高性能模式运行
// 请勿修改GameGlobal.canUseH5Renderer赋值
GameGlobal.canUseH5Renderer = isH5Renderer && isH5LibVersionValid;
// iOS高性能模式定期GC
GameGlobal.canUseiOSAutoGC = false;
// pc微信版本不满足要求
const isPcInvalid = isPc && !isPcWeChatVersionValid;
// 移动设备基础库版本或客户端版本不支持运行unity小游戏
const isMobileInvalid = isMobile && !isLibVersionValid;
// 基础库/客户端不支持iOS高性能模式
const isIOSH5Invalid = (isH5Renderer && !isH5LibVersionValid) || (!isH5Renderer && disableHighPerformanceFallback);
// 是否支持VideoPlayer组件注意开发者工具需要1.06.2310312以上版本
export const isSupportVideoPlayer = false;
// 视情况添加,没用到对应能力就不需要判断
// 是否支持webgl2
const isWebgl2SystemVersionInvalid = () => isWebgl2() && ((!isIOSWebgl2SystemVersionValid && isIOS) || (isAndroid && !isAndroidWebGL2ClientVersionValid));
// IOS高性能模式2.25.3以上基础库需要手动启动webAudio
export const webAudioNeedResume = false;
// 满足iOS高性能条件但未开通高性能模式
const needToastEnableHpMode = isDevelop && isIOS && isH5LibVersionValid && isIOSH5SystemVersionValid && !isH5Renderer;
/**
* 判断环境是否可使用coverview
* coverview实际需要基础库版本>=2.16.1但因为移动端要>=2.17.0才能运行所以移动端基本都支持coverview
*
* @export
* @returns
*/
export function canUseCoverview() {
return isMobile || isDevtools;
}
if (needToastEnableHpMode) {
console.error('此AppID未开通高性能模式\n请前往mp后台-能力地图-开发提效包-高性能模式开通\n可大幅提升游戏运行性能');
// setTimeout(() => {
// wx.showModal({
// title: '[开发版提示]建议',
// content: '此AppID未开通高性能模式\n请前往mp后台-能力地图-开发提效包-高性能模式开通\n可大幅提升游戏运行性能',
// showCancel: false,
// })
// }, 10000);
}
// @ts-ignore
if (isIOS && typeof $IOS_DEVICE_PIXEL_RATIO === 'number' && $IOS_DEVICE_PIXEL_RATIO > 0) {
// @ts-ignore
window.devicePixelRatio = $IOS_DEVICE_PIXEL_RATIO;
}
else if (isPc) {
try {
if (window.devicePixelRatio < 2) {
window.devicePixelRatio = 2;
}
}
catch (e) {
console.warn(e);
}
}
export default () => new Promise((resolve) => {
if (!isDevtools) {
if (isPcInvalid
|| isMobileInvalid
|| isIOSH5Invalid
|| isWebgl2SystemVersionInvalid()
|| isBrotliInvalid) {
let updateWechat = true;
let content = '当前微信版本过低\n请更新微信后进行游戏';
if (isIOS) {
if (!isIOSH5SystemVersionValid || (isWebgl2SystemVersionInvalid() && isIOS)) {
content = '当前操作系统版本过低\n请更新iOS系统后进行游戏';
updateWechat = false;
}
}
console.error('提示: ', content);
wx.showModal({
title: '提示',
content,
showCancel: false,
confirmText: updateWechat ? '更新微信' : '确定',
success(res) {
if (res.confirm) {
const showUpdateWechat = updateWechat && typeof wx.createBufferURL === 'function';
if (showUpdateWechat) {
wx.updateWeChatApp();
}
else {
wx.exitMiniProgram({
success: () => { },
});
}
}
},
});
return resolve(false);
}
}
return resolve(true);
});

View File

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 1042d428c715e7a6edaa2130bf753e8b
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: c86308d6578ff69e7c7713b33a4ec97a
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: df231d90a89e599be2497639bd337671
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,58 @@
const events = [];
const EventsManager = {
/**
* 注册一个事件并持续监听
* @param eventName 事件名称
* @param callback 事件的触发函数
*/
on(eventName, callback) {
events.push({
eventName,
callback,
once: false,
});
},
/**
* 注册一个事件并最多只触发一次
* @param eventName 事件名称
* @param callback 事件的触发函数
*/
once(eventName, callback) {
events.push({
eventName,
callback,
once: true,
});
},
/**
* 卸载一个事件
* @param eventName 事件名称
* @param callback 事件句柄若缺省将卸载所有同名事件
*/
off(eventName, callback) {
events.forEach((item, index) => {
if (item.eventName === eventName) {
if (!callback || item.callback === callback) {
events.splice(index, 1);
}
}
});
},
emit(eventName, ...args) {
const res = [];
const indexs = [];
events.forEach((item, index) => {
if (item.eventName === eventName) {
res.push(item.callback(...args));
if (item.once) {
indexs.unshift(index);
}
}
});
indexs.forEach((value) => {
events.splice(value, 1);
});
return res;
},
};
GameGlobal.events = EventsManager;

View File

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 34732b70a9216533b8e2642b007c6c19
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,187 @@
// @ts-nocheck
import './playable-fix';
import './weapp-adapter';
import './events';
import './texture-config';
import unityNamespace from './unity-namespace';
import '.$DOTNET_RUNTIME_FOLD/$GAME_NAME.wasm.framework.unityweb';
import './unity-sdk/index';
import checkVersion from './check-version';
import { launchEventType, scaleMode } from './plugin-config';
import UnityManager from './unity-playable-plugin/index';
const managerConfig = {
DATA_FILE_MD5: '$DATA_MD5',
CODE_FILE_MD5: '$CODE_MD5',
GAME_NAME: '$GAME_NAME',
APPID: '$APP_ID',
DATA_FILE_SIZE: '$DATA_FILE_SIZE',
OPT_DATA_FILE_SIZE: '$OPT_DATA_FILE_SIZE',
DATA_CDN: '$DEPLOY_URL',
// 资源包是否作为小游戏分包加载
loadDataPackageFromSubpackage: $LOAD_DATA_FROM_SUBPACKAGE,
// 资源包放小游戏分包加载时是否br压缩
compressDataPackage: $COMPRESS_DATA_PACKAGE,
// 需要在网络空闲时预加载的资源,支持如下形式的路径
preloadDataList: [
// 'DATA_CDN/StreamingAssets/WebGL/textures_8d265a9dfd6cb7669cdb8b726f0afb1e',
// '/WebGL/sounds_97cd953f8494c3375312e75a29c34fc2'
'$PRELOAD_LIST',
],
contextConfig: {
contextType: $WEBGL_VERSION, // 1: webgl1 2: webgl2
},
PROFILER_UPLOAD_URL: '',
};
GameGlobal.managerConfig = managerConfig;
// 版本检查
checkVersion().then((enable) => {
if (enable) {
// eslint-disable-next-line @typescript-eslint/naming-convention
// let UnityManager;
// try {
// // @ts-ignore
// UnityManager = requirePlugin('UnityPlugin', {
// enableRequireHostModule: true,
// customEnv: {
// wx,
// unityNamespace,
// document,
// canvas,
// events: GameGlobal.events,
// WXWASMSDK: GameGlobal.WXWASMSDK,
// },
// }).default;
// } catch (error) {
// GameGlobal.realtimeLogManager.error(error);
// // logManager不支持自动处理错误对象
// GameGlobal.logmanager.warn(error.stack);
// console.error('requirePlugin:', error);
// if (error.message.indexOf('not defined') !== -1) {
// console.error('!!!插件需要申请才可使用\n请勿使用测试AppID并登录 https://mp.weixin.qq.com/ 并前往:能力地图-开发提效包-快适配 开通\n阅读文档获取详情:https://github.com/wechat-miniprogram/minigame-unity-webgl-transform/blob/main/Design/Transform.md');
// }
// }
// JS堆栈能显示更完整
Error.stackTraceLimit = Infinity;
Object.assign(managerConfig, {
// callmain结束后立即隐藏封面视频
hideAfterCallmain: $HIDE_AFTER_CALLMAIN,
loadingPageConfig: {
// 以下是默认值
totalLaunchTime: 7000,
animationDuration: 100,
/**
* !!注意修改设计宽高和缩放模式后需要修改文字和进度条样式默认设计尺寸为667*375
*/
designWidth: 0,
designHeight: 0,
scaleMode: scaleMode.default,
// 以下配置的样式,尺寸相对设计宽高
textConfig: {
firstStartText: '首次加载请耐心等待',
downloadingText: ['正在加载资源'],
compilingText: '编译中',
initText: '初始化中',
completeText: '开始游戏',
textDuration: 1500,
// 文字样式
style: {
bottom: 64,
height: 24,
width: 240,
lineHeight: 24,
color: '#ffffff',
fontSize: 12,
},
},
// 进度条样式
barConfig: {
style: {
width: 240,
height: 24,
padding: 2,
bottom: 64,
backgroundColor: '#07C160',
},
},
// 一般不修改控制icon样式
iconConfig: {
visible: true,
style: {
width: 64,
height: 23,
bottom: 20,
},
},
// 加载页的素材配置
materialConfig: {
// 背景图或背景视频,两者都填时,先展示背景图,视频可播放后,播放视频
backgroundImage: '$BACKGROUND_IMAGE',
backgroundVideo: '$LOADING_VIDEO_URL',
iconImage: 'images/unity_logo.png', // icon图片一般不更换
},
},
});
GameGlobal.managerConfig = managerConfig;
// 显示启动封面
const gameManager = new UnityManager(managerConfig);
gameManager.onLaunchProgress((e) => {
// interface LaunchEvent {
// type: LaunchEventType;
// data: {
// costTimeMs: number; // 阶段耗时
// runTimeMs: number; // 总耗时
// loadDataPackageFromSubpackage: boolean; // 首包资源是否通过小游戏分包加载
// isVisible: boolean; // 当前是否处于前台onShow/onHide
// useCodeSplit: boolean; // 是否使用代码分包
// isHighPerformance: boolean; // 是否iOS高性能模式
// needDownloadDataPackage: boolean; // 本次启动是否需要下载资源包
// };
// }
if (e.type === launchEventType.launchPlugin) {
}
if (e.type === launchEventType.loadWasm) {
}
if (e.type === launchEventType.compileWasm) {
}
if (e.type === launchEventType.loadAssets) {
}
if (e.type === launchEventType.readAssets) {
}
if (e.type === launchEventType.prepareGame) {
}
});
gameManager.onModulePrepared(() => {
// eslint-disable-next-line no-restricted-syntax
for (const key in unityNamespace) {
// 动态修改DATA_CDN后同步修改全局对象
if (!GameGlobal.hasOwnProperty(key) || key === 'DATA_CDN') {
GameGlobal[key] = unityNamespace[key];
}
else {
}
}
managerConfig.DATA_CDN = GameGlobal.DATA_CDN;
gameManager.assetPath = `${(managerConfig.DATA_CDN || '').replace(/\/$/, '')}/Assets`;
});
// 插件捕获到引擎错误后,会通过此事件抛给游戏
gameManager.onLogError = function (err) {
GameGlobal.realtimeLogManager.error(err);
const isErrorObj = err && err.stack;
GameGlobal.logmanager.warn(isErrorObj ? err.stack : err);
};
// iOS高性能模式定期GC
if (GameGlobal.canUseiOSAutoGC && unityNamespace.iOSAutoGCInterval !== 0) {
setInterval(() => {
wx.triggerGC();
}, unityNamespace.iOSAutoGCInterval);
}
// 开始执行游戏启动流程
gameManager.startGame();
GameGlobal.manager = gameManager;
GameGlobal.events.on('launchOperaPushMsgToWasm', (callback, args) => GameGlobal.WXWASMSDK.WXLaunchOperaBridgeToC(callback, args));
// eslint-disable-next-line @typescript-eslint/no-unused-vars
GameGlobal.events.on('createWorker', (worker) => {
// worker created
});
}
});

View File

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 27bbc954b6c9acf0b5085697611ac63c
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,9 @@
{
"deviceOrientation": "$ORIENTATION",
"engine": {
"name": "unity"
},
"features": [
"api.fs.readCompressedFile"
]
}

View File

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 53318401508471b7ca5470d04a4ea4fb
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,42 @@
/* eslint-disable */
delete wx.getWindowInfo;
delete wx.getDeviceInfo;
delete wx.getAppBaseInfo;
wx.getPerformance = function () {
return {
now: function () {
return Date.now() * 1000;
},
};
};
wx.getRealtimeLogManager = function () {
return {
info: function (...args) {
console.log.apply(console, args);
},
warn: function (...args) {
console.warn.apply(console, args);
},
error: function (...args) {
console.error.apply(console, args);
},
setFilterMsg: function () { },
addFilterMsg: function () { },
};
};
wx.getLogManager = function () {
return {
info: function (...args) {
console.log.apply(console, args);
},
warn: function (...args) {
console.warn.apply(console, args);
},
log: function (...args) {
console.log.apply(console, args);
},
debug: function (...args) {
console.log.apply(console, args);
},
};
};

View File

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: ff36a5158a96c9e1f0a37a75c128405d
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,19 @@
export const launchEventType = {
launchPlugin: 0,
loadWasm: 1,
compileWasm: 2,
loadAssets: 3,
readAssets: 5,
prepareGame: 6, // 初始化引擎
};
// https://docs.egret.com/engine/docs/screenAdaptation/zoomMode
export const scaleMode = {
default: '',
noBorder: 'NO_BORDER',
exactFit: 'EXACT_FIT',
fixedHeight: 'FIXED_HEIGHT',
fixedWidth: 'FIXED_WIDTH',
showAll: 'SHOW_ALL',
fixedNarrow: 'FIXED_NARROW',
fixedWide: 'FIXED_WIDE',
};

View File

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 8dd9f1245b5e7a29fb9b4082b8c53e2a
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 5510926a39cec474f33c9eb89f71cee1
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,23 @@
function checkUpdate() {
const updateManager = wx.getUpdateManager();
updateManager.onCheckForUpdate(() => {
// 请求完新版本信息的回调
// console.log(res.hasUpdate)
});
updateManager.onUpdateReady(() => {
wx.showModal({
title: '更新提示',
content: '新版本已经准备好,是否重启应用?',
success(res) {
if (res.confirm) {
// 新的版本已经下载好,调用 applyUpdate 应用新版本并重启
updateManager.applyUpdate();
}
},
});
});
updateManager.onUpdateFailed(() => {
// 新版本下载失败
});
}
checkUpdate();

View File

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 789529e8f2a0743d1c48530bc088b27a
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,9 @@
wx.onWindowResize((res) => {
window.innerWidth = res.windowWidth;
window.innerHeight = res.windowHeight;
});
wx.onDeviceOrientationChange(() => {
const info = wx.getWindowInfo ? wx.getWindowInfo() : wx.getSystemInfoSync();
window.innerWidth = info.screenWidth;
window.innerHeight = info.screenHeight;
});

View File

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 3017be0d53b352511c47512d7e38fde8
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,71 @@
{
"description": "项目配置文件",
"setting": {
"urlCheck": false,
"es6": true,
"enhance": true,
"postcss": true,
"preloadBackgroundData": false,
"minified": true,
"newFeature": true,
"coverView": true,
"nodeModules": false,
"autoAudits": false,
"showShadowRootInWxmlPanel": true,
"scopeDataCheck": false,
"uglifyFileName": false,
"checkInvalidKey": true,
"checkSiteMap": true,
"uploadWithSourceMap": true,
"compileHotReLoad": false,
"useMultiFrameRuntime": true,
"useApiHook": false,
"disableUseStrict": false,
"babelSetting": {
"ignore": ["$GAME_NAME.wasm.framework.unityweb.js"],
"disablePlugins": [],
"outputPath": ""
},
"useIsolateContext": true,
"useCompilerModule": true,
"userConfirmedUseCompilerModuleSwitch": false,
"packNpmManually": false,
"packNpmRelationList": []
},
"compileType": "game",
"libVersion": "3.5.1",
"appid": "$APP_ID",
"projectname": "$PROJECT_NAME",
"simulatorType": "wechat",
"simulatorPluginLibVersion": {},
"packOptions": {
"ignore": [
{
"type": "folder",
"value": ".plugincache"
},
{
"type": "suffix",
"value": ".symbols.unityweb"
}
]
},
"condition": {
"search": {
"current": -1,
"list": []
},
"conversation": {
"current": -1,
"list": []
},
"game": {
"currentL": -1,
"list": []
},
"miniprogram": {
"current": -1,
"list": []
}
}
}

View File

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: b1f416b7624ca93d9c2ce1bf09aa9f3c
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,3 @@
GameGlobal.USED_TEXTURE_COMPRESSION = false;
GameGlobal.TEXTURE_PARALLEL_BUNDLE = false;
GameGlobal.TEXTURE_BUNDLES = '';

View File

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 59f836910cac5618583bd147de0ac5b2
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,194 @@
// @ts-nocheck
const unityNamespace = {
canvas: GameGlobal.canvas,
// cache width
canvas_width: GameGlobal.canvas.width,
// cache height
canvas_height: GameGlobal.canvas.height,
navigator: GameGlobal.navigator,
XMLHttpRequest: GameGlobal.XMLHttpRequest,
// 是否显示耗时的弹框,默认开发版时显示弹出耗时弹框
hideTimeLogModal: true,
// 是否打印详细日志
enableDebugLog: false,
// 自定义bundle中的hash长度
bundleHashLength: $BUNDLE_HASH_LENGTH,
// 单位Bytes, 1MB = 1024 KB = 1024*1024Bytes
releaseMemorySize: $DEFAULT_RELEASE_SIZE,
unityVersion: '$UNITY_VERSION',
// Color Space: Gamma、Linear、Uninitialized(未初始化的颜色空间)
unityColorSpace: '$UNITY_COLORSPACE',
convertPluginVersion: '$PLUGIN_VERSION',
// 拼在StreamingAssets前面的pathDATA_CDN + streamingUrlPrefixPath + StreamingAssets
streamingUrlPrefixPath: '',
// DATA_CDN + dataFileSubPrefix + datafilename
dataFileSubPrefix: '$DATA_FILE_SUB_PREFIX',
// 当前appid扩容后通过本字段告知插件本地存储最大容量单位MB
maxStorage: $MAX_STORAGE_SIZE,
// 纹理中的hash长度
texturesHashLength: $TEXTURE_HASH_LENGTH,
// 纹理存放路径
texturesPath: '$TEXTURES_PATH',
// 是否需要缓存纹理,
needCacheTextures: $NEED_CACHE_TEXTURES,
// AssetBundle在内存中的存活时间
ttlAssetBundle: 5,
// 是否显示性能面板
enableProfileStats: $ENABLE_PROFILE_STATS,
// 是否预载微信系统字体
preloadWXFont: $PRELOAD_WXFONT,
// iOS高性能模式定期GC间隔
iOSAutoGCInterval: $IOS_AUTO_GC_INTERVAL,
// 是否使用微信压缩纹理
usedTextureCompression: GameGlobal.USED_TEXTURE_COMPRESSION,
// 是否使用autostreaming
usedAutoStreaming: $USED_AUTO_STREAMING,
// 是否显示渲染日志(dev only)
enableRenderAnalysisLog: $ENABLE_RENDER_ANALYSIS_LOG,
// 是否dotnet runtime
useDotnetRuntime: $USE_DOTNET_RUNTIME,
// 是否用了多线程brotli压缩
useBrotliMT: $USE_BROTLI_MT,
// Boot config配置包含例如wait-for-native-debugger、player-connection-ip等信息
bootConfig: '$BOOT_CONFIG_INFO',
// 是否以Development Build构建
isDevelopmentBuild: $Is_Development_Build,
// 是否以Profiling Build导出
isProfilingBuild: $Is_Profiling_Build,
// 预留的堆内存
unityHeapReservedMemory: $UnityHeapReservedMemory,
};
// 最佳实践检测配置
unityNamespace.monitorConfig = {
// 显示优化建议弹框
showSuggestModal: $SHOW_SUGGEST_MODAL,
// 是否开启检测(只影响开发版/体验版,线上版本不会检测)
enableMonitor: true,
// 帧率低于此值的帧会被记录,用于分析长耗时帧,做了限帧的游戏应该适当调低
fps: 10,
// 是否一直检测到游戏可交互完成
showResultAfterLaunch: true,
// 仅当showResultAfterLaunch=false时有效, 在引擎初始化完成(即callmain)后多长时间停止检测
monitorDuration: 30000,
};
// 判断是否需要自动缓存的文件返回true自动缓存false不自动缓存
unityNamespace.isCacheableFile = function (path) {
// 判定为下载bundle的路径标识符此路径下的下载会自动缓存
const cacheableFileIdentifier = [$BUNDLE_PATH_IDENTIFIER];
// 命中路径标识符的情况下,并不是所有文件都有必要缓存,过滤下不需要缓存的文件
const excludeFileIdentifier = [$EXCLUDE_FILE_EXTENSIONS];
if (cacheableFileIdentifier.some(identifier => path.includes(identifier)
&& excludeFileIdentifier.every(excludeIdentifier => !path.includes(excludeIdentifier)))) {
return true;
}
return false;
};
// 是否上报此条网络异常, 返回true则上报, 返回false则忽略
unityNamespace.isReportableHttpError = function (_info) {
// const { url, error } = _info;
return true;
};
// 判断是否是AssetBundle
unityNamespace.isWXAssetBundle = function (path) {
return unityNamespace.WXAssetBundles.has(unityNamespace.PathInFileOS(path));
};
unityNamespace.PathInFileOS = function (path) {
return path.replace(`${wx.env.USER_DATA_PATH}/__GAME_FILE_CACHE`, '');
};
unityNamespace.WXAssetBundles = new Map();
// 清理缓存时是否可被自动清理返回true可自动清理返回false不可自动清理
unityNamespace.isErasableFile = function (info) {
// 用于特定AssetBundle的缓存保持
if (unityNamespace.WXAssetBundles.has(info.path)) {
return false;
}
// 达到缓存上限时,不会被自动清理的文件
const inErasableIdentifier = [];
if (inErasableIdentifier.some(identifier => info.path.includes(identifier))) {
return false;
}
return true;
};
GameGlobal.WebAssembly = GameGlobal.WXWebAssembly;
GameGlobal.unityNamespace = GameGlobal.unityNamespace || unityNamespace;
GameGlobal.realtimeLogManager = wx.getRealtimeLogManager();
GameGlobal.logmanager = wx.getLogManager({ level: 0 });
// 提前监听错误并打日志
function bindGloblException() {
// 默认上报小游戏实时日志与用户反馈日志(所有error日志+小程序框架异常)
wx.onError((result) => {
// 若manager已初始化则直接用manager打日志即可
if (GameGlobal.manager) {
GameGlobal.manager.printErr(result.message);
}
else {
GameGlobal.realtimeLogManager.error(result);
const isErrorObj = result && result.stack;
GameGlobal.logmanager.warn(isErrorObj ? result.stack : result);
console.error('onError:', result);
}
});
wx.onUnhandledRejection((result) => {
GameGlobal.realtimeLogManager.error(result);
const isErrorObj = result && result.reason && result.reason.stack;
GameGlobal.logmanager.warn(isErrorObj ? result.reason.stack : result.reason);
console.error('unhandledRejection:', result.reason);
});
// 上报初始信息
function printSystemInfo(appBaseInfo, deviceInfo) {
// eslint-disable-next-line @typescript-eslint/naming-convention
const { version, SDKVersion } = appBaseInfo;
const { platform, system } = deviceInfo;
unityNamespace.version = version;
unityNamespace.SDKVersion = SDKVersion;
unityNamespace.platform = platform;
unityNamespace.system = system;
unityNamespace.isPc = platform === 'windows' || platform === 'mac';
unityNamespace.isDevtools = platform === 'devtools';
unityNamespace.isMobile = !unityNamespace.isPc && !unityNamespace.isDevtools;
unityNamespace.isH5Renderer = GameGlobal.isIOSHighPerformanceMode;
unityNamespace.isIOS = platform === 'ios';
unityNamespace.isAndroid = platform === 'android';
const bootinfo = {
renderer: GameGlobal.isIOSHighPerformanceMode ? 'h5' : '',
isH5Plus: GameGlobal.isIOSHighPerformanceModePlus || false,
abi: deviceInfo.abi || '',
brand: deviceInfo.brand,
model: deviceInfo.model,
platform: deviceInfo.platform,
system: deviceInfo.system,
version: appBaseInfo.version,
SDKVersion: appBaseInfo.SDKVersion,
benchmarkLevel: deviceInfo.benchmarkLevel,
};
GameGlobal.realtimeLogManager.info('game starting', bootinfo);
GameGlobal.logmanager.info('game starting', bootinfo);
console.info('game starting', bootinfo);
}
const appBaseInfo = wx.getAppBaseInfo ? wx.getAppBaseInfo() : wx.getSystemInfoSync();
const deviceInfo = wx.getDeviceInfo ? wx.getDeviceInfo() : wx.getSystemInfoSync();
printSystemInfo(appBaseInfo, deviceInfo);
}
bindGloblException();
// eslint-disable-next-line no-multi-assign
GameGlobal.onCrash = GameGlobal.unityNamespace.onCrash = function () {
GameGlobal.manager.showAbort();
const windowInfo = wx.getWindowInfo ? wx.getWindowInfo() : wx.getSystemInfoSync();
wx.createFeedbackButton({
type: 'text',
text: '提交反馈',
style: {
left: (windowInfo.screenWidth - 184) / 2,
top: windowInfo.screenHeight / 3 + 140,
width: 184,
height: 40,
lineHeight: 40,
backgroundColor: '#07C160',
color: '#ffffff',
textAlign: 'center',
fontSize: 16,
borderRadius: 4,
},
});
};
export default GameGlobal.unityNamespace;

View File

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 7ccff5467a06e53a2a3281d547d0ce3d
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 3a75b8e9f3a878719105f0ec566a9624
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: a6c55be9834674b932efe3fc2217e528
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: d30b1282421864f7fbb43ef2520b2334
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 5d1493d082a84195758cff6c33aaeb44
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,71 @@
import { WEBAudio, audios, unityAudioVolume, innerAudioVolume } from './store';
import { resumeWebAudio, mkCacheDir } from './utils';
mkCacheDir();
export default {
WXGetAudioCount() {
return {
innerAudio: Object.keys(audios).length,
webAudio: WEBAudio.bufferSourceNodeLength,
buffer: WEBAudio.audioBufferLength,
};
},
WXSetAudioMute(value) {
if (typeof value !== 'boolean') {
return;
}
if (WEBAudio.isMute === value) {
return;
}
WEBAudio.isMute = value;
for (const channelInstance of Object.keys(WEBAudio.audioInstances)) {
const channel = WEBAudio.audioInstances[+channelInstance];
if (channel.source) {
channel.setVolume?.(value ? 0 : unityAudioVolume.get(channel) ?? 1);
}
}
for (const innerAudio of Object.values(audios)) {
innerAudio.volume = value ? 0 : innerAudioVolume.get(innerAudio) ?? 1;
}
},
};
const HandleInterruption = {
init() {
let INTERRUPT_LIST = {};
wx.onHide(() => {
Object.keys(audios).forEach((key) => {
if (!audios[key].paused !== false) {
INTERRUPT_LIST[key] = true;
}
});
});
wx.onShow(() => {
Object.keys(audios).forEach((key) => {
if (audios[key].paused !== false && INTERRUPT_LIST[key]) {
audios[key].play();
}
});
INTERRUPT_LIST = {};
});
wx.onAudioInterruptionBegin(() => {
Object.keys(audios).forEach((key) => {
if (!audios[key].paused !== false) {
INTERRUPT_LIST[key] = true;
}
});
});
wx.onAudioInterruptionEnd(() => {
Object.keys(audios).forEach((key) => {
if (audios[key].paused !== false && INTERRUPT_LIST[key]) {
audios[key].play();
}
});
INTERRUPT_LIST = {};
resumeWebAudio();
});
},
};
HandleInterruption.init();

View File

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 4139c3bd44af4c7dc69f2632af2b1943
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,3 @@
export const INNER_AUDIO_UNDEFINED_MSG = 'InnerAudioContext does not exist!';
export const IGNORE_ERROR_MSG = 'audio is playing, don\'t play again';
export const TEMP_DIR_PATH = `${wx.env.USER_DATA_PATH}/__GAME_FILE_CACHE/audios`;

View File

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 5be33aaff0faebb6cb307710d6f29bce
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,8 @@
import innerAudio from './inner-audio';
import unityAudio from './unity-audio';
import common from './common';
export default {
...innerAudio,
...unityAudio,
...common,
};

View File

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 2a5339de32fc23eaa8064a05371bb5ed
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,382 @@
/* eslint-disable no-param-reassign */
import moduleHelper from '../module-helper';
import { isSupportPlayBackRate } from '../../check-version';
import { audios, localAudioMap, downloadingAudioMap, innerAudioVolume, WEBAudio } from './store';
import { createInnerAudio, destroyInnerAudio, printErrMsg } from './utils';
import { IGNORE_ERROR_MSG, INNER_AUDIO_UNDEFINED_MSG } from './const';
const funs = {
getFullUrl(v) {
if (!/^https?:\/\//.test(v) && !/^wxfile:\/\//.test(v)) {
const cdnPath = GameGlobal.manager.assetPath;
v = `${cdnPath.replace(/\/$/, '')}/${v.replace(/^\//, '').replace(/^Assets\//, '')}`;
}
return v;
},
downloadAudios(paths) {
const list = paths.split(',');
return Promise.all(list.map((v) => {
const src = funs.getFullUrl(v);
return new Promise((resolve, reject) => {
if (!downloadingAudioMap[src]) {
downloadingAudioMap[src] = [
{
resolve,
reject,
},
];
if (funs.checkLocalFile(src)) {
funs.handleDownloadEnd(src, true);
}
else if (!GameGlobal.unityNamespace.isCacheableFile(src)) {
wx.downloadFile({
url: src,
success(res) {
if (res.statusCode === 200 && res.tempFilePath) {
localAudioMap[src] = res.tempFilePath;
funs.handleDownloadEnd(src, true);
}
else {
funs.handleDownloadEnd(src, false);
}
},
fail(e) {
funs.handleDownloadEnd(src, false);
printErrMsg(e);
},
});
}
else {
const xmlhttp = new GameGlobal.unityNamespace.UnityLoader.UnityCache.XMLHttpRequest();
xmlhttp.open('GET', src, true);
xmlhttp.responseType = 'arraybuffer';
xmlhttp.onsave = () => {
localAudioMap[src] = GameGlobal.manager.getCachePath(src);
funs.handleDownloadEnd(src, true);
};
xmlhttp.onsavefail = () => {
funs.handleDownloadEnd(src, false);
};
xmlhttp.onerror = () => {
funs.handleDownloadEnd(src, false);
};
xmlhttp.send();
}
}
else {
downloadingAudioMap[src].push({
resolve,
reject,
});
}
});
}));
},
handleDownloadEnd(src, succeeded) {
if (!downloadingAudioMap[src]) {
return;
}
while (downloadingAudioMap[src] && downloadingAudioMap[src].length > 0) {
const item = downloadingAudioMap[src].shift();
if (!succeeded) {
item?.reject();
}
else {
item?.resolve('');
}
}
delete downloadingAudioMap[src];
},
// 是否存在本地文件
checkLocalFile(src) {
if (localAudioMap[src]) {
return true;
}
const path = GameGlobal.manager.getCachePath(src);
if (path) {
localAudioMap[src] = path;
return true;
}
return false;
},
// 设置路径
setAudioSrc(audio, getSrc) {
return new Promise((resolve, reject) => {
const src = funs.getFullUrl(getSrc);
// 设置原始路径后面用此路径作为key值
audio.isLoading = src;
if (funs.checkLocalFile(src)) {
audio.src = localAudioMap[src];
delete audio.isLoading;
funs.handleDownloadEnd(src, true);
resolve(localAudioMap[src]);
}
else if (audio.needDownload) {
funs
.downloadAudios(src)
.then(() => {
if (audio) {
audio.src = localAudioMap[src];
delete audio.isLoading;
resolve(localAudioMap[src]);
}
else {
console.warn('资源已被删除:', src);
reject({
errCode: -1,
errMsg: '资源已被删除',
});
}
})
.catch(() => {
console.warn('资源下载失败:', src);
if (audio) {
audio.src = src;
delete audio.isLoading;
}
reject({
errCode: -1,
errMsg: '资源下载失败',
});
});
}
else {
// 不推荐这样处理,建议优先下载再使用,除非是需要立即播放的长音频文件或一次性播放音频
// console.warn('建议优先下载再使用:', src);
audio.src = src;
delete audio.isLoading;
resolve(src);
}
});
},
};
function checkHasAudio(id) {
if (audios[id]) {
return true;
}
console.error(INNER_AUDIO_UNDEFINED_MSG, id);
return false;
}
export default {
// 创建audio对象
WXCreateInnerAudioContext(src, loop, startTime, autoplay, volume, playbackRate, needDownload) {
const { audio: getAudio, id } = createInnerAudio();
getAudio.needDownload = needDownload;
if (src) {
// 设置原始src
funs.setAudioSrc(getAudio, src).catch((e) => {
moduleHelper.send('OnAudioCallback', JSON.stringify({
callbackId: id,
errMsg: 'onError',
result: JSON.stringify(e),
}));
});
}
if (loop) {
getAudio.loop = true;
}
if (autoplay) {
getAudio.autoplay = true;
}
if (typeof startTime === 'undefined') {
startTime = 0;
}
if (startTime > 0) {
getAudio.startTime = +startTime.toFixed(2);
}
let volumeValue;
if (typeof volume === 'undefined') {
volumeValue = 1;
}
else {
volumeValue = +volume.toFixed(2);
}
innerAudioVolume.set(getAudio, volumeValue);
if (WEBAudio.isMute) {
volumeValue = 0;
}
if (volumeValue !== 1) {
getAudio.volume = volumeValue;
}
if (!isSupportPlayBackRate) {
playbackRate = 1;
}
if (typeof playbackRate !== 'undefined' && playbackRate !== 1) {
getAudio.playbackRate = +playbackRate.toFixed(2);
}
return id;
},
WXInnerAudioContextSetBool(id, k, v) {
if (!checkHasAudio(id)) {
return;
}
audios[id][k] = Boolean(+v);
},
WXInnerAudioContextSetString(id, k, v) {
if (!checkHasAudio(id)) {
return;
}
if (k === 'src') {
funs.setAudioSrc(audios[id], v);
}
else if (k === 'needDownload') {
audios[id].needDownload = !!v;
}
else {
audios[id][k] = v;
}
},
WXInnerAudioContextSetFloat(id, k, v) {
if (!checkHasAudio(id)) {
return;
}
let value = +v.toFixed(2);
if (k === 'volume') {
innerAudioVolume.set(audios[id], value);
if (WEBAudio.isMute) {
value = 0;
}
}
audios[id][k] = value;
},
WXInnerAudioContextGetFloat(id, k) {
if (!checkHasAudio(id)) {
return 0;
}
return audios[id][k];
},
WXInnerAudioContextGetBool(id, k) {
if (!checkHasAudio(id)) {
return false;
}
return audios[id][k];
},
WXInnerAudioContextPlay(id) {
if (!checkHasAudio(id)) {
return;
}
const url = audios[id].isLoading;
if (url) {
if (downloadingAudioMap[url]) {
downloadingAudioMap[url].push({
resolve: () => {
if (typeof audios[id] !== 'undefined') {
audios[id].play();
}
},
reject: () => { },
});
}
else {
audios[id].src = url;
audios[id].play();
}
}
else {
audios[id].play();
}
},
WXInnerAudioContextPause(id) {
if (!checkHasAudio(id)) {
return;
}
audios[id].pause();
},
WXInnerAudioContextStop(id) {
if (!checkHasAudio(id)) {
return;
}
audios[id].stop();
},
WXInnerAudioContextDestroy(id) {
if (!checkHasAudio(id)) {
return;
}
destroyInnerAudio(id, false);
},
WXInnerAudioContextSeek(id, position) {
if (!checkHasAudio(id)) {
return;
}
audios[id].seek(+position.toFixed(3));
},
WXInnerAudioContextAddListener(id, key) {
if (!checkHasAudio(id)) {
return;
}
if (key === 'onCanplay') {
audios[id][key](() => {
// @ts-ignore
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const { duration, buffered, referrerPolicy, volume } = audios[id];
setTimeout(() => {
moduleHelper.send('OnAudioCallback', JSON.stringify({
callbackId: id,
errMsg: key,
}));
}, 0);
});
}
else if (key === 'onError') {
audios[id][key]((e) => {
if (key === 'onError') {
console.error(e);
if (e.errMsg && e.errMsg.indexOf(IGNORE_ERROR_MSG) > -1) {
return;
}
}
moduleHelper.send('OnAudioCallback', JSON.stringify({
callbackId: id,
errMsg: key,
result: JSON.stringify(e),
}));
});
}
else {
audios[id][key](() => {
moduleHelper.send('OnAudioCallback', JSON.stringify({
callbackId: id,
errMsg: key,
}));
});
}
},
WXInnerAudioContextRemoveListener(id, key) {
if (!checkHasAudio(id)) {
return;
}
audios[id][key]();
},
WXPreDownloadAudios(paths, id) {
funs
.downloadAudios(paths)
.then(() => {
moduleHelper.send('WXPreDownloadAudiosCallback', JSON.stringify({
callbackId: id.toString(),
errMsg: '0',
}));
})
.catch(() => {
moduleHelper.send('WXPreDownloadAudiosCallback', JSON.stringify({
callbackId: id.toString(),
errMsg: '1',
}));
});
},
};

View File

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 8af7397fc8269b574123cb170ae36abe
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,33 @@
export const WEBAudio = {
audioInstanceIdCounter: 0,
audioInstances: {},
audioContext: null,
audioWebEnabled: 0,
audioCache: [],
lOrientation: {
x: 0,
y: 0,
z: 0,
xUp: 0,
yUp: 0,
zUp: 0,
},
lPosition: { x: 0, y: 0, z: 0 },
audio3DSupport: 0,
audioWebSupport: 0,
bufferSourceNodeLength: 0,
audioBufferLength: 0,
isMute: false,
FAKEMOD_SAMPLERATE: 44100,
};
export const audios = {};
export const localAudioMap = {};
export const downloadingAudioMap = {};
export const unityAudioVolume = new WeakMap();
export const innerAudioVolume = new WeakMap();

View File

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 8545f64fa7c5da1b93d9c52143251d67
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: e296f47c1cb3bb001a974045fb50d01e
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,77 @@
import { uid } from '../utils';
import { isSupportCacheAudio } from '../../check-version';
import { WEBAudio, audios } from './store';
import { TEMP_DIR_PATH } from './const';
export const resumeWebAudio = () => {
WEBAudio.audioContext?.resume();
};
export const createInnerAudio = () => {
const id = uid();
const audio = (isSupportCacheAudio && WEBAudio.audioCache.length ? WEBAudio.audioCache.shift() : wx.createInnerAudioContext());
if (audio) {
audios[id] = audio;
}
return {
id,
audio,
};
};
export const destroyInnerAudio = (id, useCache) => {
if (!id) {
return;
}
if (!useCache || !isSupportCacheAudio || WEBAudio.audioCache.length > 32) {
audios[id].destroy();
}
else {
['Play', 'Pause', 'Stop', 'Canplay', 'Error', 'Ended', 'Waiting', 'Seeking', 'Seeked', 'TimeUpdate'].forEach((eventName) => {
audios[id][`off${eventName}`]();
});
const state = {
startTime: 0,
obeyMuteSwitch: true,
volume: 1,
autoplay: false,
loop: false,
referrerPolicy: '',
};
Object.keys(state).forEach((key) => {
try {
// @ts-ignore
audios[id][key] = state[key];
}
catch (e) { }
});
audios[id].stop();
const cacheAudio = audios[id];
setTimeout(() => {
WEBAudio.audioCache.push(cacheAudio);
}, 1000);
}
delete audios[id];
};
export const printErrMsg = (msg) => {
GameGlobal.manager.printErr(msg);
};
export function mkCacheDir() {
const fs = wx.getFileSystemManager();
fs.rmdir({
dirPath: TEMP_DIR_PATH,
recursive: true,
complete: () => {
fs.mkdir({
dirPath: TEMP_DIR_PATH,
});
},
});
}

View File

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: cb969ebe8eb3c4d42efab62790ebd549
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,16 @@
const callbacks = [];
let isTriggered = false;
export default {
addCreatedListener(callback) {
if (isTriggered) {
callback();
}
else {
callbacks.push(callback);
}
},
_triggerCallback() {
isTriggered = true;
callbacks.forEach(v => v());
},
};

View File

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 18c5dda3d0de0f3315721032ca22456a
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,24 @@
import response from './response';
import moduleHelper from './module-helper';
import { getDefaultData } from './utils';
export default {
WXToTempFilePathSync(conf) {
return canvas.toTempFilePathSync(getDefaultData(canvas, conf));
},
WXToTempFilePath(conf, s, f, c) {
if (conf) {
canvas.toTempFilePath({
...getDefaultData(canvas, conf),
...response.handleText(s, f, c),
success: (res) => {
moduleHelper.send('ToTempFilePathCallback', JSON.stringify({
callbackId: s,
errMsg: res.errMsg,
errCode: res.errCode || 0,
tempFilePath: res.tempFilePath,
}));
},
});
}
},
};

View File

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: b5b13e26a0a3ac6980bfa85979caf9fc
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1 @@
export const MODULE_NAME = 'WXSDKManagerHandler';

View File

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 190fb40c87bec948e8330af56fdc58f7
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,47 @@
function getObjectSize(data) {
if (data && (typeof data === 'string' || data.byteLength)) {
return data.byteLength || data.length || 0;
}
return 0;
}
export const fileInfoHandler = {
addFileInfo(filePath, data) {
if (GameGlobal.manager.fs && GameGlobal.manager.fs.addFileInfo) {
GameGlobal.manager.fs.addFileInfo({ path: filePath, size: getObjectSize(data), erasable: false });
}
},
modifyFileInfo(filePath, data) {
if (GameGlobal.manager.fs && GameGlobal.manager.fs.modifyFileInfo) {
GameGlobal.manager.fs.modifyFileInfo({ path: filePath, size: getObjectSize(data) });
}
},
removeFileInfo(filePath) {
if (GameGlobal.manager.fs && GameGlobal.manager.fs.removeFileInfo) {
GameGlobal.manager.fs.removeFileInfo(filePath);
}
},
};
export const fileInfoType = {
add: 0,
remove: 1,
modify: 2,
};
export function responseWrapper(responseHandler, info) {
const { filePath, data, type } = info;
return {
success(res) {
if (type === fileInfoType.add) {
fileInfoHandler.addFileInfo(filePath, data);
}
if (type === fileInfoType.remove) {
fileInfoHandler.removeFileInfo(filePath);
}
if (type === fileInfoType.modify) {
fileInfoHandler.modifyFileInfo(filePath, data);
}
responseHandler.success(res);
},
fail: responseHandler.fail,
complete: responseHandler.complete,
};
}

View File

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 0382294c001a0b51d5297a0addce8dd8
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,89 @@
/* eslint-disable prefer-spread */
/* eslint-disable prefer-rest-params */
export default {
init() {
this.fixTimer();
},
fixTimer() {
const wm = {};
const privateSetTimeout = window.setTimeout;
let id = 0;
const getId = function () {
id += 1;
if (id > 100000000) {
id = 0;
}
return id;
};
// @ts-ignore
window.setTimeout = function (vCallback, nDelay) {
const aArgs = Array.prototype.slice.call(arguments, 2);
const id = getId();
const t = privateSetTimeout(vCallback instanceof Function
? () => {
// @ts-ignore
vCallback.apply(null, aArgs);
delete wm[id];
}
: vCallback, nDelay);
wm[id] = t;
return id;
};
const privateClearTimeout = window.clearTimeout;
// @ts-ignore
window.clearTimeout = function (id) {
if (id) {
const t = wm[id];
if (t) {
privateClearTimeout(t);
delete wm[id];
}
}
};
const privateSetInterval = window.setInterval;
// @ts-ignore
window.setInterval = function (vCallback, nDelay) {
const aArgs = Array.prototype.slice.call(arguments, 2);
const id = getId();
const t = privateSetInterval(vCallback instanceof Function
? () => {
// @ts-ignore
vCallback.apply(null, aArgs);
}
: vCallback, nDelay);
wm[id] = t;
return id;
};
const privateClearInterval = window.clearInterval;
// @ts-ignore
window.clearInterval = function (id) {
if (id) {
const t = wm[id];
if (t) {
privateClearInterval(t);
delete wm[id];
}
}
};
const privateRequestAnimationFrame = window.requestAnimationFrame;
window.requestAnimationFrame = function (vCallback) {
const id = getId();
const t = privateRequestAnimationFrame(() => {
vCallback(0);
delete wm[id];
});
wm[id] = t;
return id;
};
const privateCancelAnimationFrame = window.cancelAnimationFrame;
window.cancelAnimationFrame = function (id) {
const t = wm[id];
if (t) {
privateCancelAnimationFrame(t);
delete wm[id];
}
};
},
};

View File

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 55b58eb65e95ddd9ec7077298874e84c
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,473 @@
/* eslint-disable no-param-reassign */
import response from './response';
import moduleHelper from './module-helper';
import { cacheArrayBuffer, formatJsonStr, formatResponse } from './utils';
import { fileInfoHandler, fileInfoType, responseWrapper } from './file-info';
function runMethod(method, option, callbackId, isString = false) {
try {
const fs = wx.getFileSystemManager();
let config;
if (typeof option === 'string') {
config = formatJsonStr(option);
}
else {
config = option;
}
if (method === 'readZipEntry' && !config.encoding) {
config.encoding = 'utf-8';
console.error('fs.readZipEntry不支持读取ArrayBuffer已改为utf-8');
}
fs[method]({
...config,
success(res) {
let returnRes = '';
if (method === 'read') {
cacheArrayBuffer(callbackId, res.arrayBuffer);
returnRes = JSON.stringify({
bytesRead: res.bytesRead,
arrayBufferLength: res.arrayBuffer?.byteLength ?? 0,
});
}
else if (method === 'readCompressedFile') {
cacheArrayBuffer(callbackId, res.data);
returnRes = JSON.stringify({
arrayBufferLength: res.data?.byteLength ?? 0,
});
}
else if (method === 'readFile') {
if (config.encoding) {
returnRes = JSON.stringify({
stringData: res.data || '',
});
}
else {
cacheArrayBuffer(callbackId, res.data);
returnRes = JSON.stringify({
arrayBufferLength: res.data?.byteLength ?? 0,
});
}
}
else {
returnRes = JSON.stringify(res);
}
// console.log(`fs.${method} success:`, res);
moduleHelper.send('FileSystemManagerCallback', JSON.stringify({
callbackId, type: 'success', res: returnRes, method: isString ? `${method}_string` : method,
}));
},
fail(res) {
moduleHelper.send('FileSystemManagerCallback', JSON.stringify({
callbackId, type: 'fail', res: JSON.stringify(res), method: isString ? `${method}_string` : method,
}));
},
complete(res) {
moduleHelper.send('FileSystemManagerCallback', JSON.stringify({
callbackId, type: 'complete', res: JSON.stringify(res), method: isString ? `${method}_string` : method,
}));
},
});
}
catch (e) {
moduleHelper.send('FileSystemManagerCallback', JSON.stringify({
callbackId, type: 'complete', res: 'fail', method: isString ? `${method}_string` : method,
}));
}
}
export default {
WXGetUserDataPath() {
return wx.env.USER_DATA_PATH;
},
WXWriteFileSync(filePath, data, encoding) {
try {
const fs = wx.getFileSystemManager();
// @ts-ignore
fs.writeFileSync(filePath, data, encoding);
fileInfoHandler.addFileInfo(filePath, data);
}
catch (e) {
console.error(e);
if (e.message) {
return e.message;
}
return 'fail';
}
return 'ok';
},
WXAccessFileSync(filePath) {
try {
const fs = wx.getFileSystemManager();
fs.accessSync(filePath);
return 'access:ok';
}
catch (e) {
if (e.message) {
return e.message;
}
return 'fail';
}
},
WXAccessFile(path, s, f, c) {
const fs = wx.getFileSystemManager();
fs.access({
path,
...response.handleText(s, f, c),
});
},
WXCopyFileSync(src, dst) {
try {
const fs = wx.getFileSystemManager();
fs.copyFileSync(src, dst);
return 'copyFile:ok';
}
catch (e) {
console.error(e);
if (e.message) {
return e.message;
}
return 'fail';
}
},
WXCopyFile(srcPath, destPath, s, f, c) {
const fs = wx.getFileSystemManager();
fs.copyFile({
srcPath,
destPath,
...response.handleText(s, f, c),
});
},
WXUnlinkSync(filePath) {
try {
const fs = wx.getFileSystemManager();
fs.unlinkSync(filePath);
fileInfoHandler.removeFileInfo(filePath);
return 'unlink:ok';
}
catch (e) {
console.error(e);
if (e.message) {
return e.message;
}
return 'fail';
}
},
WXUnlink(filePath, s, f, c) {
const fs = wx.getFileSystemManager();
fs.unlink({
filePath,
...responseWrapper(response.handleText(s, f, c), { filePath, type: fileInfoType.remove }),
});
},
WXWriteFile(filePath, data, encoding, s, f, c) {
const fs = wx.getFileSystemManager();
fs.writeFile({
filePath,
data: data.buffer,
encoding,
...responseWrapper(response.handleTextLongBack(s, f, c), { filePath, data: data.buffer, type: fileInfoType.add }),
});
},
WXWriteStringFile(filePath, data, encoding, s, f, c) {
const fs = wx.getFileSystemManager();
fs.writeFile({
filePath,
data,
encoding,
...responseWrapper(response.handleTextLongBack(s, f, c), { filePath, data, type: fileInfoType.add }),
});
},
WXAppendFile(filePath, data, encoding, s, f, c) {
const fs = wx.getFileSystemManager();
fs.appendFile({
filePath,
data: data.buffer,
encoding,
...response.handleTextLongBack(s, f, c),
});
},
WXAppendStringFile(filePath, data, encoding, s, f, c) {
const fs = wx.getFileSystemManager();
fs.appendFile({
filePath,
data,
encoding,
...response.handleTextLongBack(s, f, c),
});
},
WXWriteBinFileSync(filePath, data, encoding) {
const fs = wx.getFileSystemManager();
try {
fs.writeFileSync(filePath, data.buffer, encoding);
fileInfoHandler.addFileInfo(filePath, data.buffer);
}
catch (e) {
console.error(e);
if (e.message) {
return e.message;
}
return 'fail';
}
return 'ok';
},
WXReadFile(option, callbackId) {
runMethod('readFile', option, callbackId);
},
WXReadFileSync(option) {
const fs = wx.getFileSystemManager();
const config = formatJsonStr(option);
try {
const { filePath } = config;
const res = fs.readFileSync(config.filePath, config.encoding, config.position, config.length);
if (!config.encoding && typeof res !== 'string') {
cacheArrayBuffer(filePath, res);
return `${res.byteLength}`;
}
return res;
}
catch (e) {
console.error(e);
if (e.message) {
return e.message;
}
return 'fail';
}
},
WXMkdir(dirPath, recursive, s, f, c) {
const fs = wx.getFileSystemManager();
fs.mkdir({
dirPath,
recursive: Boolean(recursive),
...response.handleText(s, f, c),
});
},
WXMkdirSync(dirPath, recursive) {
try {
const fs = wx.getFileSystemManager();
fs.mkdirSync(dirPath, Boolean(recursive));
return 'mkdir:ok';
}
catch (e) {
console.error(e);
if (e.message) {
return e.message;
}
return 'fail';
}
},
WXRmdir(dirPath, recursive, s, f, c) {
const fs = wx.getFileSystemManager();
fs.rmdir({
dirPath,
recursive: Boolean(recursive),
...response.handleText(s, f, c),
});
},
WXRmdirSync(dirPath, recursive) {
try {
const fs = wx.getFileSystemManager();
fs.rmdirSync(dirPath, Boolean(recursive));
return 'rmdirSync:ok';
}
catch (e) {
console.error(e);
if (e.message) {
return e.message;
}
return 'fail';
}
},
WXStat(conf, callbackId) {
const config = formatJsonStr(conf);
wx.getFileSystemManager().stat({
...config,
success(res) {
if (!Array.isArray(res.stats)) {
// @ts-ignore C#中特殊处理
res.one_stat = res.stats;
// @ts-ignore C#中特殊处理
res.stats = null;
}
moduleHelper.send('StatCallback', JSON.stringify({
callbackId,
type: 'success',
res: JSON.stringify(res),
}));
},
fail(res) {
moduleHelper.send('StatCallback', JSON.stringify({
callbackId,
type: 'fail',
res: JSON.stringify(res),
}));
},
complete(res) {
// @ts-ignore C#中特殊处理
if (!Array.isArray(res.stats)) {
// @ts-ignore C#中特殊处理
res.one_stat = res.stats;
// @ts-ignore C#中特殊处理
res.stats = null;
}
moduleHelper.send('StatCallback', JSON.stringify({
callbackId,
type: 'complete',
res: JSON.stringify(res),
}));
},
});
},
WX_FileSystemManagerClose(option, callbackId) {
runMethod('close', option, callbackId);
},
WX_FileSystemManagerFstat(option, callbackId) {
runMethod('fstat', option, callbackId);
},
WX_FileSystemManagerFtruncate(option, callbackId) {
runMethod('ftruncate', option, callbackId);
},
WX_FileSystemManagerGetFileInfo(option, callbackId) {
runMethod('getFileInfo', option, callbackId);
},
WX_FileSystemManagerGetSavedFileList(option, callbackId) {
runMethod('getSavedFileList', option, callbackId);
},
WX_FileSystemManagerOpen(option, callbackId) {
runMethod('open', option, callbackId);
},
WX_FileSystemManagerRead(option, data, callbackId) {
const config = formatJsonStr(option);
config.arrayBuffer = data.buffer;
runMethod('read', config, callbackId);
},
WX_FileSystemManagerReadCompressedFile(option, callbackId) {
runMethod('readCompressedFile', option, callbackId);
},
WX_FileSystemManagerReadZipEntry(option, callbackId) {
runMethod('readZipEntry', option, callbackId);
},
WX_FileSystemManagerReadZipEntryString(option, callbackId) {
runMethod('readZipEntry', option, callbackId, true);
},
WX_FileSystemManagerReaddir(option, callbackId) {
runMethod('readdir', option, callbackId);
},
WX_FileSystemManagerRemoveSavedFile(option, callbackId) {
runMethod('removeSavedFile', option, callbackId);
},
WX_FileSystemManagerRename(option, callbackId) {
runMethod('rename', option, callbackId);
},
WX_FileSystemManagerSaveFile(option, callbackId) {
runMethod('saveFile', option, callbackId);
},
WX_FileSystemManagerTruncate(option, callbackId) {
runMethod('truncate', option, callbackId);
},
WX_FileSystemManagerUnzip(option, callbackId) {
runMethod('unzip', option, callbackId);
},
WX_FileSystemManagerWrite(option, data, callbackId) {
const config = formatJsonStr(option);
config.data = data.buffer;
runMethod('write', config, callbackId);
},
WX_FileSystemManagerWriteString(option, callbackId) {
runMethod('write', option, callbackId, true);
},
WX_FileSystemManagerReaddirSync(dirPath) {
const fs = wx.getFileSystemManager();
try {
return JSON.stringify(fs.readdirSync(dirPath) || []);
}
catch (e) {
console.error(e);
return '[]';
}
},
WX_FileSystemManagerReadCompressedFileSync(option, callbackId) {
const fs = wx.getFileSystemManager();
const res = fs.readCompressedFileSync(formatJsonStr(option));
cacheArrayBuffer(callbackId, res);
return res.byteLength;
},
WX_FileSystemManagerAppendFileStringSync(filePath, data, encoding) {
const fs = wx.getFileSystemManager();
fs.appendFileSync(filePath, data, encoding);
},
WX_FileSystemManagerAppendFileSync(filePath, data, encoding) {
const fs = wx.getFileSystemManager();
fs.appendFileSync(filePath, data.buffer, encoding);
},
WX_FileSystemManagerRenameSync(oldPath, newPath) {
const fs = wx.getFileSystemManager();
fs.renameSync(oldPath, newPath);
return 'ok';
},
WX_FileSystemManagerReadSync(option, callbackId) {
const fs = wx.getFileSystemManager();
const optionConfig = formatJsonStr(option);
optionConfig.arrayBuffer = new ArrayBuffer(optionConfig.arrayBuffer.length);
const res = fs.readSync(optionConfig);
cacheArrayBuffer(callbackId, res.arrayBuffer);
return JSON.stringify({
bytesRead: res.bytesRead,
arrayBufferLength: res.arrayBuffer?.byteLength ?? 0,
});
},
WX_FileSystemManagerFstatSync(option) {
const fs = wx.getFileSystemManager();
const res = fs.fstatSync(formatJsonStr(option));
formatResponse('Stats', res);
return JSON.stringify(res);
},
WX_FileSystemManagerStatSync(path, recursive) {
const fs = wx.getFileSystemManager();
const res = fs.statSync(path, recursive);
let resArray;
if (Array.isArray(res)) {
resArray = res;
}
else {
resArray = [res];
}
return JSON.stringify(resArray);
},
WX_FileSystemManagerWriteSync(option, data) {
const fs = wx.getFileSystemManager();
const optionConfig = formatJsonStr(option);
optionConfig.data = data.buffer;
const res = fs.writeSync(optionConfig);
return JSON.stringify(res);
},
WX_FileSystemManagerWriteStringSync(option) {
const fs = wx.getFileSystemManager();
const res = fs.writeSync(formatJsonStr(option));
return JSON.stringify(res);
},
WX_FileSystemManagerOpenSync(option) {
const fs = wx.getFileSystemManager();
return fs.openSync(formatJsonStr(option));
},
WX_FileSystemManagerSaveFileSync(tempFilePath, filePath) {
const fs = wx.getFileSystemManager();
return fs.saveFileSync(tempFilePath, filePath);
},
WX_FileSystemManagerCloseSync(option) {
const fs = wx.getFileSystemManager();
fs.closeSync(formatJsonStr(option));
return 'ok';
},
WX_FileSystemManagerFtruncateSync(option) {
const fs = wx.getFileSystemManager();
fs.ftruncateSync(formatJsonStr(option));
return 'ok';
},
WX_FileSystemManagerTruncateSync(option) {
const fs = wx.getFileSystemManager();
fs.truncateSync(formatJsonStr(option));
return 'ok';
},
};

View File

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: afc89b1700cfc764a366ce3306bb6853
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,80 @@
import moduleHelper from './module-helper';
import canvasHelper from './canvas';
import fs from './fs';
import util from './util';
import audio from './audio/index';
import texture from './texture';
import fix from './fix';
import canvasContext from './canvas-context';
import video from './video';
import logger from './logger';
import sdk from './sdk';
import videoDecoder from './video/index';
import mobileKeyboard from './mobileKeyboard/index';
import touch from './touch/index';
import specialCallbacks from './special-callbacks';
const unityVersion = '$unityVersion$';
GameGlobal.unityNamespace = GameGlobal.unityNamespace || {};
GameGlobal.unityNamespace.unityVersion = unityVersion;
window._ScaleRate = 1;
if (unityVersion && unityVersion.split('.').slice(0, 2)
.join('') < '20193') {
const width = window.innerWidth * window.devicePixelRatio;
const height = window.innerHeight * window.devicePixelRatio;
canvas.width = width;
canvas.height = height;
window._ScaleRate = window.devicePixelRatio;
}
Object.defineProperty(canvas, 'clientHeight', {
get() {
return window.innerHeight * window._ScaleRate;
},
configurable: true,
});
Object.defineProperty(canvas, 'clientWidth', {
get() {
return window.innerWidth * window._ScaleRate;
},
configurable: true,
});
Object.defineProperty(document.body, 'clientHeight', {
get() {
return window.innerHeight * window._ScaleRate;
},
configurable: true,
});
Object.defineProperty(document.body, 'clientWidth', {
get() {
return window.innerWidth * window._ScaleRate;
},
configurable: true,
});
Object.defineProperty(document, 'fullscreenEnabled', {
get() {
return true;
},
configurable: true,
});
fix.init();
const WXWASMSDK = {
WXInitializeSDK() {
moduleHelper.init();
moduleHelper.send('Inited', 200);
},
...canvasHelper,
...fs,
...util,
...audio,
...texture,
...video,
...logger,
canvasContext,
...sdk,
...videoDecoder,
...mobileKeyboard,
...touch,
...specialCallbacks,
};
GameGlobal.WXWASMSDK = WXWASMSDK;

Some files were not shown because too many files have changed in this diff Show More