mirror of
https://github.com/wechat-miniprogram/minigame-tuanjie-transform-sdk.git
synced 2025-11-12 19:25:55 +08:00
Auto-publish WXSDK.
This commit is contained in:
parent
87d21fc46b
commit
6496cbad05
@ -6,6 +6,13 @@ Removed - 删除功能/接口
|
||||
Fixed - 修复问题
|
||||
Others - 其他
|
||||
-->
|
||||
## 2024-3-28 【普通更新】
|
||||
* 普通:优化对团结版的导出支持
|
||||
### Fixed
|
||||
* 普通:兼容PlayDelayed播放
|
||||
* 普通:兼容FMOD2.02版本
|
||||
* 普通:修复FState偶现报错
|
||||
|
||||
## 2024-3-5 【普通更新】
|
||||
* 普通:WXAssetBundle支持切换CDN
|
||||
* 普通:优化VideoPlayer组件
|
||||
|
||||
74
Editor/MiniGameConfig.asset
Normal file
74
Editor/MiniGameConfig.asset
Normal file
@ -0,0 +1,74 @@
|
||||
%YAML 1.1
|
||||
%TAG !u! tag:unity3d.com,2011:
|
||||
--- !u!114 &11400000
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 0}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 1795359250, guid: 1cf430f187a0b40eda7f668318d8be23, type: 3}
|
||||
m_Name: MiniGameConfig
|
||||
m_EditorClassIdentifier:
|
||||
ProjectConf:
|
||||
projectName:
|
||||
Appid:
|
||||
CDN:
|
||||
assetLoadType: 0
|
||||
compressDataPackage: 0
|
||||
VideoUrl:
|
||||
DST:
|
||||
StreamCDN:
|
||||
bundleHashLength: 32
|
||||
bundlePathIdentifier: StreamingAssets;
|
||||
bundleExcludeExtensions: json;
|
||||
AssetsUrl:
|
||||
MemorySize: 256
|
||||
HideAfterCallMain: 1
|
||||
preloadFiles:
|
||||
Orientation: 0
|
||||
bgImageSrc: Assets/WX-WASM-SDK-V2/Runtime/wechat-default/images/background.jpg
|
||||
dataFileSubPrefix:
|
||||
maxStorage: 200
|
||||
defaultReleaseSize: 31457280
|
||||
texturesHashLength: 8
|
||||
texturesPath: Assets/Textures
|
||||
needCacheTextures: 1
|
||||
loadingBarWidth: 240
|
||||
needCheckUpdate: 0
|
||||
disableHighPerformanceFallback: 0
|
||||
IOSDevicePixelRatio: 0
|
||||
SDKOptions:
|
||||
UseFriendRelation: 0
|
||||
UseCompressedTexture: 0
|
||||
UseMiniGameChat: 0
|
||||
PreloadWXFont: 0
|
||||
CompileOptions:
|
||||
DevelopBuild: 0
|
||||
AutoProfile: 0
|
||||
ScriptOnly: 0
|
||||
Il2CppOptimizeSize: 1
|
||||
profilingFuncs: 1
|
||||
Webgl2: 0
|
||||
fbslim: 0
|
||||
DeleteStreamingAssets: 1
|
||||
ProfilingMemory: 0
|
||||
CleanBuild: 0
|
||||
CustomNodePath:
|
||||
showMonitorSuggestModal: 1
|
||||
enableProfileStats: 0
|
||||
enableRenderAnalysis: 0
|
||||
iOSAutoGCInterval: 10000
|
||||
enableIOSPerformancePlus: 0
|
||||
CompressTexture:
|
||||
halfSize: 0
|
||||
useDXT5: 0
|
||||
bundleSuffix: bundle
|
||||
parallelWithBundle: 0
|
||||
bundleDir:
|
||||
dstMinDir:
|
||||
debugMode: 0
|
||||
force: 0
|
||||
PlayerPrefsKeys: []
|
||||
@ -1,7 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6581700969f174df7a88b1cdb32c1ea4
|
||||
DefaultImporter:
|
||||
guid: 8c9a0d25ac0fe41788d270580f6208d9
|
||||
NativeFormatImporter:
|
||||
externalObjects: {}
|
||||
mainObjectFileID: 11400000
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -37,30 +37,30 @@ namespace WeChatWASM
|
||||
{
|
||||
if (Application.platform == RuntimePlatform.WindowsEditor)
|
||||
{
|
||||
return Path.Combine(Application.dataPath, "WX-WASM-SDK-V2/Editor/TextureEditor/Node/astcenc-sse4.1.exe");
|
||||
return Path.Combine(UnityUtil.GetWxSDKRootPath(), "Editor/TextureEditor/Node/astcenc-sse4.1.exe");
|
||||
}
|
||||
|
||||
if (UnityEngine.SystemInfo.processorType.ToLower().Contains("apple"))
|
||||
{
|
||||
return Path.Combine(Application.dataPath, "WX-WASM-SDK-V2/Editor/TextureEditor/Node/astcenc-neon");
|
||||
return Path.Combine(UnityUtil.GetWxSDKRootPath(), "Editor/TextureEditor/Node/astcenc-neon");
|
||||
}
|
||||
|
||||
return Path.Combine(Application.dataPath, "WX-WASM-SDK-V2/Editor/TextureEditor/Node/astcenc-avx2");
|
||||
return Path.Combine(UnityUtil.GetWxSDKRootPath(), "Editor/TextureEditor/Node/astcenc-avx2");
|
||||
}
|
||||
|
||||
public static string GetPVRTCPath()
|
||||
{
|
||||
return Path.Combine(Application.dataPath, "WX-WASM-SDK-V2/Editor/TextureEditor/Node/PVRTexToolCLI" + (Application.platform == RuntimePlatform.WindowsEditor ? ".exe" : string.Empty));
|
||||
return Path.Combine(UnityUtil.GetWxSDKRootPath(), "Editor/TextureEditor/Node/PVRTexToolCLI" + (Application.platform == RuntimePlatform.WindowsEditor ? ".exe" : string.Empty));
|
||||
}
|
||||
|
||||
public static string GetDXT5Path()
|
||||
{
|
||||
return Path.Combine(Application.dataPath, "WX-WASM-SDK-V2/Editor/TextureEditor/Node/PVRTexToolCLI" + (Application.platform == RuntimePlatform.WindowsEditor ? ".exe" : string.Empty));
|
||||
return Path.Combine(UnityUtil.GetWxSDKRootPath(), "Editor/TextureEditor/Node/PVRTexToolCLI" + (Application.platform == RuntimePlatform.WindowsEditor ? ".exe" : string.Empty));
|
||||
}
|
||||
|
||||
public static string GetPNGPath()
|
||||
{
|
||||
return Path.Combine(Application.dataPath, "WX-WASM-SDK-V2/Editor/TextureEditor/Node/pngquant" + (Application.platform == RuntimePlatform.WindowsEditor ? ".exe" : string.Empty));
|
||||
return Path.Combine(UnityUtil.GetWxSDKRootPath(), "Editor/TextureEditor/Node/pngquant" + (Application.platform == RuntimePlatform.WindowsEditor ? ".exe" : string.Empty));
|
||||
}
|
||||
|
||||
public static void TestASTC()
|
||||
|
||||
@ -24,28 +24,16 @@ namespace WeChatWASM
|
||||
public static void Init()
|
||||
{
|
||||
config = UnityUtil.GetEditorConf();
|
||||
// SDKFilePath = Path.Combine(Application.dataPath, "WX-WASM-SDK-V2", "Runtime", "wechat-default", "unity-sdk", "index.js");
|
||||
SDKFilePath = Path.Combine(UnityUtil.GetWxSDKRootPath(), "Runtime", "wechat-default", "unity-sdk", "index.js");
|
||||
// string templateHeader = (UnityUtil.GetSDKMode() == UnityUtil.SDKMode.Package && UnityUtil.GetEngineVersion() >= UnityUtil.EngineVersion.Tuanjie) ? "PACKAGE:com.qq.wx.minigame:" : "PROJECT:";
|
||||
string templateHeader = "PROJECT:";
|
||||
#if PLATFORM_WEIXINMINIGAME
|
||||
#if TUANJIE_2022_3_OR_NEWER
|
||||
PlayerSettings.WeixinMiniGame.threadsSupport = false;
|
||||
PlayerSettings.runInBackground = false;
|
||||
PlayerSettings.WeixinMiniGame.compressionFormat = WeixinMiniGameCompressionFormat.Disabled;
|
||||
#if UNITY_2022_3_OR_NEWER
|
||||
PlayerSettings.WeixinMiniGame.template = $"{templateHeader}WXTemplate2022TJ";
|
||||
#elif UNITY_2020_1_OR_NEWER
|
||||
PlayerSettings.WeixinMiniGame.template = $"{templateHeader}WXTemplate2020";
|
||||
#else
|
||||
PlayerSettings.WeixinMiniGame.template = $"{templateHeader}WXTemplate";
|
||||
#endif
|
||||
PlayerSettings.WeixinMiniGame.linkerTarget = WeixinMiniGameLinkerTarget.Wasm;
|
||||
PlayerSettings.WeixinMiniGame.dataCaching = false;
|
||||
#if UNITY_2021_2_OR_NEWER
|
||||
PlayerSettings.WeixinMiniGame.debugSymbolMode = WeixinMiniGameDebugSymbolMode.External;
|
||||
#else
|
||||
PlayerSettings.WeixinMiniGame.debugSymbols = true;
|
||||
#endif
|
||||
#else
|
||||
PlayerSettings.WebGL.threadsSupport = false;
|
||||
PlayerSettings.runInBackground = false;
|
||||
@ -79,12 +67,23 @@ namespace WeChatWASM
|
||||
public static string webglDir = "webgl"; // 导出的webgl目录
|
||||
public static string miniGameDir = "minigame"; // 生成小游戏的目录
|
||||
public static string audioDir = "Assets"; // 音频资源目录
|
||||
public static string frameworkDir = "framework";
|
||||
public static string dataFileSize = string.Empty;
|
||||
public static string codeMd5 = string.Empty;
|
||||
public static string dataMd5 = string.Empty;
|
||||
private static string SDKFilePath = string.Empty;
|
||||
public static string defaultImgSrc = "Assets/WX-WASM-SDK-V2/Runtime/wechat-default/images/background.jpg";
|
||||
|
||||
public static bool UseIL2CPP
|
||||
{
|
||||
get
|
||||
{
|
||||
#if TUANJIE_2022_3_OR_NEWER
|
||||
return PlayerSettings.GetScriptingBackend(BuildTargetGroup.WeixinMiniGame) == ScriptingImplementation.IL2CPP;
|
||||
#else
|
||||
return true;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
// 可以调用这个来集成
|
||||
public static WXExportError DoExport(bool buildWebGL = true)
|
||||
{
|
||||
@ -122,10 +121,26 @@ namespace WeChatWASM
|
||||
if (WXExtEnvDef.GETDEF("UNITY_2021_2_OR_NEWER") && !config.CompileOptions.DevelopBuild)
|
||||
{
|
||||
// 如果是2021版本,官方symbols产生有BUG,这里需要用工具将函数名提取出来
|
||||
WeChatWASM.UnityUtil.preprocessSymbols(GetWebGLSymbolPath());
|
||||
var symFile1 = "";
|
||||
if(!UseIL2CPP)
|
||||
{
|
||||
symFile1 = Path.Combine(config.ProjectConf.DST, webglDir, "Code", "wwwroot", "_framework", "dotnet.native.js.symbols");
|
||||
}
|
||||
else
|
||||
{
|
||||
var rootPath = Directory.GetParent(Application.dataPath).FullName;
|
||||
string webglDir = WXExtEnvDef.GETDEF("WEIXINMINIGAME") ? "WeixinMiniGame" : "WebGL";
|
||||
symFile1 = Path.Combine(rootPath, "Library", "Bee", "artifacts", webglDir, "build", "debug_WebGL_wasm", "build.js.symbols");
|
||||
}
|
||||
WeChatWASM.UnityUtil.preprocessSymbols(symFile1, GetWebGLSymbolPath());
|
||||
// WeChatWASM.UnityUtil.preprocessSymbols(GetWebGLSymbolPath());
|
||||
}
|
||||
|
||||
ConvertCode();
|
||||
if (!UseIL2CPP)
|
||||
{
|
||||
ConvertDotnetCode();
|
||||
}
|
||||
string dataFilePath = GetWebGLDataPath();
|
||||
string wxTextDataDir = WXAssetsTextTools.GetTextMinDataDir();
|
||||
string dataFilePathBackupDir = $"{wxTextDataDir}{WXAssetsTextTools.DS}slim";
|
||||
@ -140,7 +155,7 @@ namespace WeChatWASM
|
||||
}
|
||||
File.Copy(dataFilePath, dataFilePathBackupPath);
|
||||
|
||||
if (config.CompileOptions.fbslim && !IsInstantGameAutoStreaming())
|
||||
if (UseIL2CPP && config.CompileOptions.fbslim && !IsInstantGameAutoStreaming())
|
||||
{
|
||||
WXAssetsTextTools.FirstBundleSlim(dataFilePath, (result, info) =>
|
||||
{
|
||||
@ -248,15 +263,257 @@ namespace WeChatWASM
|
||||
return output.ToString();
|
||||
}
|
||||
|
||||
|
||||
private static void ConvertDotnetCode()
|
||||
{
|
||||
CompressAssemblyBrotli();
|
||||
ConvertDotnetRuntimeCode();
|
||||
ConvertDotnetFrameworkCode();
|
||||
}
|
||||
|
||||
private static void ConvertDotnetRuntimeCode()
|
||||
{
|
||||
var runtimePath = GetWeixinMiniGameFilePath("jsModuleRuntime")[0];
|
||||
var dotnetJs = File.ReadAllText(runtimePath, Encoding.UTF8);
|
||||
|
||||
Rule[] rules =
|
||||
{
|
||||
new Rule()
|
||||
{
|
||||
old = "await *WebAssembly\\.instantiate\\(\\w*,",
|
||||
newStr = $"await WebAssembly.instantiate(Module[\"wasmPath\"],",
|
||||
},
|
||||
new Rule()
|
||||
{
|
||||
old = "['\"]Expected methodFullName if trace is instrumented['\"]\\);?",
|
||||
newStr = "'Expected methodFullName if trace is instrumented'); return;",
|
||||
}
|
||||
};
|
||||
foreach (var rule in rules)
|
||||
{
|
||||
if (ShowMatchFailedWarning(dotnetJs, rule.old, "runtime") == false) {
|
||||
dotnetJs = Regex.Replace(dotnetJs, rule.old, rule.newStr);
|
||||
}
|
||||
}
|
||||
|
||||
File.WriteAllText(Path.Combine(config.ProjectConf.DST, miniGameDir, frameworkDir, Path.GetFileName(runtimePath)), dotnetJs, new UTF8Encoding(false));
|
||||
}
|
||||
|
||||
private static void CompressAssemblyBrotli()
|
||||
{
|
||||
GetWeixinMiniGameFilePath("assembly").ToList().ForEach(assembly => UnityUtil.brotli(assembly, assembly + ".br", "8"));
|
||||
}
|
||||
|
||||
private static void ConvertDotnetFrameworkCode()
|
||||
{
|
||||
var target = "webgl.wasm.framework.unityweb.js";
|
||||
var dotnetJsPath =
|
||||
Path.Combine(config.ProjectConf.DST, webglDir, "Code", "wwwroot", "_framework", "dotnet.js");
|
||||
var dotnetJs = File.ReadAllText(dotnetJsPath, Encoding.UTF8);
|
||||
// todo: handle dotnet js
|
||||
Rule[] rules =
|
||||
{
|
||||
new Rule()
|
||||
{
|
||||
old = "import\\.meta\\.url",
|
||||
newStr = $"pathToFileURL('/{frameworkDir}/webgl.wasm.framework.unityweb.js')",
|
||||
},
|
||||
new Rule()
|
||||
{
|
||||
old = " *(\\w*) *= *(\\w*)\\(\"js-module-runtime\"\\) *, *(\\w*) *= *(\\w*)\\(\"js-module-native\"\\)",
|
||||
newStr = $" $1 = $2(\"js-module-runtime\"), $3 = $4(\"js-module-native\"); $1.resolvedUrl = \"{Path.GetFileName(GetWeixinMiniGameFilePath("jsModuleRuntime")[0])}\";$3.resolvedUrl = \"{Path.GetFileName(GetWeixinMiniGameFilePath("jsModuleNative")[0])}\";",
|
||||
},
|
||||
new Rule()
|
||||
{
|
||||
old = "export *\\{ *(.*) *as *default *,(.*) *as *dotnet *,(.*) *as *exit *\\} *;",
|
||||
newStr = "return {legacyEntrypoint: $1, dotnet: $2, exit: $3}",
|
||||
},
|
||||
new Rule()
|
||||
{ // add symbol property for monoToBlazorAssetTypeMap
|
||||
old = "\"js-module-runtime\": *\"dotnetjs\", *\"js-module-threads\": *\"dotnetjs\"",
|
||||
newStr = "\"js-module-runtime\": \"dotnetjs\", \"js-module-threads\": \"dotnetjs\", \"symbols\": \"symbols\"",
|
||||
},
|
||||
new Rule()
|
||||
{
|
||||
old = "_e *\\|\\| *\"function\" *== *typeof *globalThis.URL[\\s\\S]*asm-features\"\\);",
|
||||
newStr = ""
|
||||
},
|
||||
new Rule()
|
||||
{
|
||||
old = "if *\\(!\\(ENVIRONMENT_IS_SHELL *\\|\\| *typeof *globalThis.URL *=== *\"function\"\\)\\)[\\s\\S]*BigInt64Array *API. *Please *use *a *modern *version. *See *also *https:\\/\\/aka.ms\\/dotnet\\-wasm\\-features\"\\);",
|
||||
newStr = ""
|
||||
}
|
||||
};
|
||||
foreach (var rule in rules)
|
||||
{
|
||||
if (ShowMatchFailedWarning(dotnetJs, rule.old, "dotnet") == false) {
|
||||
dotnetJs = Regex.Replace(dotnetJs, rule.old, rule.newStr);
|
||||
}
|
||||
}
|
||||
var header = @"WebAssembly.validate = () => true;
|
||||
const dotnet = (function () {";
|
||||
var footer = @"})();
|
||||
|
||||
function pathToFileURL(path) {
|
||||
return `file://${path}`;
|
||||
}
|
||||
|
||||
const wxFetchFile = async (url, config) => new Promise((resolve, reject) => {
|
||||
const folderPath = `${GameGlobal.manager.PLUGIN_CACHE_PATH}/${config.hash}`;
|
||||
const filePath = `${folderPath}/${config.filename}`;
|
||||
const fs = wx.getFileSystemManager();
|
||||
var readFile = fs.readFile;
|
||||
const readFileInfo = {
|
||||
filePath: filePath,
|
||||
success: async (res) => {
|
||||
resolve(res.data);
|
||||
},
|
||||
fail: (err) => {
|
||||
reject(err);
|
||||
}
|
||||
}
|
||||
if (config.brotli) {
|
||||
readFile = fs.readCompressedFile;
|
||||
readFileInfo.compressionAlgorithm = 'br';
|
||||
}
|
||||
const downloadFileInfo = {
|
||||
url: url,
|
||||
success: (res) => {
|
||||
if (res.statusCode === 200) {
|
||||
try {
|
||||
fs.accessSync(folderPath);
|
||||
} catch (e) {
|
||||
fs.mkdirSync(folderPath, true);
|
||||
}
|
||||
saveFile(res.tempFilePath, filePath, res.dataLength);
|
||||
} else {
|
||||
reject(res);
|
||||
}
|
||||
},
|
||||
fail: (err) => {
|
||||
reject(err);
|
||||
}
|
||||
};
|
||||
const saveFile = (tempFilePath, filePath, dataLength, retry = 0) => {
|
||||
try {
|
||||
fs.saveFileSync(tempFilePath, filePath);
|
||||
readFile(readFileInfo);
|
||||
} catch (e) {
|
||||
if (e.message === 'saveFileSync:fail exceeded the maximum size of the file storage limit') {
|
||||
if (retry < 3) {
|
||||
GameGlobal.manager.cleanCache(dataLength).then(() => {
|
||||
saveFile(tempFilePath, filePath, dataLength, ++retry);
|
||||
});
|
||||
} else {
|
||||
GameGlobal.manager.cleanAllCache().then(() => {
|
||||
wx.downloadFile(downloadFileInfo);
|
||||
});
|
||||
}
|
||||
} else {
|
||||
reject(e);
|
||||
}
|
||||
}
|
||||
};
|
||||
// if not use cache or cache not exists, download file
|
||||
fs.access({
|
||||
path: filePath,
|
||||
success: (res) => {
|
||||
if (config.cache && res.errMsg === 'access:ok') {
|
||||
readFile(readFileInfo);
|
||||
} else {
|
||||
wx.downloadFile(downloadFileInfo);
|
||||
}
|
||||
},
|
||||
fail: (err) => {
|
||||
wx.downloadFile(downloadFileInfo);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
dotnet.dotnet.withResourceLoader((resourceType, assetName, url, requestHash, behavior) => {
|
||||
const remoteUrl = `${GameGlobal.unityNamespace.DATA_CDN}Code/wwwroot/_framework/${assetName}`;
|
||||
switch (resourceType) {
|
||||
case 'dotnetjs':
|
||||
return assetName;
|
||||
case 'manifest':
|
||||
return new Promise((resolve, reject) => {
|
||||
wx.request({
|
||||
url: remoteUrl,
|
||||
success: (res) => {
|
||||
resolve({
|
||||
json: async () => res.data,
|
||||
headers: {
|
||||
get: () => undefined
|
||||
}
|
||||
});
|
||||
},
|
||||
fail: (err) => {
|
||||
reject(err);
|
||||
}
|
||||
});
|
||||
});
|
||||
case 'symbols':
|
||||
case 'dotnetwasm':
|
||||
return new Promise((resolve, reject) => {
|
||||
resolve({
|
||||
arrayBuffer: async () => undefined,
|
||||
status: 200,
|
||||
ok: true
|
||||
})
|
||||
});
|
||||
case 'assembly':
|
||||
const config = {
|
||||
filename: assetName + '.br',
|
||||
cache: true,
|
||||
hash: requestHash,
|
||||
brotli: true
|
||||
};
|
||||
return wxFetchFile(remoteUrl + '.br', config).then(res => ({
|
||||
arrayBuffer: async () => res,
|
||||
status: 200,
|
||||
ok: true,
|
||||
}));
|
||||
default:
|
||||
return url;
|
||||
}
|
||||
});
|
||||
var executed = false;
|
||||
var unityFramework = function (module) {
|
||||
if (executed) return;
|
||||
executed = true;
|
||||
module['noInitialRun'] = true;
|
||||
return (dotnet.legacyEntrypoint(module)).then(() => {
|
||||
module['callMain']();
|
||||
});
|
||||
};
|
||||
if (typeof exports === 'object' && typeof module === 'object') module.exports = unityFramework;
|
||||
else if (typeof define === 'function' && define['amd']) define([], function () {
|
||||
return unityFramework;
|
||||
});
|
||||
else if (typeof exports === 'object') exports['unityFramework'] = unityFramework;
|
||||
GameGlobal.unityNamespace.UnityModule = unityFramework;";
|
||||
File.WriteAllText(Path.Combine(config.ProjectConf.DST, miniGameDir, frameworkDir, target), header + dotnetJs + footer, new UTF8Encoding(false));
|
||||
}
|
||||
|
||||
private static void ConvertCode()
|
||||
{
|
||||
UnityEngine.Debug.LogFormat("[Converter] Starting to adapt framewor. Dst: " + config.ProjectConf.DST);
|
||||
|
||||
UnityUtil.DelectDir(Path.Combine(config.ProjectConf.DST, miniGameDir));
|
||||
string text = String.Empty;
|
||||
var target = "webgl.wasm.framework.unityweb.js";
|
||||
if (WXExtEnvDef.GETDEF("UNITY_2020_1_OR_NEWER"))
|
||||
{
|
||||
text = File.ReadAllText(Path.Combine(config.ProjectConf.DST, webglDir, "Build", "webgl.framework.js"), Encoding.UTF8);
|
||||
if (UseIL2CPP)
|
||||
{
|
||||
text = File.ReadAllText(Path.Combine(config.ProjectConf.DST, webglDir, "Build", "webgl.framework.js"), Encoding.UTF8);
|
||||
}
|
||||
else
|
||||
{
|
||||
var frameworkPath = GetWeixinMiniGameFilePath("jsModuleNative")[0];
|
||||
target = Path.GetFileName(frameworkPath);
|
||||
text = File.ReadAllText(frameworkPath, Encoding.UTF8);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -266,7 +523,10 @@ namespace WeChatWASM
|
||||
for (i = 0; i < ReplaceRules.rules.Length; i++)
|
||||
{
|
||||
var rule = ReplaceRules.rules[i];
|
||||
text = Regex.Replace(text, rule.old, rule.newStr);
|
||||
// text = Regex.Replace(text, rule.old, rule.newStr);
|
||||
if (ShowMatchFailedWarning(text, rule.old, "WXReplaceRules") == false) {
|
||||
text = Regex.Replace(text, rule.old, rule.newStr);
|
||||
}
|
||||
}
|
||||
string[] prefixs =
|
||||
{
|
||||
@ -318,7 +578,7 @@ namespace WeChatWASM
|
||||
{
|
||||
text += ";GameGlobal.unityNamespace.UnityModule = tuanjieFramework;";
|
||||
}
|
||||
else
|
||||
else if (UseIL2CPP)
|
||||
{
|
||||
if (text.StartsWith("(") && text.EndsWith(")"))
|
||||
{
|
||||
@ -333,8 +593,13 @@ namespace WeChatWASM
|
||||
Directory.CreateDirectory(Path.Combine(config.ProjectConf.DST, miniGameDir));
|
||||
}
|
||||
|
||||
var header = "function createWebAudio(){window.AudioContext=window.AudioContext||window.webkitAudioContext;if(window.AudioContext){return new AudioContext();}return wx.createWebAudioContext();}\n";
|
||||
if (!Directory.Exists(Path.Combine(config.ProjectConf.DST, miniGameDir, frameworkDir)))
|
||||
{
|
||||
Directory.CreateDirectory(Path.Combine(config.ProjectConf.DST, miniGameDir, frameworkDir));
|
||||
}
|
||||
|
||||
var header = "var OriginalAudioContext = window.AudioContext || window.webkitAudioContext;window.AudioContext = function() {if (this instanceof window.AudioContext) {return wx.createWebAudioContext();} else {return new OriginalAudioContext();}};";
|
||||
|
||||
if (config.CompileOptions.DevelopBuild)
|
||||
{
|
||||
header = header + RenderAnalysisRules.header;
|
||||
@ -346,8 +611,50 @@ namespace WeChatWASM
|
||||
}
|
||||
|
||||
text = header + text;
|
||||
if (!UseIL2CPP)
|
||||
{
|
||||
Rule[] nativeRules =
|
||||
{
|
||||
new Rule()
|
||||
{
|
||||
old = "if\\(Module\\.IsWxGame\\)return Math\\.random\\(\\)\\*256\\|0;abort\\(\"randomDevice\"\\)",
|
||||
newStr = "{if(Module.IsWxGame)return Math.random()*256|0;abort(\"randomDevice\")}"
|
||||
},
|
||||
new Rule()
|
||||
{
|
||||
old = "var *_scriptDir *= *import\\.meta\\.url;",
|
||||
newStr = $"var _scriptDir = \"file:///framework/webgl.wasm.framework.unityweb.js\"",
|
||||
},
|
||||
new Rule()
|
||||
{
|
||||
old = "import\\.meta\\.url",
|
||||
newStr = "_scriptDir"
|
||||
},
|
||||
new Rule()
|
||||
{
|
||||
old = "Module\\[['\"](HEAP[U,F,1-9]*)['\"]\\] *=",
|
||||
newStr = "Module['$1'] = GameGlobal.unityNamespace.Module['$1'] =",
|
||||
},
|
||||
new Rule()
|
||||
{
|
||||
old = "return *handleException\\(e\\);?",
|
||||
newStr = "return handleException(e);} finally {if (ABORT === true) return; if (Module.calledMainCb) Module.calledMainCb(); if (GameGlobal.unityNamespace.enableProfileStats) {setTimeout(() => {SendMessage('WXSDKManagerHandler', 'OpenProfileStats');}, 10000);}"
|
||||
},
|
||||
new Rule()
|
||||
{
|
||||
old = "function *callMain\\(args *= *\\[\\]\\)",
|
||||
newStr = "Object.keys(Module).forEach(key=>{if(!(key in Object.keys(GameGlobal.unityNamespace.Module))){GameGlobal.unityNamespace.Module[key]=Module[key];}});function callMain(args = [])"
|
||||
},
|
||||
};
|
||||
foreach (var rule in nativeRules)
|
||||
{
|
||||
if (ShowMatchFailedWarning(text, rule.old, "native") == false) {
|
||||
text = Regex.Replace(text, rule.old, rule.newStr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
File.WriteAllText(Path.Combine(config.ProjectConf.DST, miniGameDir, "webgl.wasm.framework.unityweb.js"), text, new UTF8Encoding(false));
|
||||
File.WriteAllText(Path.Combine(config.ProjectConf.DST, miniGameDir, target), text, new UTF8Encoding(false));
|
||||
|
||||
UnityEngine.Debug.LogFormat("[Converter] adapt framework done! ");
|
||||
}
|
||||
@ -358,7 +665,8 @@ 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";
|
||||
// PlayerSettings.WeixinMiniGame.emscriptenArgs += " -s EXPORTED_FUNCTIONS=_main,_sbrk,_emscripten_stack_get_base,_emscripten_stack_get_end";
|
||||
PlayerSettings.WeixinMiniGame.emscriptenArgs += " -s EXPORTED_FUNCTIONS=_sbrk,_emscripten_stack_get_base,_emscripten_stack_get_end";
|
||||
}
|
||||
|
||||
#else
|
||||
@ -518,6 +826,13 @@ namespace WeChatWASM
|
||||
}
|
||||
}
|
||||
|
||||
private static string[] GetWeixinMiniGameFilePath(string key)
|
||||
{
|
||||
var bootJson = Path.Combine(config.ProjectConf.DST, webglDir, "Code", "wwwroot", "_framework", "blazor.boot.json");
|
||||
var boot = JsonMapper.ToObject(File.ReadAllText(bootJson, Encoding.UTF8));
|
||||
return boot["resources"][key].Keys.Select(file => Path.Combine(config.ProjectConf.DST, webglDir, "Code", "wwwroot", "_framework", file)).ToArray();
|
||||
}
|
||||
|
||||
private static void finishExport()
|
||||
{
|
||||
int code = GenerateBinFile();
|
||||
@ -692,7 +1007,14 @@ namespace WeChatWASM
|
||||
{
|
||||
if (WXExtEnvDef.GETDEF("UNITY_2020_1_OR_NEWER"))
|
||||
{
|
||||
return Path.Combine(config.ProjectConf.DST, webglDir, "Build", "webgl.wasm");
|
||||
if (UseIL2CPP)
|
||||
{
|
||||
return Path.Combine(config.ProjectConf.DST, webglDir, "Build", "webgl.wasm");
|
||||
}
|
||||
else
|
||||
{
|
||||
return GetWeixinMiniGameFilePath("wasmNative")[0];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -1073,6 +1395,7 @@ namespace WeChatWASM
|
||||
IsInstantGameAutoStreaming() ? "true" : "false",
|
||||
(config.CompileOptions.DevelopBuild && config.CompileOptions.enableRenderAnalysis) ? "true" : "false",
|
||||
config.ProjectConf.IOSDevicePixelRatio.ToString(),
|
||||
UseIL2CPP ? "" : "/framework",
|
||||
});
|
||||
|
||||
List<Rule> replaceList = new List<Rule>(replaceArrayList);
|
||||
@ -1238,6 +1561,15 @@ namespace WeChatWASM
|
||||
return "";
|
||||
#endif
|
||||
}
|
||||
|
||||
public static bool ShowMatchFailedWarning(string text, string rule, string file)
|
||||
{
|
||||
if (Regex.IsMatch(text, rule) == false) {
|
||||
Debug.LogWarning($"UnMatched {file} rule: {rule}");
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
605
Editor/WXEditorSettingHelper.cs
Normal file
605
Editor/WXEditorSettingHelper.cs
Normal file
@ -0,0 +1,605 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEditor;
|
||||
using System.IO;
|
||||
using static WeChatWASM.WXConvertCore;
|
||||
using System;
|
||||
using System.Reflection;
|
||||
|
||||
namespace WeChatWASM
|
||||
{
|
||||
|
||||
[InitializeOnLoad]
|
||||
public class WXSettingsHelperInterface
|
||||
{
|
||||
public static WXSettingsHelper helper = new WXSettingsHelper();
|
||||
}
|
||||
|
||||
public class WXSettingsHelper
|
||||
{
|
||||
public WXSettingsHelper()
|
||||
{
|
||||
Type weixinMiniGamePackageHelpersType = Type.GetType("UnityEditor.WeixinPackageHelpers,UnityEditor");
|
||||
if (weixinMiniGamePackageHelpersType == null)
|
||||
{
|
||||
weixinMiniGamePackageHelpersType = Type.GetType("UnityEditor.WeixinMiniGamePackageHelpers,UnityEditor");
|
||||
}
|
||||
if (weixinMiniGamePackageHelpersType != null)
|
||||
{
|
||||
EventInfo onSettingsGUIEvent = weixinMiniGamePackageHelpersType.GetEvent("OnPackageSettingsGUI");
|
||||
EventInfo onPackageFocusEvent = weixinMiniGamePackageHelpersType.GetEvent("OnPackageFocus");
|
||||
EventInfo onPackageLostFocusEvent = weixinMiniGamePackageHelpersType.GetEvent("OnPackageLostFocus");
|
||||
EventInfo onBuildButtonGUIEvent = weixinMiniGamePackageHelpersType.GetEvent("OnPackageBuildButtonGUI");
|
||||
|
||||
if (onPackageFocusEvent != null)
|
||||
{
|
||||
onPackageFocusEvent.AddEventHandler(null, new Action(OnFocus));
|
||||
}
|
||||
|
||||
if (onPackageLostFocusEvent != null)
|
||||
{
|
||||
onPackageLostFocusEvent.AddEventHandler(null, new Action(OnLostFocus));
|
||||
}
|
||||
if (onSettingsGUIEvent != null)
|
||||
{
|
||||
onSettingsGUIEvent.AddEventHandler(null, new Action<EditorWindow>(OnSettingsGUI));
|
||||
}
|
||||
if (onBuildButtonGUIEvent != null)
|
||||
{
|
||||
onBuildButtonGUIEvent.AddEventHandler(null, new Action<EditorWindow>(OnBuildButtonGUI));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
loadData();
|
||||
foldInstantGame = WXConvertCore.IsInstantGameAutoStreaming();
|
||||
}
|
||||
|
||||
private static WXEditorScriptObject config = UnityUtil.GetEditorConf();
|
||||
|
||||
|
||||
public void OnFocus()
|
||||
{
|
||||
loadData();
|
||||
}
|
||||
|
||||
public void OnLostFocus()
|
||||
{
|
||||
saveData();
|
||||
}
|
||||
|
||||
public void OnDisable()
|
||||
{
|
||||
EditorUtility.SetDirty(config);
|
||||
}
|
||||
|
||||
public Texture tex;
|
||||
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("cdn", "游戏资源CDN");
|
||||
this.formInput("projectName", "小游戏项目名");
|
||||
this.formIntPopup("orientation", "游戏方向", new[] { "Portrait", "Landscape", "LandscapeLeft", "LandscapeRight" }, 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("导出路径", 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(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();
|
||||
}
|
||||
|
||||
foldLoadingConfig = EditorGUILayout.Foldout(foldLoadingConfig, "启动Loading配置");
|
||||
if (foldLoadingConfig)
|
||||
{
|
||||
EditorGUILayout.BeginVertical("frameBox", GUILayout.ExpandWidth(true));
|
||||
|
||||
GUILayout.BeginHorizontal();
|
||||
string targetBg = "bgImageSrc";
|
||||
EditorGUILayout.LabelField(string.Empty, GUILayout.Width(10));
|
||||
tex = (Texture)EditorGUILayout.ObjectField("启动背景图/视频封面", tex, typeof(Texture2D), false);
|
||||
var currentBgSrc = AssetDatabase.GetAssetPath(tex);
|
||||
if (!string.IsNullOrEmpty(currentBgSrc) && currentBgSrc != this.formInputData[targetBg])
|
||||
{
|
||||
this.formInputData[targetBg] = currentBgSrc;
|
||||
this.saveData();
|
||||
}
|
||||
GUILayout.EndHorizontal();
|
||||
|
||||
this.formInput("videoUrl", "加载阶段视频URL");
|
||||
this.formIntPopup("assetLoadType", "首包资源加载方式", new[] { "CDN", "小游戏包内" }, new[] { 0, 1 });
|
||||
this.formCheckbox("compressDataPackage", "压缩首包资源(?)", "将首包资源Brotli压缩, 降低资源大小. 注意: 首次启动耗时可能会增加200ms, 仅推荐使用小游戏分包加载时节省包体大小使用");
|
||||
this.formInput("bundleExcludeExtensions", "不自动缓存文件类型(?)", "(使用;分割)当请求url包含资源'cdn+StreamingAssets'时会自动缓存,但StreamingAssets目录下不是所有文件都需缓存,此选项配置不需要自动缓存的文件拓展名。默认值json");
|
||||
this.formInput("bundleHashLength", "Bundle名称Hash长度(?)", "自定义Bundle文件名中hash部分长度,默认值32,用于缓存控制。");
|
||||
this.formInput("preloadFiles", "预下载文件列表(?)", "使用;间隔,支持模糊匹配");
|
||||
|
||||
EditorGUILayout.EndVertical();
|
||||
}
|
||||
|
||||
foldSDKOptions = EditorGUILayout.Foldout(foldSDKOptions, "SDK功能选项");
|
||||
if (foldSDKOptions)
|
||||
{
|
||||
EditorGUILayout.BeginVertical("frameBox", GUILayout.ExpandWidth(true));
|
||||
|
||||
this.formCheckbox("useFriendRelation", "使用好友关系链");
|
||||
this.formCheckbox("useMiniGameChat", "使用社交组件");
|
||||
this.formCheckbox("preloadWXFont", "预加载微信字体(?)", "在game.js执行开始时预载微信系统字体,运行期间可使用WX.GetWXFont获取微信字体");
|
||||
|
||||
EditorGUILayout.EndVertical();
|
||||
}
|
||||
|
||||
foldDebugOptions = EditorGUILayout.Foldout(foldDebugOptions, "调试编译选项");
|
||||
if (foldDebugOptions)
|
||||
{
|
||||
EditorGUILayout.BeginVertical("frameBox", GUILayout.ExpandWidth(true));
|
||||
|
||||
|
||||
this.formCheckbox("developBuild", "Development Build");
|
||||
this.formCheckbox("autoProfile", "Auto connect Profiler");
|
||||
this.formCheckbox("scriptOnly", "Scripts Only Build");
|
||||
this.formCheckbox("il2CppOptimizeSize", "Il2Cpp Optimize Size(?)", "对应于Il2CppCodeGeneration选项,勾选时使用OptimizeSize(默认推荐),生成代码小15%左右,取消勾选则使用OptimizeSpeed。游戏中大量泛型集合的高频访问建议OptimizeSpeed,在使用HybridCLR等第三方组件时只能用OptimizeSpeed。(Dotnet Runtime模式下该选项无效)", !UseIL2CPP);
|
||||
this.formCheckbox("profilingFuncs", "Profiling Funcs");
|
||||
this.formCheckbox("profilingMemory", "Profiling Memory");
|
||||
this.formCheckbox("webgl2", "WebGL2.0(beta)");
|
||||
this.formCheckbox("iOSPerformancePlus", "iOSPerformancePlus(?)", "是否使用iOS高性能+渲染方案,有助于提升渲染兼容性、降低WebContent进程内存");
|
||||
this.formCheckbox("deleteStreamingAssets", "Clear Streaming Assets");
|
||||
this.formCheckbox("cleanBuild", "Clean WebGL Build");
|
||||
// this.formCheckbox("cleanCloudDev", "Clean Cloud Dev");
|
||||
this.formCheckbox("fbslim", "首包资源优化(?)", "导出时自动清理UnityEditor默认打包但游戏项目从未使用的资源,瘦身首包资源体积,建议所有游戏启用。(Dotnet Runtime模式下该选项暂不支持)", !UseIL2CPP, (res) =>
|
||||
{
|
||||
var fbWin = EditorWindow.GetWindow(typeof(WXFbSettingWindow), false, "首包资源优化配置面板", true);
|
||||
fbWin.minSize = new Vector2(680, 350);
|
||||
fbWin.Show();
|
||||
});
|
||||
this.formCheckbox("showMonitorSuggestModal", "显示优化建议弹窗");
|
||||
this.formCheckbox("enableProfileStats", "显示性能面板");
|
||||
this.formCheckbox("enableRenderAnalysis", "显示渲染日志(dev only)");
|
||||
EditorGUILayout.EndVertical();
|
||||
}
|
||||
|
||||
#if UNITY_INSTANTGAME
|
||||
foldInstantGame = EditorGUILayout.Foldout(foldInstantGame, "Instant Game - AutoStreaming");
|
||||
if (foldInstantGame)
|
||||
{
|
||||
EditorGUILayout.BeginVertical("frameBox", GUILayout.ExpandWidth(true));
|
||||
this.formInput("bundlePathIdentifier", "Bundle Path Identifier");
|
||||
this.formInput("dataFileSubPrefix", "Data File Sub Prefix");
|
||||
|
||||
EditorGUI.BeginDisabledGroup(true);
|
||||
this.formCheckbox("autoUploadFirstBundle", "构建后自动上传首包(?)", "仅在开启AutoStreaming生效", true);
|
||||
EditorGUI.EndDisabledGroup();
|
||||
|
||||
GUILayout.BeginHorizontal();
|
||||
EditorGUILayout.LabelField(string.Empty, GUILayout.Width(10));
|
||||
GUILayout.Label(new GUIContent("清理AS配置(?)", "如需关闭AutoStreaming选用默认发布方案则需要清理AS配置项目。"), GUILayout.Width(140));
|
||||
EditorGUI.BeginDisabledGroup(WXConvertCore.IsInstantGameAutoStreaming());
|
||||
if(GUILayout.Button(new GUIContent("恢复"),GUILayout.Width(60))){
|
||||
string identifier = config.ProjectConf.bundlePathIdentifier;
|
||||
string[] identifiers = identifier.Split(";");
|
||||
string idStr = "";
|
||||
foreach (string id in identifiers)
|
||||
{
|
||||
if (id != "AS" && id != "CUS/CustomAB")
|
||||
{
|
||||
idStr += id + ";";
|
||||
}
|
||||
}
|
||||
config.ProjectConf.bundlePathIdentifier = idStr.Trim(';');
|
||||
if (config.ProjectConf.dataFileSubPrefix == "CUS")
|
||||
{
|
||||
config.ProjectConf.dataFileSubPrefix = "";
|
||||
}
|
||||
this.loadData();
|
||||
}
|
||||
EditorGUI.EndDisabledGroup();
|
||||
GUILayout.EndHorizontal();
|
||||
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
EditorGUILayout.LabelField(string.Empty);
|
||||
if (GUILayout.Button(new GUIContent("了解Instant Game AutoStreaming", ""), linkStyle))
|
||||
{
|
||||
Application.OpenURL("https://github.com/wechat-miniprogram/minigame-unity-webgl-transform/blob/main/Design/InstantGameGuide.md");
|
||||
}
|
||||
EditorGUILayout.EndHorizontal();
|
||||
EditorGUILayout.EndVertical();
|
||||
}
|
||||
#endif
|
||||
|
||||
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();
|
||||
if (GUILayout.Button(new GUIContent("更多配置项"), GUILayout.Width(100), GUILayout.Height(25)))
|
||||
{
|
||||
var config = AssetDatabase.LoadAssetAtPath<UnityEngine.Object>("Assets/WX-WASM-SDK-V2/Editor/MiniGameConfig.asset");
|
||||
Selection.activeObject = config;
|
||||
GUIUtility.ExitGUI();
|
||||
}
|
||||
if (GUILayout.Button(new GUIContent("WebGL转小游戏(不常用)"), GUILayout.Width(150), GUILayout.Height(25)))
|
||||
{
|
||||
this.saveData();
|
||||
if (WXConvertCore.DoExport(false) == WXConvertCore.WXExportError.SUCCEED)
|
||||
{
|
||||
window.ShowNotification(new GUIContent("转换完成"));
|
||||
}
|
||||
|
||||
GUIUtility.ExitGUI();
|
||||
}
|
||||
EditorGUILayout.LabelField(string.Empty, GUILayout.MinWidth(10));
|
||||
if (GUILayout.Button(new GUIContent("生成并转换"), GUILayout.Width(100), GUILayout.Height(25)))
|
||||
{
|
||||
this.saveData();
|
||||
if (WXConvertCore.DoExport() == WXConvertCore.WXExportError.SUCCEED)
|
||||
{
|
||||
if (!WXConvertCore.IsInstantGameAutoStreaming())
|
||||
window.ShowNotification(new GUIContent("转换完成"));
|
||||
else
|
||||
{
|
||||
#if (UNITY_WEBGL || WEIXINMINIGAME) && UNITY_INSTANTGAME
|
||||
// 上传首包资源
|
||||
if (!string.IsNullOrEmpty(WXConvertCore.FirstBundlePath) && File.Exists(WXConvertCore.FirstBundlePath))
|
||||
{
|
||||
if (Unity.InstantGame.IGBuildPipeline.UploadWeChatDataFile(WXConvertCore.FirstBundlePath))
|
||||
{
|
||||
Debug.Log("转换完成并成功上传首包资源");
|
||||
window.ShowNotification(new GUIContent("转换完成并成功上传"));
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogError("首包资源上传失败,请检查网络以及Auto Streaming配置是否正确。");
|
||||
window.ShowNotification(new GUIContent("上传失败"));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogError("转换失败");
|
||||
window.ShowNotification(new GUIContent("转换失败"));
|
||||
}
|
||||
#else
|
||||
window.ShowNotification(new GUIContent("转换完成"));
|
||||
#endif
|
||||
}
|
||||
}
|
||||
GUIUtility.ExitGUI();
|
||||
}
|
||||
EditorGUILayout.EndHorizontal();
|
||||
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
EditorGUILayout.LabelField(string.Empty);
|
||||
if (GUILayout.Button(new GUIContent("了解如何实现自定义构建", ""), linkStyle))
|
||||
{
|
||||
Application.OpenURL("https://github.com/wechat-miniprogram/minigame-unity-webgl-transform/blob/main/Design/DevelopmentQAList.md#13%E5%A6%82%E4%BD%95%E8%87%AA%E5%AE%9A%E4%B9%89%E6%8E%A5%E5%85%A5%E6%9E%84%E5%BB%BA%E6%B5%81%E7%A8%8B");
|
||||
GUIUtility.ExitGUI();
|
||||
}
|
||||
EditorGUILayout.EndHorizontal();
|
||||
}
|
||||
|
||||
private Vector2 scrollRoot;
|
||||
private bool foldBaseInfo = true;
|
||||
private bool foldLoadingConfig = true;
|
||||
private bool foldSDKOptions = true;
|
||||
private bool foldDebugOptions = true;
|
||||
private bool foldInstantGame = false;
|
||||
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 SDKFilePath;
|
||||
|
||||
private void addBundlePathIdentifier(string value)
|
||||
{
|
||||
string identifier = config.ProjectConf.bundlePathIdentifier;
|
||||
if (identifier[identifier.Length - 1] != ';')
|
||||
{
|
||||
identifier += ";";
|
||||
}
|
||||
identifier += value;
|
||||
config.ProjectConf.bundlePathIdentifier = identifier;
|
||||
}
|
||||
private void loadData()
|
||||
{
|
||||
// SDKFilePath = Path.Combine(Application.dataPath, "WX-WASM-SDK-V2", "Runtime", "wechat-default", "unity-sdk", "index.js");
|
||||
SDKFilePath = Path.Combine(UnityUtil.GetWxSDKRootPath(), "Runtime", "wechat-default", "unity-sdk", "index.js");
|
||||
config = UnityUtil.GetEditorConf();
|
||||
|
||||
// Instant Game
|
||||
if (WXConvertCore.IsInstantGameAutoStreaming())
|
||||
{
|
||||
config.ProjectConf.CDN = WXConvertCore.GetInstantGameAutoStreamingCDN();
|
||||
string identifier = config.ProjectConf.bundlePathIdentifier;
|
||||
string[] identifiers = identifier.Split(';');
|
||||
bool AS = false;
|
||||
bool CUS = false;
|
||||
foreach (string id in identifiers)
|
||||
{
|
||||
if (id == "AS")
|
||||
{
|
||||
AS = true;
|
||||
}
|
||||
if (id == "CUS/CustomAB")
|
||||
{
|
||||
CUS = true;
|
||||
}
|
||||
}
|
||||
if (!AS)
|
||||
{
|
||||
this.addBundlePathIdentifier("AS");
|
||||
}
|
||||
if (!CUS)
|
||||
{
|
||||
this.addBundlePathIdentifier("CUS/CustomAB");
|
||||
}
|
||||
if (config.ProjectConf.dataFileSubPrefix != "CUS")
|
||||
{
|
||||
config.ProjectConf.dataFileSubPrefix = "CUS";
|
||||
}
|
||||
}
|
||||
|
||||
this.setData("projectName", config.ProjectConf.projectName);
|
||||
this.setData("appid", config.ProjectConf.Appid);
|
||||
this.setData("cdn", config.ProjectConf.CDN);
|
||||
this.setData("assetLoadType", config.ProjectConf.assetLoadType);
|
||||
this.setData("compressDataPackage", config.ProjectConf.compressDataPackage);
|
||||
this.setData("videoUrl", config.ProjectConf.VideoUrl);
|
||||
this.setData("orientation", (int)config.ProjectConf.Orientation);
|
||||
this.setData("dst", config.ProjectConf.DST);
|
||||
this.setData("bundleHashLength", config.ProjectConf.bundleHashLength.ToString());
|
||||
this.setData("bundlePathIdentifier", config.ProjectConf.bundlePathIdentifier);
|
||||
this.setData("bundleExcludeExtensions", config.ProjectConf.bundleExcludeExtensions);
|
||||
this.setData("preloadFiles", config.ProjectConf.preloadFiles);
|
||||
this.setData("developBuild", config.CompileOptions.DevelopBuild);
|
||||
this.setData("autoProfile", config.CompileOptions.AutoProfile);
|
||||
this.setData("scriptOnly", config.CompileOptions.ScriptOnly);
|
||||
this.setData("il2CppOptimizeSize", config.CompileOptions.Il2CppOptimizeSize);
|
||||
this.setData("profilingFuncs", config.CompileOptions.profilingFuncs);
|
||||
this.setData("profilingMemory", config.CompileOptions.ProfilingMemory);
|
||||
this.setData("deleteStreamingAssets", config.CompileOptions.DeleteStreamingAssets);
|
||||
this.setData("cleanBuild", config.CompileOptions.CleanBuild);
|
||||
this.setData("customNodePath", config.CompileOptions.CustomNodePath);
|
||||
this.setData("webgl2", config.CompileOptions.Webgl2);
|
||||
this.setData("iOSPerformancePlus", config.CompileOptions.enableIOSPerformancePlus);
|
||||
this.setData("fbslim", config.CompileOptions.fbslim);
|
||||
this.setData("useFriendRelation", config.SDKOptions.UseFriendRelation);
|
||||
this.setData("useMiniGameChat", config.SDKOptions.UseMiniGameChat);
|
||||
this.setData("preloadWXFont", config.SDKOptions.PreloadWXFont);
|
||||
this.setData("bgImageSrc", config.ProjectConf.bgImageSrc);
|
||||
tex = AssetDatabase.LoadAssetAtPath<Texture>(config.ProjectConf.bgImageSrc);
|
||||
this.setData("memorySize", config.ProjectConf.MemorySize.ToString());
|
||||
this.setData("hideAfterCallMain", config.ProjectConf.HideAfterCallMain);
|
||||
|
||||
this.setData("dataFileSubPrefix", config.ProjectConf.dataFileSubPrefix);
|
||||
this.setData("maxStorage", config.ProjectConf.maxStorage.ToString());
|
||||
this.setData("defaultReleaseSize", config.ProjectConf.defaultReleaseSize.ToString());
|
||||
this.setData("texturesHashLength", config.ProjectConf.texturesHashLength.ToString());
|
||||
this.setData("texturesPath", config.ProjectConf.texturesPath);
|
||||
this.setData("needCacheTextures", config.ProjectConf.needCacheTextures);
|
||||
this.setData("loadingBarWidth", config.ProjectConf.loadingBarWidth.ToString());
|
||||
this.setData("needCheckUpdate", config.ProjectConf.needCheckUpdate);
|
||||
this.setData("disableHighPerformanceFallback", config.ProjectConf.disableHighPerformanceFallback);
|
||||
this.setData("showMonitorSuggestModal", config.CompileOptions.showMonitorSuggestModal);
|
||||
this.setData("enableProfileStats", config.CompileOptions.enableProfileStats);
|
||||
this.setData("enableRenderAnalysis", config.CompileOptions.enableRenderAnalysis);
|
||||
this.setData("autoUploadFirstBundle", true);
|
||||
}
|
||||
|
||||
private void saveData()
|
||||
{
|
||||
config.ProjectConf.projectName = this.getDataInput("projectName");
|
||||
config.ProjectConf.Appid = this.getDataInput("appid");
|
||||
config.ProjectConf.CDN = this.getDataInput("cdn");
|
||||
config.ProjectConf.assetLoadType = this.getDataPop("assetLoadType");
|
||||
config.ProjectConf.compressDataPackage = this.getDataCheckbox("compressDataPackage");
|
||||
config.ProjectConf.VideoUrl = this.getDataInput("videoUrl");
|
||||
config.ProjectConf.Orientation = (WXScreenOritation)this.getDataPop("orientation");
|
||||
config.ProjectConf.DST = this.getDataInput("dst");
|
||||
config.ProjectConf.bundleHashLength = int.Parse(this.getDataInput("bundleHashLength"));
|
||||
config.ProjectConf.bundlePathIdentifier = this.getDataInput("bundlePathIdentifier");
|
||||
config.ProjectConf.bundleExcludeExtensions = this.getDataInput("bundleExcludeExtensions");
|
||||
config.ProjectConf.preloadFiles = this.getDataInput("preloadFiles");
|
||||
config.CompileOptions.DevelopBuild = this.getDataCheckbox("developBuild");
|
||||
config.CompileOptions.AutoProfile = this.getDataCheckbox("autoProfile");
|
||||
config.CompileOptions.ScriptOnly = this.getDataCheckbox("scriptOnly");
|
||||
config.CompileOptions.Il2CppOptimizeSize = this.getDataCheckbox("il2CppOptimizeSize");
|
||||
config.CompileOptions.profilingFuncs = this.getDataCheckbox("profilingFuncs");
|
||||
config.CompileOptions.ProfilingMemory = this.getDataCheckbox("profilingMemory");
|
||||
config.CompileOptions.DeleteStreamingAssets = this.getDataCheckbox("deleteStreamingAssets");
|
||||
config.CompileOptions.CleanBuild = this.getDataCheckbox("cleanBuild");
|
||||
config.CompileOptions.CustomNodePath = this.getDataInput("customNodePath");
|
||||
config.CompileOptions.Webgl2 = this.getDataCheckbox("webgl2");
|
||||
config.CompileOptions.enableIOSPerformancePlus = this.getDataCheckbox("iOSPerformancePlus");
|
||||
config.CompileOptions.fbslim = this.getDataCheckbox("fbslim");
|
||||
config.SDKOptions.UseFriendRelation = this.getDataCheckbox("useFriendRelation");
|
||||
config.SDKOptions.UseMiniGameChat = this.getDataCheckbox("useMiniGameChat");
|
||||
config.SDKOptions.PreloadWXFont = this.getDataCheckbox("preloadWXFont");
|
||||
config.ProjectConf.bgImageSrc = this.getDataInput("bgImageSrc");
|
||||
config.ProjectConf.MemorySize = int.Parse(this.getDataInput("memorySize"));
|
||||
config.ProjectConf.HideAfterCallMain = this.getDataCheckbox("hideAfterCallMain");
|
||||
config.ProjectConf.dataFileSubPrefix = this.getDataInput("dataFileSubPrefix");
|
||||
config.ProjectConf.maxStorage = int.Parse(this.getDataInput("maxStorage"));
|
||||
config.ProjectConf.defaultReleaseSize = int.Parse(this.getDataInput("defaultReleaseSize"));
|
||||
config.ProjectConf.texturesHashLength = int.Parse(this.getDataInput("texturesHashLength"));
|
||||
config.ProjectConf.texturesPath = this.getDataInput("texturesPath");
|
||||
config.ProjectConf.needCacheTextures = this.getDataCheckbox("needCacheTextures");
|
||||
config.ProjectConf.loadingBarWidth = int.Parse(this.getDataInput("loadingBarWidth"));
|
||||
config.ProjectConf.needCheckUpdate = this.getDataCheckbox("needCheckUpdate");
|
||||
config.ProjectConf.disableHighPerformanceFallback = this.getDataCheckbox("disableHighPerformanceFallback");
|
||||
config.CompileOptions.showMonitorSuggestModal = this.getDataCheckbox("showMonitorSuggestModal");
|
||||
config.CompileOptions.enableProfileStats = this.getDataCheckbox("enableProfileStats");
|
||||
config.CompileOptions.enableRenderAnalysis = this.getDataCheckbox("enableRenderAnalysis");
|
||||
}
|
||||
|
||||
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 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();
|
||||
}
|
||||
|
||||
private void formCheckbox(string target, string label, string help = null, bool disable = false, Action<bool> setting = 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);
|
||||
formCheckboxData[target] = EditorGUILayout.Toggle(disable ? false : formCheckboxData[target]);
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
11
Editor/WXEditorSettingHelper.cs.meta
Normal file
11
Editor/WXEditorSettingHelper.cs.meta
Normal file
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6aad761bd858d8d4880b225d799ed346
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -1,18 +1,12 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEditor;
|
||||
using System.IO;
|
||||
using static WeChatWASM.WXConvertCore;
|
||||
using System;
|
||||
|
||||
namespace WeChatWASM
|
||||
{
|
||||
|
||||
public class WXEditorWin : EditorWindow
|
||||
{
|
||||
private static WXEditorScriptObject config;
|
||||
private bool fbSlimSupport = true;
|
||||
[MenuItem("微信小游戏 / 转换小游戏", false, 1)]
|
||||
public static void Open()
|
||||
{
|
||||
@ -30,549 +24,25 @@ namespace WeChatWASM
|
||||
return WXConvertCore.DoExport(buildWebGL);
|
||||
}
|
||||
|
||||
// Start is called before the first frame update
|
||||
void Start()
|
||||
{
|
||||
foldInstantGame = WXConvertCore.IsInstantGameAutoStreaming();
|
||||
}
|
||||
|
||||
// Update is called once per frame
|
||||
void Update()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public void OnFocus()
|
||||
{
|
||||
loadData();
|
||||
WXSettingsHelperInterface.helper.OnFocus();
|
||||
}
|
||||
|
||||
public void OnLostFocus()
|
||||
{
|
||||
saveData();
|
||||
WXSettingsHelperInterface.helper.OnLostFocus();
|
||||
}
|
||||
|
||||
public void OnDisable()
|
||||
{
|
||||
EditorUtility.SetDirty(config);
|
||||
WXSettingsHelperInterface.helper.OnDisable();
|
||||
}
|
||||
|
||||
public Texture tex;
|
||||
public void OnGUI()
|
||||
{
|
||||
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");
|
||||
|
||||
this.formInput("appid", "游戏AppID");
|
||||
this.formInput("cdn", "游戏资源CDN");
|
||||
this.formInput("projectName", "小游戏项目名");
|
||||
this.formIntPopup("orientation", "游戏方向", new[] { "Portrait", "Landscape", "LandscapeLeft", "LandscapeRight" }, 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("导出路径", 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(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();
|
||||
}
|
||||
|
||||
foldLoadingConfig = EditorGUILayout.Foldout(foldLoadingConfig, "启动Loading配置");
|
||||
if (foldLoadingConfig)
|
||||
{
|
||||
EditorGUILayout.BeginVertical("frameBox");
|
||||
|
||||
GUILayout.BeginHorizontal();
|
||||
string targetBg = "bgImageSrc";
|
||||
EditorGUILayout.LabelField(string.Empty, GUILayout.Width(10));
|
||||
tex = (Texture)EditorGUILayout.ObjectField("启动背景图/视频封面", tex, typeof(Texture2D), false);
|
||||
var currentBgSrc = AssetDatabase.GetAssetPath(tex);
|
||||
if (!string.IsNullOrEmpty(currentBgSrc) && currentBgSrc != this.formInputData[targetBg])
|
||||
{
|
||||
this.formInputData[targetBg] = currentBgSrc;
|
||||
this.saveData();
|
||||
}
|
||||
GUILayout.EndHorizontal();
|
||||
|
||||
this.formInput("videoUrl", "加载阶段视频URL");
|
||||
this.formIntPopup("assetLoadType", "首包资源加载方式", new[] { "CDN", "小游戏包内" }, new[] { 0, 1 });
|
||||
this.formCheckbox("compressDataPackage", "压缩首包资源(?)", "将首包资源Brotli压缩, 降低资源大小. 注意: 首次启动耗时可能会增加200ms, 仅推荐使用小游戏分包加载时节省包体大小使用");
|
||||
this.formInput("bundleExcludeExtensions", "不自动缓存文件类型(?)", "(使用;分割)当请求url包含资源'cdn+StreamingAssets'时会自动缓存,但StreamingAssets目录下不是所有文件都需缓存,此选项配置不需要自动缓存的文件拓展名。默认值json");
|
||||
this.formInput("bundleHashLength", "Bundle名称Hash长度(?)", "自定义Bundle文件名中hash部分长度,默认值32,用于缓存控制。");
|
||||
this.formInput("preloadFiles", "预下载文件列表(?)", "使用;间隔,支持模糊匹配");
|
||||
|
||||
EditorGUILayout.EndVertical();
|
||||
}
|
||||
|
||||
foldSDKOptions = EditorGUILayout.Foldout(foldSDKOptions, "SDK功能选项");
|
||||
if (foldSDKOptions)
|
||||
{
|
||||
EditorGUILayout.BeginVertical("frameBox");
|
||||
|
||||
this.formCheckbox("useFriendRelation", "使用好友关系链");
|
||||
this.formCheckbox("useMiniGameChat", "使用社交组件");
|
||||
this.formCheckbox("preloadWXFont", "预加载微信字体(?)", "在game.js执行开始时预载微信系统字体,运行期间可使用WX.GetWXFont获取微信字体");
|
||||
|
||||
EditorGUILayout.EndVertical();
|
||||
}
|
||||
|
||||
foldDebugOptions = EditorGUILayout.Foldout(foldDebugOptions, "调试编译选项");
|
||||
if (foldDebugOptions)
|
||||
{
|
||||
EditorGUILayout.BeginVertical("frameBox");
|
||||
|
||||
|
||||
this.formCheckbox("developBuild", "Development Build");
|
||||
this.formCheckbox("autoProfile", "Auto connect Profiler");
|
||||
this.formCheckbox("scriptOnly", "Scripts Only Build");
|
||||
this.formCheckbox("il2CppOptimizeSize", "Il2Cpp Optimize Size(?)", "对应于Il2CppCodeGeneration选项,勾选时使用OptimizeSize(默认推荐),生成代码小15%左右,取消勾选则使用OptimizeSpeed。游戏中大量泛型集合的高频访问建议OptimizeSpeed,在使用HybridCLR等第三方组件时只能用OptimizeSpeed。");
|
||||
this.formCheckbox("profilingFuncs", "Profiling Funcs");
|
||||
this.formCheckbox("profilingMemory", "Profiling Memory");
|
||||
this.formCheckbox("webgl2", "WebGL2.0(beta)");
|
||||
this.formCheckbox("iOSPerformancePlus", "iOSPerformancePlus(?)", "是否使用iOS高性能+渲染方案,有助于提升渲染兼容性、降低WebContent进程内存");
|
||||
this.formCheckbox("deleteStreamingAssets", "Clear Streaming Assets");
|
||||
this.formCheckbox("cleanBuild", "Clean WebGL Build");
|
||||
// this.formCheckbox("cleanCloudDev", "Clean Cloud Dev");
|
||||
this.formCheckbox("fbslim", "首包资源优化(?)", "导出时自动清理UnityEditor默认打包但游戏项目从未使用的资源,瘦身首包资源体积,建议所有游戏启用。" + (this.fbSlimSupport ? "" : "(当前Unity Editor暂不支持该能力)"), !this.fbSlimSupport, (res) =>
|
||||
{
|
||||
var fbWin = GetWindow(typeof(WXFbSettingWindow), false, "首包资源优化配置面板", true);
|
||||
fbWin.minSize = new Vector2(680, 350);
|
||||
fbWin.Show();
|
||||
});
|
||||
this.formCheckbox("showMonitorSuggestModal", "显示优化建议弹窗");
|
||||
this.formCheckbox("enableProfileStats", "显示性能面板");
|
||||
this.formCheckbox("enableRenderAnalysis", "显示渲染日志(dev only)");
|
||||
EditorGUILayout.EndVertical();
|
||||
}
|
||||
|
||||
#if UNITY_INSTANTGAME
|
||||
foldInstantGame = EditorGUILayout.Foldout(foldInstantGame, "Instant Game - AutoStreaming");
|
||||
if (foldInstantGame)
|
||||
{
|
||||
EditorGUILayout.BeginVertical("frameBox");
|
||||
this.formInput("bundlePathIdentifier", "Bundle Path Identifier");
|
||||
this.formInput("dataFileSubPrefix", "Data File Sub Prefix");
|
||||
|
||||
EditorGUI.BeginDisabledGroup(true);
|
||||
this.formCheckbox("autoUploadFirstBundle", "构建后自动上传首包(?)", "仅在开启AutoStreaming生效", true);
|
||||
EditorGUI.EndDisabledGroup();
|
||||
|
||||
GUILayout.BeginHorizontal();
|
||||
EditorGUILayout.LabelField(string.Empty, GUILayout.Width(10));
|
||||
GUILayout.Label(new GUIContent("清理AS配置(?)", "如需关闭AutoStreaming选用默认发布方案则需要清理AS配置项目。"), GUILayout.Width(140));
|
||||
EditorGUI.BeginDisabledGroup(WXConvertCore.IsInstantGameAutoStreaming());
|
||||
if(GUILayout.Button(new GUIContent("恢复"),GUILayout.Width(60))){
|
||||
string identifier = config.ProjectConf.bundlePathIdentifier;
|
||||
string[] identifiers = identifier.Split(";");
|
||||
string idStr = "";
|
||||
foreach (string id in identifiers)
|
||||
{
|
||||
if (id != "AS" && id != "CUS/CustomAB")
|
||||
{
|
||||
idStr += id + ";";
|
||||
}
|
||||
}
|
||||
config.ProjectConf.bundlePathIdentifier = idStr.Trim(';');
|
||||
if (config.ProjectConf.dataFileSubPrefix == "CUS")
|
||||
{
|
||||
config.ProjectConf.dataFileSubPrefix = "";
|
||||
}
|
||||
this.loadData();
|
||||
}
|
||||
EditorGUI.EndDisabledGroup();
|
||||
GUILayout.EndHorizontal();
|
||||
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
EditorGUILayout.LabelField(string.Empty);
|
||||
if (GUILayout.Button(new GUIContent("了解Instant Game AutoStreaming", ""), linkStyle))
|
||||
{
|
||||
Application.OpenURL("https://github.com/wechat-miniprogram/minigame-unity-webgl-transform/blob/main/Design/InstantGameGuide.md");
|
||||
}
|
||||
EditorGUILayout.EndHorizontal();
|
||||
EditorGUILayout.EndVertical();
|
||||
}
|
||||
#endif
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
if (GUILayout.Button(new GUIContent("更多配置项"), GUILayout.Width(100), GUILayout.Height(25)))
|
||||
{
|
||||
var config = AssetDatabase.LoadAssetAtPath<UnityEngine.Object>("Assets/WX-WASM-SDK-V2/Editor/MiniGameConfig.asset");
|
||||
Selection.activeObject = config;
|
||||
GUIUtility.ExitGUI();
|
||||
}
|
||||
if (GUILayout.Button(new GUIContent("WebGL转小游戏(不常用)"), GUILayout.Width(150), GUILayout.Height(25)))
|
||||
{
|
||||
this.saveData();
|
||||
if (WXConvertCore.DoExport(false) == WXConvertCore.WXExportError.SUCCEED)
|
||||
{
|
||||
ShowNotification(new GUIContent("转换完成"));
|
||||
}
|
||||
|
||||
GUIUtility.ExitGUI();
|
||||
}
|
||||
EditorGUILayout.LabelField(string.Empty, GUILayout.MinWidth(10));
|
||||
if (GUILayout.Button(new GUIContent("生成并转换"), GUILayout.Width(100), GUILayout.Height(25)))
|
||||
{
|
||||
this.saveData();
|
||||
if (WXConvertCore.DoExport() == WXConvertCore.WXExportError.SUCCEED)
|
||||
{
|
||||
if (!WXConvertCore.IsInstantGameAutoStreaming())
|
||||
ShowNotification(new GUIContent("转换完成"));
|
||||
else
|
||||
{
|
||||
#if (UNITY_WEBGL || PLATFORM_WEIXINMINIGAME) && UNITY_INSTANTGAME
|
||||
// 上传首包资源
|
||||
if (!string.IsNullOrEmpty(WXConvertCore.FirstBundlePath) && File.Exists(WXConvertCore.FirstBundlePath))
|
||||
{
|
||||
if (Unity.InstantGame.IGBuildPipeline.UploadWeChatDataFile(WXConvertCore.FirstBundlePath))
|
||||
{
|
||||
Debug.Log("转换完成并成功上传首包资源");
|
||||
ShowNotification(new GUIContent("转换完成并成功上传"));
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogError("首包资源上传失败,请检查网络以及Auto Streaming配置是否正确。");
|
||||
ShowNotification(new GUIContent("上传失败"));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogError("转换失败");
|
||||
ShowNotification(new GUIContent("转换失败"));
|
||||
}
|
||||
#else
|
||||
ShowNotification(new GUIContent("转换完成"));
|
||||
#endif
|
||||
}
|
||||
}
|
||||
GUIUtility.ExitGUI();
|
||||
}
|
||||
EditorGUILayout.EndHorizontal();
|
||||
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
EditorGUILayout.LabelField(string.Empty);
|
||||
if (GUILayout.Button(new GUIContent("了解如何实现自定义构建", ""), linkStyle))
|
||||
{
|
||||
Application.OpenURL("https://github.com/wechat-miniprogram/minigame-unity-webgl-transform/blob/main/Design/DevelopmentQAList.md#13%E5%A6%82%E4%BD%95%E8%87%AA%E5%AE%9A%E4%B9%89%E6%8E%A5%E5%85%A5%E6%9E%84%E5%BB%BA%E6%B5%81%E7%A8%8B");
|
||||
GUIUtility.ExitGUI();
|
||||
}
|
||||
EditorGUILayout.EndHorizontal();
|
||||
|
||||
EditorGUILayout.EndScrollView();
|
||||
WXSettingsHelperInterface.helper.OnSettingsGUI(this);
|
||||
WXSettingsHelperInterface.helper.OnBuildButtonGUI(this);
|
||||
}
|
||||
|
||||
|
||||
|
||||
private Vector2 scrollRoot;
|
||||
private bool foldBaseInfo = true;
|
||||
private bool foldLoadingConfig = true;
|
||||
private bool foldSDKOptions = true;
|
||||
private bool foldDebugOptions = true;
|
||||
private bool foldInstantGame = false;
|
||||
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 SDKFilePath;
|
||||
|
||||
|
||||
private void addBundlePathIdentifier(string value)
|
||||
{
|
||||
string identifier = config.ProjectConf.bundlePathIdentifier;
|
||||
if (identifier[identifier.Length - 1] != ';')
|
||||
{
|
||||
identifier += ";";
|
||||
}
|
||||
identifier += value;
|
||||
config.ProjectConf.bundlePathIdentifier = identifier;
|
||||
}
|
||||
private void loadData()
|
||||
{
|
||||
// SDKFilePath = Path.Combine(Application.dataPath, "WX-WASM-SDK-V2", "Runtime", "wechat-default", "unity-sdk", "index.js");
|
||||
SDKFilePath = Path.Combine(UnityUtil.GetWxSDKRootPath(), "Runtime", "wechat-default", "unity-sdk", "index.js");
|
||||
config = UnityUtil.GetEditorConf();
|
||||
|
||||
// Instant Game
|
||||
if (WXConvertCore.IsInstantGameAutoStreaming())
|
||||
{
|
||||
config.ProjectConf.CDN = WXConvertCore.GetInstantGameAutoStreamingCDN();
|
||||
string identifier = config.ProjectConf.bundlePathIdentifier;
|
||||
string[] identifiers = identifier.Split(';');
|
||||
bool AS = false;
|
||||
bool CUS = false;
|
||||
foreach (string id in identifiers)
|
||||
{
|
||||
if (id == "AS")
|
||||
{
|
||||
AS = true;
|
||||
}
|
||||
if (id == "CUS/CustomAB")
|
||||
{
|
||||
CUS = true;
|
||||
}
|
||||
}
|
||||
if (!AS)
|
||||
{
|
||||
this.addBundlePathIdentifier("AS");
|
||||
}
|
||||
if (!CUS)
|
||||
{
|
||||
this.addBundlePathIdentifier("CUS/CustomAB");
|
||||
}
|
||||
if (config.ProjectConf.dataFileSubPrefix != "CUS")
|
||||
{
|
||||
config.ProjectConf.dataFileSubPrefix = "CUS";
|
||||
}
|
||||
}
|
||||
|
||||
this.setData("projectName", config.ProjectConf.projectName);
|
||||
this.setData("appid", config.ProjectConf.Appid);
|
||||
this.setData("cdn", config.ProjectConf.CDN);
|
||||
this.setData("assetLoadType", config.ProjectConf.assetLoadType);
|
||||
this.setData("compressDataPackage", config.ProjectConf.compressDataPackage);
|
||||
this.setData("videoUrl", config.ProjectConf.VideoUrl);
|
||||
this.setData("orientation", (int)config.ProjectConf.Orientation);
|
||||
this.setData("dst", config.ProjectConf.DST);
|
||||
this.setData("bundleHashLength", config.ProjectConf.bundleHashLength.ToString());
|
||||
this.setData("bundlePathIdentifier", config.ProjectConf.bundlePathIdentifier);
|
||||
this.setData("bundleExcludeExtensions", config.ProjectConf.bundleExcludeExtensions);
|
||||
this.setData("preloadFiles", config.ProjectConf.preloadFiles);
|
||||
this.setData("developBuild", config.CompileOptions.DevelopBuild);
|
||||
this.setData("autoProfile", config.CompileOptions.AutoProfile);
|
||||
this.setData("scriptOnly", config.CompileOptions.ScriptOnly);
|
||||
this.setData("il2CppOptimizeSize", config.CompileOptions.Il2CppOptimizeSize);
|
||||
this.setData("profilingFuncs", config.CompileOptions.profilingFuncs);
|
||||
this.setData("profilingMemory", config.CompileOptions.ProfilingMemory);
|
||||
this.setData("deleteStreamingAssets", config.CompileOptions.DeleteStreamingAssets);
|
||||
this.setData("cleanBuild", config.CompileOptions.CleanBuild);
|
||||
this.setData("customNodePath", config.CompileOptions.CustomNodePath);
|
||||
this.setData("webgl2", config.CompileOptions.Webgl2);
|
||||
this.setData("iOSPerformancePlus", config.CompileOptions.enableIOSPerformancePlus);
|
||||
this.setData("fbslim", config.CompileOptions.fbslim);
|
||||
this.setData("useFriendRelation", config.SDKOptions.UseFriendRelation);
|
||||
this.setData("useMiniGameChat", config.SDKOptions.UseMiniGameChat);
|
||||
this.setData("preloadWXFont", config.SDKOptions.PreloadWXFont);
|
||||
this.setData("bgImageSrc", config.ProjectConf.bgImageSrc);
|
||||
tex = AssetDatabase.LoadAssetAtPath<Texture>(config.ProjectConf.bgImageSrc);
|
||||
this.setData("memorySize", config.ProjectConf.MemorySize.ToString());
|
||||
this.setData("hideAfterCallMain", config.ProjectConf.HideAfterCallMain);
|
||||
|
||||
this.setData("dataFileSubPrefix", config.ProjectConf.dataFileSubPrefix);
|
||||
this.setData("maxStorage", config.ProjectConf.maxStorage.ToString());
|
||||
this.setData("defaultReleaseSize", config.ProjectConf.defaultReleaseSize.ToString());
|
||||
this.setData("texturesHashLength", config.ProjectConf.texturesHashLength.ToString());
|
||||
this.setData("texturesPath", config.ProjectConf.texturesPath);
|
||||
this.setData("needCacheTextures", config.ProjectConf.needCacheTextures);
|
||||
this.setData("loadingBarWidth", config.ProjectConf.loadingBarWidth.ToString());
|
||||
this.setData("needCheckUpdate", config.ProjectConf.needCheckUpdate);
|
||||
this.setData("disableHighPerformanceFallback", config.ProjectConf.disableHighPerformanceFallback);
|
||||
this.setData("showMonitorSuggestModal", config.CompileOptions.showMonitorSuggestModal);
|
||||
this.setData("enableProfileStats", config.CompileOptions.enableProfileStats);
|
||||
this.setData("enableRenderAnalysis", config.CompileOptions.enableRenderAnalysis);
|
||||
this.setData("autoUploadFirstBundle", true);
|
||||
}
|
||||
|
||||
private void saveData()
|
||||
{
|
||||
config.ProjectConf.projectName = this.getDataInput("projectName");
|
||||
config.ProjectConf.Appid = this.getDataInput("appid");
|
||||
config.ProjectConf.CDN = this.getDataInput("cdn");
|
||||
config.ProjectConf.assetLoadType = this.getDataPop("assetLoadType");
|
||||
config.ProjectConf.compressDataPackage = this.getDataCheckbox("compressDataPackage");
|
||||
config.ProjectConf.VideoUrl = this.getDataInput("videoUrl");
|
||||
config.ProjectConf.Orientation = (WXScreenOritation)this.getDataPop("orientation");
|
||||
config.ProjectConf.DST = this.getDataInput("dst");
|
||||
config.ProjectConf.bundleHashLength = int.Parse(this.getDataInput("bundleHashLength"));
|
||||
config.ProjectConf.bundlePathIdentifier = this.getDataInput("bundlePathIdentifier");
|
||||
config.ProjectConf.bundleExcludeExtensions = this.getDataInput("bundleExcludeExtensions");
|
||||
config.ProjectConf.preloadFiles = this.getDataInput("preloadFiles");
|
||||
config.CompileOptions.DevelopBuild = this.getDataCheckbox("developBuild");
|
||||
config.CompileOptions.AutoProfile = this.getDataCheckbox("autoProfile");
|
||||
config.CompileOptions.ScriptOnly = this.getDataCheckbox("scriptOnly");
|
||||
config.CompileOptions.Il2CppOptimizeSize = this.getDataCheckbox("il2CppOptimizeSize");
|
||||
config.CompileOptions.profilingFuncs = this.getDataCheckbox("profilingFuncs");
|
||||
config.CompileOptions.ProfilingMemory = this.getDataCheckbox("profilingMemory");
|
||||
config.CompileOptions.DeleteStreamingAssets = this.getDataCheckbox("deleteStreamingAssets");
|
||||
config.CompileOptions.CleanBuild = this.getDataCheckbox("cleanBuild");
|
||||
config.CompileOptions.CustomNodePath = this.getDataInput("customNodePath");
|
||||
config.CompileOptions.Webgl2 = this.getDataCheckbox("webgl2");
|
||||
config.CompileOptions.enableIOSPerformancePlus = this.getDataCheckbox("iOSPerformancePlus");
|
||||
config.CompileOptions.fbslim = this.getDataCheckbox("fbslim");
|
||||
config.SDKOptions.UseFriendRelation = this.getDataCheckbox("useFriendRelation");
|
||||
config.SDKOptions.UseMiniGameChat = this.getDataCheckbox("useMiniGameChat");
|
||||
config.SDKOptions.PreloadWXFont = this.getDataCheckbox("preloadWXFont");
|
||||
config.ProjectConf.bgImageSrc = this.getDataInput("bgImageSrc");
|
||||
config.ProjectConf.MemorySize = int.Parse(this.getDataInput("memorySize"));
|
||||
config.ProjectConf.HideAfterCallMain = this.getDataCheckbox("hideAfterCallMain");
|
||||
config.ProjectConf.dataFileSubPrefix = this.getDataInput("dataFileSubPrefix");
|
||||
config.ProjectConf.maxStorage = int.Parse(this.getDataInput("maxStorage"));
|
||||
config.ProjectConf.defaultReleaseSize = int.Parse(this.getDataInput("defaultReleaseSize"));
|
||||
config.ProjectConf.texturesHashLength = int.Parse(this.getDataInput("texturesHashLength"));
|
||||
config.ProjectConf.texturesPath = this.getDataInput("texturesPath");
|
||||
config.ProjectConf.needCacheTextures = this.getDataCheckbox("needCacheTextures");
|
||||
config.ProjectConf.loadingBarWidth = int.Parse(this.getDataInput("loadingBarWidth"));
|
||||
config.ProjectConf.needCheckUpdate = this.getDataCheckbox("needCheckUpdate");
|
||||
config.ProjectConf.disableHighPerformanceFallback = this.getDataCheckbox("disableHighPerformanceFallback");
|
||||
config.CompileOptions.showMonitorSuggestModal = this.getDataCheckbox("showMonitorSuggestModal");
|
||||
config.CompileOptions.enableProfileStats = this.getDataCheckbox("enableProfileStats");
|
||||
config.CompileOptions.enableRenderAnalysis = this.getDataCheckbox("enableRenderAnalysis");
|
||||
}
|
||||
|
||||
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 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();
|
||||
}
|
||||
|
||||
private void formCheckbox(string target, string label, string help = null, bool disable = false, Action<bool> setting = 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);
|
||||
formCheckboxData[target] = EditorGUILayout.Toggle(formCheckboxData[target]);
|
||||
|
||||
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();
|
||||
|
||||
EditorGUILayout.LabelField(string.Empty);
|
||||
GUILayout.EndHorizontal();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@ -105,6 +105,10 @@ namespace WeChatWASM
|
||||
// #endif
|
||||
// return null;
|
||||
// });
|
||||
WXExtEnvDef.RegisterAction("WXConvertCore.UseIL2CPP", (args) =>
|
||||
{
|
||||
return WXConvertCore.UseIL2CPP;
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2,7 +2,7 @@
|
||||
{
|
||||
public class WXPluginVersion
|
||||
{
|
||||
public static string pluginVersion = "202403061052"; // 这一行不要改他,导出的时候会自动替换
|
||||
public static string pluginVersion = "202403281243"; // 这一行不要改他,导出的时候会自动替换
|
||||
}
|
||||
|
||||
public class WXPluginConf
|
||||
|
||||
Binary file not shown.
@ -1,5 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: dbb11f91282684564a2c405c5c485013
|
||||
guid: 89f24ea7e42cd084ab0d5bbd61fa1e3a
|
||||
TextScriptImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: cbdd86a6659a24968be342c46c0eeb03
|
||||
guid: abc091d8a2f753b49a0e435c823e2c91
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
|
||||
108
Runtime/Plugins/AES.jslib
Normal file
108
Runtime/Plugins/AES.jslib
Normal file
@ -0,0 +1,108 @@
|
||||
var WebAesLibrary = {
|
||||
$aesManager: {
|
||||
instance: null,
|
||||
mode: 0,
|
||||
padding: null,
|
||||
encCallback: null,
|
||||
decCallback: null,
|
||||
},
|
||||
|
||||
WebAesInitialize: function (
|
||||
mode,
|
||||
keyBuffer,
|
||||
keySize,
|
||||
ivBuffer,
|
||||
ivSize,
|
||||
encCallback,
|
||||
decCallback,
|
||||
counter,
|
||||
segmentSize
|
||||
) {
|
||||
if (typeof window === "undefined" || !window.aesjs) {
|
||||
throw new Error("Fail to initialize WebAES. window.aesjs not found.");
|
||||
}
|
||||
var aesjs = window.aesjs;
|
||||
var key = new Uint8Array(Module.HEAPU8.buffer, keyBuffer, keySize);
|
||||
var iv = new Uint8Array(Module.HEAPU8.buffer, ivBuffer, ivSize);
|
||||
switch (mode) {
|
||||
case 1: // CBC
|
||||
aesManager.instance = new aesjs.ModeOfOperation.cbc(key, iv);
|
||||
break;
|
||||
case 2: // ECB
|
||||
aesManager.instance = new aesjs.ModeOfOperation.ecb(key);
|
||||
break;
|
||||
case 3: // OFB
|
||||
aesManager.instance = new aesjs.ModeOfOperation.ofb(key, iv);
|
||||
break;
|
||||
case 4: // CFB
|
||||
aesManager.instance = new aesjs.ModeOfOperation.cfb(
|
||||
key,
|
||||
iv,
|
||||
segmentSize
|
||||
);
|
||||
break;
|
||||
case 5:
|
||||
break; // Reserved for CTS
|
||||
case 6: // CTR, Not used by interop yet
|
||||
aesManager.instance = new aesjs.ModeOfOperation.ctr(key, counter);
|
||||
break;
|
||||
default:
|
||||
// Default to ECB
|
||||
aesManager.instance = new aesjs.ModeOfOperation.ecb(key);
|
||||
}
|
||||
aesManager.encCallback = encCallback;
|
||||
aesManager.decCallback = decCallback;
|
||||
},
|
||||
WebAesFinalize: function () {
|
||||
aesManager = {
|
||||
instance: null,
|
||||
mode: 0,
|
||||
padding: null,
|
||||
encCallback: null,
|
||||
decCallback: null,
|
||||
};
|
||||
},
|
||||
WebAesEncrypt: function (plainPtr, size, needPad) {
|
||||
if (aesManager.instance === null) {
|
||||
throw new Error("Must call initialize before encrypt");
|
||||
}
|
||||
var key = new Uint8Array(Module.HEAPU8.buffer, plainPtr, size);
|
||||
if (needPad) {
|
||||
key = aesjs.padding.pkcs7.pad(key);
|
||||
}
|
||||
// result is Uint8Array
|
||||
var result = aesManager.instance.encrypt(key);
|
||||
var buffer = _malloc(result.length);
|
||||
HEAPU8.set(result, buffer);
|
||||
try {
|
||||
if (aesManager.encCallback) {
|
||||
Module.dynCall_viii(aesManager.encCallback, 1, buffer, result.length);
|
||||
}
|
||||
} finally {
|
||||
_free(buffer);
|
||||
}
|
||||
},
|
||||
WebAesDecrypt: function (cipherPtr, size, needStrip) {
|
||||
if (aesManager.instance === null) {
|
||||
throw new Error("Must call initialize before decrypt");
|
||||
}
|
||||
var key = new Uint8Array(Module.HEAPU8.buffer, cipherPtr, size);
|
||||
// result is Uint8Array
|
||||
var result = aesManager.instance.decrypt(key, needStrip);
|
||||
if (needStrip) {
|
||||
result = aesjs.padding.pkcs7.strip(result);
|
||||
}
|
||||
var buffer = _malloc(result.length);
|
||||
HEAPU8.set(result, buffer);
|
||||
try {
|
||||
if (aesManager.decCallback) {
|
||||
Module.dynCall_viii(aesManager.decCallback, 0, buffer, result.length);
|
||||
}
|
||||
} finally {
|
||||
_free(buffer);
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
autoAddDeps(WebAesLibrary, "$aesManager");
|
||||
mergeInto(LibraryManager.library, WebAesLibrary);
|
||||
21
Runtime/Plugins/AES.jslib.meta
Normal file
21
Runtime/Plugins/AES.jslib.meta
Normal file
@ -0,0 +1,21 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a8be7960d079402392e951de6e3978b7
|
||||
PluginImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
iconMap: {}
|
||||
executionOrder: {}
|
||||
defineConstraints: []
|
||||
isPreloaded: 0
|
||||
isOverridable: 0
|
||||
isExplicitlyReferenced: 0
|
||||
validateReferences: 1
|
||||
platformData:
|
||||
- first:
|
||||
Any:
|
||||
second:
|
||||
enabled: 1
|
||||
settings: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
8
Runtime/Plugins/MD5.jslib
Normal file
8
Runtime/Plugins/MD5.jslib
Normal file
@ -0,0 +1,8 @@
|
||||
mergeInto(LibraryManager.library, {
|
||||
_WebMD5: function(rawData, dataLength, result) {
|
||||
var data = new Uint8Array(Module.HEAPU8.buffer, rawData, dataLength);
|
||||
var md5Result = window.md5WASM(data, true); // Assuming this always returns a Uint8Array of 16 bytes
|
||||
|
||||
Module.HEAPU8.set(md5Result, result);
|
||||
}
|
||||
});
|
||||
21
Runtime/Plugins/MD5.jslib.meta
Normal file
21
Runtime/Plugins/MD5.jslib.meta
Normal file
@ -0,0 +1,21 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9250060552104a8388aaff7dc4f4dde7
|
||||
PluginImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
iconMap: {}
|
||||
executionOrder: {}
|
||||
defineConstraints: []
|
||||
isPreloaded: 0
|
||||
isOverridable: 0
|
||||
isExplicitlyReferenced: 0
|
||||
validateReferences: 1
|
||||
platformData:
|
||||
- first:
|
||||
Any:
|
||||
second:
|
||||
enabled: 1
|
||||
settings: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -508,7 +508,11 @@ mergeInto(LibraryManager.library, {
|
||||
if (typeof TOTAL_MEMORY !== "undefined") {
|
||||
return TOTAL_MEMORY
|
||||
}
|
||||
return buffer.byteLength;
|
||||
if (wasmMemory && wasmMemory.buffer) {
|
||||
return wasmMemory.buffer.byteLength;
|
||||
}
|
||||
console.error('Fail to find wasmMemory.buffer, TotalMemorySize is not correct.');
|
||||
return 0;
|
||||
},
|
||||
WXGetTotalStackSize: function() {
|
||||
return TOTAL_STACK;
|
||||
@ -783,7 +787,11 @@ mergeInto(LibraryManager.library, {
|
||||
window.WXWASMSDK.WX_OperateGameRecorderVideo(_WXPointer_stringify_adaptor(option));
|
||||
},
|
||||
WXChatCreate: function (option) {
|
||||
return window.WXWASMSDK.WXChatCreate(_WXPointer_stringify_adaptor(option));
|
||||
var returnStr = window.WXWASMSDK.WXChatCreate(_WXPointer_stringify_adaptor(option));
|
||||
var bufferSize = lengthBytesUTF8(returnStr || '') + 1;
|
||||
var buffer = _malloc(bufferSize);
|
||||
stringToUTF8(returnStr, buffer, bufferSize);
|
||||
return buffer;
|
||||
},
|
||||
WXChatHide: function () {
|
||||
window.WXWASMSDK.WXChatHide();
|
||||
|
||||
1252
Runtime/Plugins/crypto.jspre
Normal file
1252
Runtime/Plugins/crypto.jspre
Normal file
File diff suppressed because it is too large
Load Diff
21
Runtime/Plugins/crypto.jspre.meta
Normal file
21
Runtime/Plugins/crypto.jspre.meta
Normal file
@ -0,0 +1,21 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 71bc98cdcdfd4e059f97a9d2bd913e7f
|
||||
PluginImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
iconMap: {}
|
||||
executionOrder: {}
|
||||
defineConstraints: []
|
||||
isPreloaded: 0
|
||||
isOverridable: 0
|
||||
isExplicitlyReferenced: 0
|
||||
validateReferences: 1
|
||||
platformData:
|
||||
- first:
|
||||
Any:
|
||||
second:
|
||||
enabled: 1
|
||||
settings: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -1,4 +1,5 @@
|
||||
<linker>
|
||||
<assembly fullname="wx-runtime" preserve="all"/>
|
||||
<assembly fullname="LitJson" preserve="all"/>
|
||||
<assembly fullname="Wx" preserve="all"/>
|
||||
</linker>
|
||||
Binary file not shown.
@ -1,7 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6c79fcf12fc194476b7241375856274b
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -1,5 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 01d4a3ad9ca6f47fc9c50416a5ba3ed2
|
||||
guid: 7d41c663172388842a5d3b037200a60d
|
||||
TextScriptImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
|
||||
Binary file not shown.
@ -1,7 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 07510318632604babbaaafba80f57ef5
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -1,5 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0cd7a7a3759f5466bb8fe9ff96ce5227
|
||||
guid: 7cf82b7695e9a6e4f91fb8e1f00510c7
|
||||
TextScriptImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
|
||||
@ -7,9 +7,9 @@ using System.Collections.Generic;
|
||||
|
||||
using UnityEngine;
|
||||
using UnityEngine.Profiling;
|
||||
using WeChatWASM;
|
||||
|
||||
#if UNITY_WEBGL || WEIXINMINIGAME || UNITY_EDITOR
|
||||
using WeChatWASM;
|
||||
public class WXProfileStatsScript : MonoBehaviour, WeChatWASM.WXSDKManagerHandler.WXProfileStatsScript
|
||||
{
|
||||
private string statsText;
|
||||
|
||||
108
Runtime/WebAES.cs
Normal file
108
Runtime/WebAES.cs
Normal file
@ -0,0 +1,108 @@
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
using AOT;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
namespace WeChatWASM
|
||||
{
|
||||
public class WebAES
|
||||
{
|
||||
public static byte[] EncryptedBytes;
|
||||
public static byte[] DecryptedBytes;
|
||||
public static bool initialized;
|
||||
public static System.IntPtr keyPtr, ivPtr;
|
||||
public delegate void AesCallback(int enc, System.IntPtr resPtr, int resSize);
|
||||
|
||||
[DllImport("__Internal")]
|
||||
public static extern void WebAesInitialize(
|
||||
int mode,
|
||||
System.IntPtr keyPtr, int keySize,
|
||||
System.IntPtr ivPtr, int ivSize,
|
||||
AesCallback encCallback, AesCallback decCallback,
|
||||
int counter = 0, int segmentSize = 0);
|
||||
[DllImport("__Internal")]
|
||||
public static extern void WebAesFinalize();
|
||||
[DllImport("__Internal")]
|
||||
public static extern void WebAesEncrypt(System.IntPtr plainBytesPtr, int size, int needPad);
|
||||
[DllImport("__Internal")]
|
||||
public static extern void WebAesDecrypt(System.IntPtr encryptedBytesPtr, int size, int needStrip);
|
||||
|
||||
// TODO: consider passing a unique id so that we can initialize multiple instances.
|
||||
public static void Initialize(System.Security.Cryptography.CipherMode mode, byte[] key,
|
||||
byte[] iv, int counter = 0, int segmentSize = 0)
|
||||
{
|
||||
if (initialized)
|
||||
{
|
||||
Debug.Log("Already initialized! Please call Finalize() before initialize again.");
|
||||
return;
|
||||
}
|
||||
if (mode == CipherMode.CTS)
|
||||
{
|
||||
Debug.LogError("CTS not supported!");
|
||||
return;
|
||||
}
|
||||
|
||||
int keySize = key.Length;
|
||||
keyPtr = Marshal.AllocHGlobal(keySize);
|
||||
Marshal.Copy(key, 0, keyPtr, keySize);
|
||||
|
||||
int ivSize = iv.Length;
|
||||
ivPtr = Marshal.AllocHGlobal(ivSize);
|
||||
Marshal.Copy(iv, 0, ivPtr, ivSize);
|
||||
WebAesInitialize(
|
||||
(int)mode,
|
||||
keyPtr, keySize, ivPtr, ivSize,
|
||||
OnAecCrypto, OnAecCrypto,
|
||||
counter, segmentSize);
|
||||
initialized = true;
|
||||
}
|
||||
|
||||
[MonoPInvokeCallback(typeof(AesCallback))]
|
||||
public static void OnAecCrypto(int enc, System.IntPtr resPtr, int resSize)
|
||||
{
|
||||
byte[] res = new byte[resSize];
|
||||
Marshal.Copy(resPtr, res, 0, resSize);
|
||||
if (enc == 1)
|
||||
{
|
||||
EncryptedBytes = res;
|
||||
}
|
||||
else
|
||||
{
|
||||
DecryptedBytes = res;
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: consider passing a unique id so we can destroy by instance.
|
||||
public static void Finalize()
|
||||
{
|
||||
EncryptedBytes = null;
|
||||
DecryptedBytes = null;
|
||||
Marshal.FreeHGlobal(keyPtr);
|
||||
Marshal.FreeHGlobal(ivPtr);
|
||||
initialized = false;
|
||||
WebAesFinalize();
|
||||
}
|
||||
|
||||
// Use UTF-8 as it is used as default format for StreamReader
|
||||
public static byte[] Encode(string plainStr, bool needPad = true)
|
||||
{
|
||||
var bytes = Encoding.UTF8.GetBytes(plainStr);
|
||||
var bytesPtr = Marshal.AllocHGlobal(bytes.Length);
|
||||
Marshal.Copy(bytes, 0, bytesPtr, bytes.Length);
|
||||
WebAesEncrypt(bytesPtr, bytes.Length, needPad ? 1 : 0);
|
||||
Marshal.FreeHGlobal(bytesPtr);
|
||||
return EncryptedBytes;
|
||||
}
|
||||
|
||||
public static string Decode(byte[] bytes, bool needStrip = true)
|
||||
{
|
||||
var bytesPtr = Marshal.AllocHGlobal(bytes.Length);
|
||||
Marshal.Copy(bytes, 0, bytesPtr, bytes.Length);
|
||||
WebAesDecrypt(bytesPtr, bytes.Length, needStrip ? 1 : 0);
|
||||
Marshal.FreeHGlobal(bytesPtr);
|
||||
return Encoding.UTF8.GetString(DecryptedBytes);
|
||||
}
|
||||
}
|
||||
}
|
||||
3
Runtime/WebAES.cs.meta
Normal file
3
Runtime/WebAES.cs.meta
Normal file
@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d9e79ef28f134cfcbafaedb5f052df60
|
||||
timeCreated: 1707119327
|
||||
31
Runtime/WebMD5.cs
Normal file
31
Runtime/WebMD5.cs
Normal file
@ -0,0 +1,31 @@
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace WeChatWASM
|
||||
{
|
||||
public class WebMD5
|
||||
{
|
||||
|
||||
[DllImport("__Internal", EntryPoint = "_WebMD5")]
|
||||
private static extern void getMD5Bytes(IntPtr byteArray, int length, IntPtr result);
|
||||
|
||||
public static byte[] GetMD5Bytes(byte[] input)
|
||||
{
|
||||
var inputLength = input.Length;
|
||||
var inputPtr = Marshal.AllocHGlobal(inputLength);
|
||||
Marshal.Copy(input, 0, inputPtr, inputLength);
|
||||
|
||||
var resultPtr = Marshal.AllocHGlobal(16); // MD5 hash is 16 bytes
|
||||
|
||||
getMD5Bytes(inputPtr, inputLength, resultPtr);
|
||||
|
||||
byte[] result = new byte[16];
|
||||
Marshal.Copy(resultPtr, result, 0, 16);
|
||||
|
||||
Marshal.FreeHGlobal(inputPtr);
|
||||
Marshal.FreeHGlobal(resultPtr);
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
3
Runtime/WebMD5.cs.meta
Normal file
3
Runtime/WebMD5.cs.meta
Normal file
@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ee32301e25b2402fa31faba7435a1367
|
||||
timeCreated: 1705137445
|
||||
@ -6,7 +6,7 @@ import './weapp-adapter';
|
||||
import './events';
|
||||
import 'texture-config.js';
|
||||
import unityNamespace from './unity-namespace';
|
||||
import './$GAME_NAME.wasm.framework.unityweb';
|
||||
import '.$DOTNET_RUNTIME_FOLD/$GAME_NAME.wasm.framework.unityweb';
|
||||
import './unity-sdk/index.js';
|
||||
import checkVersion from './check-version';
|
||||
import { launchEventType, scaleMode } from './plugin-config';
|
||||
|
||||
@ -153,6 +153,10 @@ export class AudioChannelInstance {
|
||||
gain;
|
||||
callback = 0;
|
||||
userData = 0;
|
||||
loop = false;
|
||||
loopStart = 0;
|
||||
loopEnd = 0;
|
||||
deleyTime = 0;
|
||||
constructor(callback, userData) {
|
||||
if (WEBAudio.audioContext) {
|
||||
this.gain = WEBAudio.audioContext.createGain();
|
||||
@ -169,6 +173,26 @@ export class AudioChannelInstance {
|
||||
this.gain.disconnect();
|
||||
}
|
||||
}
|
||||
setLoop(loop) {
|
||||
this.loop = loop;
|
||||
if (!this.source || this.source.loop == loop) {
|
||||
return;
|
||||
}
|
||||
this.source.loop = loop;
|
||||
}
|
||||
setLoopPoints(loopStart, loopEnd) {
|
||||
this.loopStart = loopStart;
|
||||
this.loopEnd = loopEnd;
|
||||
if (!this.source) {
|
||||
return;
|
||||
}
|
||||
if (this.source.loopStart !== loopStart) {
|
||||
this.source.loopStart = loopStart;
|
||||
}
|
||||
if (this.source.loopEnd !== loopEnd) {
|
||||
this.source.loopEnd = loopEnd;
|
||||
}
|
||||
}
|
||||
playUrl(startTime, url, startOffset, volume, soundClip) {
|
||||
try {
|
||||
this.setup(url);
|
||||
@ -265,6 +289,8 @@ export class AudioChannelInstance {
|
||||
}
|
||||
this.source.canPlayFnList.push(fn);
|
||||
this.source.mediaElement.onCanplay(fn);
|
||||
this.source.mediaElement.loop = this.loop;
|
||||
this.deleyTime = startTime;
|
||||
this.source.start(startTime, startOffset);
|
||||
this.source.playbackStartTime = startTime - startOffset / this.source.playbackRateValue;
|
||||
}
|
||||
@ -298,6 +324,9 @@ export class AudioChannelInstance {
|
||||
this.gain.gain.value = volume;
|
||||
}
|
||||
}
|
||||
this.source.loop = this.loop;
|
||||
this.source.loopStart = this.loopStart;
|
||||
this.source.loopEnd = this.loopEnd;
|
||||
this.source.start(startTime, startOffset);
|
||||
this.source.playbackStartTime = startTime - startOffset / this.source.playbackRateValue;
|
||||
}
|
||||
@ -355,7 +384,7 @@ export class AudioChannelInstance {
|
||||
return true;
|
||||
}
|
||||
if (this.source.mediaElement) {
|
||||
return (this.source.mediaElement.paused || this.source.pauseRequested) ?? true;
|
||||
return (!this.source.isPlaying || this.source.pauseRequested) ?? true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@ -373,9 +402,9 @@ export class AudioChannelInstance {
|
||||
}
|
||||
const pausedSource = {
|
||||
isPausedMockNode: true,
|
||||
loop: source.loop,
|
||||
loopStart: source.loopStart,
|
||||
loopEnd: source.loopEnd,
|
||||
loop: this.loop,
|
||||
loopStart: this.loopStart,
|
||||
loopEnd: this.loopEnd,
|
||||
buffer: source.buffer,
|
||||
playbackRate: source.playbackRateValue,
|
||||
playbackPausedAtPosition: source.estimatePlaybackPosition(),
|
||||
@ -396,7 +425,8 @@ export class AudioChannelInstance {
|
||||
return;
|
||||
}
|
||||
if (this.source.mediaElement) {
|
||||
this.source.start();
|
||||
this.source.start(this.deleyTime);
|
||||
delete this.deleyTime;
|
||||
return;
|
||||
}
|
||||
const pausedSource = this.source;
|
||||
@ -1043,7 +1073,7 @@ export default {
|
||||
if (!channel.source) {
|
||||
return;
|
||||
}
|
||||
channel.source.loop = loop > 0;
|
||||
channel.setLoop(loop > 0);
|
||||
},
|
||||
_JS_Sound_SetLoopPoints(channelInstance, loopStart, loopEnd) {
|
||||
if (WEBAudio.audioWebEnabled === 0) {
|
||||
@ -1056,8 +1086,7 @@ export default {
|
||||
if (!channel.source) {
|
||||
return;
|
||||
}
|
||||
channel.source.loopStart = loopStart;
|
||||
channel.source.loopEnd = loopEnd;
|
||||
channel.setLoopPoints(loopStart, loopEnd);
|
||||
},
|
||||
_JS_Sound_SetPaused(channelInstance, paused) {
|
||||
if (WEBAudio.audioWebEnabled === 0) {
|
||||
|
||||
@ -24,32 +24,32 @@ function runMethod(method, option, callbackId, isString = false) {
|
||||
cacheArrayBuffer(callbackId, res.arrayBuffer);
|
||||
returnRes = JSON.stringify({
|
||||
bytesRead: res.bytesRead,
|
||||
arrayBufferLength: res.arrayBuffer.byteLength,
|
||||
arrayBufferLength: res.arrayBuffer?.byteLength ?? 0,
|
||||
});
|
||||
}
|
||||
else if (method === 'readCompressedFile') {
|
||||
cacheArrayBuffer(callbackId, res.data);
|
||||
returnRes = JSON.stringify({
|
||||
arrayBufferLength: res.data.byteLength,
|
||||
arrayBufferLength: res.data?.byteLength ?? 0,
|
||||
});
|
||||
}
|
||||
else if (method === 'readFile') {
|
||||
if (config.encoding) {
|
||||
returnRes = JSON.stringify({
|
||||
stringData: res.data,
|
||||
stringData: res.data || '',
|
||||
});
|
||||
}
|
||||
else {
|
||||
cacheArrayBuffer(callbackId, res.data);
|
||||
returnRes = JSON.stringify({
|
||||
arrayBufferLength: res.data.byteLength,
|
||||
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,
|
||||
}));
|
||||
@ -400,7 +400,7 @@ export default {
|
||||
cacheArrayBuffer(callbackId, res.arrayBuffer);
|
||||
return JSON.stringify({
|
||||
bytesRead: res.bytesRead,
|
||||
arrayBufferLength: res.arrayBuffer.byteLength,
|
||||
arrayBufferLength: res.arrayBuffer?.byteLength ?? 0,
|
||||
});
|
||||
},
|
||||
WX_FileSystemManagerFstatSync(option) {
|
||||
|
||||
@ -225,6 +225,9 @@ function convertBase64ToData(input) {
|
||||
return input;
|
||||
}
|
||||
export function cacheArrayBuffer(callbackId, data) {
|
||||
if (!callbackId || !data) {
|
||||
return;
|
||||
}
|
||||
tempCacheObj[callbackId] = data;
|
||||
}
|
||||
export function setArrayBuffer(buffer, offset, callbackId) {
|
||||
|
||||
@ -1 +1 @@
|
||||
{"name":"com.qq.weixin.minigame","displayName":"WXSDK","description":"WeChat Mini Game Tuanjie Engine Adapter SDK Package.","version":"0.1.2","unity":"2019.4","unityRelease":"29f1","keywords":["Tuanjie","WX"],"dependencies":{}}
|
||||
{"name":"com.qq.weixin.minigame","displayName":"WXSDK","description":"WeChat Mini Game Tuanjie Engine Adapter SDK Package.","version":"0.1.3","unity":"2019.4","unityRelease":"29f1","keywords":["Tuanjie","WX"],"dependencies":{}}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user