整理项目
This commit is contained in:
parent
6de0517da3
commit
87af2478d9
19
Assets/Assets.index
Normal file
19
Assets/Assets.index
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
{
|
||||||
|
"name": "Assets",
|
||||||
|
"type": "asset",
|
||||||
|
"roots": [],
|
||||||
|
"includes": [],
|
||||||
|
"excludes": [
|
||||||
|
"Temp/",
|
||||||
|
"External/"
|
||||||
|
],
|
||||||
|
"baseScore": 100,
|
||||||
|
"options": {
|
||||||
|
"disabled": false,
|
||||||
|
"files": true,
|
||||||
|
"directories": false,
|
||||||
|
"types": true,
|
||||||
|
"properties": false,
|
||||||
|
"dependencies": false
|
||||||
|
}
|
||||||
|
}
|
||||||
10
Assets/Assets.index.meta
Normal file
10
Assets/Assets.index.meta
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: c94aab290ea3af541a337f4e1ced6fc5
|
||||||
|
ScriptedImporter:
|
||||||
|
internalIDToNameTable: []
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
|
script: {fileID: 11500000, guid: 595da1eac225fa84fb9c2d465cc69e8b, type: 3}
|
||||||
8
Assets/Editor.meta
Normal file
8
Assets/Editor.meta
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 014f172e8fc3a4dce9aa440f77db1fc4
|
||||||
|
folderAsset: yes
|
||||||
|
DefaultImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
8
Assets/Editor/BFBuildProjectTools.meta
Normal file
8
Assets/Editor/BFBuildProjectTools.meta
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: c3ad7118b0eaf4f3c8c00ccd6a2c25dd
|
||||||
|
folderAsset: yes
|
||||||
|
DefaultImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
102
Assets/Editor/BFBuildProjectTools/BuildInfo.cs
Normal file
102
Assets/Editor/BFBuildProjectTools/BuildInfo.cs
Normal file
@ -0,0 +1,102 @@
|
|||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System;
|
||||||
|
using BF;
|
||||||
|
|
||||||
|
namespace BFEditor.Build
|
||||||
|
{
|
||||||
|
[Serializable]
|
||||||
|
public class BuildInfoCollection
|
||||||
|
{
|
||||||
|
public List<BuildInfo> infos = new List<BuildInfo>();
|
||||||
|
|
||||||
|
public BuildInfo GetFirstInfo()
|
||||||
|
{
|
||||||
|
if (infos.Count > 0)
|
||||||
|
{
|
||||||
|
return infos[0];
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[Serializable]
|
||||||
|
public class BuildInfo
|
||||||
|
{
|
||||||
|
public string bundleName; // 包名
|
||||||
|
public string version; // 版本号
|
||||||
|
public string mode; // 渠道名_debug 或 渠道名_release
|
||||||
|
public int version_code = 1; // 各自渠道的version_code
|
||||||
|
public List<BulidGitInfo> git_info; // 打包的git信息
|
||||||
|
|
||||||
|
[NonSerialized]
|
||||||
|
public bool skipVersion = false; // 是否跳过版本校验
|
||||||
|
|
||||||
|
public bool IsGPChannel()
|
||||||
|
{
|
||||||
|
return bundleName == "com.idle.ko.io";
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool IsGPOfficial()
|
||||||
|
{
|
||||||
|
return bundleName == "com.idle.ko.io";
|
||||||
|
}
|
||||||
|
|
||||||
|
// dev包使用mono编译,不会导出as工程
|
||||||
|
public bool IsDevChannel()
|
||||||
|
{
|
||||||
|
return bundleName == "com.juzu.b5.dev" || bundleName == "com.juzu.b5.dev.android" ||
|
||||||
|
bundleName == "com.juzu.b5.dev.ios";
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool IsReleaseChannel()
|
||||||
|
{
|
||||||
|
return !IsDevChannel();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 是否是内网release
|
||||||
|
public bool IsLanRelease()
|
||||||
|
{
|
||||||
|
return bundleName == "com.juzu.b5.release.android" || bundleName == "com.juzu.b5.release.ios";
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool IsPublish()
|
||||||
|
{
|
||||||
|
return !IsDevChannel() && !IsLanRelease();
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool IsIOSPlatform()
|
||||||
|
{
|
||||||
|
return bundleName.Contains("ios");
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool IsAndroidPlatform()
|
||||||
|
{
|
||||||
|
return !IsIOSPlatform();
|
||||||
|
}
|
||||||
|
|
||||||
|
public string GetBundleName()
|
||||||
|
{
|
||||||
|
return bundleName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public string GetVersion()
|
||||||
|
{
|
||||||
|
return version;
|
||||||
|
}
|
||||||
|
|
||||||
|
public BFLanguageInfo GetLanguageInfo()
|
||||||
|
{
|
||||||
|
var languageInfo = BFPlatform.GetLanguageInfo(bundleName);
|
||||||
|
return languageInfo;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[Serializable]
|
||||||
|
public class BulidGitInfo
|
||||||
|
{
|
||||||
|
public string project_name;
|
||||||
|
public string branch;
|
||||||
|
public string hash;
|
||||||
|
}
|
||||||
|
}
|
||||||
11
Assets/Editor/BFBuildProjectTools/BuildInfo.cs.meta
Normal file
11
Assets/Editor/BFBuildProjectTools/BuildInfo.cs.meta
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 98c301e11d6db4eb2bb04a9fabbb524d
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
201
Assets/Editor/BFBuildProjectTools/BuildMenu.cs
Normal file
201
Assets/Editor/BFBuildProjectTools/BuildMenu.cs
Normal file
@ -0,0 +1,201 @@
|
|||||||
|
using System.IO;
|
||||||
|
using UnityEditor;
|
||||||
|
using UnityEngine;
|
||||||
|
using BFEditor.Resource;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace BFEditor.Build
|
||||||
|
{
|
||||||
|
public static class BuildMenu
|
||||||
|
{
|
||||||
|
[MenuItem("打包工具/编译并加密lua代码", priority = 1)]
|
||||||
|
static void CompileLuaManually()
|
||||||
|
{
|
||||||
|
var succ = CompileScriptsUtils.CompileAndEncryptLua(true);
|
||||||
|
if (succ)
|
||||||
|
{
|
||||||
|
EditorUtility.DisplayDialog("提示", "编译并加密Lua成功", "确定");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
EditorUtility.DisplayDialog("提示", "编译Lua失败", "确定");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[MenuItem("打包工具/打包前准备", priority = 101)]
|
||||||
|
static void PrepareForBuild()
|
||||||
|
{
|
||||||
|
CompileScriptsUtils.RegenerateXLuaCode(true); // 重新生产XLua
|
||||||
|
MainAtlasTools.UpdateMainAtlas(); // 更新atlas
|
||||||
|
LanguageAtlasTools.UpdateLanguageAtlas(); // 更新多语言atlas
|
||||||
|
MaterialTools.ClearFbxDefaultMaterial(); // 清理fbx默认材质
|
||||||
|
ShaderDependenciesTools.ClearAllShaderDependencies(); // 清理shader依赖资源
|
||||||
|
ShaderVariantsTools.GenerateVariantCollection(); // 收集shader变体
|
||||||
|
CompileScriptsUtils.CompileAndEncryptLua(true); // 编译并且加密lua代码
|
||||||
|
AssetBundleUtils.SetAllAssetsBundleName(); // 设置abName
|
||||||
|
}
|
||||||
|
|
||||||
|
[MenuItem("打包工具/AssetBundles/设置ABName", priority = 201)]
|
||||||
|
public static void SetAssetsInfoExcludeLua()
|
||||||
|
{
|
||||||
|
AssetBundleUtils.SetAllAssetsBundleName();
|
||||||
|
EditorUtility.DisplayDialog("提示", "设置ABName成功", "确定");
|
||||||
|
}
|
||||||
|
|
||||||
|
[MenuItem("打包工具/AssetBundles/AB Build(Debug)", priority = 202)]
|
||||||
|
public static void BuildAssetBundlesDebug()
|
||||||
|
{
|
||||||
|
var outputPath = Application.streamingAssetsPath;
|
||||||
|
var success = AssetBundleUtils.BuildAssetBundles(EditorUserBuildSettings.activeBuildTarget, outputPath, false,
|
||||||
|
BuildAssetBundleOptions.ChunkBasedCompression, new BF.BFLanguageInfo(new List<string> { "en", "cn"}));
|
||||||
|
if (success)
|
||||||
|
{
|
||||||
|
EditorUtility.DisplayDialog("提示", "Build AB(Debug)成功", "确定");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
EditorUtility.DisplayDialog("提示", "Build AB(Debug)失败", "确定");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[MenuItem("打包工具/AssetBundles/AB Build(Release)", priority = 203)]
|
||||||
|
public static void BuildAssetBundlesRelease()
|
||||||
|
{
|
||||||
|
var outputPath = Application.streamingAssetsPath;
|
||||||
|
var success = AssetBundleUtils.BuildAssetBundles(EditorUserBuildSettings.activeBuildTarget, outputPath, true,
|
||||||
|
BuildAssetBundleOptions.ChunkBasedCompression, new BF.BFLanguageInfo(new List<string> { "en", "cn"}));
|
||||||
|
if (success)
|
||||||
|
{
|
||||||
|
EditorUtility.DisplayDialog("提示", "Build AB(Release)成功", "确定");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
EditorUtility.DisplayDialog("提示", "Build AB(Release)失败", "确定");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[MenuItem("打包工具/AssetBundles/生成AB Config", priority = 204)]
|
||||||
|
static void GenerateABConfig()
|
||||||
|
{
|
||||||
|
var outputPath = Application.streamingAssetsPath;
|
||||||
|
AssetBundleUtils.GenerateAssetBundleConfig(outputPath, new BF.BFLanguageInfo(new List<string> { "en", "cn"}));
|
||||||
|
EditorUtility.DisplayDialog("提示", "生成配置文件", "确定");
|
||||||
|
}
|
||||||
|
|
||||||
|
[MenuItem("打包工具/AssetBundles/检查循环依赖", priority = 205)]
|
||||||
|
static void CheckABCycleDepend()
|
||||||
|
{
|
||||||
|
if (!ABCycleDependUtils.CheckABCycleDepend(Application.streamingAssetsPath))
|
||||||
|
{
|
||||||
|
EditorUtility.DisplayDialog("提示", "存在循环依赖", "确定");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
EditorUtility.DisplayDialog("提示", "不存在循环依赖", "确定");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[MenuItem("打包工具/AssetBundles/生成热更资源", priority = 206)]
|
||||||
|
static void GenUpdateRes()
|
||||||
|
{
|
||||||
|
if(!Directory.Exists(Application.streamingAssetsPath))
|
||||||
|
{
|
||||||
|
Debug.Log("streamingAssets 不存在");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var abccPath = Path.Combine(Application.streamingAssetsPath, "ab_config.bytes");
|
||||||
|
if (!File.Exists(abccPath))
|
||||||
|
{
|
||||||
|
Debug.LogError("ab_config.bytes不存在");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var bytes = File.ReadAllBytes(abccPath);
|
||||||
|
var json = BF.AssetBundleConfigCollection.Decompress(bytes);
|
||||||
|
var abcc = BF.AssetBundleConfigCollection.Create(json);
|
||||||
|
var dirInfo = new DirectoryInfo(Application.streamingAssetsPath);
|
||||||
|
var files = dirInfo.GetFiles("*.*", SearchOption.AllDirectories);
|
||||||
|
var assetFiles = new List<string>();
|
||||||
|
var dirPath = Path.Combine(Application.streamingAssetsPath, "../../update");
|
||||||
|
if (!Directory.Exists(dirPath))
|
||||||
|
{
|
||||||
|
Directory.CreateDirectory(dirPath);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Directory.Delete(dirPath, true);
|
||||||
|
Directory.CreateDirectory(dirPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 先设置版本号并保存下ab_config
|
||||||
|
abcc.version = "1.0.0";
|
||||||
|
var newJson = abcc.ToJson();
|
||||||
|
var newBytes = BF.AssetBundleConfigCollection.Compress(newJson);
|
||||||
|
File.WriteAllBytes(Path.Combine(dirPath, "ab_config.bytes"), newBytes);
|
||||||
|
|
||||||
|
// 初始化所有ab文件以及对应的md5
|
||||||
|
var mainConfig = abcc.mainConfigs;
|
||||||
|
Dictionary<string, string> md5Dict = new Dictionary<string, string>();
|
||||||
|
for (var i = 0; i < mainConfig.Count; ++i)
|
||||||
|
{
|
||||||
|
md5Dict.Add(mainConfig[i].assetBundlePath, mainConfig[i].md5);
|
||||||
|
}
|
||||||
|
|
||||||
|
int pathLength = Application.streamingAssetsPath.Length;
|
||||||
|
for (var i = 0; i < files.Length; ++i)
|
||||||
|
{
|
||||||
|
var fileInfo = files[i];
|
||||||
|
if (fileInfo.Extension.ToLower() == ".meta")
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (fileInfo.Name.EndsWith(".DS_Store"))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (fileInfo.Name.CompareTo("ab_config.bytes") == 0)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var md5 = BF.GameLaunchUtils.GetFileMD5(fileInfo.FullName);
|
||||||
|
var fileName = fileInfo.FullName.Substring(pathLength + 1).Replace("\\", "/");
|
||||||
|
if (md5Dict.ContainsKey(fileName))
|
||||||
|
{
|
||||||
|
if (md5Dict[fileName].CompareTo(md5) == 0)
|
||||||
|
{
|
||||||
|
md5Dict.Remove(fileName);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
File.Copy(fileInfo.FullName, Path.Combine(dirPath, md5));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Debug.Log("md5校验失败:" + fileName);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (md5Dict.Count <= 0)
|
||||||
|
{
|
||||||
|
Debug.Log("热更资源生成完毕,版本号:" + abcc.version);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Directory.Delete(dirPath, true);
|
||||||
|
Debug.Log("热更资源生成失败,版本号:" + abcc.version);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[MenuItem("打包工具/打包窗口", priority = 301)]
|
||||||
|
static void ShowBuildWindow()
|
||||||
|
{
|
||||||
|
BuildProjectWindow.ShowWindow();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
11
Assets/Editor/BFBuildProjectTools/BuildMenu.cs.meta
Normal file
11
Assets/Editor/BFBuildProjectTools/BuildMenu.cs.meta
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: a9a1a94adda2446978f1dbee68170fc1
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
328
Assets/Editor/BFBuildProjectTools/BuildProjectTools.cs
Normal file
328
Assets/Editor/BFBuildProjectTools/BuildProjectTools.cs
Normal file
@ -0,0 +1,328 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
using UnityEditor;
|
||||||
|
using UnityEngine;
|
||||||
|
using BFEditor.Resource;
|
||||||
|
using BF;
|
||||||
|
|
||||||
|
namespace BFEditor.Build
|
||||||
|
{
|
||||||
|
public static class BuildProjectTools
|
||||||
|
{
|
||||||
|
static string AssetBundleITPath = Application.dataPath + "/../Build/output/{0}";
|
||||||
|
static string AssetBundleCachePath = Application.dataPath + "/../HistoryAssetBundles";
|
||||||
|
|
||||||
|
static BuildProjectTools()
|
||||||
|
{
|
||||||
|
BuildAndroidUtils.EnsureJavaHome();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 提供给neo出包接口
|
||||||
|
/// </summary>
|
||||||
|
public static void BuildBFPlayer()
|
||||||
|
{
|
||||||
|
var dict = BFEditorUtils.GetCommandLineArgs();
|
||||||
|
if (dict.TryGetValue("data", out string dataStr))
|
||||||
|
{
|
||||||
|
Debug.Log("BuildBFPlayer " + dataStr);
|
||||||
|
var json = "{\"infos\":" + dataStr + "}";
|
||||||
|
var buildInfoCollection = JsonUtility.FromJson<BuildInfoCollection>(json);
|
||||||
|
if (!BuildBFPlayer(buildInfoCollection.GetFirstInfo()))
|
||||||
|
{
|
||||||
|
throw new Exception();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw new Exception();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static bool BuildBFPlayer(BuildInfo buildInfo)
|
||||||
|
{
|
||||||
|
// assetbundles
|
||||||
|
if (!BuildResources(buildInfo, Application.streamingAssetsPath, true))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 删除不进包的多语言
|
||||||
|
// if (!DeleteOverLanguageAb(buildInfo))
|
||||||
|
// {
|
||||||
|
// return false;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// 打包
|
||||||
|
if (!BuildPlayer(buildInfo))
|
||||||
|
{
|
||||||
|
Debug.LogError("[bferror]buildPlayer失败");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
AssetDatabase.Refresh();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool BuildPlayer(BuildInfo buildInfo)
|
||||||
|
{
|
||||||
|
Debug.Log("[bfinfo]开始打包, bundleName : " + buildInfo.bundleName + " version : " + buildInfo.version + " mode : " + buildInfo.mode);
|
||||||
|
|
||||||
|
var watch = new System.Diagnostics.Stopwatch();
|
||||||
|
watch.Start();
|
||||||
|
|
||||||
|
var result = false;
|
||||||
|
|
||||||
|
if (buildInfo.IsAndroidPlatform() && BuildAndroidUtils.BuildAndroidPlayer(buildInfo))
|
||||||
|
{
|
||||||
|
result = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if UNITY_EDITOR_OSX
|
||||||
|
if (buildInfo.IsIOSPlatform() && BuildIOSUtils.BuildIOSPlayer(buildInfo))
|
||||||
|
{
|
||||||
|
result = true;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (result)
|
||||||
|
{
|
||||||
|
watch.Stop();
|
||||||
|
Debug.Log("[bfinfo]打包完成,耗时: " + BFEditorUtils.GetTimeStr(watch.ElapsedMilliseconds));
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 提供给neo打热更接口
|
||||||
|
/// </summary>
|
||||||
|
public static void BuildResources()
|
||||||
|
{
|
||||||
|
var dict = BFEditorUtils.GetCommandLineArgs();
|
||||||
|
if (dict.TryGetValue("data", out string dataStr))
|
||||||
|
{
|
||||||
|
Debug.Log("BuildResources " + dataStr);
|
||||||
|
var json = "{\"infos\":" + dataStr + "}";
|
||||||
|
var buildInfoCollection = JsonUtility.FromJson<BuildInfoCollection>(json);
|
||||||
|
var bulidInfo = buildInfoCollection.GetFirstInfo();
|
||||||
|
var itPath = string.Format(AssetBundleITPath, bulidInfo.mode);
|
||||||
|
if (!BuildResources(bulidInfo, itPath, false))
|
||||||
|
{
|
||||||
|
throw new Exception();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw new Exception();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static bool BuildResources(BuildInfo buildInfo, string outputPath, bool needCopyToITPath)
|
||||||
|
{
|
||||||
|
if (Directory.Exists(outputPath))
|
||||||
|
{
|
||||||
|
Directory.Delete(outputPath, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 首先尝试从缓存获取
|
||||||
|
// if (TryGetAbFromCache(buildInfo, outputPath))
|
||||||
|
// {
|
||||||
|
// // 拷贝资源到it上传路径
|
||||||
|
// // if (needCopyToITPath)
|
||||||
|
// // {
|
||||||
|
// // CopyResToITPath(buildInfo, outputPath);
|
||||||
|
// // }
|
||||||
|
// return true;
|
||||||
|
// }
|
||||||
|
|
||||||
|
var watch = new System.Diagnostics.Stopwatch();
|
||||||
|
watch.Start();
|
||||||
|
|
||||||
|
// var buildTarget = buildInfo.IsIOSPlatform() ? BuildTarget.iOS : BuildTarget.Android;
|
||||||
|
var isRelease = buildInfo.IsReleaseChannel();
|
||||||
|
Debug.Log("[bfinfo]开始打包资源, bundleName : " + buildInfo.bundleName + " version : " + buildInfo.version + " mode : " + buildInfo.mode);
|
||||||
|
|
||||||
|
// // 检查平台
|
||||||
|
// if (EditorUserBuildSettings.activeBuildTarget != buildTarget)
|
||||||
|
// {
|
||||||
|
// Debug.LogError("[bferror]当前没有在对应平台");
|
||||||
|
// return false;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// 更新atlas
|
||||||
|
MainAtlasTools.UpdateMainAtlas();
|
||||||
|
// LanguageAtlasTools.UpdateLanguageAtlas();
|
||||||
|
|
||||||
|
// 生成tmp字体
|
||||||
|
TMPTools.GenFormalFontAsset(false);
|
||||||
|
|
||||||
|
// 清理fbx默认材质
|
||||||
|
MaterialTools.ClearFbxDefaultMaterial();
|
||||||
|
|
||||||
|
// 清理shader依赖资源
|
||||||
|
ShaderDependenciesTools.ClearAllShaderDependencies();
|
||||||
|
|
||||||
|
// 收集shader变体
|
||||||
|
ShaderVariantsTools.GenerateVariantCollection();
|
||||||
|
|
||||||
|
// ios因为环境问题,先不编译,打版本前提前编译好
|
||||||
|
if (EditorUserBuildSettings.activeBuildTarget == BuildTarget.Android)
|
||||||
|
{
|
||||||
|
// 编译并且加密lua代码
|
||||||
|
if (!CompileScriptsUtils.CompileAndEncryptLua(!isRelease))
|
||||||
|
{
|
||||||
|
Debug.LogError("[bferror]lua代码编译失败");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 设置abName
|
||||||
|
AssetBundleUtils.SetAllAssetsBundleName();
|
||||||
|
|
||||||
|
// 打ab资源
|
||||||
|
if (!AssetBundleUtils.BuildAssetBundles(EditorUserBuildSettings.activeBuildTarget, outputPath, isRelease, BuildAssetBundleOptions.ChunkBasedCompression,
|
||||||
|
buildInfo.GetLanguageInfo(), buildInfo.version))
|
||||||
|
{
|
||||||
|
Debug.LogError("[bferror]打ab失败");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检查循环依赖
|
||||||
|
if (!ABCycleDependUtils.CheckABCycleDepend(outputPath))
|
||||||
|
{
|
||||||
|
Debug.LogError("[bferror]打ab失败,ab存在循环依赖");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 本地缓存ab
|
||||||
|
if (buildInfo.IsReleaseChannel())
|
||||||
|
{
|
||||||
|
Debug.Log("[bfinfo]正在缓存assetbundles...");
|
||||||
|
BFEditorUtils.CopyDirWithIgnore(outputPath, Path.Combine(AssetBundleCachePath, buildInfo.version), new List<string> { ".meta" });
|
||||||
|
}
|
||||||
|
|
||||||
|
// 拷贝资源到it上传路径
|
||||||
|
// if (needCopyToITPath)
|
||||||
|
// {
|
||||||
|
// CopyResToITPath(buildInfo, outputPath);
|
||||||
|
// }
|
||||||
|
|
||||||
|
watch.Stop();
|
||||||
|
Debug.Log("[bfinfo]资源打包完成,耗时: " + BFEditorUtils.GetTimeStr(watch.ElapsedMilliseconds));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 尝试从缓存中获取ab,会进行md5校验
|
||||||
|
/// </summary>
|
||||||
|
static bool TryGetAbFromCache(BuildInfo buildInfo, string outputPath)
|
||||||
|
{
|
||||||
|
var cachePath = Path.Combine(AssetBundleCachePath, buildInfo.version);
|
||||||
|
if (!Directory.Exists(cachePath))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (CheckCacheAbMd5(cachePath, buildInfo))
|
||||||
|
{
|
||||||
|
Debug.Log(string.Format("[bfinfo]正在拷贝本地缓存资源 {0} ---> {1}", cachePath, outputPath));
|
||||||
|
BFEditorUtils.CopyDirWithIgnore(cachePath, outputPath, new List<string> { ".meta" });
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void CopyResToITPath(BuildInfo buildInfo, string outputPath)
|
||||||
|
{
|
||||||
|
Debug.Log("[bfinfo]正在拷贝assetbundles到运维上传路径...");
|
||||||
|
var itPath = string.Format(AssetBundleITPath, buildInfo.mode);
|
||||||
|
if (Directory.Exists(itPath))
|
||||||
|
{
|
||||||
|
Directory.Delete(itPath, true);
|
||||||
|
}
|
||||||
|
BFEditorUtils.CopyDirWithIgnore(outputPath, itPath, new List<string> { ".meta" });
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 校验缓存资源
|
||||||
|
/// </summary>
|
||||||
|
static bool CheckCacheAbMd5(string abPath, BuildInfo buildInfo)
|
||||||
|
{
|
||||||
|
Debug.Log("[bfinfo]正在校验缓存资源...");
|
||||||
|
|
||||||
|
var abccPath = Path.Combine(abPath, "ab_config.bytes");
|
||||||
|
if (!File.Exists(abccPath))
|
||||||
|
{
|
||||||
|
Debug.LogError("[bferror]校验缓存资源失败 ab_config.bytes不存在");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
var bytes = File.ReadAllBytes(abccPath);
|
||||||
|
var json = AssetBundleConfigCollection.Decompress(bytes);
|
||||||
|
var abcc = AssetBundleConfigCollection.Create(json);
|
||||||
|
foreach (var abc in abcc.mainConfigs)
|
||||||
|
{
|
||||||
|
var path = Path.Combine(abPath, abc.assetBundlePath);
|
||||||
|
if (!File.Exists(path))
|
||||||
|
{
|
||||||
|
Debug.LogError(string.Format("[bferror]校验缓存资源失败 {0} 文件丢失", abc.assetBundlePath));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
var md5 = GameLaunchUtils.GetFileMD5(path);
|
||||||
|
if (md5 != abc.md5)
|
||||||
|
{
|
||||||
|
Debug.LogError(string.Format("[bferror]校验缓存资源失败 {0} 文件md5不一致", abc.assetBundlePath));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 只有版本号不一样, 则修改abConfig的版本号
|
||||||
|
if (abcc.version != buildInfo.version)
|
||||||
|
{
|
||||||
|
Debug.Log(string.Format("[bfinfo]资源版本号不一样,修改版本号,缓存资源版本{0}, 目标版本{1}", abcc.version, buildInfo.version));
|
||||||
|
abcc.version = buildInfo.version;
|
||||||
|
var newJson = abcc.ToJson();
|
||||||
|
var newBytes = AssetBundleConfigCollection.Compress(newJson);
|
||||||
|
File.WriteAllBytes(abccPath, newBytes);
|
||||||
|
}
|
||||||
|
|
||||||
|
Debug.Log("[bfinfo]缓存资源校验完成");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 剔除冗余的多语言资源
|
||||||
|
/// </summary>
|
||||||
|
static bool DeleteOverLanguageAb(BuildInfo buildInfo)
|
||||||
|
{
|
||||||
|
var bundleName = buildInfo.bundleName;
|
||||||
|
var languageInfo = BFPlatform.GetLanguageInfo(bundleName);
|
||||||
|
if (languageInfo == null)
|
||||||
|
{
|
||||||
|
Debug.LogError("[bferror]没有对应的多语言info " + bundleName);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (var languagePath in AssetBundleUtils.languagePathList)
|
||||||
|
{
|
||||||
|
var languageAbDirPath = Application.streamingAssetsPath + "/" + languagePath;
|
||||||
|
var subLanguageDirs = Directory.GetDirectories(languageAbDirPath);
|
||||||
|
foreach (var dir in subLanguageDirs)
|
||||||
|
{
|
||||||
|
var dirInfo = new DirectoryInfo(dir);
|
||||||
|
var name = dirInfo.Name;
|
||||||
|
if (languageInfo.Contains(name))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
Debug.Log("[bfinfo]剔除不进包的多语言资源 " + dirInfo.FullName);
|
||||||
|
dirInfo.Delete(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
11
Assets/Editor/BFBuildProjectTools/BuildProjectTools.cs.meta
Normal file
11
Assets/Editor/BFBuildProjectTools/BuildProjectTools.cs.meta
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: ac8ec7aa30c1f4f98b7a67d46ea7385e
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
@ -0,0 +1,8 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: f98c4d80bcf5640b483894634dc8d744
|
||||||
|
folderAsset: yes
|
||||||
|
DefaultImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
@ -0,0 +1,89 @@
|
|||||||
|
using UnityEditor;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
namespace BFEditor.Build
|
||||||
|
{
|
||||||
|
public enum BFPlatformOptions
|
||||||
|
{
|
||||||
|
AndroidDev = 1,
|
||||||
|
IOSDev,
|
||||||
|
AndroidRelease,
|
||||||
|
AndroidGP,
|
||||||
|
}
|
||||||
|
|
||||||
|
public class BuildProjectWindow : EditorWindow
|
||||||
|
{
|
||||||
|
BFPlatformOptions platform = BFPlatformOptions.AndroidDev;
|
||||||
|
const string ANDROID_DEV_PACKAGE_NAME = "com.juzu.b5.dev.android";
|
||||||
|
const string ANDROID_RELEASE_PACKAGE_NAME = "com.juzu.b5.release.android";
|
||||||
|
const string ANDROID_GP_PACKAGE_NAME = "com.idle.ko.io";
|
||||||
|
const string IOS_PACKAGE_NAME = "com.juzu.b5.dev.ios";
|
||||||
|
|
||||||
|
public BuildProjectWindow()
|
||||||
|
{
|
||||||
|
titleContent = new GUIContent("打包");
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnEnable() { }
|
||||||
|
|
||||||
|
void OnGUI()
|
||||||
|
{
|
||||||
|
GUILayout.BeginVertical("box");
|
||||||
|
|
||||||
|
EditorGUILayout.LabelField("选择渠道");
|
||||||
|
platform = (BFPlatformOptions)EditorGUILayout.EnumPopup("", platform);
|
||||||
|
EditorGUILayout.Space();
|
||||||
|
|
||||||
|
EditorGUILayout.LabelField("版本: 0.1.0");
|
||||||
|
EditorGUILayout.Space();
|
||||||
|
|
||||||
|
string packageName;
|
||||||
|
string mode;
|
||||||
|
bool skipVersion = false;
|
||||||
|
if (platform == BFPlatformOptions.AndroidDev)
|
||||||
|
{
|
||||||
|
packageName = ANDROID_DEV_PACKAGE_NAME;
|
||||||
|
skipVersion = true;
|
||||||
|
mode = "dev_debug";
|
||||||
|
}
|
||||||
|
else if(platform == BFPlatformOptions.AndroidRelease)
|
||||||
|
{
|
||||||
|
packageName = ANDROID_RELEASE_PACKAGE_NAME;
|
||||||
|
mode = "release_release";
|
||||||
|
}
|
||||||
|
else if(platform == BFPlatformOptions.AndroidGP)
|
||||||
|
{
|
||||||
|
packageName = ANDROID_GP_PACKAGE_NAME;
|
||||||
|
mode = "publish_release";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
packageName = IOS_PACKAGE_NAME;
|
||||||
|
mode = "dev_debug";
|
||||||
|
}
|
||||||
|
EditorGUILayout.LabelField("包名: " + packageName);
|
||||||
|
EditorGUILayout.LabelField("mode: " + mode);
|
||||||
|
EditorGUILayout.Space();
|
||||||
|
|
||||||
|
EditorGUILayout.Space();
|
||||||
|
|
||||||
|
if (GUILayout.Button("一键打包"))
|
||||||
|
{
|
||||||
|
var buildInfo = new BuildInfo();
|
||||||
|
buildInfo.version = "0.1.0";
|
||||||
|
buildInfo.mode = mode;
|
||||||
|
buildInfo.bundleName = packageName;
|
||||||
|
buildInfo.skipVersion = skipVersion;
|
||||||
|
BuildProjectTools.BuildBFPlayer(buildInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
GUILayout.EndVertical();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void ShowWindow()
|
||||||
|
{
|
||||||
|
var window = GetWindow<BuildProjectWindow>();
|
||||||
|
window.Show();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: b74f96676758549c29495458431d37f1
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
8
Assets/Editor/BFBuildProjectTools/Utils.meta
Normal file
8
Assets/Editor/BFBuildProjectTools/Utils.meta
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: ae58ebe8667fa4656b85f29785cdd799
|
||||||
|
folderAsset: yes
|
||||||
|
DefaultImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
@ -0,0 +1,81 @@
|
|||||||
|
using System.Linq;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using UnityEngine;
|
||||||
|
using UnityEditor;
|
||||||
|
using System.IO;
|
||||||
|
|
||||||
|
namespace BFEditor.Build
|
||||||
|
{
|
||||||
|
public class ABCycleDependUtils
|
||||||
|
{
|
||||||
|
static AssetBundleManifest manifest;
|
||||||
|
|
||||||
|
public static bool CheckABCycleDepend(string outputPath)
|
||||||
|
{
|
||||||
|
Debug.Log("[bfinfo]检查循环依赖...");
|
||||||
|
manifest = GetManifest(outputPath);
|
||||||
|
if (manifest == null)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
var result = true;
|
||||||
|
|
||||||
|
var allABs = manifest.GetAllAssetBundles();
|
||||||
|
|
||||||
|
var totalCount = allABs.Length;
|
||||||
|
var unit = (float)totalCount / 100;
|
||||||
|
var index = 1;
|
||||||
|
var i = 0;
|
||||||
|
|
||||||
|
foreach (var ab in allABs)
|
||||||
|
{
|
||||||
|
if (i >= index * unit)
|
||||||
|
{
|
||||||
|
EditorUtility.DisplayProgressBar("提示", "正在检查ab循环依赖...", (float)index / 100);
|
||||||
|
index++;
|
||||||
|
}
|
||||||
|
|
||||||
|
result = CheckCycleDepend(ab) && result;
|
||||||
|
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
EditorUtility.ClearProgressBar();
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static AssetBundleManifest GetManifest(string outputPath)
|
||||||
|
{
|
||||||
|
var streamPath = Path.Combine(outputPath, "asset_bundle_manifest.ab");
|
||||||
|
if (!File.Exists(streamPath))
|
||||||
|
{
|
||||||
|
Debug.LogError("文件不存在 " + streamPath);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
var assetBundle = AssetBundle.LoadFromFile(streamPath);
|
||||||
|
var manifest = assetBundle.LoadAsset<AssetBundleManifest>("AssetBundleManifest");
|
||||||
|
assetBundle.Unload(false);
|
||||||
|
return manifest;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool CheckCycleDepend(string assetBundle)
|
||||||
|
{
|
||||||
|
var result = true;
|
||||||
|
var depends = manifest.GetAllDependencies(assetBundle);
|
||||||
|
|
||||||
|
foreach (var depend in depends)
|
||||||
|
{
|
||||||
|
var depend2 = manifest.GetAllDependencies(depend);
|
||||||
|
if (depend2.Contains(assetBundle))
|
||||||
|
{
|
||||||
|
Debug.LogError("存在循环依赖 " + assetBundle + " " + depend);
|
||||||
|
result = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 4e62f74612c9e41159c96c93494d668e
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
949
Assets/Editor/BFBuildProjectTools/Utils/AssetBundleUtils.cs
Normal file
949
Assets/Editor/BFBuildProjectTools/Utils/AssetBundleUtils.cs
Normal file
@ -0,0 +1,949 @@
|
|||||||
|
using UnityEngine;
|
||||||
|
using UnityEditor;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
using System.Text.RegularExpressions;
|
||||||
|
using System.Collections;
|
||||||
|
using BF;
|
||||||
|
|
||||||
|
namespace BFEditor.Build
|
||||||
|
{
|
||||||
|
struct ABNameInfo
|
||||||
|
{
|
||||||
|
public string name;
|
||||||
|
public string path;
|
||||||
|
}
|
||||||
|
|
||||||
|
public class AssetBundleUtils
|
||||||
|
{
|
||||||
|
const string ASSETS_STR = "Assets/";
|
||||||
|
const string FIRST_LUA = "lua/app/first/first.lua.bytes";
|
||||||
|
const string PROTOC_LUA = "lua/app/first/protoc.lua.bytes";
|
||||||
|
const string FIRST_TEXT_LUA = "lua/app/first/first_text.lua.bytes";
|
||||||
|
|
||||||
|
static string assetDirectory = Application.dataPath + "/";
|
||||||
|
public static List<string> languagePathList = new List<string> { "arts/language/", "lua/app/config/strings/" };
|
||||||
|
|
||||||
|
//需要忽略的文件后缀
|
||||||
|
static Dictionary<string, bool> ignoreResSuffix = new Dictionary<string, bool>() {
|
||||||
|
{ ".meta", true },
|
||||||
|
{ ".ds_store", true },
|
||||||
|
{ ".cs", true },
|
||||||
|
{ ".fnt", true },
|
||||||
|
{ ".unity", true },
|
||||||
|
{ ".ttf", true },
|
||||||
|
{ ".otf", true },
|
||||||
|
};
|
||||||
|
|
||||||
|
public static void ClearStreamingAssets()
|
||||||
|
{
|
||||||
|
Debug.Log("[bfinfo]清理streamingAssets...");
|
||||||
|
EditorUtility.DisplayProgressBar("提示", "正在清理streamingAssets...", 1);
|
||||||
|
|
||||||
|
var path = Path.Combine(Application.dataPath, "StreamingAssets");
|
||||||
|
if (Directory.Exists(path))
|
||||||
|
{
|
||||||
|
var di = new DirectoryInfo(path);
|
||||||
|
di.Delete(true);
|
||||||
|
AssetDatabase.Refresh();
|
||||||
|
}
|
||||||
|
|
||||||
|
EditorUtility.ClearProgressBar();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 打对应平台下的AB
|
||||||
|
/// </summary>
|
||||||
|
public static bool BuildAssetBundles(BuildTarget target, string outputPath, bool release, BuildAssetBundleOptions options,
|
||||||
|
BFLanguageInfo languageInfo, string version = "0.1.0")
|
||||||
|
{
|
||||||
|
Debug.Log("[bfinfo]正在build assetbundle...");
|
||||||
|
|
||||||
|
if (languageInfo == null)
|
||||||
|
{
|
||||||
|
Debug.LogError("[bferror]BuildAssetBundles: languageInfo = null");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
var streamingPath = Application.streamingAssetsPath;
|
||||||
|
|
||||||
|
if (Directory.Exists(streamingPath))
|
||||||
|
{
|
||||||
|
Directory.Delete(streamingPath, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!Directory.Exists(outputPath))
|
||||||
|
{
|
||||||
|
Directory.CreateDirectory(outputPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
AssetBundleManifest manifest;
|
||||||
|
if (release)
|
||||||
|
{
|
||||||
|
manifest = BuildPipeline.BuildAssetBundles(outputPath, options |
|
||||||
|
BuildAssetBundleOptions.StrictMode |
|
||||||
|
BuildAssetBundleOptions.DisableLoadAssetByFileName |
|
||||||
|
BuildAssetBundleOptions.DisableLoadAssetByFileNameWithExtension |
|
||||||
|
BuildAssetBundleOptions.DeterministicAssetBundle,
|
||||||
|
target);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
manifest = BuildPipeline.BuildAssetBundles(outputPath, options |
|
||||||
|
BuildAssetBundleOptions.StrictMode |
|
||||||
|
BuildAssetBundleOptions.DisableLoadAssetByFileName |
|
||||||
|
BuildAssetBundleOptions.DisableLoadAssetByFileNameWithExtension |
|
||||||
|
BuildAssetBundleOptions.DeterministicAssetBundle,
|
||||||
|
target);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (manifest == null)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!RebuildMp4AssetsBundle(outputPath, target))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
DeleteManifest(outputPath);
|
||||||
|
RenameManifest(outputPath);
|
||||||
|
GenerateAssetBundleConfig(outputPath, languageInfo, version); //生成 assetbundleconfig 配置文件
|
||||||
|
|
||||||
|
AssetDatabase.Refresh();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void DeleteManifest(string abPath)
|
||||||
|
{
|
||||||
|
var dir = new DirectoryInfo(abPath);
|
||||||
|
var files = dir.GetFiles("*.manifest", SearchOption.AllDirectories);
|
||||||
|
for (var i = 0; i < files.Length; ++i)
|
||||||
|
{
|
||||||
|
var fileInfo = files[i];
|
||||||
|
FileUtil.DeleteFileOrDirectory(fileInfo.FullName);
|
||||||
|
}
|
||||||
|
|
||||||
|
AssetDatabase.Refresh();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void RenameManifest(string abPath)
|
||||||
|
{
|
||||||
|
var manifestName = "";
|
||||||
|
int subIndex;
|
||||||
|
if (abPath[abPath.Length - 1] == '/')
|
||||||
|
{
|
||||||
|
subIndex = abPath.LastIndexOf('/', abPath.Length - 2);
|
||||||
|
if (subIndex >= 0)
|
||||||
|
{
|
||||||
|
manifestName = abPath.Substring(subIndex + 1, abPath.Length - subIndex - 2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
subIndex = abPath.LastIndexOf('/');
|
||||||
|
if (subIndex >= 0)
|
||||||
|
{
|
||||||
|
manifestName = abPath.Substring(subIndex + 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var manifestPath = Path.Combine(abPath, manifestName);
|
||||||
|
var manifestNewPath = Path.Combine(abPath, "asset_bundle_manifest.ab");
|
||||||
|
Debug.Log(manifestPath);
|
||||||
|
Debug.Log(manifestNewPath);
|
||||||
|
File.Move(manifestPath, manifestNewPath);
|
||||||
|
|
||||||
|
AssetDatabase.Refresh();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void GenerateAssetBundleConfig(string abPath, BFLanguageInfo languageInfo, string version = "0.1.0")
|
||||||
|
{
|
||||||
|
var abcc = new AssetBundleConfigCollection();
|
||||||
|
abcc.version = version;
|
||||||
|
|
||||||
|
var manifestPath = Path.Combine(abPath, "asset_bundle_manifest.ab");
|
||||||
|
var fileInfo = new FileInfo(manifestPath);
|
||||||
|
var abc = new AssetBundleConfig();
|
||||||
|
abc.assetBundlePath = "asset_bundle_manifest.ab";
|
||||||
|
abc.md5 = GetFileMD5(manifestPath);
|
||||||
|
abc.rawSize = fileInfo.Length;
|
||||||
|
abcc.AddAssetBundleConfig(abc);
|
||||||
|
|
||||||
|
var dirInfo = new DirectoryInfo(abPath);
|
||||||
|
var floders = dirInfo.GetDirectories();
|
||||||
|
for (int i = 0; i < floders.Length; i++)
|
||||||
|
{
|
||||||
|
var f = floders[i];
|
||||||
|
WriteInfo(abPath, f.Name, abcc, languageInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
var bytes = AssetBundleConfigCollection.Compress(abcc.ToJson());
|
||||||
|
File.WriteAllBytes(Path.Combine(abPath, "ab_config.bytes"), bytes);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void WriteInfo(string rootPath, string path, AssetBundleConfigCollection abcc, BFLanguageInfo languageInfo)
|
||||||
|
{
|
||||||
|
var searchPath = Path.Combine(rootPath, path);
|
||||||
|
var dirInfo = new DirectoryInfo(searchPath);
|
||||||
|
var files = dirInfo.GetFiles();
|
||||||
|
var subDirs = dirInfo.GetDirectories();
|
||||||
|
for (int i = 0; i < files.Length; i++)
|
||||||
|
{
|
||||||
|
var f = files[i];
|
||||||
|
var extension = f.Extension;
|
||||||
|
if (extension == ".meta" || extension == ".DS_Store")
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
var abCfg = new AssetBundleConfig();
|
||||||
|
abCfg.assetBundlePath = Path.Combine(path, f.Name).Replace("\\", "/");
|
||||||
|
var bundle = AssetBundle.LoadFromFile(f.FullName);
|
||||||
|
var assets = bundle.GetAllAssetNames();
|
||||||
|
abCfg.assetsPath = assets;
|
||||||
|
bundle.Unload(true);
|
||||||
|
abCfg.md5 = GetFileMD5(f.FullName);
|
||||||
|
abCfg.rawSize = f.Length;
|
||||||
|
if (abCfg == null)
|
||||||
|
{
|
||||||
|
Debug.LogError("f : " + f.FullName);
|
||||||
|
}
|
||||||
|
if (TryGetLanguageName(abCfg.assetBundlePath, languageInfo, out string languageName))
|
||||||
|
{
|
||||||
|
abcc.AddLangAssetBundleConfig(languageName, abCfg);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
abcc.AddAssetBundleConfig(abCfg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < subDirs.Length; i++)
|
||||||
|
{
|
||||||
|
var subDir = Path.Combine(path, subDirs[i].Name);
|
||||||
|
WriteInfo(rootPath, subDir, abcc, languageInfo);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 是否是多语言包资源
|
||||||
|
/// </summary>
|
||||||
|
static bool TryGetLanguageName(string abPath, BFLanguageInfo languageInfo, out string languageName)
|
||||||
|
{
|
||||||
|
if(true)
|
||||||
|
{
|
||||||
|
languageName = "";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
foreach (var startStr in languagePathList)
|
||||||
|
{
|
||||||
|
if (abPath.Contains(startStr))
|
||||||
|
{
|
||||||
|
var startIndex = abPath.IndexOf(startStr);
|
||||||
|
var temp = abPath.Substring(startIndex + startStr.Length);
|
||||||
|
var endIndex = temp.IndexOf("/");
|
||||||
|
var name = temp.Remove(endIndex);
|
||||||
|
if (languageInfo.Contains(name))
|
||||||
|
{
|
||||||
|
languageName = "";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!Resource.ResourceProcessConfig.languageNames.Contains(name))
|
||||||
|
{
|
||||||
|
languageName = "";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
languageName = name;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
languageName = "";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void RegenerateABConfigMd5(string abPath, string version = "")
|
||||||
|
{
|
||||||
|
Debug.Log("[bfinfo]正在重新生成abConfig md5...");
|
||||||
|
var abConfigPath = Path.Combine(abPath, "ab_config.bytes");
|
||||||
|
var bytes = File.ReadAllBytes(abConfigPath);
|
||||||
|
var json = AssetBundleConfigCollection.Decompress(bytes);
|
||||||
|
var abcc = AssetBundleConfigCollection.Create(json);
|
||||||
|
foreach (var abc in abcc.allConfigs)
|
||||||
|
{
|
||||||
|
abc.md5 = GetFileMD5(Path.Combine(abPath, abc.assetBundlePath));
|
||||||
|
}
|
||||||
|
if (!string.IsNullOrEmpty(version))
|
||||||
|
{
|
||||||
|
abcc.version = version;
|
||||||
|
}
|
||||||
|
var newJson = abcc.ToJson();
|
||||||
|
var newBytes = AssetBundleConfigCollection.Compress(newJson);
|
||||||
|
File.WriteAllBytes(abConfigPath, newBytes);
|
||||||
|
}
|
||||||
|
|
||||||
|
static string GetFileMD5(string filePath)
|
||||||
|
{
|
||||||
|
return GameLaunchUtils.GetFileMD5(filePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 重新打包mp4AB 不使用压缩
|
||||||
|
/// </summary>
|
||||||
|
public static bool RebuildMp4AssetsBundle(string outputPath, BuildTarget target)
|
||||||
|
{
|
||||||
|
var suc = true;
|
||||||
|
|
||||||
|
var videoAbPath = Path.Combine(outputPath, "arts/video");
|
||||||
|
if (!Directory.Exists(videoAbPath))
|
||||||
|
{
|
||||||
|
Directory.CreateDirectory(videoAbPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
var fileInfos = new DirectoryInfo(videoAbPath).GetFiles();
|
||||||
|
foreach (var fInfo in fileInfos)
|
||||||
|
{
|
||||||
|
if (fInfo.Extension != ".ab")
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
var fileName = fInfo.Name;
|
||||||
|
fInfo.Delete();
|
||||||
|
var tempPath = outputPath + "_temp";
|
||||||
|
if (Directory.Exists(tempPath))
|
||||||
|
{
|
||||||
|
Directory.Delete(tempPath, true);
|
||||||
|
}
|
||||||
|
Directory.CreateDirectory(tempPath);
|
||||||
|
var buildMap = new AssetBundleBuild[1];
|
||||||
|
var cgAbName = "arts/video/" + fileName;
|
||||||
|
buildMap[0].assetBundleName = cgAbName;
|
||||||
|
var mp4Assets = new string[1];
|
||||||
|
mp4Assets[0] = "Assets/arts/video/" + Path.GetFileNameWithoutExtension(fileName);
|
||||||
|
buildMap[0].assetNames = mp4Assets;
|
||||||
|
var manifest = BuildPipeline.BuildAssetBundles(tempPath, buildMap, BuildAssetBundleOptions.UncompressedAssetBundle, target);
|
||||||
|
if (manifest)
|
||||||
|
{
|
||||||
|
File.Move(Path.Combine(tempPath, cgAbName), Path.Combine(outputPath, cgAbName));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Debug.LogError("[bferror]重新打包mp4不压缩ab失败 " + fileName);
|
||||||
|
suc = false;
|
||||||
|
}
|
||||||
|
Directory.Delete(tempPath, true);
|
||||||
|
}
|
||||||
|
AssetDatabase.Refresh();
|
||||||
|
return suc;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 设置所有资源的ABName
|
||||||
|
/// </summary>
|
||||||
|
public static void SetAllAssetsBundleName()
|
||||||
|
{
|
||||||
|
Debug.Log("[bfinfo]设置资源abName...");
|
||||||
|
float total = 14;
|
||||||
|
float index = 1;
|
||||||
|
|
||||||
|
ClearFolderABName(Path.Combine(Application.dataPath, "arts", "effects"));
|
||||||
|
ClearFolderABName(Path.Combine(Application.dataPath, "first"));
|
||||||
|
|
||||||
|
SetLuaAssetBundleName(index++ / total);
|
||||||
|
SetSceneABName(index++ / total);
|
||||||
|
SetAnimationsABName(Path.Combine(Application.dataPath, "arts", "animations"), index++ / total);
|
||||||
|
SetAtlasABName(Path.Combine(Application.dataPath, "arts", "atlas"), index++ / total);
|
||||||
|
// SetEffectsABName(Path.Combine(Application.dataPath, "arts", "effects"), index++ / total);
|
||||||
|
SetBMFontsABName(Path.Combine(Application.dataPath, "arts", "fonts", "bmfonts"), index++ / total);
|
||||||
|
SetTmpFontsABName(Path.Combine(Application.dataPath, "arts", "fonts", "tmpfonts"), index++ / total);
|
||||||
|
SetMaterialABName(Path.Combine(Application.dataPath, "arts", "materials"), index++ / total);
|
||||||
|
SetModelsABName(Path.Combine(Application.dataPath, "arts", "models"), index++ / total);
|
||||||
|
SetShadersABName(Path.Combine(Application.dataPath, "arts", "shaders"), index++ / total);
|
||||||
|
SetSoundsABName(Path.Combine(Application.dataPath, "arts", "sounds"), index++ / total);
|
||||||
|
SetTexturesABName(Path.Combine(Application.dataPath, "arts", "textures"), index++ / total);
|
||||||
|
SetPrefabsABName(Path.Combine(Application.dataPath, "prefabs"), index++ / total);
|
||||||
|
SetProtoABName(Path.Combine(Application.dataPath, "proto"), index++ / total);
|
||||||
|
SetSpineABName(Path.Combine(Application.dataPath, "arts", "spines"), index++ / total);
|
||||||
|
SetFirstABName(Path.Combine(Application.dataPath, "first"), index++ / total);
|
||||||
|
// SetTimelineABName(Path.Combine(Application.dataPath, "arts", "timeline"), 16f / total);
|
||||||
|
// SetVideoABName(Path.Combine(Application.dataPath, "arts", "video"), 17f / total);
|
||||||
|
// SetLanguageResABName(Resource.ResourceProcessConfig.LANGUAGE_PATH, 19f / total);
|
||||||
|
// SetBakedatasABName(Path.Combine(Application.dataPath, "arts", "bakedatas"), 21f / total);
|
||||||
|
// SetLightProbesABName(Path.Combine(Application.dataPath, "arts", "lightprobes"), 22f / total);
|
||||||
|
// SetReflectionsABName(Path.Combine(Application.dataPath, "arts", "reflections"), 23f / total);
|
||||||
|
|
||||||
|
EditorUtility.ClearProgressBar();
|
||||||
|
AssetDatabase.SaveAssets();
|
||||||
|
AssetDatabase.Refresh();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void SetLuaAssetBundleName(float progress)
|
||||||
|
{
|
||||||
|
EditorUtility.DisplayProgressBar("提示", "正在设置lua ABName", progress);
|
||||||
|
|
||||||
|
var dirInfo = new DirectoryInfo(Path.Combine(Application.dataPath, "lua"));
|
||||||
|
SetABNameByFile(dirInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void SetAnimationsABName(string dirPath, float progress)
|
||||||
|
{
|
||||||
|
EditorUtility.DisplayProgressBar("提示", "正在设置animation ABName", progress);
|
||||||
|
|
||||||
|
string[] subDirList = { "ui", "frame" };
|
||||||
|
for (var i = 0; i < subDirList.Length; ++i)
|
||||||
|
{
|
||||||
|
var dirInfo = new DirectoryInfo(Path.Combine(dirPath, subDirList[i]));
|
||||||
|
if (dirInfo.Exists)
|
||||||
|
{
|
||||||
|
SetABNameBySubDir(dirInfo);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// atlas和textures里的图片是一一对应的,所以ab name设置为一样的
|
||||||
|
static void SetAtlasABName(string dirPath, float progress)
|
||||||
|
{
|
||||||
|
EditorUtility.DisplayProgressBar("提示", "正在设置atlas ABName", progress);
|
||||||
|
|
||||||
|
var abNameInfos = new List<ABNameInfo>();
|
||||||
|
|
||||||
|
string[] subDirList = { "ui", "icon" };
|
||||||
|
for (var i = 0; i < subDirList.Length; ++i)
|
||||||
|
{
|
||||||
|
var dirInfo = new DirectoryInfo(Path.Combine(dirPath, subDirList[i]));
|
||||||
|
var files = dirInfo.GetFiles("*.*", SearchOption.AllDirectories);
|
||||||
|
for (var j = 0; j < files.Length; ++j)
|
||||||
|
{
|
||||||
|
var fileInfo = files[j];
|
||||||
|
|
||||||
|
if (CheckIgnoreOrHidden(fileInfo))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
ABNameInfo ab;
|
||||||
|
ab.name = fileInfo.FullName.Substring(assetDirectory.Length).Replace(".asset", "").Replace(".spriteatlas", "").Replace("atlas", "textures");
|
||||||
|
var relativePath = fileInfo.FullName.Substring(assetDirectory.Length);
|
||||||
|
ab.path = relativePath;
|
||||||
|
abNameInfos.Add(ab);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (var relativePath in abNameInfos)
|
||||||
|
{
|
||||||
|
SetAssetBundleName(ASSETS_STR + relativePath.path, relativePath.name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void SetEffectsABName(string dirPath, float progress)
|
||||||
|
{
|
||||||
|
EditorUtility.DisplayProgressBar("提示", "正在设置特效 ABName", progress);
|
||||||
|
|
||||||
|
SetEffectsCommonABName(Path.Combine(dirPath, "texture"));
|
||||||
|
SetEffectsCommonABName(Path.Combine(dirPath, "models"));
|
||||||
|
|
||||||
|
// arts/effects/material 的子文件夹
|
||||||
|
string[] materialSubDirList = { "battle", "buff", "ui", "show" };
|
||||||
|
var materialSubDirPath = Path.Combine(dirPath, "material");
|
||||||
|
var dirInfo = new DirectoryInfo(materialSubDirPath);
|
||||||
|
var subDirs = dirInfo.GetDirectories();
|
||||||
|
for (var i = 0; i < subDirs.Length; ++i)
|
||||||
|
{
|
||||||
|
if(((IList)materialSubDirList).Contains(subDirs[i].Name))
|
||||||
|
{
|
||||||
|
var subDirInfo = new DirectoryInfo(Path.Combine(materialSubDirPath, subDirs[i].Name));
|
||||||
|
SetABNameBySubDir(subDirInfo);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SetABNameByDir(subDirs[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void SetEffectsCommonABName(string dirPath)
|
||||||
|
{
|
||||||
|
var dir = new DirectoryInfo(dirPath);
|
||||||
|
var files = dir.GetFiles("*.*", SearchOption.AllDirectories);
|
||||||
|
var assetFiles = new List<string>();
|
||||||
|
|
||||||
|
for (var i = 0; i < files.Length; ++i)
|
||||||
|
{
|
||||||
|
var fileInfo = files[i];
|
||||||
|
|
||||||
|
if (CheckIgnoreOrHidden(fileInfo))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
var relativePath = fileInfo.FullName.Substring(assetDirectory.Length);
|
||||||
|
assetFiles.Add(relativePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (var relativePath in assetFiles)
|
||||||
|
{
|
||||||
|
//prefab设置为和同名特效一个ab包
|
||||||
|
if (relativePath.ToLower().Contains("prefab"))
|
||||||
|
{
|
||||||
|
var abName = relativePath.Replace("prefab", "fbx");
|
||||||
|
SetAssetBundleName(ASSETS_STR + relativePath, abName);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SetAssetBundleName(ASSETS_STR + relativePath, relativePath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void SetBMFontsABName(string dirPath, float progress)
|
||||||
|
{
|
||||||
|
EditorUtility.DisplayProgressBar("提示", "正在设置BMFonts ABName", progress);
|
||||||
|
|
||||||
|
var dirInfo = new DirectoryInfo(dirPath);
|
||||||
|
SetABNameBySubDir(dirInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void SetMaterialABName(string dirPath, float progress)
|
||||||
|
{
|
||||||
|
EditorUtility.DisplayProgressBar("提示", "正在设置材质 ABName", progress);
|
||||||
|
|
||||||
|
var dirInfo = new DirectoryInfo(dirPath);
|
||||||
|
SetABNameByDir(dirInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void SetShadersABName(string dirPath, float progress)
|
||||||
|
{
|
||||||
|
EditorUtility.DisplayProgressBar("提示", "正在设置shader ABName", progress);
|
||||||
|
|
||||||
|
var dirInfo = new DirectoryInfo(dirPath);
|
||||||
|
SetABNameByDir(dirInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void SetModelsABName(string dirPath, float progress)
|
||||||
|
{
|
||||||
|
EditorUtility.DisplayProgressBar("提示", "正在设置模型 ABName", progress);
|
||||||
|
|
||||||
|
// 这几个文件夹按子文件夹来打ab,其他的文件夹就直接按每个文件夹打一个ab
|
||||||
|
string[] subDirList = { "characters", "maps", "maincity", "battle", "weapon" };
|
||||||
|
var dirInfo = new DirectoryInfo(dirPath);
|
||||||
|
var subDirs = dirInfo.GetDirectories();
|
||||||
|
for (var i = 0; i < subDirs.Length; ++i)
|
||||||
|
{
|
||||||
|
if(((IList)subDirList).Contains(subDirs[i].Name))
|
||||||
|
{
|
||||||
|
var subDirInfo = new DirectoryInfo(Path.Combine(dirPath, subDirs[i].Name));
|
||||||
|
SetABNameBySubDir(subDirInfo);
|
||||||
|
|
||||||
|
// // 角色材质因为改动比较频繁,和模型打包在一起的话热更的时候会导致热更量比较大,所以单独设置一下
|
||||||
|
// if(subDirs[i].Name == "characters")
|
||||||
|
// {
|
||||||
|
// var materialPath = BFEditorUtils.GetAssetPathsWithSuffix(subDirInfo.FullName, ".mat");
|
||||||
|
// foreach (var path in materialPath)
|
||||||
|
// {
|
||||||
|
// SetABNameByDirName(path);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SetABNameByDir(subDirs[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void SetSoundsABName(string dirPath, float progress)
|
||||||
|
{
|
||||||
|
EditorUtility.DisplayProgressBar("提示", "正在设置sounds ABName", progress);
|
||||||
|
|
||||||
|
var dirInfo = new DirectoryInfo(dirPath);
|
||||||
|
SetABNameByFile(dirInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void SetVideoABName(string dirPath, float progress)
|
||||||
|
{
|
||||||
|
EditorUtility.DisplayProgressBar("提示", "正在设置video ABName", progress);
|
||||||
|
|
||||||
|
var dirInfo = new DirectoryInfo(dirPath);
|
||||||
|
SetABNameByFile(dirInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void SetSpineABName(string dirPath, float progress)
|
||||||
|
{
|
||||||
|
EditorUtility.DisplayProgressBar("提示", "正在设置spine ABName", progress);
|
||||||
|
|
||||||
|
string[] dirList = { "ui", "characters", "battle" };
|
||||||
|
for (var i = 0; i < dirList.Length; ++i)
|
||||||
|
{
|
||||||
|
var dirInfo = new DirectoryInfo(Path.Combine(dirPath, dirList[i]));
|
||||||
|
SetABNameBySubDir(dirInfo);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void SetTexturesABName(string dirPath, float progress)
|
||||||
|
{
|
||||||
|
EditorUtility.DisplayProgressBar("提示", "正在设置texture ABName", progress);
|
||||||
|
|
||||||
|
SetSpriteABName(dirPath);
|
||||||
|
SetBackgroundABName(dirPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void SetSpriteABName(string dirPath)
|
||||||
|
{
|
||||||
|
string[] dirList = { "ui", "icon" };
|
||||||
|
for (var i = 0; i < dirList.Length; ++i)
|
||||||
|
{
|
||||||
|
var dirInfo = new DirectoryInfo(Path.Combine(dirPath, dirList[i]));
|
||||||
|
SetABNameBySubDir(dirInfo);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void SetBackgroundABName(string dirPath)
|
||||||
|
{
|
||||||
|
var dirInfo = new DirectoryInfo(Path.Combine(dirPath, "background"));
|
||||||
|
SetABNameByFile(dirInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void SetPrefabsABName(string dirPath, float progress)
|
||||||
|
{
|
||||||
|
EditorUtility.DisplayProgressBar("提示", "正在设置perfab ABName", progress);
|
||||||
|
|
||||||
|
var dirInfo = new DirectoryInfo(dirPath);
|
||||||
|
SetABNameByFile(dirInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void SetProtoABName(string dirPath, float progress)
|
||||||
|
{
|
||||||
|
EditorUtility.DisplayProgressBar("提示", "正在设置proto ABName", progress);
|
||||||
|
|
||||||
|
var dirInfo = new DirectoryInfo(dirPath);
|
||||||
|
var pathList = new List<string>();
|
||||||
|
|
||||||
|
var files = dirInfo.GetFiles("*.*", SearchOption.AllDirectories);
|
||||||
|
for (var i = 0; i < files.Length; ++i)
|
||||||
|
{
|
||||||
|
var fileInfo = files[i];
|
||||||
|
|
||||||
|
if (CheckIgnoreOrHidden(fileInfo))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
var relativePath = fileInfo.FullName.Substring(assetDirectory.Length);
|
||||||
|
pathList.Add(relativePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (var path in pathList)
|
||||||
|
{
|
||||||
|
SetAssetBundleName(ASSETS_STR + path, "proto/proto");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void SetSceneABName(float progress)
|
||||||
|
{
|
||||||
|
EditorUtility.DisplayProgressBar("提示", "正在设置scene ABName", progress);
|
||||||
|
|
||||||
|
var scenes = GetBuildScenes();
|
||||||
|
foreach (var scene in scenes)
|
||||||
|
{
|
||||||
|
SetAssetBundleName(scene, scene.Replace("Assets/", ""));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void SetTimelineABName(string dirPath, float progress)
|
||||||
|
{
|
||||||
|
EditorUtility.DisplayProgressBar("提示", "正在设置timeline ABName", progress);
|
||||||
|
|
||||||
|
var dirInfo = new DirectoryInfo(dirPath);
|
||||||
|
SetABNameByFile(dirInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void SetFirstABName(string dirPath, float progress)
|
||||||
|
{
|
||||||
|
EditorUtility.DisplayProgressBar("提示", "正在设置首包ABName", progress);
|
||||||
|
|
||||||
|
var dirInfo = new DirectoryInfo(dirPath);
|
||||||
|
var pathList = new List<string>();
|
||||||
|
|
||||||
|
var files = dirInfo.GetFiles("*.*", SearchOption.AllDirectories);
|
||||||
|
for (var i = 0; i < files.Length; ++i)
|
||||||
|
{
|
||||||
|
var fileInfo = files[i];
|
||||||
|
|
||||||
|
if (CheckIgnoreOrHidden(fileInfo))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
var relativePath = fileInfo.FullName.Substring(assetDirectory.Length);
|
||||||
|
pathList.Add(relativePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
pathList.Add(FIRST_LUA);
|
||||||
|
pathList.Add(PROTOC_LUA);
|
||||||
|
pathList.Add(FIRST_TEXT_LUA);
|
||||||
|
|
||||||
|
foreach (var path in pathList)
|
||||||
|
{
|
||||||
|
SetAssetBundleName(ASSETS_STR + path, "first/first");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void SetLanguageResABName(string dirPath, float progress)
|
||||||
|
{
|
||||||
|
EditorUtility.DisplayProgressBar("提示", "正在设置多语言资源 ABName", progress);
|
||||||
|
var dirInfo = new DirectoryInfo(dirPath);
|
||||||
|
var files = dirInfo.GetFiles("*.*", SearchOption.AllDirectories);
|
||||||
|
foreach (var f in files)
|
||||||
|
{
|
||||||
|
if (CheckIgnoreOrHidden(f))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
var dirName = Path.GetDirectoryName(f.FullName);
|
||||||
|
var abName = dirName.Substring(assetDirectory.Length);
|
||||||
|
var relativePath = f.FullName.Substring(assetDirectory.Length);
|
||||||
|
SetAssetBundleName(ASSETS_STR + relativePath, abName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void SetTmpFontsABName(string dirPath, float progress)
|
||||||
|
{
|
||||||
|
EditorUtility.DisplayProgressBar("提示", "正在设置tmp font ABName", progress);
|
||||||
|
var dirInfo = new DirectoryInfo(dirPath);
|
||||||
|
SetABNameBySubDir(dirInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void SetBakedatasABName(string dirPath, float progress)
|
||||||
|
{
|
||||||
|
EditorUtility.DisplayProgressBar("提示", "正在设置bakedatas ABName", progress);
|
||||||
|
var dirInfo = new DirectoryInfo(dirPath);
|
||||||
|
SetABNameBySubDir(dirInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void SetLightProbesABName(string dirPath, float progress)
|
||||||
|
{
|
||||||
|
EditorUtility.DisplayProgressBar("提示", "正在设置lightprobe ABName", progress);
|
||||||
|
var dirInfo = new DirectoryInfo(dirPath);
|
||||||
|
SetABNameBySubDir(dirInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void SetReflectionsABName(string dirPath, float progress)
|
||||||
|
{
|
||||||
|
EditorUtility.DisplayProgressBar("提示", "正在设置reflection ABName", progress);
|
||||||
|
var dirInfo = new DirectoryInfo(dirPath);
|
||||||
|
SetABNameBySubDir(dirInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 通过文件名设置abName, dirInfo下的每个资源的abName都设置为fileName
|
||||||
|
/// </summary>
|
||||||
|
static void SetABNameByFile(DirectoryInfo dirInfo)
|
||||||
|
{
|
||||||
|
var files = dirInfo.GetFiles("*.*", SearchOption.AllDirectories);
|
||||||
|
var assetFiles = new List<string>();
|
||||||
|
|
||||||
|
for (var i = 0; i < files.Length; ++i)
|
||||||
|
{
|
||||||
|
var fileInfo = files[i];
|
||||||
|
|
||||||
|
if (CheckIgnoreOrHidden(fileInfo))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
var relativePath = fileInfo.FullName.Substring(assetDirectory.Length);
|
||||||
|
assetFiles.Add(relativePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (var relativePath in assetFiles)
|
||||||
|
{
|
||||||
|
SetAssetBundleName(ASSETS_STR + relativePath, relativePath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 根据dirInfo下的二级文件夹名设置资源abName
|
||||||
|
/// </summary>
|
||||||
|
static void SetABNameBySubDir(DirectoryInfo dirInfo)
|
||||||
|
{
|
||||||
|
var dirs = dirInfo.GetDirectories();
|
||||||
|
for (var i = 0; i < dirs.Length; i++)
|
||||||
|
{
|
||||||
|
SetABNameByDir(dirs[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 根据文件夹路径设置资源的abName
|
||||||
|
/// </summary>
|
||||||
|
static void SetABNameByDirName(string relativeFilePath)
|
||||||
|
{
|
||||||
|
if (!File.Exists(relativeFilePath))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var dirPath = Path.GetDirectoryName(relativeFilePath);
|
||||||
|
var name = dirPath.Replace("\\", "/").Replace(ASSETS_STR, "");
|
||||||
|
SetAssetBundleName(relativeFilePath, name);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 根据文件夹路径设置资源的abName, dirInfo下的资源abName都设置为dirPath相对路径
|
||||||
|
/// </summary>
|
||||||
|
static void SetABNameByDir(DirectoryInfo dirInfo)
|
||||||
|
{
|
||||||
|
var abInfos = new List<ABNameInfo>();
|
||||||
|
|
||||||
|
var files = dirInfo.GetFiles("*.*", SearchOption.AllDirectories);
|
||||||
|
for (var i = 0; i < files.Length; ++i)
|
||||||
|
{
|
||||||
|
var fileInfo = files[i];
|
||||||
|
|
||||||
|
if (CheckIgnoreOrHidden(fileInfo))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
ABNameInfo into;
|
||||||
|
into.name = dirInfo.FullName.Substring(assetDirectory.Length);
|
||||||
|
var relativePath = fileInfo.FullName.Substring(assetDirectory.Length);
|
||||||
|
into.path = relativePath;
|
||||||
|
abInfos.Add(into);
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (var abInfo in abInfos)
|
||||||
|
{
|
||||||
|
SetAssetBundleName(ASSETS_STR + abInfo.path, abInfo.name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ClearFolderABName(string dirPath)
|
||||||
|
{
|
||||||
|
var dirInfo = new DirectoryInfo(dirPath);
|
||||||
|
var files = dirInfo.GetFiles("*.*", SearchOption.AllDirectories);
|
||||||
|
var assetFiles = new List<string>();
|
||||||
|
|
||||||
|
for (var i = 0; i < files.Length; ++i)
|
||||||
|
{
|
||||||
|
var fileInfo = files[i];
|
||||||
|
|
||||||
|
if (CheckIgnoreOrHidden(fileInfo))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
var relativePath = fileInfo.FullName.Substring(assetDirectory.Length);
|
||||||
|
assetFiles.Add(relativePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (var relativePath in assetFiles)
|
||||||
|
{
|
||||||
|
ClearAssetBundleName(ASSETS_STR + relativePath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ClearAssetBundleName(string assetPath)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrEmpty(assetPath))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!assetPath.Contains("Editor/"))
|
||||||
|
{
|
||||||
|
var importer = AssetImporter.GetAtPath(assetPath);
|
||||||
|
if (importer == null)
|
||||||
|
{
|
||||||
|
AssetDatabase.ImportAsset(assetPath);
|
||||||
|
importer = AssetImporter.GetAtPath(assetPath);
|
||||||
|
}
|
||||||
|
if (!string.IsNullOrEmpty(importer.assetBundleName))
|
||||||
|
{
|
||||||
|
importer.assetBundleName = string.Empty;
|
||||||
|
EditorUtility.SetDirty(importer);
|
||||||
|
AssetDatabase.WriteImportSettingsIfDirty(assetPath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void SetAssetBundleName(string assetPath, string bundleName)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrEmpty(assetPath) || string.IsNullOrWhiteSpace(bundleName))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Regex.IsMatch(assetPath, @"[\u4e00-\u9fbb]"))
|
||||||
|
{
|
||||||
|
Debug.LogError("AssetBundleUtils SetAssetBundleName: " + assetPath + " 存在中文");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!assetPath.Contains("Editor/"))
|
||||||
|
{
|
||||||
|
bundleName = bundleName.ToLower() + ".ab";
|
||||||
|
|
||||||
|
//所有AB名设定为相对于assets目录
|
||||||
|
var special = "assets/";
|
||||||
|
if (bundleName.Contains(special))
|
||||||
|
{
|
||||||
|
bundleName = bundleName.Substring(special.Length);
|
||||||
|
}
|
||||||
|
|
||||||
|
var changed = false;
|
||||||
|
var importer = AssetImporter.GetAtPath(assetPath);
|
||||||
|
if (importer == null)
|
||||||
|
{
|
||||||
|
AssetDatabase.ImportAsset(assetPath);
|
||||||
|
importer = AssetImporter.GetAtPath(assetPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (string.IsNullOrEmpty(importer.assetBundleName) || !string.Equals(importer.assetBundleName, bundleName))
|
||||||
|
{
|
||||||
|
importer.assetBundleName = bundleName;
|
||||||
|
EditorUtility.SetDirty(importer);
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (changed)
|
||||||
|
{
|
||||||
|
AssetDatabase.WriteImportSettingsIfDirty(assetPath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool CheckIgnoreOrHidden(FileInfo fi)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (((fi.Attributes & FileAttributes.Hidden) > 0) || ((fi.Attributes & FileAttributes.System) > 0))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ignoreResSuffix.ContainsKey(fi.Extension.ToLower()))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static string[] GetBuildScenes()
|
||||||
|
{
|
||||||
|
var result = new List<string>();
|
||||||
|
foreach (var scene in EditorBuildSettings.scenes)
|
||||||
|
{
|
||||||
|
if (scene == null)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (scene.enabled)
|
||||||
|
{
|
||||||
|
result.Add(scene.path);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result.ToArray();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: c60f44f4fc5e74f0d97a4a65a91f12d6
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
542
Assets/Editor/BFBuildProjectTools/Utils/BuildAndroidUtils.cs
Normal file
542
Assets/Editor/BFBuildProjectTools/Utils/BuildAndroidUtils.cs
Normal file
@ -0,0 +1,542 @@
|
|||||||
|
using UnityEngine;
|
||||||
|
using UnityEditor;
|
||||||
|
using System.IO;
|
||||||
|
using UnityEditor.Build.Reporting;
|
||||||
|
using System.Text.RegularExpressions;
|
||||||
|
using System;
|
||||||
|
using System.Threading;
|
||||||
|
|
||||||
|
namespace BFEditor.Build
|
||||||
|
{
|
||||||
|
public static class BuildAndroidUtils
|
||||||
|
{
|
||||||
|
const string JAVA_HOME_ENVIRONMENT = "JAVA_HOME";
|
||||||
|
const string JAVA_HOME_ENVIRONMENT_PATH = "/Applications/Unity/PlaybackEngines/AndroidPlayer/Tools/OpenJDK/MacOS";
|
||||||
|
const string ANDROID_DEFINE_SYMBOLS = "THREAD_SAFE;USE_AB";
|
||||||
|
const string AS_PROJECT_PATH = "BFVersions/android";
|
||||||
|
const string GRADLE_PATH = "/Users/aoddabao/.gradle/wrapper/dists/gradle-5.6.4-all/ankdp27end7byghfw1q2sw75f/gradle-5.6.4/bin/gradle";
|
||||||
|
const string BUGLY_APP_ID = "1eb4e5e560";
|
||||||
|
const string BUGLY_APP_KEY = "99e249db-4eeb-440e-83e7-c2bd80e8b5e4";
|
||||||
|
|
||||||
|
static Thread buglyUploadThread;
|
||||||
|
static string ReleaseSOPath = Application.dataPath + "/../BFVersions/android/ub-release/src/main/jniLibs";
|
||||||
|
static string BuglyPath = Application.dataPath + "/../Bugly";
|
||||||
|
static string BuglySOPath = Application.dataPath + "/../Bugly/so";
|
||||||
|
static string GradleExcuteProjectPath = Application.dataPath + "/../BFVersions/android/ub-release";
|
||||||
|
static string DevAsProjectPath = Application.dataPath + "/../BFVersions/android/dz_dev";
|
||||||
|
static string LanReleaseAsProjectPath = Application.dataPath + "/../BFVersions/android/dz_release";
|
||||||
|
static string GoogleAsProjectPath = Application.dataPath + "/../BFVersions/android/dz_google_apk";
|
||||||
|
static string GoogleCommonProjectPath = Application.dataPath + "/../BFVersions/android/google_common";
|
||||||
|
static string GPAsProjectPath = Application.dataPath + "/../BFVersions/android/ub-gp"; // gp删档测试渠道
|
||||||
|
static string GPOfficialAsProjectPath = Application.dataPath + "/../BFVersions/android/ub-google"; // gp正式渠道
|
||||||
|
static string SignShellPath = Application.dataPath + "/../BFFiles/androidkey";
|
||||||
|
static string GpAlginShellPath = Application.dataPath + "/../BFFiles/androidkey";
|
||||||
|
|
||||||
|
static BuildAndroidUtils()
|
||||||
|
{
|
||||||
|
EnsureJavaHome();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void EnsureJavaHome()
|
||||||
|
{
|
||||||
|
// var javaHomeEnvironment = Environment.GetEnvironmentVariable(JAVA_HOME_ENVIRONMENT);
|
||||||
|
// if (string.IsNullOrEmpty(javaHomeEnvironment))
|
||||||
|
// {
|
||||||
|
// Environment.SetEnvironmentVariable(JAVA_HOME_ENVIRONMENT, JAVA_HOME_ENVIRONMENT_PATH);
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 打包android
|
||||||
|
/// </summary>
|
||||||
|
public static bool BuildAndroidPlayer(BuildInfo buildInfo)
|
||||||
|
{
|
||||||
|
var buildTarget = BuildTarget.Android;
|
||||||
|
|
||||||
|
// 检查平台
|
||||||
|
if (EditorUserBuildSettings.activeBuildTarget != buildTarget)
|
||||||
|
{
|
||||||
|
Debug.LogError("[bferror]当前没有在对应平台");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 重新生成XLua
|
||||||
|
CompileScriptsUtils.RegenerateXLuaCode(true);
|
||||||
|
|
||||||
|
// 打包设置
|
||||||
|
BuildSettings(buildInfo);
|
||||||
|
|
||||||
|
// 开始打包
|
||||||
|
var bpOptions = GetBuildOptions(buildInfo);
|
||||||
|
var report = BuildPipeline.BuildPlayer(bpOptions);
|
||||||
|
|
||||||
|
// 打包成功
|
||||||
|
if (report.summary.result == BuildResult.Succeeded)
|
||||||
|
{
|
||||||
|
return BuildAndroidAPK(buildInfo);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Debug.LogError("[bferror]unity打包失败");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 打包设置
|
||||||
|
/// </summary>
|
||||||
|
static void BuildSettings(BuildInfo buildInfo)
|
||||||
|
{
|
||||||
|
// 设置bundleVersion
|
||||||
|
PlayerSettings.bundleVersion = buildInfo.version;
|
||||||
|
|
||||||
|
// 设置VersionCode
|
||||||
|
PlayerSettings.Android.bundleVersionCode = buildInfo.version_code;
|
||||||
|
|
||||||
|
// 设置竖屏
|
||||||
|
PlayerSettings.defaultInterfaceOrientation = UIOrientation.Portrait;
|
||||||
|
PlayerSettings.allowedAutorotateToPortrait = false;
|
||||||
|
PlayerSettings.allowedAutorotateToPortraitUpsideDown = false;
|
||||||
|
PlayerSettings.allowedAutorotateToLandscapeLeft = false;
|
||||||
|
PlayerSettings.allowedAutorotateToLandscapeRight = false;
|
||||||
|
|
||||||
|
// 安卓构建目标CPU架构
|
||||||
|
PlayerSettings.Android.targetArchitectures = AndroidArchitecture.ARMv7 | AndroidArchitecture.ARM64;
|
||||||
|
|
||||||
|
// 强加Internet权限
|
||||||
|
PlayerSettings.Android.forceInternetPermission = true;
|
||||||
|
|
||||||
|
// 关闭启动动画
|
||||||
|
PlayerSettings.SplashScreen.show = false;
|
||||||
|
|
||||||
|
// 设置包名
|
||||||
|
PlayerSettings.SetApplicationIdentifier(BuildTargetGroup.Android, buildInfo.bundleName);
|
||||||
|
Debug.Log("[bfinfo]设置包名:" + buildInfo.bundleName);
|
||||||
|
|
||||||
|
// 跳过版本控制
|
||||||
|
var symbols = ANDROID_DEFINE_SYMBOLS;
|
||||||
|
if (buildInfo.skipVersion)
|
||||||
|
{
|
||||||
|
symbols = symbols + ";SKIP_VERSION;";
|
||||||
|
}
|
||||||
|
|
||||||
|
PlayerSettings.SetScriptingDefineSymbolsForGroup(BuildTargetGroup.Android, symbols);
|
||||||
|
Debug.Log("[bfinfo]设置defineSymbols: " + symbols);
|
||||||
|
|
||||||
|
// 是否是dev
|
||||||
|
var development = buildInfo.IsDevChannel() ? true : false;
|
||||||
|
EditorUserBuildSettings.development = development;
|
||||||
|
|
||||||
|
// 商品名称
|
||||||
|
// 应用名
|
||||||
|
if (buildInfo.IsPublish())
|
||||||
|
{
|
||||||
|
PlayerSettings.productName = "K.O";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
PlayerSettings.productName = development ? "b5-dev" : "b5-release";
|
||||||
|
}
|
||||||
|
// BuildType设置dev/release
|
||||||
|
EditorUserBuildSettings.androidBuildType = development ? AndroidBuildType.Debug : AndroidBuildType.Release;
|
||||||
|
|
||||||
|
// 是否导出as工程
|
||||||
|
// EditorUserBuildSettings.exportAsGoogleAndroidProject = development ? false : true;
|
||||||
|
EditorUserBuildSettings.exportAsGoogleAndroidProject = true;
|
||||||
|
|
||||||
|
// dev使用Mono release使用IL2CPP
|
||||||
|
var scriptImp = development ? ScriptingImplementation.Mono2x : ScriptingImplementation.IL2CPP;
|
||||||
|
PlayerSettings.SetScriptingBackend(BuildTargetGroup.Android, scriptImp);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取打包参数
|
||||||
|
/// </summary>
|
||||||
|
static BuildPlayerOptions GetBuildOptions(BuildInfo buildInfo)
|
||||||
|
{
|
||||||
|
var bpOptions = new BuildPlayerOptions();
|
||||||
|
bpOptions.scenes = AssetBundleUtils.GetBuildScenes();
|
||||||
|
bpOptions.target = BuildTarget.Android;
|
||||||
|
|
||||||
|
// if (buildInfo.IsDevChannel())
|
||||||
|
// {
|
||||||
|
// bpOptions.locationPathName = GetDevApkPathName(buildInfo);
|
||||||
|
// Debug.Log("[bfinfo]apk path : " + bpOptions.locationPathName);
|
||||||
|
// }
|
||||||
|
// else
|
||||||
|
// {
|
||||||
|
// bpOptions.locationPathName = GetASProjectPathName();
|
||||||
|
// Debug.Log("[bfinfo]asProject path : " + bpOptions.locationPathName);
|
||||||
|
// }
|
||||||
|
bpOptions.locationPathName = GetASProjectPathName(buildInfo);
|
||||||
|
|
||||||
|
BuildOptions options;
|
||||||
|
if (buildInfo.IsReleaseChannel())
|
||||||
|
{
|
||||||
|
options = BuildOptions.None;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
options = BuildOptions.Development;
|
||||||
|
}
|
||||||
|
|
||||||
|
bpOptions.options = options;
|
||||||
|
return bpOptions;
|
||||||
|
}
|
||||||
|
|
||||||
|
static string GetDevApkPathName(BuildInfo buildInfo)
|
||||||
|
{
|
||||||
|
var apkName = buildInfo.skipVersion ? "dz_dev_skip_version.apk" : "dz_dev_debug.apk";
|
||||||
|
var path = Path.Combine(AS_PROJECT_PATH, apkName);
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
|
||||||
|
static string GetASProjectPathName(BuildInfo buildInfo)
|
||||||
|
{
|
||||||
|
var dir = Path.Combine(AS_PROJECT_PATH, buildInfo.mode);
|
||||||
|
if (Directory.Exists(dir))
|
||||||
|
{
|
||||||
|
Directory.Delete(dir, true);
|
||||||
|
}
|
||||||
|
return dir;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool BuildAPK(BuildInfo buildInfo)
|
||||||
|
{
|
||||||
|
if (buildInfo.IsGPChannel())
|
||||||
|
{
|
||||||
|
MergeGPToReleaseProject(buildInfo);
|
||||||
|
FixGradleVersion(buildInfo.version_code, buildInfo.version);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (buildInfo.IsLanRelease())
|
||||||
|
{
|
||||||
|
AddBuglyParamsToReleaseProject();
|
||||||
|
}
|
||||||
|
|
||||||
|
Debug.Log("[bfinfo]正在buildApk...");
|
||||||
|
var success = true;
|
||||||
|
var args = "";
|
||||||
|
if (buildInfo.IsReleaseChannel())
|
||||||
|
{
|
||||||
|
args += " assembleRelease";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
args += " assembleDebug";
|
||||||
|
}
|
||||||
|
|
||||||
|
BFEditorUtils.RunCommond(GRADLE_PATH, args, GradleExcuteProjectPath,
|
||||||
|
(msg) =>
|
||||||
|
{
|
||||||
|
},
|
||||||
|
(errorMsg) =>
|
||||||
|
{
|
||||||
|
if (errorMsg.Contains("BUILD FAILED") || errorMsg.Contains("FAILURE") || errorMsg.Contains("ERROR"))
|
||||||
|
{
|
||||||
|
success = false;
|
||||||
|
Debug.LogError("[bferror] " + errorMsg);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (buildInfo.IsGPChannel())
|
||||||
|
{
|
||||||
|
// 尝试制作并上传bugly符号表 开新Thread不影响打包流程
|
||||||
|
if (success)
|
||||||
|
{
|
||||||
|
CopySOAndUploadBuglySymbol(buildInfo.bundleName, buildInfo.version);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return success;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool BuildAAB(BuildInfo buildInfo)
|
||||||
|
{
|
||||||
|
var result = true;
|
||||||
|
if(buildInfo.IsGPChannel())
|
||||||
|
{
|
||||||
|
// MergeGPToReleaseProject(buildInfo);
|
||||||
|
// FixGradleVersion(buildInfo.version_code, buildInfo.version);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool BuildAndroidAPK(BuildInfo buildInfo)
|
||||||
|
{
|
||||||
|
var result = true;
|
||||||
|
if(buildInfo.IsDevChannel())
|
||||||
|
{
|
||||||
|
MergeProject(buildInfo, DevAsProjectPath);
|
||||||
|
}
|
||||||
|
else if(buildInfo.IsLanRelease())
|
||||||
|
{
|
||||||
|
MergeProject(buildInfo, LanReleaseAsProjectPath);
|
||||||
|
}
|
||||||
|
else if(buildInfo.IsGPChannel())
|
||||||
|
{
|
||||||
|
MergeProject(buildInfo, GoogleAsProjectPath);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 合并dev工程
|
||||||
|
/// </summary>
|
||||||
|
static void MergeProject(BuildInfo buildInfo, String asProjectPath)
|
||||||
|
{
|
||||||
|
Debug.Log("[bfinfo]正在整合dev project...");
|
||||||
|
|
||||||
|
var dir = Path.Combine(Application.dataPath, "../", AS_PROJECT_PATH, buildInfo.mode);
|
||||||
|
|
||||||
|
var javaPath = Path.Combine(dir, "unityLibrary/src/main/java");
|
||||||
|
var manifestPath = Path.Combine(dir, "unityLibrary/src/main/AndroidManifest.xml");
|
||||||
|
|
||||||
|
// 获取到unity打出的build-id
|
||||||
|
var reader = new StreamReader(new FileStream(manifestPath, FileMode.Open));
|
||||||
|
string buildIdLine;
|
||||||
|
while ((buildIdLine = reader.ReadLine()) != null)
|
||||||
|
{
|
||||||
|
if (buildIdLine.Contains("unity.build-id"))
|
||||||
|
{
|
||||||
|
Debug.Log("[bfinfo]修正build-id: " + buildIdLine);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
reader.Close();
|
||||||
|
reader.Dispose();
|
||||||
|
|
||||||
|
if (Directory.Exists(javaPath))
|
||||||
|
{
|
||||||
|
var di = new DirectoryInfo(javaPath);
|
||||||
|
di.Delete(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
BFEditorUtils.CopyDir(GoogleCommonProjectPath, dir);
|
||||||
|
// 获取到google_common复制过去的build.gradle和AndroidManifest
|
||||||
|
var buildGradlePath = Path.Combine(dir, "launcher/build.gradle");
|
||||||
|
var text = File.ReadAllText(buildGradlePath);
|
||||||
|
var regex = new Regex("REPLACE_APPLICATION_ID");
|
||||||
|
text = regex.Replace(text, buildInfo.bundleName);
|
||||||
|
File.WriteAllText(buildGradlePath, text);
|
||||||
|
|
||||||
|
var androidManifestPath = Path.Combine(dir, "launcher/src/main/AndroidManifest.xml");
|
||||||
|
text = File.ReadAllText(androidManifestPath);
|
||||||
|
regex = new Regex("REPLACE_APPLICATION_ID");
|
||||||
|
text = regex.Replace(text, buildInfo.bundleName);
|
||||||
|
File.WriteAllText(androidManifestPath, text);
|
||||||
|
|
||||||
|
BFEditorUtils.CopyDir(asProjectPath, dir);
|
||||||
|
|
||||||
|
text = File.ReadAllText(manifestPath);
|
||||||
|
regex = new Regex("REPLACE_BUILD_ID");
|
||||||
|
text = regex.Replace(text, buildIdLine);
|
||||||
|
File.WriteAllText(manifestPath, text);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 合并gp工程
|
||||||
|
/// </summary>
|
||||||
|
static void MergeGPToReleaseProject(BuildInfo buildInfo)
|
||||||
|
{
|
||||||
|
Debug.Log("[bfinfo]正在整合gp渠道sdk...");
|
||||||
|
|
||||||
|
var javaPath = GradleExcuteProjectPath + "/src/main/java";
|
||||||
|
var manifestPath = GradleExcuteProjectPath + "/src/main/AndroidManifest.xml";
|
||||||
|
|
||||||
|
// 获取到unity打出的build-id
|
||||||
|
var reader = new StreamReader(new FileStream(manifestPath, FileMode.Open));
|
||||||
|
string buildIdLine;
|
||||||
|
while ((buildIdLine = reader.ReadLine()) != null)
|
||||||
|
{
|
||||||
|
if (buildIdLine.Contains("unity.build-id"))
|
||||||
|
{
|
||||||
|
Debug.Log("[bfinfo]修正build-id: " + buildIdLine);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
reader.Close();
|
||||||
|
reader.Dispose();
|
||||||
|
|
||||||
|
if (Directory.Exists(javaPath))
|
||||||
|
{
|
||||||
|
var di = new DirectoryInfo(javaPath);
|
||||||
|
di.Delete(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (buildInfo.IsGPOfficial())
|
||||||
|
{
|
||||||
|
BFEditorUtils.CopyDir(GPOfficialAsProjectPath, GradleExcuteProjectPath);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
BFEditorUtils.CopyDir(GPAsProjectPath, GradleExcuteProjectPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
var text = File.ReadAllText(manifestPath);
|
||||||
|
var regex = new Regex("REPLACE_BUILD_ID");
|
||||||
|
text = regex.Replace(text, buildIdLine);
|
||||||
|
File.WriteAllText(manifestPath, text);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// fix versionCode versionName
|
||||||
|
/// </summary>
|
||||||
|
static void FixGradleVersion(int versionCode, string versionName)
|
||||||
|
{
|
||||||
|
Debug.Log("[bfinfo]修正build.gradle: VersionCode " + versionCode + " VersionName " + versionName);
|
||||||
|
var gradleFilePath = Path.Combine(GradleExcuteProjectPath, "build.gradle");
|
||||||
|
var text = File.ReadAllText(gradleFilePath);
|
||||||
|
var regex = new Regex("versionCode 1");
|
||||||
|
text = regex.Replace(text, string.Format("versionCode {0}", versionCode));
|
||||||
|
regex = new Regex("versionName '0.1'");
|
||||||
|
text = regex.Replace(text, string.Format("versionName '{0}'", versionName));
|
||||||
|
File.WriteAllText(gradleFilePath, text);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 内网Release包接入Bugly
|
||||||
|
/// </summary>
|
||||||
|
static void AddBuglyParamsToReleaseProject()
|
||||||
|
{
|
||||||
|
// 修改build.grade
|
||||||
|
var gradleFilePath = Path.Combine(GradleExcuteProjectPath, "build.gradle");
|
||||||
|
var text = File.ReadAllText(gradleFilePath);
|
||||||
|
var regex = new Regex("implementation");
|
||||||
|
var match = regex.Match(text);
|
||||||
|
var index = match.Index;
|
||||||
|
text = text.Insert(index, "\n" +
|
||||||
|
"implementation 'com.tencent.bugly:crashreport:latest.release'\n" +
|
||||||
|
"implementation 'com.tencent.bugly:nativecrashreport:latest.release'\n");
|
||||||
|
File.WriteAllText(gradleFilePath, text);
|
||||||
|
|
||||||
|
// 修改AndroidManifest.xml
|
||||||
|
var manifestPath = GradleExcuteProjectPath + "/src/main/AndroidManifest.xml";
|
||||||
|
text = File.ReadAllText(manifestPath);
|
||||||
|
regex = new Regex("<uses-permission");
|
||||||
|
match = regex.Match(text);
|
||||||
|
index = match.Index;
|
||||||
|
text = text.Insert(index, "\n" +
|
||||||
|
"<uses-permission android:name='android.permission.READ_PHONE_STATE' />\n" +
|
||||||
|
"<uses-permission android:name='android.permission.ACCESS_WIFI_STATE' />\n" +
|
||||||
|
"<uses-permission android:name='android.permission.READ_LOGS' />\n" +
|
||||||
|
"<uses-permission android:name='android.permission.POST_NOTIFICATIONS'/>\n");
|
||||||
|
File.WriteAllText(manifestPath, text);
|
||||||
|
|
||||||
|
// 修改UnityPlayerActivity.java
|
||||||
|
var javaPath = GradleExcuteProjectPath + "/src/main/java/com/juzu/ub/release/android/UnityPlayerActivity.java";
|
||||||
|
text = File.ReadAllText(javaPath);
|
||||||
|
regex = new Regex("import");
|
||||||
|
match = regex.Match(text);
|
||||||
|
index = match.Index;
|
||||||
|
text = text.Insert(index, "\nimport com.tencent.bugly.crashreport.CrashReport;");
|
||||||
|
regex = new Regex("requestFocus\\(\\);");
|
||||||
|
match = regex.Match(text);
|
||||||
|
index = match.Index;
|
||||||
|
var length = match.Length;
|
||||||
|
var formatInsertString = string.Format("\nCrashReport.initCrashReport(getApplicationContext(), \"{0}\", false);", BUGLY_APP_ID);
|
||||||
|
text = text.Insert(index + length, formatInsertString);
|
||||||
|
File.WriteAllText(javaPath, text);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// release包加密后签名
|
||||||
|
/// </summary>
|
||||||
|
static bool ReleaseApkSign()
|
||||||
|
{
|
||||||
|
Debug.Log("[bfinfo]正在签名apk...");
|
||||||
|
var success = true;
|
||||||
|
BFEditorUtils.RunCommond("sh", "release_sign.sh", SignShellPath,
|
||||||
|
(msg) =>
|
||||||
|
{
|
||||||
|
},
|
||||||
|
(errorMsg) =>
|
||||||
|
{
|
||||||
|
Debug.LogError("[bferror] " + errorMsg);
|
||||||
|
success = false;
|
||||||
|
});
|
||||||
|
return success;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// gp包对齐
|
||||||
|
/// </summary>
|
||||||
|
static bool GPApkAlign()
|
||||||
|
{
|
||||||
|
Debug.Log("[bfinfo]正在对齐apk...");
|
||||||
|
var success = true;
|
||||||
|
BFEditorUtils.RunCommond("sh", "gp_align.sh", GpAlginShellPath,
|
||||||
|
(msg) =>
|
||||||
|
{
|
||||||
|
},
|
||||||
|
(errorMsg) =>
|
||||||
|
{
|
||||||
|
Debug.LogError("[bferror] " + errorMsg);
|
||||||
|
success = false;
|
||||||
|
});
|
||||||
|
return success;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// google official包对齐
|
||||||
|
/// </summary>
|
||||||
|
static bool GoogleOfficialApkAlign()
|
||||||
|
{
|
||||||
|
Debug.Log("[bfinfo]正在对齐apk...");
|
||||||
|
var success = true;
|
||||||
|
BFEditorUtils.RunCommond("sh", "google_align.sh", GpAlginShellPath,
|
||||||
|
(msg) =>
|
||||||
|
{
|
||||||
|
},
|
||||||
|
(errorMsg) =>
|
||||||
|
{
|
||||||
|
Debug.LogError("[bferror] " + errorMsg);
|
||||||
|
success = false;
|
||||||
|
});
|
||||||
|
return success;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// CopyRelease文件夹内的so到bugly文件夹,制作并上传Bugly符号表
|
||||||
|
/// 因是非出包必要步骤,且依赖网络环境和腾讯服务器,有时会失败,所以开一个Thread来处理
|
||||||
|
/// </summary>
|
||||||
|
static void CopySOAndUploadBuglySymbol(string bundleName, string version)
|
||||||
|
{
|
||||||
|
// 将release的so复制到bugly文件下
|
||||||
|
BFEditorUtils.CopyDir(ReleaseSOPath, BuglySOPath);
|
||||||
|
|
||||||
|
// 开启Thread处理打包so和上传
|
||||||
|
TryCloseUploadThread();
|
||||||
|
var args = "bugly.sh" + " " + BUGLY_APP_ID + " " + BUGLY_APP_KEY + " " + bundleName + " " + version;
|
||||||
|
buglyUploadThread = new Thread(new ThreadStart(() => { UploadBuglySymbol(args); }));
|
||||||
|
buglyUploadThread.IsBackground = true;
|
||||||
|
buglyUploadThread.Start();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void UploadBuglySymbol(string args)
|
||||||
|
{
|
||||||
|
BFEditorUtils.RunCommond("sh", args, BuglyPath,
|
||||||
|
(msg) =>
|
||||||
|
{
|
||||||
|
Debug.Log("UploadBuglySymbol: " + msg);
|
||||||
|
},
|
||||||
|
(errorMsg) =>
|
||||||
|
{
|
||||||
|
Debug.LogError("[bferror] UploadBuglySymbol: " + errorMsg);
|
||||||
|
});
|
||||||
|
|
||||||
|
TryCloseUploadThread();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void TryCloseUploadThread()
|
||||||
|
{
|
||||||
|
if (buglyUploadThread != null)
|
||||||
|
{
|
||||||
|
var tmp = buglyUploadThread;
|
||||||
|
buglyUploadThread = null;
|
||||||
|
tmp.Abort();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 35368348f3bae40948e89353e96cb24c
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
348
Assets/Editor/BFBuildProjectTools/Utils/BuildIOSUtils.cs
Normal file
348
Assets/Editor/BFBuildProjectTools/Utils/BuildIOSUtils.cs
Normal file
@ -0,0 +1,348 @@
|
|||||||
|
#if UNITY_EDITOR_OSX
|
||||||
|
using UnityEngine;
|
||||||
|
using UnityEditor;
|
||||||
|
using UnityEditor.Build.Reporting;
|
||||||
|
using UnityEditor.iOS.Xcode;
|
||||||
|
using System.IO;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
namespace BFEditor.Build
|
||||||
|
{
|
||||||
|
public static class BuildIOSUtils
|
||||||
|
{
|
||||||
|
#if UNITY_EDITOR_OSX
|
||||||
|
const string IOS_DEFINE_SYMBOLS = "THREAD_SAFE;USE_AB";
|
||||||
|
const string DEV_XCODE_LOCAL_PATH = "BFVersions/ios/dev";
|
||||||
|
const string RELEASE_XCODE_LOCAL_PATH = "BFVersions/ios/release";
|
||||||
|
|
||||||
|
static string devXCodePath = Application.dataPath + "/../" + DEV_XCODE_LOCAL_PATH;
|
||||||
|
static string releaseXCodePath = Application.dataPath + "/../" + RELEASE_XCODE_LOCAL_PATH;
|
||||||
|
static string devOptionsPListPath = Application.dataPath + "/../" + "BFVersions/ios/exports/dev/ExportOptions.plist";
|
||||||
|
static string releaseOptionsPListPath = Application.dataPath + "/../" + "BFVersions/ios/exports/release/ExportOptions.plist";
|
||||||
|
static string publishOptionsPListPath = Application.dataPath + "/../" + "BFVersions/ios/exports/dis/ExportOptions.plist";
|
||||||
|
|
||||||
|
public static bool BuildIOSPlayer(BuildInfo buildInfo)
|
||||||
|
{
|
||||||
|
var buildTarget = BuildTarget.iOS;
|
||||||
|
|
||||||
|
// 检查平台
|
||||||
|
if (EditorUserBuildSettings.activeBuildTarget != buildTarget)
|
||||||
|
{
|
||||||
|
Debug.LogError("[bferror]当前没有在对应平台");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 重新生成XLua
|
||||||
|
CompileScriptsUtils.RegenerateXLuaCode(true);
|
||||||
|
|
||||||
|
// 打包设置
|
||||||
|
BuildSettings(buildInfo);
|
||||||
|
|
||||||
|
// 开始打包
|
||||||
|
var bpOptions = GetBuildOptions(buildInfo);
|
||||||
|
var report = BuildPipeline.BuildPlayer(bpOptions);
|
||||||
|
if (report.summary.result == BuildResult.Succeeded)
|
||||||
|
{
|
||||||
|
return BuildIpaFromXCode(buildInfo);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Debug.LogError("[bferror]unity打包xcode失败");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 打包设置
|
||||||
|
/// </summary>
|
||||||
|
static void BuildSettings(BuildInfo buildInfo)
|
||||||
|
{
|
||||||
|
// 设置bundleVersion
|
||||||
|
PlayerSettings.bundleVersion = buildInfo.version;
|
||||||
|
|
||||||
|
// 设置buildNumber
|
||||||
|
PlayerSettings.iOS.buildNumber = buildInfo.version_code.ToString();
|
||||||
|
|
||||||
|
// 设置竖屏
|
||||||
|
PlayerSettings.defaultInterfaceOrientation = UIOrientation.Portrait;
|
||||||
|
PlayerSettings.allowedAutorotateToPortrait = false;
|
||||||
|
PlayerSettings.allowedAutorotateToPortraitUpsideDown = false;
|
||||||
|
PlayerSettings.allowedAutorotateToLandscapeLeft = false;
|
||||||
|
PlayerSettings.allowedAutorotateToLandscapeRight = false;
|
||||||
|
|
||||||
|
// 允许Xcode根据appleDeveloperTeamID自动签署应用程序
|
||||||
|
PlayerSettings.iOS.appleEnableAutomaticSigning = !buildInfo.IsPublish();
|
||||||
|
|
||||||
|
// 使用手动签名时iOS资源调配配置文件的类型,自动
|
||||||
|
PlayerSettings.iOS.iOSManualProvisioningProfileType = buildInfo.IsPublish() ? ProvisioningProfileType.Distribution : ProvisioningProfileType.Automatic;
|
||||||
|
|
||||||
|
// 关闭启动动画
|
||||||
|
PlayerSettings.SplashScreen.show = false;
|
||||||
|
|
||||||
|
// 设置包名
|
||||||
|
PlayerSettings.SetApplicationIdentifier(BuildTargetGroup.iOS, buildInfo.bundleName);
|
||||||
|
Debug.Log("[bfinfo]设置包名:" + buildInfo.bundleName);
|
||||||
|
|
||||||
|
// 是否跳过版本控制
|
||||||
|
var symbols = IOS_DEFINE_SYMBOLS;
|
||||||
|
if (buildInfo.skipVersion)
|
||||||
|
{
|
||||||
|
symbols = symbols + ";SKIP_VERSION;";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
PlayerSettings.SetScriptingDefineSymbolsForGroup(BuildTargetGroup.iOS, symbols);
|
||||||
|
Debug.Log("[bfinfo]设置defineSymbols: " + symbols);
|
||||||
|
|
||||||
|
// 是否是dev
|
||||||
|
var development = buildInfo.IsDevChannel();
|
||||||
|
EditorUserBuildSettings.development = development;
|
||||||
|
|
||||||
|
// 商品名称
|
||||||
|
if (buildInfo.IsPublish())
|
||||||
|
{
|
||||||
|
PlayerSettings.productName = "Heroic Expedition";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
PlayerSettings.productName = development ? "b5-dev" : "b5-release";
|
||||||
|
}
|
||||||
|
|
||||||
|
// BuildType设置dev/release
|
||||||
|
EditorUserBuildSettings.iOSBuildConfigType = development ? iOSBuildType.Debug : iOSBuildType.Release;
|
||||||
|
|
||||||
|
// 使用IL2CPP
|
||||||
|
var scriptImp = ScriptingImplementation.IL2CPP;
|
||||||
|
PlayerSettings.SetScriptingBackend(BuildTargetGroup.iOS, scriptImp);
|
||||||
|
|
||||||
|
// 目标平台架构,目前支持ARM64
|
||||||
|
PlayerSettings.SetArchitecture(BuildTargetGroup.iOS, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取打包参数
|
||||||
|
/// </summary>
|
||||||
|
static BuildPlayerOptions GetBuildOptions(BuildInfo buildInfo)
|
||||||
|
{
|
||||||
|
var bpOptions = new BuildPlayerOptions();
|
||||||
|
bpOptions.scenes = AssetBundleUtils.GetBuildScenes();
|
||||||
|
bpOptions.target = BuildTarget.iOS;
|
||||||
|
|
||||||
|
var path = buildInfo.IsReleaseChannel() ? RELEASE_XCODE_LOCAL_PATH : DEV_XCODE_LOCAL_PATH;
|
||||||
|
bpOptions.locationPathName = path;
|
||||||
|
Debug.Log("[bfinfo]xcode path : " + path);
|
||||||
|
var absolutePath = buildInfo.IsReleaseChannel() ? releaseXCodePath : devXCodePath;
|
||||||
|
if (Directory.Exists(absolutePath))
|
||||||
|
{
|
||||||
|
Directory.Delete(absolutePath, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!buildInfo.IsPublish())
|
||||||
|
{
|
||||||
|
var options = BuildOptions.Development | BuildOptions.ConnectWithProfiler | BuildOptions.AllowDebugging;
|
||||||
|
bpOptions.options = options;
|
||||||
|
}
|
||||||
|
return bpOptions;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 打包ipa
|
||||||
|
/// </summary>
|
||||||
|
static bool BuildIpaFromXCode(BuildInfo buildInfo)
|
||||||
|
{
|
||||||
|
// 修改XCode设置
|
||||||
|
FixXCodeProject(buildInfo);
|
||||||
|
|
||||||
|
// 权限
|
||||||
|
UnlockKeyChain();
|
||||||
|
|
||||||
|
// archive
|
||||||
|
if (!Archive(buildInfo))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 导出ipa
|
||||||
|
if (!ExportIpa(buildInfo))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// xCode工程设置
|
||||||
|
/// </summary>
|
||||||
|
static void FixXCodeProject(BuildInfo buildInfo)
|
||||||
|
{
|
||||||
|
var isDev = buildInfo.IsDevChannel();
|
||||||
|
var xCodeProjectPath = isDev ? devXCodePath : releaseXCodePath;
|
||||||
|
|
||||||
|
var path = xCodeProjectPath + "/Unity-iPhone.xcodeproj/project.pbxproj";
|
||||||
|
var pbxProject = new PBXProject();
|
||||||
|
pbxProject.ReadFromFile(path);
|
||||||
|
var targetGuid = pbxProject.TargetGuidByName("Unity-iPhone");
|
||||||
|
pbxProject.AddBuildProperty(targetGuid, "OTHER_LDFLAGS", "-ObjC");
|
||||||
|
pbxProject.SetBuildProperty(targetGuid, "ENABLE_BITCODE", "NO");
|
||||||
|
pbxProject.SetBuildProperty(targetGuid, "ENABLE_BITCODE", "NO");
|
||||||
|
pbxProject.SetBuildProperty(targetGuid, "DEVELOPMENT_TEAM", "49QQW8856Q");
|
||||||
|
if (buildInfo.IsPublish())
|
||||||
|
{
|
||||||
|
pbxProject.SetBuildProperty(targetGuid, "PROVISIONING_PROFILE_SPECIFIER", "ub_appstore_dis");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 添加系统库
|
||||||
|
AddSystemLibReferenceToProject(pbxProject, targetGuid, "libsqlite3.tbd");
|
||||||
|
AddSystemLibReferenceToProject(pbxProject, targetGuid, "libz.1.tbd");
|
||||||
|
AddSystemLibReferenceToProject(pbxProject, targetGuid, "libiconv.2.tbd");
|
||||||
|
AddSystemLibReferenceToProject(pbxProject, targetGuid, "libresolv.9.tbd");
|
||||||
|
|
||||||
|
var pListPath = Path.Combine(xCodeProjectPath, "Info.plist");
|
||||||
|
var pList = new PlistDocument();
|
||||||
|
pList.ReadFromFile(pListPath);
|
||||||
|
|
||||||
|
// 版本号
|
||||||
|
var vKey = "CFBundleShortVersionString";
|
||||||
|
var vValue = new PlistElementString(buildInfo.version);
|
||||||
|
var pListRoot = pList.root;
|
||||||
|
var rootDict = pListRoot.values;
|
||||||
|
if (!rootDict.ContainsKey(vKey))
|
||||||
|
{
|
||||||
|
rootDict.Add(vKey, vValue);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
rootDict[vKey] = vValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// VersionCode
|
||||||
|
var vCodeKey = "CFBundleVersion";
|
||||||
|
var vCodeValue = new PlistElementString(buildInfo.version_code.ToString());
|
||||||
|
if (!rootDict.ContainsKey(vCodeKey))
|
||||||
|
{
|
||||||
|
rootDict.Add(vCodeKey, vCodeValue);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
rootDict[vCodeKey] = vCodeValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 数美SDK会使用位置,必须加入这个说明
|
||||||
|
var localtionKey = "NSLocationWhenInUseUsageDescription";
|
||||||
|
var localtionValue = new PlistElementString("We use your location to give you a better localization.");
|
||||||
|
if (!rootDict.ContainsKey(localtionKey))
|
||||||
|
{
|
||||||
|
rootDict.Add(localtionKey, localtionValue);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
rootDict[localtionKey] = localtionValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 提审提示缺少出口合规证明,这里直接设置为false即可
|
||||||
|
var encryptionKey = "ITSAppUsesNonExemptEncryption";
|
||||||
|
var encryptionValue = new PlistElementBoolean(false);
|
||||||
|
if (!rootDict.ContainsKey(encryptionKey))
|
||||||
|
{
|
||||||
|
rootDict.Add(encryptionKey, encryptionValue);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
rootDict[encryptionKey] = encryptionValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
pList.WriteToFile(pListPath);
|
||||||
|
pbxProject.WriteToFile(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
//添加系统lib方法
|
||||||
|
static void AddSystemLibReferenceToProject(PBXProject pbxProject, string targetGuid, string lib)
|
||||||
|
{
|
||||||
|
var fileGuid = pbxProject.AddFile("usr/lib/" + lib, "Frameworks/" + lib, PBXSourceTree.Sdk);
|
||||||
|
pbxProject.AddFileToBuild(targetGuid, fileGuid);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Archive
|
||||||
|
/// </summary>
|
||||||
|
static bool Archive(BuildInfo buildInfo)
|
||||||
|
{
|
||||||
|
Debug.Log("[bfinfo]正在archive...");
|
||||||
|
var result = true;
|
||||||
|
var xCodeProjectPath = buildInfo.IsDevChannel() ? devXCodePath : releaseXCodePath;
|
||||||
|
var archivePath = xCodeProjectPath + "/build/archive/Unity-iPhone.xcarchive";
|
||||||
|
var args = string.Format("archive -scheme Unity-iPhone -configuration Release -archivePath {0}", archivePath);
|
||||||
|
BFEditorUtils.RunCommond("xcodebuild", args, xCodeProjectPath,
|
||||||
|
(info) =>
|
||||||
|
{
|
||||||
|
Debug.Log(info);
|
||||||
|
},
|
||||||
|
(error) =>
|
||||||
|
{
|
||||||
|
if (error.Contains("ARCHIVE FAILED")) // 失败标志
|
||||||
|
{
|
||||||
|
result = false;
|
||||||
|
}
|
||||||
|
Debug.LogError("[bferror] " + error);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 导出ipa
|
||||||
|
/// </summary>
|
||||||
|
static bool ExportIpa(BuildInfo buildInfo)
|
||||||
|
{
|
||||||
|
Debug.Log("[bfinfo]正在导出ipa...");
|
||||||
|
var result = false;
|
||||||
|
var xCodeProjectPath = buildInfo.IsDevChannel() ? devXCodePath : releaseXCodePath;
|
||||||
|
string exportPListPath;
|
||||||
|
if (buildInfo.IsPublish())
|
||||||
|
{
|
||||||
|
exportPListPath = publishOptionsPListPath;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
exportPListPath = buildInfo.IsDevChannel() ? devOptionsPListPath : releaseOptionsPListPath;
|
||||||
|
}
|
||||||
|
var ipaPath = xCodeProjectPath + "/build/ipa";
|
||||||
|
var archivePath = xCodeProjectPath + "/build/archive/Unity-iPhone.xcarchive";
|
||||||
|
var args = string.Format("-exportArchive -archivePath {0} -exportPath {1} -exportOptionsPlist {2} -allowProvisioningUpdates", archivePath, ipaPath, exportPListPath);
|
||||||
|
BFEditorUtils.RunCommond("xcodebuild", args, null,
|
||||||
|
(info) =>
|
||||||
|
{
|
||||||
|
if(info.Contains("EXPORT SUCCEEDED"))
|
||||||
|
{
|
||||||
|
result = true;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
(error) =>
|
||||||
|
{
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 远程打包签名ipa时需要钥匙串权限
|
||||||
|
/// </summary>
|
||||||
|
static void UnlockKeyChain()
|
||||||
|
{
|
||||||
|
BFEditorUtils.RunCommond("security", "-v unlock-keychain -p '123456' /Users/aoddabao/Library/Keychains/login.keychain-db", null,
|
||||||
|
(msg) =>
|
||||||
|
{
|
||||||
|
Debug.Log(msg);
|
||||||
|
},
|
||||||
|
(msg) =>
|
||||||
|
{
|
||||||
|
Debug.LogError(msg);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: dd7491cac14794410bc8cd2205ea1daf
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
189
Assets/Editor/BFBuildProjectTools/Utils/CompileScriptsUtils.cs
Normal file
189
Assets/Editor/BFBuildProjectTools/Utils/CompileScriptsUtils.cs
Normal file
@ -0,0 +1,189 @@
|
|||||||
|
using System;
|
||||||
|
using UnityEngine;
|
||||||
|
using System.IO;
|
||||||
|
using UnityEditor;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using CSObjectWrapEditor;
|
||||||
|
using XLua;
|
||||||
|
using System.Diagnostics;
|
||||||
|
|
||||||
|
namespace BFEditor.Build
|
||||||
|
{
|
||||||
|
public static class CompileScriptsUtils
|
||||||
|
{
|
||||||
|
public static void CompileAndEncryptLua()
|
||||||
|
{
|
||||||
|
if (!CompileAndEncryptLua(true))
|
||||||
|
{
|
||||||
|
throw new Exception();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static bool CompileAndEncryptLua(bool debugFlag)
|
||||||
|
{
|
||||||
|
var result = false;
|
||||||
|
if (CompileDevLuaToRunLua(debugFlag))
|
||||||
|
{
|
||||||
|
ProjectEncryptUtils.EncryptLua();
|
||||||
|
result = true;
|
||||||
|
}
|
||||||
|
AssetDatabase.SaveAssets();
|
||||||
|
AssetDatabase.Refresh();
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static bool CompileDevLuaToRunLua(bool debugFlag = true)
|
||||||
|
{
|
||||||
|
UnityEngine.Debug.Log("[bfinfo]编译lua代码...");
|
||||||
|
var srcDir = Path.Combine(Application.dataPath, "Developer/lua");
|
||||||
|
var destDir = Path.Combine(Application.dataPath, "lua");
|
||||||
|
return CompileLua(srcDir, destDir, debugFlag);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool CompileLua(string srcDir, string destDir, bool debugFlag)
|
||||||
|
{
|
||||||
|
var startTime = DateTime.Now.Ticks;
|
||||||
|
var srcFileMap = new Dictionary<string, bool>();
|
||||||
|
|
||||||
|
#if UNITY_EDITOR_OSX
|
||||||
|
var scriptPath = Path.Combine(Application.dataPath, "../tools/luac/mac/compile.sh");
|
||||||
|
var luacPath = Path.Combine(Application.dataPath, "../tools/luac/mac/luac");
|
||||||
|
#else
|
||||||
|
srcDir = srcDir.Replace('\\', '/');
|
||||||
|
destDir = destDir.Replace('\\', '/');
|
||||||
|
var scriptPath = Path.Combine(Application.dataPath, "../tools/luac/windows/compile.bat").Replace('\\', '/');
|
||||||
|
var luacPath = Path.Combine(Application.dataPath, "../tools/luac/windows/luac.exe").Replace('\\', '/');
|
||||||
|
#endif
|
||||||
|
if (luacPath.Length == 0 || !File.Exists(luacPath))
|
||||||
|
{
|
||||||
|
EditorUtility.ClearProgressBar();
|
||||||
|
EditorUtility.DisplayDialog("提示", "编译Lua失败 找不到luac", "确定");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
EditorUtility.DisplayProgressBar("提示", "正在编译lua文件...", 0);
|
||||||
|
|
||||||
|
var srcDirInfo = new DirectoryInfo(srcDir);
|
||||||
|
var srcFiles = srcDirInfo.GetFiles("*.lua", SearchOption.AllDirectories);
|
||||||
|
var fileList = new List<FileInfo>(srcFiles);
|
||||||
|
|
||||||
|
for (int i = fileList.Count - 1; i >= 0; i--)
|
||||||
|
{
|
||||||
|
if (fileList[i].DirectoryName.Contains("/Test/"))
|
||||||
|
{
|
||||||
|
fileList.RemoveAt(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var totalCount = fileList.Count;
|
||||||
|
var unit = (float)totalCount / 100;
|
||||||
|
|
||||||
|
for (var i = 0; i < fileList.Count; ++i)
|
||||||
|
{
|
||||||
|
|
||||||
|
var fileInfo = fileList[i];
|
||||||
|
var assetName = fileInfo.FullName.Substring(srcDir.Length) + ".bytes";
|
||||||
|
srcFileMap[assetName] = true;
|
||||||
|
|
||||||
|
var subPath = "";
|
||||||
|
#if UNITY_EDITOR_WIN
|
||||||
|
var subIndex = assetName.Replace('\\', '/').LastIndexOf('/');
|
||||||
|
#else
|
||||||
|
var subIndex = assetName.LastIndexOf('/');
|
||||||
|
#endif
|
||||||
|
if (subIndex >= 0)
|
||||||
|
{
|
||||||
|
subPath = assetName.Substring(0, subIndex + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
var copyPath = destDir + subPath;
|
||||||
|
if (!Directory.Exists(copyPath))
|
||||||
|
{
|
||||||
|
Directory.CreateDirectory(copyPath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#if UNITY_EDITOR_OSX
|
||||||
|
var startInfo = new ProcessStartInfo("sh");
|
||||||
|
startInfo.Arguments = scriptPath + " " + srcDir + " " + srcDir.Length + " " + destDir + " " + luacPath;
|
||||||
|
#else
|
||||||
|
var startInfo = new ProcessStartInfo(scriptPath);
|
||||||
|
startInfo.Arguments = " " + srcDir + " " + srcDir.Length + " " + destDir + " " + luacPath;
|
||||||
|
#endif
|
||||||
|
startInfo.WorkingDirectory = srcDir;
|
||||||
|
startInfo.UseShellExecute = false;
|
||||||
|
startInfo.RedirectStandardInput = true;
|
||||||
|
startInfo.RedirectStandardOutput = true;
|
||||||
|
startInfo.CreateNoWindow = true;
|
||||||
|
var process = new Process();
|
||||||
|
process.StartInfo = startInfo;
|
||||||
|
process.Start();
|
||||||
|
|
||||||
|
process.BeginOutputReadLine();
|
||||||
|
process.OutputDataReceived += (sender, e) =>
|
||||||
|
{
|
||||||
|
if (!string.IsNullOrEmpty(e.Data))
|
||||||
|
{
|
||||||
|
UnityEngine.Debug.Log(e.Data);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
process.WaitForExit();
|
||||||
|
process.Close();
|
||||||
|
|
||||||
|
EditorUtility.ClearProgressBar();
|
||||||
|
|
||||||
|
var deleteList = new List<string>();
|
||||||
|
var destDirInfo = new DirectoryInfo(destDir);
|
||||||
|
var destFiles = destDirInfo.GetFiles("*.bytes", SearchOption.AllDirectories);
|
||||||
|
for (var i = 0; i < destFiles.Length; ++i)
|
||||||
|
{
|
||||||
|
var fileInfo = destFiles[i];
|
||||||
|
var assetName = fileInfo.FullName.Substring(destDir.Length);
|
||||||
|
if (!srcFileMap.ContainsKey(assetName))
|
||||||
|
{
|
||||||
|
deleteList.Add(fileInfo.FullName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (deleteList.Count > 0)
|
||||||
|
{
|
||||||
|
EditorUtility.DisplayProgressBar("提示", "正在删除失效lua文件", 0);
|
||||||
|
var count = deleteList.Count;
|
||||||
|
foreach (var path in deleteList)
|
||||||
|
{
|
||||||
|
UnityEngine.Debug.LogWarning("Delete dest lua compile file " + path);
|
||||||
|
File.Delete(path);
|
||||||
|
}
|
||||||
|
EditorUtility.ClearProgressBar();
|
||||||
|
}
|
||||||
|
|
||||||
|
var endTime = DateTime.Now.Ticks;
|
||||||
|
UnityEngine.Debug.Log("Lua文件已完成编译,用时" + (endTime - startTime) / 10000 + "毫秒");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void RegenerateXLuaCode(bool showDialog = false)
|
||||||
|
{
|
||||||
|
if (showDialog)
|
||||||
|
{
|
||||||
|
EditorUtility.DisplayProgressBar("提示", "正在重新生成xlua代码...", 1);
|
||||||
|
}
|
||||||
|
UnityEngine.Debug.Log("[bfinfo]重新生成XLuaCode...");
|
||||||
|
|
||||||
|
DelegateBridge.Gen_Flag = true;
|
||||||
|
|
||||||
|
Generator.ClearAll();
|
||||||
|
AssetDatabase.SaveAssets();
|
||||||
|
AssetDatabase.Refresh();
|
||||||
|
|
||||||
|
Generator.GenAll();
|
||||||
|
AssetDatabase.SaveAssets();
|
||||||
|
AssetDatabase.Refresh();
|
||||||
|
|
||||||
|
if (showDialog)
|
||||||
|
{
|
||||||
|
EditorUtility.ClearProgressBar();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: ca190fa95df874509962ffcc3ae95883
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
156
Assets/Editor/BFBuildProjectTools/Utils/ProjectEncryptUtils.cs
Normal file
156
Assets/Editor/BFBuildProjectTools/Utils/ProjectEncryptUtils.cs
Normal file
@ -0,0 +1,156 @@
|
|||||||
|
using UnityEngine;
|
||||||
|
using UnityEditor;
|
||||||
|
using System.IO;
|
||||||
|
using System;
|
||||||
|
|
||||||
|
namespace BFEditor.Build
|
||||||
|
{
|
||||||
|
public static class ProjectEncryptUtils
|
||||||
|
{
|
||||||
|
const string NHP_PATH = "BFVersions/NHPProtect/NHPProtect.jar";
|
||||||
|
const string LUA_ENCRYPT_KEY = "reD9xI4k5MR0qqi8";
|
||||||
|
const string LUA_ENCRYPT_HEAD = "bf_encrypt_lua";
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// assetBundle加密
|
||||||
|
/// </summary>
|
||||||
|
public static bool EncryptAssetBundle(string abPath, bool showDialog = false)
|
||||||
|
{
|
||||||
|
Debug.Log("[bfinfo]正在加密assetbundle...");
|
||||||
|
|
||||||
|
var success = true;
|
||||||
|
var path = Application.dataPath.Replace("Assets", NHP_PATH);
|
||||||
|
var args = string.Format("-jar {0} -SingleAstEnc {1}", path, abPath);
|
||||||
|
|
||||||
|
EditorUtility.DisplayProgressBar("提示", "正在加密assetbundle...", 0.5f);
|
||||||
|
BFEditorUtils.RunCommond("java", args, null,
|
||||||
|
(msg) =>
|
||||||
|
{
|
||||||
|
Debug.Log(msg);
|
||||||
|
},
|
||||||
|
(errorMsg) =>
|
||||||
|
{
|
||||||
|
Debug.LogError(errorMsg);
|
||||||
|
success = false;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
EditorUtility.ClearProgressBar();
|
||||||
|
|
||||||
|
if (success)
|
||||||
|
{
|
||||||
|
Directory.Delete(abPath, true);
|
||||||
|
Debug.Log("删除未加密AB:" + abPath);
|
||||||
|
var dest = abPath;
|
||||||
|
var src = dest + "_encrypted";
|
||||||
|
Directory.Move(src, dest);
|
||||||
|
Debug.Log("加密AB路径改名:" + src + "---->" + dest);
|
||||||
|
|
||||||
|
var tips = "加密AssetBundle成功";
|
||||||
|
if (showDialog)
|
||||||
|
{
|
||||||
|
EditorUtility.DisplayDialog("提示", tips, "确定");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Debug.Log(tips);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (showDialog)
|
||||||
|
{
|
||||||
|
EditorUtility.DisplayDialog("提示", "加密AssetBundle失败", "确定");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Debug.LogError("加密AssetBundle失败");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return success;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// apk加密
|
||||||
|
/// </summary>
|
||||||
|
public static bool EncryptApk(string apkPath, bool showDialog = false)
|
||||||
|
{
|
||||||
|
var success = true;
|
||||||
|
var path = Application.dataPath.Replace("Assets", NHP_PATH);
|
||||||
|
var args = string.Format("-jar {0} -yunconfig -apksign -zipalign -input ", path) + apkPath;
|
||||||
|
|
||||||
|
EditorUtility.DisplayProgressBar("提示", "正在加密apk", 0.5f);
|
||||||
|
BFEditorUtils.RunCommond("java", args, null,
|
||||||
|
(msg) =>
|
||||||
|
{
|
||||||
|
Debug.Log(msg);
|
||||||
|
},
|
||||||
|
(errorMsg) =>
|
||||||
|
{
|
||||||
|
Debug.LogError(errorMsg);
|
||||||
|
success = false;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
EditorUtility.ClearProgressBar();
|
||||||
|
|
||||||
|
if (success)
|
||||||
|
{
|
||||||
|
var fileName = Path.GetFileNameWithoutExtension(apkPath);
|
||||||
|
var encryptedName = apkPath.Replace(fileName, fileName + "_encrypted");
|
||||||
|
var tips = "加密APK成功,APK路径:" + encryptedName;
|
||||||
|
if (showDialog)
|
||||||
|
{
|
||||||
|
EditorUtility.DisplayDialog("提示", tips, "确定");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Debug.Log(tips);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (showDialog)
|
||||||
|
{
|
||||||
|
EditorUtility.DisplayDialog("提示", "加密APK失败", "确定");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Debug.LogError("加密APK失败");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return success;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void EncryptLua()
|
||||||
|
{
|
||||||
|
Debug.Log("[bfinfo]正在加密lua...");
|
||||||
|
var luaPath = Path.Combine(Application.dataPath, "lua");
|
||||||
|
var dirInfo = new DirectoryInfo(luaPath);
|
||||||
|
var srcFiles = dirInfo.GetFiles("*.lua.bytes", SearchOption.AllDirectories);
|
||||||
|
foreach (var file in srcFiles)
|
||||||
|
{
|
||||||
|
var bytes = File.ReadAllBytes(file.FullName);
|
||||||
|
var index = 0;
|
||||||
|
foreach (var item in bytes)
|
||||||
|
{
|
||||||
|
bytes[index] = (byte)(item ^ (LUA_ENCRYPT_KEY[index % LUA_ENCRYPT_KEY.Length]));
|
||||||
|
index++;
|
||||||
|
}
|
||||||
|
|
||||||
|
var newbytes = new byte[bytes.Length + LUA_ENCRYPT_HEAD.Length];
|
||||||
|
index = 0;
|
||||||
|
foreach (var item in LUA_ENCRYPT_HEAD)
|
||||||
|
{
|
||||||
|
var headByte = (byte)item;
|
||||||
|
newbytes[index] = headByte;
|
||||||
|
index++;
|
||||||
|
}
|
||||||
|
foreach (var item in bytes)
|
||||||
|
{
|
||||||
|
newbytes[index] = item;
|
||||||
|
index++;
|
||||||
|
}
|
||||||
|
File.WriteAllBytes(file.FullName, newbytes);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: e02b19e0e0c844a35bf28a5c4468c8ac
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
8
Assets/Editor/BFEditorTools.meta
Normal file
8
Assets/Editor/BFEditorTools.meta
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 3a32c4bea05a13f438f066d3bbbceed9
|
||||||
|
folderAsset: yes
|
||||||
|
DefaultImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
63
Assets/Editor/BFEditorTools/BFEditorApplication.cs
Normal file
63
Assets/Editor/BFEditorTools/BFEditorApplication.cs
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using UnityEngine;
|
||||||
|
using UnityEditor;
|
||||||
|
using System.IO;
|
||||||
|
|
||||||
|
namespace BFEditor
|
||||||
|
{
|
||||||
|
[InitializeOnLoadAttribute]
|
||||||
|
public static class BFEditorApplication
|
||||||
|
{
|
||||||
|
private const string DEFAULT_FONT_PATH = "assets/arts/fonts/tmpfonts/default/tmpfont/font_sdf.asset";
|
||||||
|
private const string DEFAULT_FONT_NUMBER_PATH = "assets/arts/fonts/tmpfonts/default/tmpfont/font_number_sdf.asset";
|
||||||
|
private const string DEFAULT_FONT_BATTLE_PATH = "assets/arts/fonts/tmpfonts/battle/font_battle_sdf.asset";
|
||||||
|
static BFEditorApplication()
|
||||||
|
{
|
||||||
|
EditorApplication.playModeStateChanged += PlayModeStateChanged;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void PlayModeStateChanged(PlayModeStateChange state)
|
||||||
|
{
|
||||||
|
// 编辑器下离开play模式
|
||||||
|
if (state == PlayModeStateChange.ExitingPlayMode)
|
||||||
|
{
|
||||||
|
// 游戏运行的时候处理了一下default字体资源,这里就需要重置一下,否则无法正常显示文本
|
||||||
|
if (File.Exists(DEFAULT_FONT_PATH))
|
||||||
|
{
|
||||||
|
var fontAsset = AssetDatabase.LoadAssetAtPath<TMPro.TMP_FontAsset>(DEFAULT_FONT_PATH);
|
||||||
|
if (fontAsset)
|
||||||
|
{
|
||||||
|
// fontAsset.characterTable.Clear();
|
||||||
|
fontAsset.ClearFontAssetData();
|
||||||
|
EditorUtility.SetDirty(fontAsset);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (File.Exists(DEFAULT_FONT_NUMBER_PATH))
|
||||||
|
{
|
||||||
|
var fontAsset = AssetDatabase.LoadAssetAtPath<TMPro.TMP_FontAsset>(DEFAULT_FONT_NUMBER_PATH);
|
||||||
|
if (fontAsset)
|
||||||
|
{
|
||||||
|
// fontAsset.characterTable.Clear();
|
||||||
|
fontAsset.ClearFontAssetData();
|
||||||
|
EditorUtility.SetDirty(fontAsset);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (File.Exists(DEFAULT_FONT_BATTLE_PATH))
|
||||||
|
{
|
||||||
|
var fontAsset = AssetDatabase.LoadAssetAtPath<TMPro.TMP_FontAsset>(DEFAULT_FONT_BATTLE_PATH);
|
||||||
|
if (fontAsset)
|
||||||
|
{
|
||||||
|
// fontAsset.characterTable.Clear();
|
||||||
|
fontAsset.ClearFontAssetData();
|
||||||
|
EditorUtility.SetDirty(fontAsset);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
AssetDatabase.SaveAssets();
|
||||||
|
AssetDatabase.Refresh();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
11
Assets/Editor/BFEditorTools/BFEditorApplication.cs.meta
Normal file
11
Assets/Editor/BFEditorTools/BFEditorApplication.cs.meta
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 6e67102436d9cf440b64bebc204af464
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
8
Assets/Editor/BFGameplayTools.meta
Normal file
8
Assets/Editor/BFGameplayTools.meta
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 1178d9f9413f147fca1c5bcdfb5b7ec8
|
||||||
|
folderAsset: yes
|
||||||
|
DefaultImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
8
Assets/Editor/BFGameplayTools/EmojiTools.meta
Normal file
8
Assets/Editor/BFGameplayTools/EmojiTools.meta
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: c0a28c232ddcd41f2a198b4fdf04c673
|
||||||
|
folderAsset: yes
|
||||||
|
DefaultImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
302
Assets/Editor/BFGameplayTools/EmojiTools/EmojiEditor.cs
Normal file
302
Assets/Editor/BFGameplayTools/EmojiTools/EmojiEditor.cs
Normal file
@ -0,0 +1,302 @@
|
|||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
using System.Text;
|
||||||
|
using System.Text.RegularExpressions;
|
||||||
|
using UnityEditor;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
namespace BFEditor
|
||||||
|
{
|
||||||
|
public class EmojiEditor : EditorWindow
|
||||||
|
{
|
||||||
|
[MenuItem("BF编辑器/Emoji表情配置")]
|
||||||
|
public static void EmojiConfiguration()
|
||||||
|
{
|
||||||
|
|
||||||
|
EmojiEditor window = ScriptableObject.CreateInstance<EmojiEditor>();
|
||||||
|
window.ShowUtility();
|
||||||
|
}
|
||||||
|
|
||||||
|
void OnInspectorUpdate()
|
||||||
|
{
|
||||||
|
Repaint();
|
||||||
|
}
|
||||||
|
|
||||||
|
private int emojiSize = 0;
|
||||||
|
private int columnCount = 0;
|
||||||
|
//读取PNG路径
|
||||||
|
private const string READ_EMOJI_PATH_PREFS = "read_emoji_path";
|
||||||
|
private string readEmojiPath = "";
|
||||||
|
//生成texture路径
|
||||||
|
private const string GET_EMOJI_PATH_PREFS = "tar_emoji_path";
|
||||||
|
private string tarEmojiPath = "";
|
||||||
|
//配置表路径
|
||||||
|
private const string CONFIG_PATH_PREFS = "emoji_config_path";
|
||||||
|
private string tarCfgPath = "";
|
||||||
|
|
||||||
|
private string newTextureName = "emoji_total";
|
||||||
|
private string cfgName = "emoji_info";
|
||||||
|
|
||||||
|
private Dictionary<int,Dictionary<int, List<float>>> emojiUVs = new Dictionary<int, Dictionary<int, List<float>>>();
|
||||||
|
public void OnGUI()
|
||||||
|
{
|
||||||
|
emojiSize = EditorGUILayout.IntField("单个表情像素", emojiSize);
|
||||||
|
EditorGUILayout.Space();
|
||||||
|
columnCount = EditorGUILayout.IntField("图片表情列数", columnCount);
|
||||||
|
EditorGUILayout.Space();
|
||||||
|
|
||||||
|
//emoji路径
|
||||||
|
if (GUILayout.Button("选择读取Emoji目标路径"))
|
||||||
|
{
|
||||||
|
var readEmojiPath = EditorUtility.OpenFolderPanel("生成png目标文件夹", "", "");
|
||||||
|
if (!string.IsNullOrEmpty(readEmojiPath))
|
||||||
|
{
|
||||||
|
PlayerPrefs.SetString(READ_EMOJI_PATH_PREFS, readEmojiPath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
readEmojiPath = PlayerPrefs.GetString(READ_EMOJI_PATH_PREFS, "");
|
||||||
|
EditorGUILayout.LabelField("读取Emoji文件路径", readEmojiPath);
|
||||||
|
EditorGUILayout.Space();
|
||||||
|
|
||||||
|
//生成目标路径
|
||||||
|
if (GUILayout.Button("选择生成目标路径"))
|
||||||
|
{
|
||||||
|
var tarGetPath = EditorUtility.OpenFolderPanel("生成png目标文件夹", "", "");
|
||||||
|
if (!string.IsNullOrEmpty(tarGetPath))
|
||||||
|
{
|
||||||
|
PlayerPrefs.SetString(GET_EMOJI_PATH_PREFS, tarGetPath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
tarEmojiPath = PlayerPrefs.GetString(GET_EMOJI_PATH_PREFS, "");
|
||||||
|
EditorGUILayout.LabelField("生成PNG文件路径", tarEmojiPath);
|
||||||
|
//生成PNG名
|
||||||
|
newTextureName = EditorGUILayout.TextField("生成PNG名", newTextureName);
|
||||||
|
EditorGUILayout.Space();
|
||||||
|
|
||||||
|
//配置表路径
|
||||||
|
if (GUILayout.Button("选择配置表目标路径"))
|
||||||
|
{
|
||||||
|
var tarCfgPath = EditorUtility.OpenFolderPanel("生成配置表目标文件夹", "", "");
|
||||||
|
if (!string.IsNullOrEmpty(tarCfgPath))
|
||||||
|
{
|
||||||
|
PlayerPrefs.SetString(CONFIG_PATH_PREFS, tarCfgPath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
tarCfgPath = PlayerPrefs.GetString(CONFIG_PATH_PREFS, "");
|
||||||
|
EditorGUILayout.LabelField("生成配置表文件路径", tarCfgPath);
|
||||||
|
cfgName = EditorGUILayout.TextField("生成配置表名", cfgName);
|
||||||
|
|
||||||
|
EditorGUILayout.Space();
|
||||||
|
|
||||||
|
//合成PNG
|
||||||
|
if (GUILayout.Button("合成PNG并生成配置"))
|
||||||
|
{
|
||||||
|
if (string.IsNullOrEmpty(tarEmojiPath))
|
||||||
|
{
|
||||||
|
EditorUtility.DisplayDialog("提示", "没有指定PNG生成文件夹路径", "确定");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!Directory.Exists(tarEmojiPath))
|
||||||
|
{
|
||||||
|
EditorUtility.DisplayDialog("提示", "生成PNG文件夹路径不存在", "确定");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (string.IsNullOrEmpty(readEmojiPath))
|
||||||
|
{
|
||||||
|
EditorUtility.DisplayDialog("提示", "没有指定读取emoji文件夹路径", "确定");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!Directory.Exists(readEmojiPath))
|
||||||
|
{
|
||||||
|
EditorUtility.DisplayDialog("提示", "读取emoji文件夹路径不存在", "确定");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (string.IsNullOrEmpty(tarCfgPath))
|
||||||
|
{
|
||||||
|
EditorUtility.DisplayDialog("提示", "没有指定配置表文件夹路径", "确定");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!Directory.Exists(tarCfgPath))
|
||||||
|
{
|
||||||
|
EditorUtility.DisplayDialog("提示", "配置表文件夹路径不存在", "确定");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
EncodePng();
|
||||||
|
SaveUVsConfig();
|
||||||
|
|
||||||
|
AssetDatabase.SaveAssets();
|
||||||
|
AssetDatabase.Refresh();
|
||||||
|
EditorUtility.DisplayDialog("提示", "生成PNG和配置表完成", "确定");
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void EncodePng()
|
||||||
|
{
|
||||||
|
if (emojiSize == 0 || columnCount == 0)
|
||||||
|
{
|
||||||
|
EditorUtility.DisplayDialog("提示", "表情参数不正确", "确定");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
emojiUVs.Clear();
|
||||||
|
|
||||||
|
//先计算生成texture大小
|
||||||
|
var width = emojiSize * columnCount;
|
||||||
|
|
||||||
|
var exp = 1;
|
||||||
|
while (exp < width)
|
||||||
|
{
|
||||||
|
exp <<= 1;
|
||||||
|
}
|
||||||
|
width = exp;
|
||||||
|
|
||||||
|
|
||||||
|
var height = 0;
|
||||||
|
//读取totalCount
|
||||||
|
var pngs = Directory.GetFiles(readEmojiPath, "*.png");
|
||||||
|
Debug.Log("表情总数 " + pngs.Length);
|
||||||
|
var totalCount = pngs.Length;
|
||||||
|
|
||||||
|
var otherNum = totalCount % columnCount;
|
||||||
|
if (otherNum == 0)
|
||||||
|
{
|
||||||
|
height = (int)Mathf.Ceil(totalCount / columnCount) * emojiSize;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
height = ((int)(totalCount / columnCount) + 1)* emojiSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
exp = 1;
|
||||||
|
while (exp < height)
|
||||||
|
{
|
||||||
|
exp <<= 1;
|
||||||
|
}
|
||||||
|
height = exp;
|
||||||
|
|
||||||
|
var newTexture = new Texture2D(width, height, TextureFormat.ARGB32, false);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
var tmpPngPath = "";
|
||||||
|
var row = 0;
|
||||||
|
var column = 0;
|
||||||
|
var countDown = 0;
|
||||||
|
foreach (var pngPath in pngs)
|
||||||
|
{
|
||||||
|
tmpPngPath = pngPath.Substring(pngPath.IndexOf("Assets"));
|
||||||
|
tmpPngPath = tmpPngPath.Replace('\\', '/');
|
||||||
|
var texture = (Texture2D)AssetDatabase.LoadAssetAtPath(tmpPngPath, typeof(Texture2D));
|
||||||
|
if (texture.width != emojiSize || texture.height != emojiSize)
|
||||||
|
{
|
||||||
|
Debug.LogErrorFormat("{0} 表情大小不符合规范 width : {1} height : {2}", texture.name, texture.width, texture.height);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Color32[] colors = texture.GetPixels32();
|
||||||
|
|
||||||
|
row = countDown % columnCount;
|
||||||
|
column = countDown / columnCount;
|
||||||
|
|
||||||
|
//画上去
|
||||||
|
var xPos = row * emojiSize;
|
||||||
|
var yPos = column * emojiSize;
|
||||||
|
newTexture.SetPixels32(xPos, yPos, emojiSize, emojiSize, colors);
|
||||||
|
//config
|
||||||
|
if (!Regex.IsMatch(texture.name,@"emoji\d{1,}_\d{1,}"))
|
||||||
|
{
|
||||||
|
Debug.LogErrorFormat("{0} 表情名称不符合规范", texture.name);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var index1 = texture.name.Substring(5, 1);
|
||||||
|
var index2 = int.Parse(texture.name.Split('_')[1]);
|
||||||
|
|
||||||
|
var emojiTypeIndex = int.Parse(index1);
|
||||||
|
Dictionary<int, List<float>> emojiInfos;
|
||||||
|
if (!emojiUVs.TryGetValue(emojiTypeIndex, out emojiInfos))
|
||||||
|
{
|
||||||
|
emojiInfos = new Dictionary<int, List<float>>();
|
||||||
|
emojiUVs.Add(emojiTypeIndex, emojiInfos);
|
||||||
|
}
|
||||||
|
var uvs = new List<float>(8);
|
||||||
|
Debug.LogWarning(xPos);
|
||||||
|
Debug.LogWarning(yPos);
|
||||||
|
|
||||||
|
Debug.LogWarning(width);
|
||||||
|
Debug.LogWarning(height);
|
||||||
|
|
||||||
|
uvs.Add((float)xPos / width); //uv0
|
||||||
|
uvs.Add((float)(yPos + emojiSize) / height);
|
||||||
|
uvs.Add((float)(xPos + emojiSize) / width); //uv1
|
||||||
|
uvs.Add((float)(yPos + emojiSize) / height);
|
||||||
|
uvs.Add((float)(xPos + emojiSize) / width); //uv2
|
||||||
|
uvs.Add((float)yPos / height);
|
||||||
|
uvs.Add((float)xPos / width); //uv3
|
||||||
|
uvs.Add((float)yPos / height);
|
||||||
|
|
||||||
|
emojiInfos.Add(index2, uvs);
|
||||||
|
countDown++;
|
||||||
|
}
|
||||||
|
|
||||||
|
newTexture.Apply();
|
||||||
|
|
||||||
|
string path = tarEmojiPath + "/" + newTextureName + ".png";
|
||||||
|
File.WriteAllBytes(path, newTexture.EncodeToPNG());
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SaveUVsConfig()
|
||||||
|
{
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
string space = "\t";
|
||||||
|
string doubleSpace = "\t\t";
|
||||||
|
string tripleSpace = "\t\t\t";
|
||||||
|
string fourthSpace = "\t\t\t\t";
|
||||||
|
|
||||||
|
sb.Append("local emojiInfo = {\n");
|
||||||
|
|
||||||
|
foreach (var pairs in emojiUVs)
|
||||||
|
{
|
||||||
|
sb.Append(space + "[" + (pairs.Key) + "] = {\n");
|
||||||
|
var countDown = 1;
|
||||||
|
foreach (var _pairs in pairs.Value)
|
||||||
|
{
|
||||||
|
sb.Append(doubleSpace + "[" + countDown + "] = {\n");
|
||||||
|
sb.Append(tripleSpace + "[1] = " + _pairs.Value[0] + ",\n");
|
||||||
|
sb.Append(tripleSpace + "[2] = " + _pairs.Value[1] + ",\n");
|
||||||
|
sb.Append(tripleSpace + "[3] = " + _pairs.Value[2] + ",\n");
|
||||||
|
sb.Append(tripleSpace + "[4] = " + _pairs.Value[3] + ",\n");
|
||||||
|
sb.Append(tripleSpace + "[5] = " + _pairs.Value[4] + ",\n");
|
||||||
|
sb.Append(tripleSpace + "[6] = " + _pairs.Value[5] + ",\n");
|
||||||
|
sb.Append(tripleSpace + "[7] = " + _pairs.Value[6] + ",\n");
|
||||||
|
sb.Append(tripleSpace + "[8] = " + _pairs.Value[7] + ",\n");
|
||||||
|
sb.Append(doubleSpace + "},\n");
|
||||||
|
countDown++;
|
||||||
|
}
|
||||||
|
sb.Append(space + "},\n");
|
||||||
|
}
|
||||||
|
sb.Append("}\n");
|
||||||
|
sb.Append("return emojiInfo");
|
||||||
|
|
||||||
|
using (StreamWriter fs = new StreamWriter(tarCfgPath + "/" + cfgName + ".lua"))
|
||||||
|
{
|
||||||
|
Debug.Log(sb.ToString());
|
||||||
|
fs.Write(sb.ToString());
|
||||||
|
}
|
||||||
|
|
||||||
|
// using (FileStream fs = File.Open(tarCfgPath + "/" + cfgName + ".lua", FileMode.Create))
|
||||||
|
// {
|
||||||
|
// BinaryWriter bw = new BinaryWriter(fs);
|
||||||
|
// bw.Write(sb.ToString());
|
||||||
|
// }
|
||||||
|
|
||||||
|
Close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
11
Assets/Editor/BFGameplayTools/EmojiTools/EmojiEditor.cs.meta
Normal file
11
Assets/Editor/BFGameplayTools/EmojiTools/EmojiEditor.cs.meta
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 422ece0c0fb534a07b07f6e29083ff08
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
32
Assets/Editor/BFGameplayTools/GameplayEditorMenu.cs
Normal file
32
Assets/Editor/BFGameplayTools/GameplayEditorMenu.cs
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using UnityEngine;
|
||||||
|
using UnityEditor;
|
||||||
|
using System.IO;
|
||||||
|
|
||||||
|
namespace BFEditor
|
||||||
|
{
|
||||||
|
public static class GameplayEditorMenu
|
||||||
|
{
|
||||||
|
[MenuItem("BF编辑器/新手引导编辑器")]
|
||||||
|
static void OpenTutorialEditor()
|
||||||
|
{
|
||||||
|
var designExcelPath = ExportExcelTools.GetDesignExcelPath();
|
||||||
|
if (string.IsNullOrEmpty(designExcelPath) || !Directory.Exists(designExcelPath))
|
||||||
|
{
|
||||||
|
OpenTutorialExcelPathWindow();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
TutorialConfigWindow window = (TutorialConfigWindow)EditorWindow.GetWindow<TutorialConfigWindow>("新手引导配置窗口");
|
||||||
|
window.Show();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void OpenTutorialExcelPathWindow()
|
||||||
|
{
|
||||||
|
var window = (TutorialExcelPathWindow)EditorWindow.GetWindowWithRect(typeof(TutorialExcelPathWindow),
|
||||||
|
new Rect(Screen.width / 2, Screen.height / 2, 500, 120), true);
|
||||||
|
window.Show();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
11
Assets/Editor/BFGameplayTools/GameplayEditorMenu.cs.meta
Normal file
11
Assets/Editor/BFGameplayTools/GameplayEditorMenu.cs.meta
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: b46cfe5ea519140f1bcde8dba5de5b83
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
8
Assets/Editor/BFGameplayTools/TutorialTools.meta
Normal file
8
Assets/Editor/BFGameplayTools/TutorialTools.meta
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: ebf35dbfd5a53274db3dfb279d55ef72
|
||||||
|
folderAsset: yes
|
||||||
|
DefaultImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
@ -0,0 +1,528 @@
|
|||||||
|
#if UNITY_EDITOR && UNITY_STANDALONE
|
||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using UnityEngine;
|
||||||
|
using UnityEditor;
|
||||||
|
using NPOI.SS.UserModel;
|
||||||
|
using System.Linq;
|
||||||
|
using System.IO;
|
||||||
|
using System;
|
||||||
|
|
||||||
|
namespace BFEditor
|
||||||
|
{
|
||||||
|
public class TutorialConfigBridge
|
||||||
|
{
|
||||||
|
static TutorialConfigBridge instance;
|
||||||
|
public static TutorialConfigBridge Instance
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if (instance == null)
|
||||||
|
{
|
||||||
|
instance = new TutorialConfigBridge();
|
||||||
|
}
|
||||||
|
return instance;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public const int EXTRA_ROW_NUM = 4;//约定的非内容行数
|
||||||
|
public const int SOURCE_ROW_INDEX = 1;//约定可作为格式规范的行
|
||||||
|
|
||||||
|
private static string tutorialExcelPath;
|
||||||
|
public IWorkbook tutorialConfig;
|
||||||
|
//excel表内容 *******************************************************************F*****************************
|
||||||
|
public int idIndex;
|
||||||
|
public int nextIndex;
|
||||||
|
public int guideTypeStrIndex;
|
||||||
|
public int guideDescribeStrIndex;
|
||||||
|
public int typeIndex;
|
||||||
|
public int stageIndex;
|
||||||
|
public int importantIndex;
|
||||||
|
public int stepsIndex;
|
||||||
|
public int targetIndex;
|
||||||
|
public int conditionIndex;
|
||||||
|
public int nextConditionIndex;
|
||||||
|
public int actionIndex;
|
||||||
|
public int paramsIndex;
|
||||||
|
//表现相关
|
||||||
|
public int handPosIndex;
|
||||||
|
public int boxPosIndex;
|
||||||
|
public int arrowIndex;
|
||||||
|
public int boxHeadIndex;
|
||||||
|
public int boxHeadActIndex;
|
||||||
|
public int boxHeadFlipIndex;
|
||||||
|
public int boxHeadPositionIndex;
|
||||||
|
public int animationPosIndex;
|
||||||
|
public int boxHeadScaleIndex;
|
||||||
|
public int voiceIndex;
|
||||||
|
public int highlightIndex;
|
||||||
|
public int radiusIndex;
|
||||||
|
public int maskColorIndex;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 打开窗口前调用 用于加载Excel表内容
|
||||||
|
/// </summary>
|
||||||
|
public bool LoadTutorialExcel()
|
||||||
|
{
|
||||||
|
var tutorialExcelPath = ExportExcelTools.GetDesignExcelPath() + "/tutorial.xlsx";
|
||||||
|
tutorialConfig = BFExcelHelper.GetWorkbook(tutorialExcelPath);
|
||||||
|
|
||||||
|
idIndex = tutorialConfig.GetBFConfigKeyColumnIndex();
|
||||||
|
nextIndex = tutorialConfig.GetBFConfigfieldColumnIndex("next");
|
||||||
|
guideTypeStrIndex = tutorialConfig.GetBFConfigfieldColumnIndex("guideTypeStr");
|
||||||
|
guideDescribeStrIndex = tutorialConfig.GetBFConfigfieldColumnIndex("guideDescribeStr");
|
||||||
|
typeIndex = tutorialConfig.GetBFConfigfieldColumnIndex("type");
|
||||||
|
stageIndex = tutorialConfig.GetBFConfigfieldColumnIndex("stage");
|
||||||
|
importantIndex = tutorialConfig.GetBFConfigfieldColumnIndex("important");
|
||||||
|
stepsIndex = tutorialConfig.GetBFConfigfieldColumnIndex("steps");
|
||||||
|
targetIndex = tutorialConfig.GetBFConfigfieldColumnIndex("target");
|
||||||
|
conditionIndex = tutorialConfig.GetBFConfigfieldColumnIndex("condition");
|
||||||
|
nextConditionIndex = tutorialConfig.GetBFConfigfieldColumnIndex("nextCondition");
|
||||||
|
actionIndex = tutorialConfig.GetBFConfigfieldColumnIndex("action");
|
||||||
|
paramsIndex = tutorialConfig.GetBFConfigfieldColumnIndex("params");
|
||||||
|
handPosIndex = tutorialConfig.GetBFConfigfieldColumnIndex("handPos");
|
||||||
|
boxPosIndex = tutorialConfig.GetBFConfigfieldColumnIndex("boxPos");
|
||||||
|
arrowIndex = tutorialConfig.GetBFConfigfieldColumnIndex("arrow");
|
||||||
|
boxHeadIndex = tutorialConfig.GetBFConfigfieldColumnIndex("boxHead");
|
||||||
|
boxHeadActIndex = tutorialConfig.GetBFConfigfieldColumnIndex("boxHeadAct");
|
||||||
|
boxHeadFlipIndex = tutorialConfig.GetBFConfigfieldColumnIndex("boxHeadFlip");
|
||||||
|
boxHeadPositionIndex = tutorialConfig.GetBFConfigfieldColumnIndex("boxHeadPosition");
|
||||||
|
animationPosIndex = tutorialConfig.GetBFConfigfieldColumnIndex("animationPos");
|
||||||
|
boxHeadScaleIndex = tutorialConfig.GetBFConfigfieldColumnIndex("boxHeadScale");
|
||||||
|
voiceIndex = tutorialConfig.GetBFConfigfieldColumnIndex("voice");
|
||||||
|
highlightIndex = tutorialConfig.GetBFConfigfieldColumnIndex("highlight");
|
||||||
|
radiusIndex = tutorialConfig.GetBFConfigfieldColumnIndex("radius");
|
||||||
|
maskColorIndex = tutorialConfig.GetBFConfigfieldColumnIndex("maskColor");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ICell _GetCell(int index, int columnIndex)
|
||||||
|
{
|
||||||
|
var sheet = tutorialConfig.GetBFSheet();
|
||||||
|
var row = sheet.GetRow(index);
|
||||||
|
var cell = row.GetBFMissingCell(columnIndex);
|
||||||
|
return cell;
|
||||||
|
}
|
||||||
|
|
||||||
|
public string _GetCellValue(int index, int columnIndex)
|
||||||
|
{
|
||||||
|
string cellValue = string.Empty;
|
||||||
|
var cell = _GetCell(index, columnIndex);
|
||||||
|
switch (cell.CellType)
|
||||||
|
{
|
||||||
|
case CellType.String://字符串类型
|
||||||
|
cellValue = cell.StringCellValue;
|
||||||
|
break;
|
||||||
|
case CellType.Numeric: //数值类型
|
||||||
|
cellValue = cell.NumericCellValue.ToString();
|
||||||
|
break;
|
||||||
|
case CellType.Formula: //公式
|
||||||
|
cell.SetCellType(CellType.Numeric);
|
||||||
|
cellValue = cell.NumericCellValue.ToString();
|
||||||
|
break;
|
||||||
|
case CellType.Blank:
|
||||||
|
break;
|
||||||
|
case CellType.Boolean:
|
||||||
|
break;
|
||||||
|
case CellType.Error:
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return cellValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void _SetCellValue(int index, int columnIndex, string value)
|
||||||
|
{
|
||||||
|
var cell = _GetCell(index, columnIndex);
|
||||||
|
cell.SetCellValue(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
//默认引导类型说明
|
||||||
|
public string GetDefaultGuideTypeStr(TutorialType type)
|
||||||
|
{
|
||||||
|
string value = string.Empty;
|
||||||
|
switch (type)
|
||||||
|
{
|
||||||
|
case TutorialType.NONE:
|
||||||
|
value = string.Empty;
|
||||||
|
break;
|
||||||
|
case TutorialType.CLICK:
|
||||||
|
value = "【手指】";
|
||||||
|
break;
|
||||||
|
case TutorialType.CLICK_AND_TEXT:
|
||||||
|
value = "【文本框】【手指】";
|
||||||
|
break;
|
||||||
|
case TutorialType.TEXT:
|
||||||
|
value = "【文本框】";
|
||||||
|
break;
|
||||||
|
case TutorialType.HIGHLIGHT_AND_TEXT:
|
||||||
|
value = "【文本框】【高亮】";
|
||||||
|
break;
|
||||||
|
case TutorialType.CLICK_FULL_SCREEN:
|
||||||
|
value = "【手指】";
|
||||||
|
break;
|
||||||
|
case TutorialType.TALK:
|
||||||
|
value = "【剧情】";
|
||||||
|
break;
|
||||||
|
case TutorialType.ACTION:
|
||||||
|
value = "【事件】";
|
||||||
|
break;
|
||||||
|
case TutorialType.CLICK_IN_BUILDING_MARK:
|
||||||
|
value = "【手指】";
|
||||||
|
break;
|
||||||
|
case TutorialType.FIND_BUILDING_IN_SCENE:
|
||||||
|
value = "【手指】";
|
||||||
|
break;
|
||||||
|
case TutorialType.HIGHLIGHT_BOSS:
|
||||||
|
value = "【文本框】【高亮】";
|
||||||
|
break;
|
||||||
|
case TutorialType.HIGHLIGHT_COMEOUT:
|
||||||
|
value = "【文本框】【高亮】";
|
||||||
|
break;
|
||||||
|
case TutorialType.HIGHLIGHT_BATTLE_UNIT:
|
||||||
|
value = "【文本框】【高亮】";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
value = string.Empty;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
//数据Get Set ******************************************************************************
|
||||||
|
|
||||||
|
//ID
|
||||||
|
public string GetID(int index)
|
||||||
|
{
|
||||||
|
return _GetCellValue(index, idIndex);
|
||||||
|
}
|
||||||
|
public void SetID(int index, string value)
|
||||||
|
{
|
||||||
|
_SetCellValue(index, idIndex, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
//Next
|
||||||
|
public string GetNextID(int index)
|
||||||
|
{
|
||||||
|
return _GetCellValue(index, nextIndex);
|
||||||
|
}
|
||||||
|
public void SetNextID(int index, string value)
|
||||||
|
{
|
||||||
|
_SetCellValue(index, nextIndex, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
//GuideTypeStr
|
||||||
|
public string GetGuideTypeStr(int index)
|
||||||
|
{
|
||||||
|
return _GetCellValue(index, guideTypeStrIndex);
|
||||||
|
}
|
||||||
|
public void SetGuideTypeStr(int index, string value)
|
||||||
|
{
|
||||||
|
_SetCellValue(index, guideTypeStrIndex, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
//GuideDescribeStr
|
||||||
|
public string GetGuideDescribeStr(int index)
|
||||||
|
{
|
||||||
|
return _GetCellValue(index, guideDescribeStrIndex);
|
||||||
|
}
|
||||||
|
public void SetGuideDescribeStr(int index, string value)
|
||||||
|
{
|
||||||
|
_SetCellValue(index, guideDescribeStrIndex, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
//Type
|
||||||
|
public string GetType(int index)
|
||||||
|
{
|
||||||
|
return _GetCellValue(index, typeIndex);
|
||||||
|
}
|
||||||
|
public void SetType(int index, string value)
|
||||||
|
{
|
||||||
|
_SetCellValue(index, typeIndex, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
//Stage
|
||||||
|
public string GetStage(int index)
|
||||||
|
{
|
||||||
|
return _GetCellValue(index, stageIndex);
|
||||||
|
}
|
||||||
|
public void SetStage(int index, string value)
|
||||||
|
{
|
||||||
|
_SetCellValue(index, stageIndex, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
//Important
|
||||||
|
public string GetImportant(int index)
|
||||||
|
{
|
||||||
|
return _GetCellValue(index, importantIndex);
|
||||||
|
}
|
||||||
|
public void SetImportant(int index, string value)
|
||||||
|
{
|
||||||
|
_SetCellValue(index, importantIndex, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
//Steps
|
||||||
|
public string GetSteps(int index)
|
||||||
|
{
|
||||||
|
return _GetCellValue(index, stepsIndex);
|
||||||
|
}
|
||||||
|
public void SetSteps(int index, string value)
|
||||||
|
{
|
||||||
|
_SetCellValue(index, stepsIndex, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
//Target
|
||||||
|
public string GetTarget(int index)
|
||||||
|
{
|
||||||
|
return _GetCellValue(index, targetIndex);
|
||||||
|
}
|
||||||
|
public void SetTarget(int index, string value)
|
||||||
|
{
|
||||||
|
_SetCellValue(index, targetIndex, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
//Condition
|
||||||
|
public string GetCondition(int index)
|
||||||
|
{
|
||||||
|
return _GetCellValue(index, conditionIndex);
|
||||||
|
}
|
||||||
|
public void SetCondition(int index, string value)
|
||||||
|
{
|
||||||
|
_SetCellValue(index, conditionIndex, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
//NextCondition
|
||||||
|
public string GetNextCondition(int index)
|
||||||
|
{
|
||||||
|
return _GetCellValue(index, nextConditionIndex);
|
||||||
|
}
|
||||||
|
public void SetNextCondition(int index, string value)
|
||||||
|
{
|
||||||
|
_SetCellValue(index, nextConditionIndex, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
//Action
|
||||||
|
public string GetAction(int index)
|
||||||
|
{
|
||||||
|
return _GetCellValue(index, actionIndex);
|
||||||
|
}
|
||||||
|
public void SetAction(int index, string value)
|
||||||
|
{
|
||||||
|
_SetCellValue(index, actionIndex, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
//ActionParams
|
||||||
|
public string GetActionParams(int index)
|
||||||
|
{
|
||||||
|
return _GetCellValue(index, paramsIndex);
|
||||||
|
}
|
||||||
|
public void SetActionParams(int index, string value)
|
||||||
|
{
|
||||||
|
_SetCellValue(index, paramsIndex, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
//HandPos
|
||||||
|
public string GetHandPos(int index)
|
||||||
|
{
|
||||||
|
return _GetCellValue(index, handPosIndex);
|
||||||
|
}
|
||||||
|
public void SetHandPos(int index, string value)
|
||||||
|
{
|
||||||
|
_SetCellValue(index, handPosIndex, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
//BoxPos
|
||||||
|
public string GetBoxPos(int index)
|
||||||
|
{
|
||||||
|
return _GetCellValue(index, boxPosIndex);
|
||||||
|
}
|
||||||
|
public void SetBoxPos(int index, string value)
|
||||||
|
{
|
||||||
|
_SetCellValue(index, boxPosIndex, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
//Arrow
|
||||||
|
public string GetArrow(int index)
|
||||||
|
{
|
||||||
|
return _GetCellValue(index, arrowIndex);
|
||||||
|
}
|
||||||
|
public void SetArrow(int index, string value)
|
||||||
|
{
|
||||||
|
_SetCellValue(index, arrowIndex, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
//BoxHead
|
||||||
|
public string GetBoxHead(int index)
|
||||||
|
{
|
||||||
|
return _GetCellValue(index, boxHeadIndex);
|
||||||
|
}
|
||||||
|
public void SetBoxHead(int index, string value)
|
||||||
|
{
|
||||||
|
_SetCellValue(index, boxHeadIndex, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
//BoxHeadAct
|
||||||
|
public string GetBoxHeadAct(int index)
|
||||||
|
{
|
||||||
|
return _GetCellValue(index, boxHeadActIndex);
|
||||||
|
}
|
||||||
|
public void SetBoxHeadAct(int index, string value)
|
||||||
|
{
|
||||||
|
_SetCellValue(index, boxHeadActIndex, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
//BoxHeadFlip
|
||||||
|
public string GetBoxHeadFlip(int index)
|
||||||
|
{
|
||||||
|
return _GetCellValue(index, boxHeadFlipIndex);
|
||||||
|
}
|
||||||
|
public void SetBoxHeadFlip(int index, string value)
|
||||||
|
{
|
||||||
|
_SetCellValue(index, boxHeadFlipIndex, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
//BoxHeadPosition
|
||||||
|
public string GetBoxHeadPosition(int index)
|
||||||
|
{
|
||||||
|
return _GetCellValue(index, boxHeadPositionIndex);
|
||||||
|
}
|
||||||
|
public void SetBoxHeadPosition(int index, string value)
|
||||||
|
{
|
||||||
|
_SetCellValue(index, boxHeadPositionIndex, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
//AnimationPos
|
||||||
|
public string GetAnimationPosition(int index)
|
||||||
|
{
|
||||||
|
return _GetCellValue(index, animationPosIndex);
|
||||||
|
}
|
||||||
|
public void SetAnimationPosition(int index, string value)
|
||||||
|
{
|
||||||
|
_SetCellValue(index, animationPosIndex, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
//BoxHeadScale
|
||||||
|
public string GetBoxHeadScale(int index)
|
||||||
|
{
|
||||||
|
return _GetCellValue(index, boxHeadScaleIndex);
|
||||||
|
}
|
||||||
|
public void SetBoxHeadScale(int index, string value)
|
||||||
|
{
|
||||||
|
_SetCellValue(index, boxHeadScaleIndex, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
//Voice
|
||||||
|
public string GetVoice(int index)
|
||||||
|
{
|
||||||
|
return _GetCellValue(index, voiceIndex);
|
||||||
|
}
|
||||||
|
public void SetVoice(int index, string value)
|
||||||
|
{
|
||||||
|
_SetCellValue(index, voiceIndex, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
//Voice
|
||||||
|
public string GetHighlight(int index)
|
||||||
|
{
|
||||||
|
return _GetCellValue(index, highlightIndex);
|
||||||
|
}
|
||||||
|
public void SetHighlight(int index, string value)
|
||||||
|
{
|
||||||
|
_SetCellValue(index, highlightIndex, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
//Radius
|
||||||
|
public string GetRadius(int index)
|
||||||
|
{
|
||||||
|
return _GetCellValue(index, radiusIndex);
|
||||||
|
}
|
||||||
|
public void SetRadius(int index, string value)
|
||||||
|
{
|
||||||
|
_SetCellValue(index, radiusIndex, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
//MaskColor
|
||||||
|
public string GetMaskColor(int index)
|
||||||
|
{
|
||||||
|
return _GetCellValue(index, maskColorIndex);
|
||||||
|
}
|
||||||
|
public void SetMaskColor(int index, string value)
|
||||||
|
{
|
||||||
|
_SetCellValue(index, maskColorIndex, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
//通用方法 ******************************************************************************
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获得实际行数
|
||||||
|
/// </summary>
|
||||||
|
public int GetRowNum()
|
||||||
|
{
|
||||||
|
if (tutorialConfig == null)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
var sheet = tutorialConfig.GetBFSheet();
|
||||||
|
return sheet.LastRowNum + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 插入一条新引导
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="index"></param>
|
||||||
|
public void InsertRow(int index)
|
||||||
|
{
|
||||||
|
if (tutorialConfig == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
var sheet = tutorialConfig.GetBFSheet();
|
||||||
|
//如果不是在最末处添加 则需要移动
|
||||||
|
if (index < sheet.LastRowNum + 1)
|
||||||
|
{
|
||||||
|
sheet.ShiftRows(index, sheet.LastRowNum, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
var row = sheet.CreateRow(index);
|
||||||
|
var sourceRow = sheet.GetRow(SOURCE_ROW_INDEX);//作为可参考的原row
|
||||||
|
for (int i = 0; i < sourceRow.LastCellNum; i++)
|
||||||
|
{
|
||||||
|
var cell = row.CreateCell(i);
|
||||||
|
cell.SetCellType(sourceRow.GetCell(i).CellType);
|
||||||
|
}
|
||||||
|
//保存
|
||||||
|
SaveExcel();
|
||||||
|
//重新加载
|
||||||
|
LoadTutorialExcel();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 删除一条引导
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="index"></param>
|
||||||
|
public void DeleteRow(int index)
|
||||||
|
{
|
||||||
|
if (tutorialConfig == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
var sheet = tutorialConfig.GetBFSheet();
|
||||||
|
sheet.ShiftRows(index + 1, sheet.LastRowNum + 1, -1);
|
||||||
|
//保存
|
||||||
|
SaveExcel();
|
||||||
|
//重新加载
|
||||||
|
LoadTutorialExcel();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 将现有数据保存至Excel
|
||||||
|
/// </summary>
|
||||||
|
public void SaveExcel()
|
||||||
|
{
|
||||||
|
if (tutorialConfig == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
var tutorialExcelPath = ExportExcelTools.GetDesignExcelPath() + "/tutorial.xlsx";
|
||||||
|
tutorialConfig.SaveBFExcel(tutorialExcelPath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 19658d10401c3094cb0acc279ab71e30
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
@ -0,0 +1,750 @@
|
|||||||
|
using System.Text;
|
||||||
|
using System;
|
||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using UnityEngine;
|
||||||
|
using UnityEditor;
|
||||||
|
|
||||||
|
namespace BFEditor
|
||||||
|
{
|
||||||
|
public class TutorialConfigWindow : EditorWindow
|
||||||
|
{
|
||||||
|
#if UNITY_EDITOR && UNITY_STANDALONE
|
||||||
|
int selectIndex = -1;//当前选中的引导Index
|
||||||
|
const float WidthOfLeftPanel = 850;
|
||||||
|
const float WidthOfMiddlePanel = 350;
|
||||||
|
const float WidthOfRightPanel = 300;
|
||||||
|
Vector2 leftScrollPos;
|
||||||
|
Vector2 middleScrollPos;
|
||||||
|
Vector2 rightScrollPos;
|
||||||
|
|
||||||
|
const int DEFAULT_MASK_COLOR = 156;//默认遮罩颜色
|
||||||
|
void Awake()
|
||||||
|
{
|
||||||
|
TutorialConfigBridge.Instance.LoadTutorialExcel();
|
||||||
|
}
|
||||||
|
|
||||||
|
void OnGUI()
|
||||||
|
{
|
||||||
|
DrawOverviewArea();
|
||||||
|
DrawDetailArea();
|
||||||
|
DrawHelpArea();
|
||||||
|
}
|
||||||
|
|
||||||
|
void DrawOverviewArea()
|
||||||
|
{
|
||||||
|
GUILayout.BeginArea(new Rect(0, 0, WidthOfLeftPanel, position.height));
|
||||||
|
leftScrollPos = EditorGUILayout.BeginScrollView(leftScrollPos);
|
||||||
|
for (int i = TutorialConfigBridge.EXTRA_ROW_NUM; i < TutorialConfigBridge.Instance.GetRowNum(); i++)
|
||||||
|
{
|
||||||
|
GUILayout.BeginHorizontal();
|
||||||
|
EditorGUILayout.LabelField(string.Format("ID:{0}", TutorialConfigBridge.Instance.GetID(i)), GUILayout.Width(80));
|
||||||
|
EditorGUILayout.LabelField(string.Format("类型:{0}", TutorialConfigBridge.Instance.GetGuideTypeStr(i)), GUILayout.Width(200));
|
||||||
|
EditorGUILayout.LabelField(string.Format("说明:{0}", TutorialConfigBridge.Instance.GetGuideDescribeStr(i)), GUILayout.Width(300));
|
||||||
|
if (GUILayout.Button("查看", GUILayout.Width(50)))
|
||||||
|
{
|
||||||
|
selectIndex = i;
|
||||||
|
}
|
||||||
|
if (GUILayout.Button("上方插入", GUILayout.Width(60)))
|
||||||
|
{
|
||||||
|
TutorialConfigBridge.Instance.InsertRow(i);
|
||||||
|
Repaint();
|
||||||
|
}
|
||||||
|
if (GUILayout.Button("下方插入", GUILayout.Width(60)))
|
||||||
|
{
|
||||||
|
TutorialConfigBridge.Instance.InsertRow(i + 1);
|
||||||
|
Repaint();
|
||||||
|
}
|
||||||
|
if (GUILayout.Button("删除", GUILayout.Width(50)))
|
||||||
|
{
|
||||||
|
TutorialConfigBridge.Instance.DeleteRow(i);
|
||||||
|
Repaint();
|
||||||
|
}
|
||||||
|
GUILayout.EndHorizontal();
|
||||||
|
}
|
||||||
|
EditorGUILayout.EndScrollView();
|
||||||
|
GUILayout.EndArea();
|
||||||
|
}
|
||||||
|
|
||||||
|
void DrawDetailArea()
|
||||||
|
{
|
||||||
|
GUILayout.BeginArea(new Rect(WidthOfLeftPanel + 20, 0, WidthOfMiddlePanel, position.height));
|
||||||
|
middleScrollPos = EditorGUILayout.BeginScrollView(middleScrollPos);
|
||||||
|
if (TutorialConfigBridge.EXTRA_ROW_NUM <= selectIndex && selectIndex < TutorialConfigBridge.Instance.GetRowNum())
|
||||||
|
{
|
||||||
|
var id = TutorialConfigBridge.Instance.GetID(selectIndex);
|
||||||
|
var idType = TutorialIdType.NONE; // 引导大类型
|
||||||
|
if (!string.IsNullOrEmpty(id))
|
||||||
|
{
|
||||||
|
idType = (TutorialIdType)(int.Parse(id) / 10000);
|
||||||
|
}
|
||||||
|
|
||||||
|
//版本
|
||||||
|
if (idType == TutorialIdType.VERSION)
|
||||||
|
{
|
||||||
|
DrawID();
|
||||||
|
}
|
||||||
|
//其他(强引导1,功能开启2,功能指引4,跳转8)
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DrawID();
|
||||||
|
DrawNext();
|
||||||
|
DrawType();
|
||||||
|
DrawGuideTypeStr();
|
||||||
|
DrawDescribeStr();
|
||||||
|
|
||||||
|
EditorGUILayout.Space();
|
||||||
|
|
||||||
|
DrawImportantAndSteps();
|
||||||
|
|
||||||
|
EditorGUILayout.Space();
|
||||||
|
|
||||||
|
DrawTarget();
|
||||||
|
|
||||||
|
EditorGUILayout.Space();
|
||||||
|
|
||||||
|
DrawStage();
|
||||||
|
DrawCondition();
|
||||||
|
DrawNextCondition();
|
||||||
|
DrawAction();
|
||||||
|
DrawParams();
|
||||||
|
|
||||||
|
EditorGUILayout.Space();
|
||||||
|
|
||||||
|
DrawHandPos();
|
||||||
|
DrawBoxPos();
|
||||||
|
DrawArrow();
|
||||||
|
DrawBoxHead();
|
||||||
|
DrawBoxHeadAct();
|
||||||
|
DrawBoxHeadFlip();
|
||||||
|
DrawBoxHeadPosition();
|
||||||
|
DrawAnimationPos();
|
||||||
|
DrawBoxHeadScale();
|
||||||
|
DrawHighlight();
|
||||||
|
DrawRadius();
|
||||||
|
DrawMaskColor();
|
||||||
|
|
||||||
|
EditorGUILayout.Space();
|
||||||
|
|
||||||
|
DrawVoice();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
EditorGUILayout.EndScrollView();
|
||||||
|
GUILayout.EndArea();
|
||||||
|
}
|
||||||
|
|
||||||
|
void DrawHelpArea()
|
||||||
|
{
|
||||||
|
GUILayout.BeginArea(new Rect(WidthOfLeftPanel + WidthOfMiddlePanel + 40, 0, WidthOfRightPanel, position.height));
|
||||||
|
rightScrollPos = EditorGUILayout.BeginScrollView(rightScrollPos);
|
||||||
|
|
||||||
|
DrawGuideTypeHelp();
|
||||||
|
DrawImportantTypeHelp();
|
||||||
|
DrawConditionTypeHelp();
|
||||||
|
DrawActionTypeHelp();
|
||||||
|
|
||||||
|
EditorGUILayout.EndScrollView();
|
||||||
|
GUILayout.EndArea();
|
||||||
|
}
|
||||||
|
|
||||||
|
//详细绘制 *******************************************************************************************
|
||||||
|
|
||||||
|
void DrawID()
|
||||||
|
{
|
||||||
|
EditorGUILayout.BeginHorizontal();
|
||||||
|
EditorGUI.BeginChangeCheck();
|
||||||
|
var value = EditorGUILayout.TextField("ID(int):", TutorialConfigBridge.Instance.GetID(selectIndex));
|
||||||
|
if (EditorGUI.EndChangeCheck())
|
||||||
|
{
|
||||||
|
int parseInt = 0;
|
||||||
|
if (int.TryParse(value, out parseInt))
|
||||||
|
{
|
||||||
|
TutorialConfigBridge.Instance.SetID(selectIndex, value);
|
||||||
|
UpdateExcel();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Debug.LogError("ID需要为5位整数");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
EditorGUILayout.EndHorizontal();
|
||||||
|
}
|
||||||
|
void DrawNext()
|
||||||
|
{
|
||||||
|
EditorGUILayout.BeginHorizontal();
|
||||||
|
EditorGUI.BeginChangeCheck();
|
||||||
|
var value = EditorGUILayout.TextField("NextID(int):", TutorialConfigBridge.Instance.GetNextID(selectIndex));
|
||||||
|
if (EditorGUI.EndChangeCheck())
|
||||||
|
{
|
||||||
|
int parseInt = 0;
|
||||||
|
if (int.TryParse(value, out parseInt))
|
||||||
|
{
|
||||||
|
TutorialConfigBridge.Instance.SetNextID(selectIndex, value);
|
||||||
|
UpdateExcel();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Debug.LogError("NextID需要为5位整数");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
EditorGUILayout.EndHorizontal();
|
||||||
|
}
|
||||||
|
void DrawType()
|
||||||
|
{
|
||||||
|
EditorGUILayout.BeginHorizontal();
|
||||||
|
EditorGUI.BeginChangeCheck();
|
||||||
|
var curType = TutorialConfigBridge.Instance.GetType(selectIndex);
|
||||||
|
var curTypeEnum = TutorialType.NONE;
|
||||||
|
if (!string.IsNullOrEmpty(curType))
|
||||||
|
{
|
||||||
|
curTypeEnum = (TutorialType)int.Parse(curType);
|
||||||
|
}
|
||||||
|
var newType = (TutorialType)EditorGUILayout.EnumPopup("引导类型:", curTypeEnum);
|
||||||
|
if (EditorGUI.EndChangeCheck())
|
||||||
|
{
|
||||||
|
var value = ((int)newType).ToString();
|
||||||
|
TutorialConfigBridge.Instance.SetType(selectIndex, value);
|
||||||
|
//自动配置TypeStr
|
||||||
|
TutorialConfigBridge.Instance.SetGuideTypeStr(selectIndex, TutorialConfigBridge.Instance.GetDefaultGuideTypeStr(newType));
|
||||||
|
UpdateExcel();
|
||||||
|
}
|
||||||
|
EditorGUILayout.EndHorizontal();
|
||||||
|
}
|
||||||
|
void DrawGuideTypeStr()
|
||||||
|
{
|
||||||
|
EditorGUILayout.BeginHorizontal();
|
||||||
|
EditorGUI.BeginChangeCheck();
|
||||||
|
var value = EditorGUILayout.TextField("类型说明(string):", TutorialConfigBridge.Instance.GetGuideTypeStr(selectIndex));
|
||||||
|
if (EditorGUI.EndChangeCheck())
|
||||||
|
{
|
||||||
|
TutorialConfigBridge.Instance.SetGuideTypeStr(selectIndex, value);
|
||||||
|
UpdateExcel();
|
||||||
|
}
|
||||||
|
EditorGUILayout.EndHorizontal();
|
||||||
|
}
|
||||||
|
void DrawDescribeStr()
|
||||||
|
{
|
||||||
|
EditorGUILayout.BeginHorizontal();
|
||||||
|
EditorGUI.BeginChangeCheck();
|
||||||
|
var value = EditorGUILayout.TextField("引导说明(string):", TutorialConfigBridge.Instance.GetGuideDescribeStr(selectIndex));
|
||||||
|
if (EditorGUI.EndChangeCheck())
|
||||||
|
{
|
||||||
|
TutorialConfigBridge.Instance.SetGuideDescribeStr(selectIndex, value);
|
||||||
|
UpdateExcel();
|
||||||
|
}
|
||||||
|
EditorGUILayout.EndHorizontal();
|
||||||
|
}
|
||||||
|
|
||||||
|
void DrawStage()
|
||||||
|
{
|
||||||
|
EditorGUILayout.BeginHorizontal();
|
||||||
|
EditorGUI.BeginChangeCheck();
|
||||||
|
var value = EditorGUILayout.TextField("触发关卡(int):", TutorialConfigBridge.Instance.GetStage(selectIndex));
|
||||||
|
if (EditorGUI.EndChangeCheck())
|
||||||
|
{
|
||||||
|
int parseInt = 0;
|
||||||
|
if (int.TryParse(value, out parseInt))
|
||||||
|
{
|
||||||
|
TutorialConfigBridge.Instance.SetStage(selectIndex, value);
|
||||||
|
UpdateExcel();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Debug.LogError("Stage需要为整数");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
EditorGUILayout.EndHorizontal();
|
||||||
|
}
|
||||||
|
void DrawImportantAndSteps()
|
||||||
|
{
|
||||||
|
EditorGUILayout.BeginHorizontal();
|
||||||
|
EditorGUI.BeginChangeCheck();
|
||||||
|
var value = EditorGUILayout.TextField("关键节点类型(string):", TutorialConfigBridge.Instance.GetImportant(selectIndex));
|
||||||
|
if (EditorGUI.EndChangeCheck())
|
||||||
|
{
|
||||||
|
TutorialConfigBridge.Instance.SetImportant(selectIndex, value);
|
||||||
|
UpdateExcel();
|
||||||
|
}
|
||||||
|
EditorGUILayout.EndHorizontal();
|
||||||
|
//Steps
|
||||||
|
if (!string.IsNullOrEmpty(value))
|
||||||
|
{
|
||||||
|
EditorGUILayout.BeginHorizontal();
|
||||||
|
EditorGUI.BeginChangeCheck();
|
||||||
|
var value2 = EditorGUILayout.TextField("中断时重启步骤([int]):", TutorialConfigBridge.Instance.GetSteps(selectIndex));
|
||||||
|
if (EditorGUI.EndChangeCheck())
|
||||||
|
{
|
||||||
|
TutorialConfigBridge.Instance.SetSteps(selectIndex, value2);
|
||||||
|
UpdateExcel();
|
||||||
|
}
|
||||||
|
EditorGUILayout.EndHorizontal();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var value2 = TutorialConfigBridge.Instance.GetSteps(selectIndex);
|
||||||
|
if (!string.IsNullOrEmpty(value2))
|
||||||
|
{
|
||||||
|
//清空steps
|
||||||
|
TutorialConfigBridge.Instance.SetSteps(selectIndex, string.Empty);
|
||||||
|
UpdateExcel();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void DrawTarget()
|
||||||
|
{
|
||||||
|
EditorGUILayout.BeginHorizontal();
|
||||||
|
EditorGUI.BeginChangeCheck();
|
||||||
|
var value = EditorGUILayout.TextField("UI目标(string):", TutorialConfigBridge.Instance.GetTarget(selectIndex));
|
||||||
|
if (EditorGUI.EndChangeCheck())
|
||||||
|
{
|
||||||
|
TutorialConfigBridge.Instance.SetTarget(selectIndex, value);
|
||||||
|
UpdateExcel();
|
||||||
|
}
|
||||||
|
EditorGUILayout.EndHorizontal();
|
||||||
|
}
|
||||||
|
void DrawCondition()
|
||||||
|
{
|
||||||
|
//type
|
||||||
|
EditorGUILayout.BeginHorizontal();
|
||||||
|
EditorGUI.BeginChangeCheck();
|
||||||
|
var curCondition = TutorialConfigBridge.Instance.GetCondition(selectIndex);
|
||||||
|
var curConditionTypeEnum = TutorialConditionType.NONE;
|
||||||
|
var curConditionValue = 0;
|
||||||
|
if (!string.IsNullOrEmpty(curCondition))
|
||||||
|
{
|
||||||
|
Vector2Int formatCurCondition = SplitStringToVector2Int(curCondition);
|
||||||
|
curConditionTypeEnum = (TutorialConditionType)formatCurCondition.x;
|
||||||
|
curConditionValue = formatCurCondition.y;
|
||||||
|
}
|
||||||
|
var newConditionType = (TutorialConditionType)EditorGUILayout.EnumPopup("触发条件类型:", curConditionTypeEnum);
|
||||||
|
if (EditorGUI.EndChangeCheck())
|
||||||
|
{
|
||||||
|
//如果设置为None 则清空数据
|
||||||
|
if (newConditionType == TutorialConditionType.NONE)
|
||||||
|
{
|
||||||
|
TutorialConfigBridge.Instance.SetCondition(selectIndex, string.Empty);
|
||||||
|
UpdateExcel();
|
||||||
|
}
|
||||||
|
//正常更新type
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var newValue = Vector2IntToString(new Vector2Int((int)newConditionType, curConditionValue));
|
||||||
|
TutorialConfigBridge.Instance.SetCondition(selectIndex, newValue);
|
||||||
|
UpdateExcel();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
EditorGUILayout.EndHorizontal();
|
||||||
|
//value
|
||||||
|
if (curConditionTypeEnum != TutorialConditionType.NONE)
|
||||||
|
{
|
||||||
|
EditorGUILayout.BeginHorizontal();
|
||||||
|
EditorGUI.BeginChangeCheck();
|
||||||
|
var value = EditorGUILayout.TextField("触发条件参数(int):", curConditionValue.ToString());
|
||||||
|
if (EditorGUI.EndChangeCheck())
|
||||||
|
{
|
||||||
|
int parseInt = 0;
|
||||||
|
if (int.TryParse(value, out parseInt))
|
||||||
|
{
|
||||||
|
var newValue2 = Vector2IntToString(new Vector2Int((int)newConditionType, parseInt));
|
||||||
|
TutorialConfigBridge.Instance.SetCondition(selectIndex, newValue2);
|
||||||
|
UpdateExcel();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Debug.LogError("触发条件参数需要为整数");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
EditorGUILayout.EndHorizontal();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void DrawNextCondition()
|
||||||
|
{
|
||||||
|
//type
|
||||||
|
EditorGUILayout.BeginHorizontal();
|
||||||
|
EditorGUI.BeginChangeCheck();
|
||||||
|
var curCondition = TutorialConfigBridge.Instance.GetNextCondition(selectIndex);
|
||||||
|
var curConditionTypeEnum = TutorialConditionType.NONE;
|
||||||
|
var curConditionValue = 0;
|
||||||
|
if (!string.IsNullOrEmpty(curCondition))
|
||||||
|
{
|
||||||
|
Vector2Int formatCurCondition = SplitStringToVector2Int(curCondition);
|
||||||
|
curConditionTypeEnum = (TutorialConditionType)formatCurCondition.x;
|
||||||
|
curConditionValue = formatCurCondition.y;
|
||||||
|
}
|
||||||
|
var newConditionType = (TutorialConditionType)EditorGUILayout.EnumPopup("结束条件类型:", curConditionTypeEnum);
|
||||||
|
if (EditorGUI.EndChangeCheck())
|
||||||
|
{
|
||||||
|
//如果设置为None 则清空数据
|
||||||
|
if (newConditionType == TutorialConditionType.NONE)
|
||||||
|
{
|
||||||
|
TutorialConfigBridge.Instance.SetNextCondition(selectIndex, string.Empty);
|
||||||
|
UpdateExcel();
|
||||||
|
}
|
||||||
|
//正常更新type
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var newValue = Vector2IntToString(new Vector2Int((int)newConditionType, curConditionValue));
|
||||||
|
TutorialConfigBridge.Instance.SetNextCondition(selectIndex, newValue);
|
||||||
|
UpdateExcel();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
EditorGUILayout.EndHorizontal();
|
||||||
|
//value
|
||||||
|
if (curConditionTypeEnum != TutorialConditionType.NONE)
|
||||||
|
{
|
||||||
|
EditorGUILayout.BeginHorizontal();
|
||||||
|
EditorGUI.BeginChangeCheck();
|
||||||
|
var value = EditorGUILayout.TextField("结束条件参数(int):", curConditionValue.ToString());
|
||||||
|
if (EditorGUI.EndChangeCheck())
|
||||||
|
{
|
||||||
|
int parseInt = 0;
|
||||||
|
if (int.TryParse(value, out parseInt))
|
||||||
|
{
|
||||||
|
var newValue2 = Vector2IntToString(new Vector2Int((int)newConditionType, parseInt));
|
||||||
|
TutorialConfigBridge.Instance.SetNextCondition(selectIndex, newValue2);
|
||||||
|
UpdateExcel();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Debug.LogError("结束条件参数需要为整数");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
EditorGUILayout.EndHorizontal();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void DrawAction()
|
||||||
|
{
|
||||||
|
EditorGUILayout.BeginHorizontal();
|
||||||
|
EditorGUI.BeginChangeCheck();
|
||||||
|
var curType = TutorialConfigBridge.Instance.GetAction(selectIndex);
|
||||||
|
var curTypeEnum = TutorialActionType.NONE;
|
||||||
|
if (!string.IsNullOrEmpty(curType))
|
||||||
|
{
|
||||||
|
curTypeEnum = (TutorialActionType)int.Parse(curType);
|
||||||
|
}
|
||||||
|
var newType = (TutorialActionType)EditorGUILayout.EnumPopup("特殊行为:", curTypeEnum);
|
||||||
|
if (EditorGUI.EndChangeCheck())
|
||||||
|
{
|
||||||
|
var value = ((int)newType).ToString();
|
||||||
|
TutorialConfigBridge.Instance.SetAction(selectIndex, value);
|
||||||
|
UpdateExcel();
|
||||||
|
}
|
||||||
|
EditorGUILayout.EndHorizontal();
|
||||||
|
}
|
||||||
|
void DrawParams()
|
||||||
|
{
|
||||||
|
EditorGUILayout.BeginHorizontal();
|
||||||
|
EditorGUI.BeginChangeCheck();
|
||||||
|
var value = EditorGUILayout.TextField("特殊参数([int]):", TutorialConfigBridge.Instance.GetActionParams(selectIndex));
|
||||||
|
if (EditorGUI.EndChangeCheck())
|
||||||
|
{
|
||||||
|
TutorialConfigBridge.Instance.SetActionParams(selectIndex, value);
|
||||||
|
UpdateExcel();
|
||||||
|
}
|
||||||
|
EditorGUILayout.EndHorizontal();
|
||||||
|
}
|
||||||
|
//表现相关
|
||||||
|
void DrawHandPos()
|
||||||
|
{
|
||||||
|
EditorGUILayout.BeginHorizontal();
|
||||||
|
EditorGUI.BeginChangeCheck();
|
||||||
|
var curValue = TutorialConfigBridge.Instance.GetHandPos(selectIndex);
|
||||||
|
Vector2Int formatCurValue = SplitStringToVector2Int(curValue);
|
||||||
|
var newValue = EditorGUILayout.Vector2IntField("手指偏移:", formatCurValue);
|
||||||
|
if (EditorGUI.EndChangeCheck())
|
||||||
|
{
|
||||||
|
var value = Vector2IntToString(newValue);
|
||||||
|
TutorialConfigBridge.Instance.SetHandPos(selectIndex, value);
|
||||||
|
UpdateExcel();
|
||||||
|
}
|
||||||
|
EditorGUILayout.EndHorizontal();
|
||||||
|
}
|
||||||
|
void DrawBoxPos()
|
||||||
|
{
|
||||||
|
EditorGUILayout.BeginHorizontal();
|
||||||
|
EditorGUI.BeginChangeCheck();
|
||||||
|
var curValue = TutorialConfigBridge.Instance.GetBoxPos(selectIndex);
|
||||||
|
Vector2Int formatCurValue = SplitStringToVector2Int(curValue);
|
||||||
|
var newValue = EditorGUILayout.Vector2IntField("文本框偏移:", formatCurValue);
|
||||||
|
if (EditorGUI.EndChangeCheck())
|
||||||
|
{
|
||||||
|
var value = Vector2IntToString(newValue);
|
||||||
|
TutorialConfigBridge.Instance.SetBoxPos(selectIndex, value);
|
||||||
|
UpdateExcel();
|
||||||
|
}
|
||||||
|
EditorGUILayout.EndHorizontal();
|
||||||
|
}
|
||||||
|
void DrawArrow()
|
||||||
|
{
|
||||||
|
EditorGUILayout.BeginHorizontal();
|
||||||
|
EditorGUI.BeginChangeCheck();
|
||||||
|
var curValue = TutorialConfigBridge.Instance.GetArrow(selectIndex);
|
||||||
|
var toggleValue = EditorGUILayout.Toggle("文本框箭头:", curValue == "1");
|
||||||
|
if (EditorGUI.EndChangeCheck())
|
||||||
|
{
|
||||||
|
var value = toggleValue ? "1" : string.Empty;
|
||||||
|
TutorialConfigBridge.Instance.SetArrow(selectIndex, value);
|
||||||
|
UpdateExcel();
|
||||||
|
}
|
||||||
|
EditorGUILayout.EndHorizontal();
|
||||||
|
}
|
||||||
|
void DrawBoxHead()
|
||||||
|
{
|
||||||
|
EditorGUILayout.BeginHorizontal();
|
||||||
|
EditorGUI.BeginChangeCheck();
|
||||||
|
var value = EditorGUILayout.TextField("引导员形象(string):", TutorialConfigBridge.Instance.GetBoxHead(selectIndex));
|
||||||
|
if (EditorGUI.EndChangeCheck())
|
||||||
|
{
|
||||||
|
TutorialConfigBridge.Instance.SetBoxHead(selectIndex, value);
|
||||||
|
UpdateExcel();
|
||||||
|
}
|
||||||
|
EditorGUILayout.EndHorizontal();
|
||||||
|
}
|
||||||
|
void DrawBoxHeadAct()
|
||||||
|
{
|
||||||
|
EditorGUILayout.BeginHorizontal();
|
||||||
|
EditorGUI.BeginChangeCheck();
|
||||||
|
var curValue = TutorialConfigBridge.Instance.GetBoxHeadAct(selectIndex);
|
||||||
|
var toggleValue = EditorGUILayout.Toggle("引导员show动作(仅对话类):", curValue == "1");
|
||||||
|
if (EditorGUI.EndChangeCheck())
|
||||||
|
{
|
||||||
|
var value = toggleValue ? "1" : string.Empty;
|
||||||
|
TutorialConfigBridge.Instance.SetBoxHeadAct(selectIndex, value);
|
||||||
|
UpdateExcel();
|
||||||
|
}
|
||||||
|
EditorGUILayout.EndHorizontal();
|
||||||
|
}
|
||||||
|
void DrawBoxHeadFlip()
|
||||||
|
{
|
||||||
|
EditorGUILayout.BeginHorizontal();
|
||||||
|
EditorGUI.BeginChangeCheck();
|
||||||
|
var curValue = TutorialConfigBridge.Instance.GetBoxHeadFlip(selectIndex);
|
||||||
|
var toggleValue = EditorGUILayout.Toggle("引导员翻转:", curValue == "1");
|
||||||
|
if (EditorGUI.EndChangeCheck())
|
||||||
|
{
|
||||||
|
var value = toggleValue ? "1" : string.Empty;
|
||||||
|
TutorialConfigBridge.Instance.SetBoxHeadFlip(selectIndex, value);
|
||||||
|
UpdateExcel();
|
||||||
|
}
|
||||||
|
EditorGUILayout.EndHorizontal();
|
||||||
|
}
|
||||||
|
void DrawBoxHeadPosition()
|
||||||
|
{
|
||||||
|
EditorGUILayout.BeginHorizontal();
|
||||||
|
EditorGUI.BeginChangeCheck();
|
||||||
|
var curValue = TutorialConfigBridge.Instance.GetBoxHeadPosition(selectIndex);
|
||||||
|
var toggleValue = EditorGUILayout.Toggle("引导员是否在左边(剧情专用):", curValue == "1");
|
||||||
|
if (EditorGUI.EndChangeCheck())
|
||||||
|
{
|
||||||
|
var value = toggleValue ? "1" : string.Empty;
|
||||||
|
TutorialConfigBridge.Instance.SetBoxHeadPosition(selectIndex, value);
|
||||||
|
UpdateExcel();
|
||||||
|
}
|
||||||
|
EditorGUILayout.EndHorizontal();
|
||||||
|
}
|
||||||
|
void DrawAnimationPos()
|
||||||
|
{
|
||||||
|
EditorGUILayout.BeginHorizontal();
|
||||||
|
EditorGUI.BeginChangeCheck();
|
||||||
|
var curValue = TutorialConfigBridge.Instance.GetAnimationPosition(selectIndex);
|
||||||
|
Vector2Int formatCurValue = SplitStringToVector2Int(curValue);
|
||||||
|
var newValue = EditorGUILayout.Vector2IntField("引导员偏移:", formatCurValue);
|
||||||
|
if (EditorGUI.EndChangeCheck())
|
||||||
|
{
|
||||||
|
var value = Vector2IntToString(newValue);
|
||||||
|
TutorialConfigBridge.Instance.SetAnimationPosition(selectIndex, value);
|
||||||
|
UpdateExcel();
|
||||||
|
}
|
||||||
|
EditorGUILayout.EndHorizontal();
|
||||||
|
}
|
||||||
|
void DrawBoxHeadScale()
|
||||||
|
{
|
||||||
|
EditorGUILayout.BeginHorizontal();
|
||||||
|
EditorGUI.BeginChangeCheck();
|
||||||
|
var value = EditorGUILayout.TextField("引导员缩放(1000标准值)(int):", TutorialConfigBridge.Instance.GetBoxHeadScale(selectIndex));
|
||||||
|
if (EditorGUI.EndChangeCheck())
|
||||||
|
{
|
||||||
|
int parseInt = 0;
|
||||||
|
if (int.TryParse(value, out parseInt))
|
||||||
|
{
|
||||||
|
TutorialConfigBridge.Instance.SetBoxHeadScale(selectIndex, value);
|
||||||
|
UpdateExcel();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Debug.LogError("BoxHeadScale需要为整数");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
EditorGUILayout.EndHorizontal();
|
||||||
|
}
|
||||||
|
void DrawHighlight()
|
||||||
|
{
|
||||||
|
EditorGUILayout.BeginHorizontal();
|
||||||
|
EditorGUI.BeginChangeCheck();
|
||||||
|
var curValue = TutorialConfigBridge.Instance.GetHighlight(selectIndex);
|
||||||
|
var toggleValue = EditorGUILayout.Toggle("高亮形状(默认圆,勾上为方形):", curValue == "1");
|
||||||
|
if (EditorGUI.EndChangeCheck())
|
||||||
|
{
|
||||||
|
var value = toggleValue ? "1" : string.Empty;
|
||||||
|
TutorialConfigBridge.Instance.SetHighlight(selectIndex, value);
|
||||||
|
UpdateExcel();
|
||||||
|
}
|
||||||
|
EditorGUILayout.EndHorizontal();
|
||||||
|
}
|
||||||
|
void DrawRadius()
|
||||||
|
{
|
||||||
|
EditorGUILayout.BeginHorizontal();
|
||||||
|
EditorGUI.BeginChangeCheck();
|
||||||
|
var value = EditorGUILayout.TextField("高亮半径(默认100)(int):", TutorialConfigBridge.Instance.GetRadius(selectIndex));
|
||||||
|
if (EditorGUI.EndChangeCheck())
|
||||||
|
{
|
||||||
|
int parseInt = 0;
|
||||||
|
if (int.TryParse(value, out parseInt))
|
||||||
|
{
|
||||||
|
TutorialConfigBridge.Instance.SetRadius(selectIndex, value);
|
||||||
|
UpdateExcel();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Debug.LogError("Radius需要为整数");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
EditorGUILayout.EndHorizontal();
|
||||||
|
}
|
||||||
|
void DrawMaskColor()
|
||||||
|
{
|
||||||
|
EditorGUILayout.BeginHorizontal();
|
||||||
|
EditorGUI.BeginChangeCheck();
|
||||||
|
var curValue = TutorialConfigBridge.Instance.GetMaskColor(selectIndex);
|
||||||
|
var curSliderValue = DEFAULT_MASK_COLOR;
|
||||||
|
if (!string.IsNullOrEmpty(curValue))
|
||||||
|
{
|
||||||
|
curSliderValue = int.Parse(curValue);
|
||||||
|
}
|
||||||
|
var sliderValue = EditorGUILayout.IntSlider("遮罩颜色值(剧情类无效):", curSliderValue, 0, 255);
|
||||||
|
if (EditorGUI.EndChangeCheck())
|
||||||
|
{
|
||||||
|
var value = sliderValue.ToString();
|
||||||
|
TutorialConfigBridge.Instance.SetMaskColor(selectIndex, value);
|
||||||
|
UpdateExcel();
|
||||||
|
}
|
||||||
|
EditorGUILayout.EndHorizontal();
|
||||||
|
}
|
||||||
|
void DrawVoice()
|
||||||
|
{
|
||||||
|
EditorGUILayout.BeginHorizontal();
|
||||||
|
EditorGUI.BeginChangeCheck();
|
||||||
|
var value = EditorGUILayout.TextField("语音(string):", TutorialConfigBridge.Instance.GetVoice(selectIndex));
|
||||||
|
if (EditorGUI.EndChangeCheck())
|
||||||
|
{
|
||||||
|
TutorialConfigBridge.Instance.SetVoice(selectIndex, value);
|
||||||
|
UpdateExcel();
|
||||||
|
}
|
||||||
|
EditorGUILayout.EndHorizontal();
|
||||||
|
}
|
||||||
|
|
||||||
|
//帮助绘制 *******************************************************************************************
|
||||||
|
|
||||||
|
void DrawGuideTypeHelp()
|
||||||
|
{
|
||||||
|
//TODO
|
||||||
|
}
|
||||||
|
|
||||||
|
void DrawImportantTypeHelp()
|
||||||
|
{
|
||||||
|
//TODO
|
||||||
|
}
|
||||||
|
|
||||||
|
void DrawConditionTypeHelp()
|
||||||
|
{
|
||||||
|
//TODO
|
||||||
|
}
|
||||||
|
|
||||||
|
void DrawActionTypeHelp()
|
||||||
|
{
|
||||||
|
//TODO
|
||||||
|
}
|
||||||
|
|
||||||
|
//通用接口 *******************************************************************************************
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 将[a,b,c...,x]格式的string类型转为int[]类型
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="value"></param>
|
||||||
|
int[] SplitStringToIntArray(string value)
|
||||||
|
{
|
||||||
|
int[] array = null;
|
||||||
|
if (value.StartsWith("[") && value.EndsWith("]"))
|
||||||
|
{
|
||||||
|
var valueStrs = value.Split(',', '[', ']');
|
||||||
|
array = new int[valueStrs.Length];
|
||||||
|
for (int i = 0; i < array.Length - 2; i++)
|
||||||
|
{
|
||||||
|
array[i] = int.Parse(valueStrs[i + 1]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return array;
|
||||||
|
}
|
||||||
|
|
||||||
|
string IntArrayToString(int[] array)
|
||||||
|
{
|
||||||
|
string stringValue = string.Empty;
|
||||||
|
if (array != null && array.Length > 0)
|
||||||
|
{
|
||||||
|
stringValue = "[";
|
||||||
|
for (int i = 0; i < array.Length; i++)
|
||||||
|
{
|
||||||
|
stringValue = stringValue + array[i];
|
||||||
|
if (i < array.Length - 1)
|
||||||
|
{
|
||||||
|
stringValue = stringValue + ",";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
stringValue = stringValue + "]";
|
||||||
|
}
|
||||||
|
return stringValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 将[a,b]格式的string类型转为Vector2Int类型
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="value"></param>
|
||||||
|
Vector2Int SplitStringToVector2Int(string value)
|
||||||
|
{
|
||||||
|
Vector2Int array = new Vector2Int();
|
||||||
|
if (value.StartsWith("[") && value.EndsWith("]"))
|
||||||
|
{
|
||||||
|
var valueStrs = value.Split(',', '[', ']');
|
||||||
|
if (valueStrs.Length == 4)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < 2; i++)
|
||||||
|
{
|
||||||
|
array[i] = int.Parse(valueStrs[i + 1]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return array;
|
||||||
|
}
|
||||||
|
|
||||||
|
string Vector2IntToString(Vector2Int value)
|
||||||
|
{
|
||||||
|
string stringValue = string.Empty;
|
||||||
|
stringValue = string.Format("[{0},{1}]", value.x, value.y);
|
||||||
|
return stringValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 更新Excel
|
||||||
|
/// </summary>
|
||||||
|
void UpdateExcel()
|
||||||
|
{
|
||||||
|
TutorialConfigBridge.Instance.SaveExcel();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: ea051dd4e587f364da7c06ae6b9c4730
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
72
Assets/Editor/BFGameplayTools/TutorialTools/TutorialEnum.cs
Normal file
72
Assets/Editor/BFGameplayTools/TutorialTools/TutorialEnum.cs
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
namespace BFEditor
|
||||||
|
{
|
||||||
|
public enum TutorialIdType
|
||||||
|
{
|
||||||
|
NONE = 0,
|
||||||
|
FORCE = 1,
|
||||||
|
FUNCTION_OPEN = 2,
|
||||||
|
// SPECIAL = 3,//不会在编辑器中生成
|
||||||
|
FUNCTION_GUIDE = 4,
|
||||||
|
JUMP = 8,
|
||||||
|
VERSION = 9,
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum TutorialType
|
||||||
|
{
|
||||||
|
NONE = 0,
|
||||||
|
CLICK = 2,
|
||||||
|
CLICK_AND_TEXT = 4,
|
||||||
|
TEXT = 5,
|
||||||
|
HIGHLIGHT_AND_TEXT = 6,
|
||||||
|
CLICK_FULL_SCREEN = 7,
|
||||||
|
TALK = 8,
|
||||||
|
ACTION = 10,
|
||||||
|
CLICK_IN_BUILDING_MARK = 22, // 城建商店里点击
|
||||||
|
FIND_BUILDING_IN_SCENE = 23, // 在城建中找到已建造的建筑
|
||||||
|
HIGHLIGHT_BOSS = 31, // 高亮 boss建筑
|
||||||
|
HIGHLIGHT_COMEOUT = 32, // 高亮 上阵
|
||||||
|
HIGHLIGHT_BATTLE_UNIT = 42, // 高亮 特定战斗单位
|
||||||
|
CLICK_AND_TEXT_FOR_HANG_UP = 51, // 领取挂机奖励专用
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum TutorialActionType
|
||||||
|
{
|
||||||
|
NONE = 0,
|
||||||
|
SET_GESTURE_ENABLE = 1, // 设置手势有效
|
||||||
|
SET_GESTURE_DISABLE = 2, // 设置手势无效
|
||||||
|
SET_BATTLE_TUTORIAL = 3, // 设定为引导战斗,无法退出
|
||||||
|
SET_BATTLE_NORMAL = 4, // 设定为正常战斗
|
||||||
|
SET_PURCHASE_BUILDING_ENABLE = 5, // 设置城建购买按钮是否有效
|
||||||
|
SELECT_SUMMON_TYPE = 6, // 选择抽卡类别
|
||||||
|
SELECT_TEAM_MEMBER = 7, // 上阵选人
|
||||||
|
SELECT_HERO_LIST = 8, // 找到英雄列表中的英雄cell
|
||||||
|
SELECT_BATTLE_UNIT = 9, // 选择特定的战斗单位
|
||||||
|
SELECT_TARGET_BUY_BUILDING = 10, // 选择城建商店特定建筑
|
||||||
|
WAIT_UI_OR_PLOT_OVER = 11, // 特定UI打开或收到插画播放结束的消息
|
||||||
|
WAIT_SUMMON_DISPLAY = 12, // 等待抽卡展示结束
|
||||||
|
WAIT_COMEOUT_UI_LOAD_OVER = 13, // 出战界面是否全部加载完毕
|
||||||
|
WAIT_BATTLE_START_AND_PAUSE = 14, // 当战斗相机初始动画完毕后 暂停
|
||||||
|
RESUME_AND_START_BATTLE = 15, // 恢复继续战斗(相机初始动画配对)
|
||||||
|
WAIT_BATTLE = 16, // 等待战斗进行,此阶段允许普通ui操作
|
||||||
|
WAIT_LEVEL_UP_UI = 17, // 等待升级界面弹出完毕
|
||||||
|
WAIT_TIME = 18, // 等待一定时间
|
||||||
|
WAIT_UI_CLOSE = 19, // 等待一个UI关闭
|
||||||
|
SHOW_RISK_SIDE_BAR = 20, // 播放侧边栏显示效果
|
||||||
|
WAIT_BATTLE_ROUND_AND_PAUSE = 21, // 当战斗到特定回合时 暂停
|
||||||
|
RESUME_AND_START_ROUND = 22, // 恢复继续战斗(回合暂停配对)
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum TutorialConditionType
|
||||||
|
{
|
||||||
|
NONE = 0,
|
||||||
|
UI_OPEN = 2,
|
||||||
|
UI_CLOSE = 3,
|
||||||
|
CLICK = 4,
|
||||||
|
SCENE = 6,
|
||||||
|
TEAM_MEMBER_NUM = 11,//出战选人数量
|
||||||
|
SUMMON_CELL_CENTER = 12,
|
||||||
|
HAS_BUILDING = 31,
|
||||||
|
HERO_LEVEL = 41,
|
||||||
|
HERO_EQUIP = 42,
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: aebbd4a7fac4d2a40893fa73b2432c99
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
@ -0,0 +1,75 @@
|
|||||||
|
using System;
|
||||||
|
using System.IO;
|
||||||
|
using UnityEditor;
|
||||||
|
using UnityEngine;
|
||||||
|
using XLua;
|
||||||
|
using Debug = UnityEngine.Debug;
|
||||||
|
|
||||||
|
namespace BFEditor
|
||||||
|
{
|
||||||
|
public class TutorialExcelPathWindow : EditorWindow
|
||||||
|
{
|
||||||
|
private string designExcelPath = "";
|
||||||
|
private bool designSuccFlag = false;
|
||||||
|
private bool skillSpecialSuccFlag = false;
|
||||||
|
private bool isDev = false;
|
||||||
|
|
||||||
|
public TutorialExcelPathWindow()
|
||||||
|
{
|
||||||
|
this.titleContent = new GUIContent("引导文件");
|
||||||
|
}
|
||||||
|
|
||||||
|
void Awake()
|
||||||
|
{
|
||||||
|
var luaPath = Path.Combine(Application.dataPath, "Developer/lua/main.lua").Replace("\\", "/");
|
||||||
|
isDev = File.Exists(luaPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnEnable()
|
||||||
|
{
|
||||||
|
designExcelPath = ExportExcelTools.GetDesignExcelPath();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnGUI()
|
||||||
|
{
|
||||||
|
#region 设置Excel路径
|
||||||
|
GUILayout.Space(18);
|
||||||
|
GUILayout.BeginHorizontal();
|
||||||
|
GUILayout.Label("选择excel路径");
|
||||||
|
GUILayout.TextField(designExcelPath, GUILayout.Width(300));
|
||||||
|
if (GUILayout.Button("选择", GUILayout.Width(80)))
|
||||||
|
{
|
||||||
|
string openPath = EditorUtility.OpenFolderPanel("select excel path", designExcelPath, "");
|
||||||
|
if (openPath.CompareTo("") != 0){
|
||||||
|
designExcelPath = openPath;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
GUILayout.EndHorizontal();
|
||||||
|
GUILayout.Space(10);
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region 导出lua
|
||||||
|
GUILayout.BeginHorizontal();
|
||||||
|
GUILayout.Space(150);
|
||||||
|
if (GUILayout.Button("打开引导编辑器", GUILayout.Width(200), GUILayout.Height(40)))
|
||||||
|
{
|
||||||
|
OnClickOpen();
|
||||||
|
}
|
||||||
|
GUILayout.EndHorizontal();
|
||||||
|
GUILayout.Space(30);
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnClickOpen()
|
||||||
|
{
|
||||||
|
if (string.IsNullOrEmpty(designExcelPath) || !Directory.Exists(designExcelPath))
|
||||||
|
{
|
||||||
|
EditorUtility.DisplayDialog("错误", "excel路径不存在,请先设置正确路径", "ok");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
ExportExcelTools.SetDesignExcelPath(designExcelPath);
|
||||||
|
TutorialConfigWindow window = (TutorialConfigWindow)EditorWindow.GetWindow<TutorialConfigWindow>("新手引导配置窗口");
|
||||||
|
window.Show();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 963622b8a91482b4c970e021edbb6949
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
8
Assets/Editor/BFOthersTools.meta
Normal file
8
Assets/Editor/BFOthersTools.meta
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 5282b035d70f4434fadf9a695e8eb07c
|
||||||
|
folderAsset: yes
|
||||||
|
DefaultImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
8
Assets/Editor/BFOthersTools/AccountTools.meta
Normal file
8
Assets/Editor/BFOthersTools/AccountTools.meta
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: fa658ac58df2245a29c13ebde6b63185
|
||||||
|
folderAsset: yes
|
||||||
|
DefaultImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
61
Assets/Editor/BFOthersTools/AccountTools/AddAccountWindow.cs
Normal file
61
Assets/Editor/BFOthersTools/AccountTools/AddAccountWindow.cs
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
using System;
|
||||||
|
using UnityEngine;
|
||||||
|
using UnityEditor;
|
||||||
|
|
||||||
|
namespace BFEditor
|
||||||
|
{
|
||||||
|
public class AddAccountWindow : EditorWindow
|
||||||
|
{
|
||||||
|
static Action<string> onClickAdd;
|
||||||
|
|
||||||
|
string accountJson;
|
||||||
|
|
||||||
|
static AddAccountWindow window;
|
||||||
|
|
||||||
|
AddAccountWindow()
|
||||||
|
{
|
||||||
|
this.titleContent = new GUIContent("添加账号");
|
||||||
|
}
|
||||||
|
|
||||||
|
void OnGUI()
|
||||||
|
{
|
||||||
|
GUILayout.Space(10);
|
||||||
|
|
||||||
|
GUILayout.BeginHorizontal();
|
||||||
|
GUILayout.Space(20);
|
||||||
|
|
||||||
|
var style = new GUIStyle(GUI.skin.textField);
|
||||||
|
style.wordWrap = true;
|
||||||
|
accountJson = GUILayout.TextField(accountJson, style, GUILayout.Width(400), GUILayout.Height(150));
|
||||||
|
|
||||||
|
GUILayout.EndHorizontal();
|
||||||
|
|
||||||
|
GUILayout.Space(20);
|
||||||
|
|
||||||
|
if (GUILayout.Button("导入"))
|
||||||
|
{
|
||||||
|
if (onClickAdd != null)
|
||||||
|
{
|
||||||
|
onClickAdd(accountJson);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void OpenWindow(Action<string> action)
|
||||||
|
{
|
||||||
|
var rect = new Rect(Screen.width / 2, Screen.height / 2, 450, 245);
|
||||||
|
window = (AddAccountWindow)EditorWindow.GetWindowWithRect(typeof(AddAccountWindow), rect);
|
||||||
|
window.Show();
|
||||||
|
|
||||||
|
onClickAdd = action;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void CloseWindow()
|
||||||
|
{
|
||||||
|
if (window != null)
|
||||||
|
{
|
||||||
|
window.Close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 1ca3d97ccc66a49b4be8d5c5456e184a
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
348
Assets/Editor/BFOthersTools/AccountTools/SelectAccontWindow.cs
Normal file
348
Assets/Editor/BFOthersTools/AccountTools/SelectAccontWindow.cs
Normal file
@ -0,0 +1,348 @@
|
|||||||
|
using System.IO;
|
||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using UnityEngine;
|
||||||
|
using UnityEditor;
|
||||||
|
using BF;
|
||||||
|
|
||||||
|
namespace BFEditor
|
||||||
|
{
|
||||||
|
[System.Serializable]
|
||||||
|
public class Role
|
||||||
|
{
|
||||||
|
public string id;
|
||||||
|
public string pwd;
|
||||||
|
public string serverName;
|
||||||
|
public string roleName;
|
||||||
|
}
|
||||||
|
|
||||||
|
[System.Serializable]
|
||||||
|
public class RoleList
|
||||||
|
{
|
||||||
|
public List<Role> list = new List<Role>();
|
||||||
|
|
||||||
|
public void SortSelf()
|
||||||
|
{
|
||||||
|
list.Sort((Role x, Role y) =>
|
||||||
|
{
|
||||||
|
return int.Parse(x.id) - int.Parse(y.id);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class SelectAccontWindow : EditorWindow
|
||||||
|
{
|
||||||
|
const string KEY_ROLE_LIST = "ROLE_LIST";
|
||||||
|
const string KEY_ACCOUNT = "ACCOUNT";
|
||||||
|
|
||||||
|
string curId = "";
|
||||||
|
RoleList roleList = new RoleList();
|
||||||
|
Vector2 scrollPos;
|
||||||
|
List<Role> currentRoleList = new List<Role>();
|
||||||
|
GUIStyle yellowStyle;
|
||||||
|
GUIStyle greenStyle;
|
||||||
|
|
||||||
|
void OnEnable()
|
||||||
|
{
|
||||||
|
this.titleContent = new GUIContent("选择账号");
|
||||||
|
|
||||||
|
var curAccountStr = PlayerPrefs.GetString(KEY_ACCOUNT);
|
||||||
|
if (curAccountStr.Contains("|"))
|
||||||
|
{
|
||||||
|
curId = curAccountStr.Split('|')[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
var roleListStr = PlayerPrefs.GetString(KEY_ROLE_LIST, "");
|
||||||
|
if (roleListStr != "")
|
||||||
|
{
|
||||||
|
roleList = JsonUtility.FromJson(roleListStr, typeof(RoleList)) as RoleList;
|
||||||
|
roleList.SortSelf();
|
||||||
|
}
|
||||||
|
|
||||||
|
RefreshCurrentRoleList();
|
||||||
|
}
|
||||||
|
|
||||||
|
void RefreshCurrentRoleList()
|
||||||
|
{
|
||||||
|
currentRoleList.Clear();
|
||||||
|
foreach (var role in roleList.list)
|
||||||
|
{
|
||||||
|
if (role.id == curId)
|
||||||
|
{
|
||||||
|
currentRoleList.Add(role);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void OnGUI()
|
||||||
|
{
|
||||||
|
yellowStyle = new GUIStyle(GUI.skin.label);
|
||||||
|
yellowStyle.normal.textColor = Color.yellow;
|
||||||
|
|
||||||
|
greenStyle = new GUIStyle(GUI.skin.label);
|
||||||
|
greenStyle.normal.textColor = Color.green;
|
||||||
|
|
||||||
|
DrawTop();
|
||||||
|
DrawCurrentAccount();
|
||||||
|
DrawScrollView();
|
||||||
|
}
|
||||||
|
|
||||||
|
void DrawTop()
|
||||||
|
{
|
||||||
|
GUILayout.Space(10);
|
||||||
|
GUILayout.BeginHorizontal();
|
||||||
|
GUILayout.Space(10);
|
||||||
|
|
||||||
|
if (GUILayout.Button("清除所有账号", GUILayout.Width(90), GUILayout.Height(25)))
|
||||||
|
{
|
||||||
|
OnClickClearAll();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (GUILayout.Button("导入账号", GUILayout.Width(90), GUILayout.Height(25)))
|
||||||
|
{
|
||||||
|
OnClickImport();
|
||||||
|
}
|
||||||
|
|
||||||
|
GUILayout.EndHorizontal();
|
||||||
|
GUILayout.Space(2);
|
||||||
|
GUILayout.Box("", GUI.skin.box, GUILayout.Width(520), GUILayout.Height(2));
|
||||||
|
GUILayout.Space(5);
|
||||||
|
}
|
||||||
|
|
||||||
|
void OnClickClearAll()
|
||||||
|
{
|
||||||
|
if (EditorUtility.DisplayDialog("提示", "确认清楚所有账号吗", "确认", "取消"))
|
||||||
|
{
|
||||||
|
PlayerPrefs.DeleteKey(KEY_ROLE_LIST);
|
||||||
|
PlayerPrefs.DeleteKey(KEY_ACCOUNT);
|
||||||
|
roleList.list.Clear();
|
||||||
|
curId = "";
|
||||||
|
RefreshCurrentRoleList();
|
||||||
|
BFLog.Log("清除所有账号成功");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void OnClickImport()
|
||||||
|
{
|
||||||
|
AddAccountWindow.OpenWindow((string json) =>
|
||||||
|
{
|
||||||
|
if (string.IsNullOrEmpty(json))
|
||||||
|
{
|
||||||
|
EditorUtility.DisplayDialog("提示", "格式不正确", "ok");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var addRoleList = JsonUtility.FromJson(json, typeof(RoleList)) as RoleList;
|
||||||
|
if (addRoleList == null || addRoleList.list.Count == 0)
|
||||||
|
{
|
||||||
|
EditorUtility.DisplayDialog("提示", "格式不正确", "ok");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
EditorUtility.DisplayDialog("提示", "导入成功", "ok");
|
||||||
|
AddAccountWindow.CloseWindow();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void DrawCurrentAccount()
|
||||||
|
{
|
||||||
|
GUILayout.BeginHorizontal();
|
||||||
|
GUILayout.Space(10);
|
||||||
|
|
||||||
|
GUILayout.Label("当前账号: " + curId, GUILayout.Width(130));
|
||||||
|
if (GUILayout.Button("导出", GUILayout.Width(50)))
|
||||||
|
{
|
||||||
|
OnClickExport(curId);
|
||||||
|
}
|
||||||
|
|
||||||
|
GUILayout.EndHorizontal();
|
||||||
|
GUILayout.Space(5);
|
||||||
|
|
||||||
|
GUILayout.BeginHorizontal();
|
||||||
|
GUILayout.Space(10);
|
||||||
|
GUILayout.Label("账号id", yellowStyle, GUILayout.Width(100));
|
||||||
|
GUILayout.Label("服务器", yellowStyle, GUILayout.Width(90));
|
||||||
|
GUILayout.Label("角色名", yellowStyle, GUILayout.Width(90));
|
||||||
|
GUILayout.EndHorizontal();
|
||||||
|
|
||||||
|
var count = 0;
|
||||||
|
foreach (var role in currentRoleList)
|
||||||
|
{
|
||||||
|
GUILayout.BeginHorizontal();
|
||||||
|
GUILayout.Space(10);
|
||||||
|
if (count == 0)
|
||||||
|
{
|
||||||
|
GUILayout.Label(role.id, GUILayout.Width(100));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
GUILayout.Label("", GUILayout.Width(100));
|
||||||
|
}
|
||||||
|
GUILayout.Label(role.serverName, GUILayout.Width(90));
|
||||||
|
GUILayout.Label(role.roleName, GUILayout.Width(90));
|
||||||
|
|
||||||
|
GUILayout.EndHorizontal();
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
|
||||||
|
GUILayout.Space(5);
|
||||||
|
GUILayout.Box("", GUI.skin.box, GUILayout.Width(520), GUILayout.Height(2));
|
||||||
|
GUILayout.Space(5);
|
||||||
|
}
|
||||||
|
|
||||||
|
void OnClickExport(string id)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrEmpty(id))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var json = "";
|
||||||
|
var tempRoleList = new RoleList();
|
||||||
|
|
||||||
|
foreach (var role in roleList.list)
|
||||||
|
{
|
||||||
|
if (id == role.id)
|
||||||
|
{
|
||||||
|
tempRoleList.list.Add(role);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
json = JsonUtility.ToJson(tempRoleList);
|
||||||
|
var te = new TextEditor();
|
||||||
|
te.text = json;
|
||||||
|
te.SelectAll();
|
||||||
|
te.Copy();
|
||||||
|
}
|
||||||
|
|
||||||
|
void DrawScrollView()
|
||||||
|
{
|
||||||
|
GUILayout.BeginHorizontal();
|
||||||
|
GUILayout.Space(10);
|
||||||
|
GUILayout.Label("所有账号:");
|
||||||
|
GUILayout.EndHorizontal();
|
||||||
|
|
||||||
|
GUILayout.BeginHorizontal();
|
||||||
|
GUILayout.Space(10);
|
||||||
|
GUILayout.Label("账号id", yellowStyle, GUILayout.Width(100));
|
||||||
|
GUILayout.Label("服务器", yellowStyle, GUILayout.Width(90));
|
||||||
|
GUILayout.Label("角色名", yellowStyle, GUILayout.Width(90));
|
||||||
|
GUILayout.EndHorizontal();
|
||||||
|
|
||||||
|
scrollPos = GUILayout.BeginScrollView(scrollPos, GUILayout.Width(510));
|
||||||
|
var removedId = "";
|
||||||
|
var idRecord = "";
|
||||||
|
foreach (var role in roleList.list)
|
||||||
|
{
|
||||||
|
if (role.id != idRecord && idRecord != "")
|
||||||
|
{
|
||||||
|
GUILayout.Space(15);
|
||||||
|
}
|
||||||
|
|
||||||
|
GUILayout.BeginHorizontal();
|
||||||
|
GUILayout.Space(10);
|
||||||
|
|
||||||
|
if (idRecord != role.id)
|
||||||
|
{
|
||||||
|
if (curId == role.id)
|
||||||
|
{
|
||||||
|
GUILayout.Label(role.id + "(✔)", greenStyle, GUILayout.Width(100));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
GUILayout.Label(role.id, GUILayout.Width(100));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
GUILayout.Label("", GUILayout.Width(100));
|
||||||
|
}
|
||||||
|
|
||||||
|
GUILayout.Label(role.serverName, GUILayout.Width(90));
|
||||||
|
GUILayout.Label(role.roleName, GUILayout.Width(90));
|
||||||
|
|
||||||
|
if (idRecord != role.id)
|
||||||
|
{
|
||||||
|
if (curId == role.id)
|
||||||
|
{
|
||||||
|
GUILayout.Label("(当前号✔)", greenStyle, GUILayout.Width(55));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (GUILayout.Button("切换", GUILayout.Width(55)))
|
||||||
|
{
|
||||||
|
OnClickSelect(role);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (GUILayout.Button("移除", GUILayout.Width(55)))
|
||||||
|
{
|
||||||
|
if (OnClickClear(role.id))
|
||||||
|
{
|
||||||
|
removedId = role.id;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (GUILayout.Button("导出", GUILayout.Width(55)))
|
||||||
|
{
|
||||||
|
OnClickExport(role.id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
idRecord = role.id;
|
||||||
|
GUILayout.EndHorizontal();
|
||||||
|
}
|
||||||
|
GUILayout.EndScrollView();
|
||||||
|
|
||||||
|
if (removedId != "")
|
||||||
|
{
|
||||||
|
RemoveAccount(removedId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void OnClickSelect(Role role)
|
||||||
|
{
|
||||||
|
var accountStr = role.id + "|" + role.pwd;
|
||||||
|
PlayerPrefs.SetString(KEY_ACCOUNT, accountStr);
|
||||||
|
curId = role.id;
|
||||||
|
RefreshCurrentRoleList();
|
||||||
|
BFLog.Log("选择账号:" + role.id);
|
||||||
|
|
||||||
|
//对于新版本 还要更新专用数据
|
||||||
|
PlayerPrefs.SetString("ULogin_Auto_Login_Key", string.Empty);
|
||||||
|
PlayerPrefs.SetString("DroidHang_Once_ShuMeiID", role.pwd);
|
||||||
|
PlayerPrefs.Save();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool OnClickClear(string id)
|
||||||
|
{
|
||||||
|
if (EditorUtility.DisplayDialog("提示", "确认移除吗", "确认", "取消"))
|
||||||
|
{
|
||||||
|
if (id == curId)
|
||||||
|
{
|
||||||
|
curId = "";
|
||||||
|
PlayerPrefs.DeleteKey(KEY_ACCOUNT);
|
||||||
|
RefreshCurrentRoleList();
|
||||||
|
}
|
||||||
|
BFLog.Log("移除账号:" + id);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void RemoveAccount(string id)
|
||||||
|
{
|
||||||
|
for (int i = roleList.list.Count - 1; i >= 0; i--)
|
||||||
|
{
|
||||||
|
var role = roleList.list[i];
|
||||||
|
if (role.id == id)
|
||||||
|
{
|
||||||
|
roleList.list.RemoveAt(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
PlayerPrefs.SetString(KEY_ROLE_LIST, JsonUtility.ToJson(roleList));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 88d0e25a31d3e48d2b4d579a1b6c4a77
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
8
Assets/Editor/BFOthersTools/ExportExcelTools.meta
Normal file
8
Assets/Editor/BFOthersTools/ExportExcelTools.meta
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 925e46ee8fb9c42a898c17ca034d5283
|
||||||
|
folderAsset: yes
|
||||||
|
DefaultImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
564
Assets/Editor/BFOthersTools/ExportExcelTools/ExportExcelTools.cs
Normal file
564
Assets/Editor/BFOthersTools/ExportExcelTools/ExportExcelTools.cs
Normal file
@ -0,0 +1,564 @@
|
|||||||
|
using System;
|
||||||
|
using System.IO;
|
||||||
|
using UnityEngine;
|
||||||
|
using UnityEditor;
|
||||||
|
using System.Text;
|
||||||
|
using XLua;
|
||||||
|
|
||||||
|
namespace BFEditor
|
||||||
|
{
|
||||||
|
public static class ExportExcelTools
|
||||||
|
{
|
||||||
|
private const string DESIGN_EXCEL_KEY = "bf_excel_tool_excel_key";
|
||||||
|
private static bool failFlag = false;
|
||||||
|
private static bool designSuccFlag = false;
|
||||||
|
private static string failLog = "";
|
||||||
|
/// <summary>
|
||||||
|
/// 提供给neo平台调用的一键导表
|
||||||
|
/// </summary>
|
||||||
|
public static void ExportExcelToLua()
|
||||||
|
{
|
||||||
|
var designExcelPath = PlayerPrefs.GetString(DESIGN_EXCEL_KEY, "");
|
||||||
|
if (string.IsNullOrEmpty(designExcelPath) || !Directory.Exists(designExcelPath))
|
||||||
|
{
|
||||||
|
Debug.LogError("[bferror]没有配置正确的excel路径 " + designExcelPath);
|
||||||
|
throw new Exception();
|
||||||
|
}
|
||||||
|
|
||||||
|
var luaPath = Application.dataPath + "/Developer/lua/app/config";
|
||||||
|
if (!Directory.Exists(luaPath))
|
||||||
|
{
|
||||||
|
Debug.LogError("[bferror]没有找到lua路径 " + luaPath);
|
||||||
|
throw new Exception();
|
||||||
|
}
|
||||||
|
|
||||||
|
var relitivePath = Application.dataPath;
|
||||||
|
relitivePath = relitivePath.Remove(relitivePath.Length - 6, 6);
|
||||||
|
var pythonToolPath = relitivePath + "Tools/tranexcel";
|
||||||
|
if (!Directory.Exists(pythonToolPath))
|
||||||
|
{
|
||||||
|
Debug.LogError("[bferror]没有找到pythonToolPath " + pythonToolPath);
|
||||||
|
throw new Exception();
|
||||||
|
}
|
||||||
|
|
||||||
|
var success = true;
|
||||||
|
var localizationPythonToolPath = relitivePath + "Tools/localization";
|
||||||
|
BFEditorUtils.RunCommond("python", "tran.py " + designExcelPath + "/ " + luaPath + "/", pythonToolPath, (str) =>
|
||||||
|
{
|
||||||
|
}, (str) =>
|
||||||
|
{
|
||||||
|
Debug.LogError("[bferror] " + str);
|
||||||
|
success = false;
|
||||||
|
});
|
||||||
|
|
||||||
|
BFEditorUtils.RunCommond("python", "exceltolua.py " + designExcelPath + " " + luaPath + " " + "1", localizationPythonToolPath, (str) =>
|
||||||
|
{
|
||||||
|
}, (str) =>
|
||||||
|
{
|
||||||
|
Debug.LogError("[bferror] " + str);
|
||||||
|
success = false;
|
||||||
|
});
|
||||||
|
|
||||||
|
SpecialProcessSkill(true, (isSuccess) =>
|
||||||
|
{
|
||||||
|
success = isSuccess;
|
||||||
|
if (!isSuccess)
|
||||||
|
{
|
||||||
|
Debug.LogError("[bferror] " + "技能表转换失败");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
var sb = ExportExcelTools.CheckLuaConfig(true);
|
||||||
|
if (sb.ToString().Length > 0)
|
||||||
|
{
|
||||||
|
success = false;
|
||||||
|
Debug.LogError("[bferror] 导表规范检查异常:" + sb.ToString());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!success)
|
||||||
|
{
|
||||||
|
throw new Exception();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static StringBuilder CheckLuaConfig(bool isDeveloper)
|
||||||
|
{
|
||||||
|
//加载lua配置测试
|
||||||
|
LuaEnv env = new LuaEnv();
|
||||||
|
env.AddLoader((ref string scriptPath) =>
|
||||||
|
{
|
||||||
|
var text = LoadGameLuaScriptText(scriptPath, isDeveloper);
|
||||||
|
return text;
|
||||||
|
});
|
||||||
|
|
||||||
|
// 检查多语言配置
|
||||||
|
String luaTextConfigPath = null;
|
||||||
|
String suffix = "";
|
||||||
|
if(isDeveloper)
|
||||||
|
{
|
||||||
|
suffix = "*.lua";
|
||||||
|
luaTextConfigPath = "Assets/developer/lua/app/config/strings";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
suffix = "*.lua.bytes";
|
||||||
|
luaTextConfigPath = "Assets/lua/app/config/strings";
|
||||||
|
}
|
||||||
|
var luaTextDirInfo = new DirectoryInfo(luaTextConfigPath);
|
||||||
|
var luaTextFileInfos = luaTextDirInfo.GetFiles(suffix, SearchOption.AllDirectories);
|
||||||
|
|
||||||
|
var sb = new StringBuilder();
|
||||||
|
foreach (var file in luaTextFileInfos)
|
||||||
|
{
|
||||||
|
var name = file.FullName.Replace("\\", "/");
|
||||||
|
var index = name.IndexOf(luaTextConfigPath);
|
||||||
|
name = name.Substring(index + luaTextConfigPath.Length + 1).Replace(".lua", "").Replace(".bytes", "");
|
||||||
|
try
|
||||||
|
{
|
||||||
|
env.DoString("require " + "'app/config/strings/" + name + "'");
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
sb.Append(name + " 配置异常\n" + e.Message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检查monster
|
||||||
|
String luaConfigPath = null;
|
||||||
|
if(isDeveloper)
|
||||||
|
{
|
||||||
|
luaConfigPath = "Assets/developer/lua/app/config";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
luaConfigPath = "Assets/lua/app/config";
|
||||||
|
}
|
||||||
|
var configDirInfo = new DirectoryInfo(luaConfigPath);
|
||||||
|
var configFileInfos = configDirInfo.GetFiles(suffix, SearchOption.TopDirectoryOnly);
|
||||||
|
string monsterConfigListLua = "{";
|
||||||
|
foreach (var file in configFileInfos)
|
||||||
|
{
|
||||||
|
var fileName = file.Name.ToLower();
|
||||||
|
if(fileName.Contains("monster_"))
|
||||||
|
{
|
||||||
|
monsterConfigListLua += "'" + fileName.Replace(".lua", "").Replace(".bytes", "") + "',";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
monsterConfigListLua += "}";
|
||||||
|
var luaScriptString = "local ids = {}\n local MONSTER_LIST = " + monsterConfigListLua + "\n";
|
||||||
|
luaScriptString += @"local str = {}
|
||||||
|
for i, name in ipairs(MONSTER_LIST) do
|
||||||
|
if name ~= 'monster_base' and name ~= 'monster_position' and name ~= 'monster_position_base' then
|
||||||
|
local data = require('app/config/' .. name).data
|
||||||
|
for k, v in pairs(data) do
|
||||||
|
if ids[k] then
|
||||||
|
table.insert(str, name .. '和' .. ids[k] .. '存在相同的mosnter id:' .. k)
|
||||||
|
end
|
||||||
|
ids[k] = name
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if #str > 0 then
|
||||||
|
return table.concat(str, '\n');
|
||||||
|
end
|
||||||
|
return ''";
|
||||||
|
var resultStr = env.DoString(luaScriptString);
|
||||||
|
if (resultStr.Length > 0)
|
||||||
|
{
|
||||||
|
foreach(var strObj in resultStr)
|
||||||
|
{
|
||||||
|
var str = Convert.ToString(strObj);
|
||||||
|
if(!String.IsNullOrEmpty(str))
|
||||||
|
{
|
||||||
|
sb.Append(str + "\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 检查怪物的坐标信息
|
||||||
|
var luaScriptString2 = @"local MONSTER_POSITION_KEY = { 'monster_1','monster_2','monster_3','monster_4','monster_5','monster_6','monster_7','monster_8','monster_9','monster_10','monster_11','monster_12'}
|
||||||
|
local list = {'enemy_id_1', 'enemy_id_2', 'enemy_id_3'}
|
||||||
|
local list2 = {'enemy_position_1', 'enemy_position_2', 'enemy_position_3'}
|
||||||
|
local positionConf = require('app/config/monster_position_base').data
|
||||||
|
local monsterPositionConf = require('app/config/monster_position').data
|
||||||
|
local stage = require('app/config/story_stage').data
|
||||||
|
local str = {}
|
||||||
|
for k, v in pairs(stage) do
|
||||||
|
for k2, v2 in ipairs(list) do
|
||||||
|
if v[v2] then
|
||||||
|
local monsterPosition = v[list2[k2]]
|
||||||
|
for i, monsterId in ipairs(v[v2]) do
|
||||||
|
local monsterPositionInfo = monsterPositionConf[monsterPosition]
|
||||||
|
local positionInfo = positionConf[monsterPositionInfo[MONSTER_POSITION_KEY[i]]]
|
||||||
|
if positionInfo == nil then
|
||||||
|
table.insert(str, 'stage表的id为' .. k .. '的第' .. k2 .. '波怪的坐标有问题')
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
local stage2 = require('app/config/adventure_stage').data
|
||||||
|
for k, v in pairs(stage2) do
|
||||||
|
for k2, v2 in ipairs(list) do
|
||||||
|
if v[v2] then
|
||||||
|
local monsterPosition = v[list2[k2]]
|
||||||
|
for i, monsterId in ipairs(v[v2]) do
|
||||||
|
local monsterPositionInfo = monsterPositionConf[monsterPosition]
|
||||||
|
local positionInfo = positionConf[monsterPositionInfo[MONSTER_POSITION_KEY[i]]]
|
||||||
|
if positionInfo == nil then
|
||||||
|
table.insert(str, 'adventure_stage表的id为' .. k .. '的第' .. k2 .. '波怪的坐标有问题')
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if #str > 0 then
|
||||||
|
return table.concat(str, '\n');
|
||||||
|
end
|
||||||
|
return ''";
|
||||||
|
var resultStr2 = env.DoString(luaScriptString2);
|
||||||
|
if (resultStr2.Length > 0)
|
||||||
|
{
|
||||||
|
foreach(var strObj in resultStr2)
|
||||||
|
{
|
||||||
|
var str = Convert.ToString(strObj);
|
||||||
|
if(!String.IsNullOrEmpty(str))
|
||||||
|
{
|
||||||
|
sb.Append(str + "\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
env.Dispose();
|
||||||
|
return sb;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static bool FastExportExcelToLua(bool isDeveloper, string designExcelPath)
|
||||||
|
{
|
||||||
|
failFlag = false;
|
||||||
|
designSuccFlag = true;
|
||||||
|
failLog = "";
|
||||||
|
string relitivePath = Application.dataPath;
|
||||||
|
relitivePath = relitivePath.Remove(relitivePath.Length - 6, 6);
|
||||||
|
string luaPath;
|
||||||
|
string pythonToolPath;
|
||||||
|
|
||||||
|
if(isDeveloper)
|
||||||
|
{
|
||||||
|
luaPath = Application.dataPath + "/Developer/lua/app/config";
|
||||||
|
pythonToolPath = relitivePath + "Tools/tranexcel";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
luaPath = Application.dataPath + "/lua/app/config";
|
||||||
|
pythonToolPath = relitivePath + "Tools/tranexcel2";
|
||||||
|
}
|
||||||
|
string localizationPythonToolPath = relitivePath + "Tools/localization";
|
||||||
|
|
||||||
|
// 强制使用新的导表工具 python3.4以上
|
||||||
|
// pythonToolPath = relitivePath + "Tools/tranexcel_new";
|
||||||
|
// localizationPythonToolPath = relitivePath + "Tools/localization_new";
|
||||||
|
|
||||||
|
if (string.IsNullOrEmpty(pythonToolPath) || !Directory.Exists(pythonToolPath))
|
||||||
|
{
|
||||||
|
Debug.LogError(string.Format("python工具不存在,请检查 {0}", pythonToolPath));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (string.IsNullOrEmpty(luaPath) || !Directory.Exists(luaPath))
|
||||||
|
{
|
||||||
|
Debug.LogWarning(string.Format("lua config path not exist!, auto create {0}", luaPath));
|
||||||
|
Directory.CreateDirectory(luaPath);
|
||||||
|
}
|
||||||
|
string isDevStr = isDeveloper?"1":"0";
|
||||||
|
// BFEditorUtils.RunCommond("python", "tran.py " + designExcelPath + "/ " + luaPath + "/" + " " + isDevStr, pythonToolPath, DesignOnOutput, OnError);
|
||||||
|
BFEditorUtils.RunCommond("python", "tran.py " + designExcelPath + "/ " + luaPath + "/", pythonToolPath, DesignOnOutput, OnError);
|
||||||
|
BFEditorUtils.RunCommond("python", "exceltolua.py " + designExcelPath + " " + luaPath + " " + isDevStr, localizationPythonToolPath, ProceduralOnOutput, OnError);
|
||||||
|
|
||||||
|
// ExportExcelTools.SpecialProcessSkill(isDeveloper, SkillSpecialOnOutput);
|
||||||
|
// ExportExcelTools.dealMonsterConfig(isDeveloper);
|
||||||
|
// var sb = ExportExcelTools.CheckLuaConfig(isDeveloper);
|
||||||
|
// if (sb.ToString().Length > 0)
|
||||||
|
// {
|
||||||
|
// failFlag = true;
|
||||||
|
// designSuccFlag = false;
|
||||||
|
// Debug.Log("导表规范检查异常!!!");
|
||||||
|
// Debug.Log(sb.ToString());
|
||||||
|
// EditorUtility.DisplayDialog("导入失败配置", sb.ToString(), "ok");
|
||||||
|
// }
|
||||||
|
// else
|
||||||
|
// {
|
||||||
|
// Debug.Log("配置规范检查通过.");
|
||||||
|
// }
|
||||||
|
|
||||||
|
AssetDatabase.SaveAssets();
|
||||||
|
AssetDatabase.Refresh();
|
||||||
|
|
||||||
|
if(designSuccFlag && !failFlag)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void DesignOnOutput(string outputmsg)
|
||||||
|
{
|
||||||
|
if (outputmsg.Contains("转换成功"))
|
||||||
|
{
|
||||||
|
designSuccFlag = true;
|
||||||
|
}
|
||||||
|
if (outputmsg.Contains("转换失败"))
|
||||||
|
{
|
||||||
|
failFlag = true;
|
||||||
|
failLog = failLog + outputmsg;
|
||||||
|
}
|
||||||
|
Debug.Log(outputmsg);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void OnError(string errorMsg)
|
||||||
|
{
|
||||||
|
failFlag = true;
|
||||||
|
failLog = errorMsg;
|
||||||
|
Debug.Log(errorMsg);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void ProceduralOnOutput(string outputmsg)
|
||||||
|
{
|
||||||
|
if (outputmsg.Contains("转换失败"))
|
||||||
|
{
|
||||||
|
failFlag = true;
|
||||||
|
failLog = failLog + outputmsg;
|
||||||
|
}
|
||||||
|
Debug.Log(outputmsg);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void SkillSpecialOnOutput(bool isSuccess)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
private static byte[] LoadGameLuaScriptText(string scriptPath, bool isDeveloper)
|
||||||
|
{
|
||||||
|
byte[] result = null;
|
||||||
|
String luaPath = null;
|
||||||
|
// 开发路径加载
|
||||||
|
if (isDeveloper)
|
||||||
|
{
|
||||||
|
luaPath = Application.dataPath + "/Developer/lua/" + scriptPath + ".lua";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
luaPath = Application.dataPath + "/lua/" + scriptPath + ".lua.bytes";
|
||||||
|
}
|
||||||
|
if (File.Exists(luaPath))
|
||||||
|
{
|
||||||
|
result = File.ReadAllBytes(luaPath);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Debug.LogError("lua file is missing : " + luaPath);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 特殊处理技能多语言表 (加入程序导表和neo平台调用)
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="readLuaPath"></param>
|
||||||
|
public static void SpecialProcessSkill(bool isDeveloper, Action<bool> callback)
|
||||||
|
{
|
||||||
|
var result = ProcessSkillConfig(isDeveloper);
|
||||||
|
if (result)
|
||||||
|
{
|
||||||
|
if (callback != null)
|
||||||
|
{
|
||||||
|
callback(result);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static bool ProcessSkillConfig(bool isDeveloper)
|
||||||
|
{
|
||||||
|
LuaEnv luaEnv = new LuaEnv();
|
||||||
|
luaEnv.AddLoader(Loader);
|
||||||
|
|
||||||
|
var rootPath = "";
|
||||||
|
if (isDeveloper)
|
||||||
|
{
|
||||||
|
rootPath = Application.dataPath + "/Developer/lua/app/config/strings";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
rootPath = Application.dataPath + "/lua/app/config/strings";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!Directory.Exists(rootPath))
|
||||||
|
{
|
||||||
|
Debug.LogError("没有找到配置表strings 文件夹");
|
||||||
|
throw new Exception();
|
||||||
|
}
|
||||||
|
|
||||||
|
luaEnv.Global.Set<string, bool>("isDeveloper", isDeveloper);
|
||||||
|
luaEnv.DoString(@"require 'Editor/BFOthersTools/ExportExcelTools/processSkillConfigTools.lua'");
|
||||||
|
|
||||||
|
var dirInfo = new DirectoryInfo(rootPath);
|
||||||
|
var reWrite = luaEnv.Global.Get<LuaFunction>("reWrite");
|
||||||
|
|
||||||
|
foreach (var languagePath in dirInfo.GetDirectories())
|
||||||
|
{
|
||||||
|
var skillPath = "";
|
||||||
|
if (isDeveloper)
|
||||||
|
{
|
||||||
|
skillPath = languagePath.FullName + "/skill.lua";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
skillPath = languagePath.FullName + "/skill.lua.bytes";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!File.Exists(skillPath))
|
||||||
|
{
|
||||||
|
Debug.LogWarning("skill表不存在 " + skillPath);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
var str = File.ReadAllText(skillPath);
|
||||||
|
var result = reWrite.Call(languagePath.Name, str);
|
||||||
|
|
||||||
|
// Debug.Log(result[0].ToString());
|
||||||
|
if (result[0].ToString() != "Error")
|
||||||
|
{
|
||||||
|
//重新写入文件
|
||||||
|
File.WriteAllText(skillPath,result[0].ToString());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
private static byte[] Loader(ref string path)
|
||||||
|
{
|
||||||
|
path = Application.dataPath + "/" + path;
|
||||||
|
if (!File.Exists(path))
|
||||||
|
{
|
||||||
|
Debug.LogWarning("无文件lua " + path);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return File.ReadAllBytes(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static string GetDesignExcelPath()
|
||||||
|
{
|
||||||
|
return PlayerPrefs.GetString(DESIGN_EXCEL_KEY, "");
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void SetDesignExcelPath(string path)
|
||||||
|
{
|
||||||
|
PlayerPrefs.SetString(DESIGN_EXCEL_KEY, path);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void dealMonsterConfig(bool isDeveloper)
|
||||||
|
{
|
||||||
|
//加载lua配置测试
|
||||||
|
LuaEnv env = new LuaEnv();
|
||||||
|
env.AddLoader((ref string scriptPath) =>
|
||||||
|
{
|
||||||
|
scriptPath = "app/config/" + scriptPath;
|
||||||
|
var text = LoadGameLuaScriptText(scriptPath, isDeveloper);
|
||||||
|
return text;
|
||||||
|
});
|
||||||
|
|
||||||
|
String suffix = "";
|
||||||
|
|
||||||
|
String luaConfigPath = null;
|
||||||
|
if(isDeveloper)
|
||||||
|
{
|
||||||
|
luaConfigPath = Application.dataPath + "/Developer/lua/app/config";
|
||||||
|
suffix = "*.lua";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
luaConfigPath = Application.dataPath + "/lua/app/config";
|
||||||
|
suffix = "*.lua.bytes";
|
||||||
|
}
|
||||||
|
var configDirInfo = new DirectoryInfo(luaConfigPath);
|
||||||
|
var configFileInfos = configDirInfo.GetFiles(suffix, SearchOption.TopDirectoryOnly);
|
||||||
|
string monsterList = "local monsterList = {";
|
||||||
|
foreach (var file in configFileInfos)
|
||||||
|
{
|
||||||
|
var name = file.FullName.Replace("\\", "/");
|
||||||
|
var index = name.IndexOf(luaConfigPath);
|
||||||
|
name = name.Substring(index + luaConfigPath.Length + 1).Replace(".lua", "").Replace(".bytes", "");
|
||||||
|
if(name.Contains("monster_") && !name.Contains("position") && !name.Contains("monster_base"))
|
||||||
|
{
|
||||||
|
monsterList += "'" + name + "',";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
monsterList += "}";
|
||||||
|
string luaScriptString = @"function tableConfigToString(value, tab, tabCount)
|
||||||
|
tab = tab or ' '
|
||||||
|
tabCount = tabCount and tabCount or 1
|
||||||
|
local t = {}
|
||||||
|
for k, value in pairs(value) do
|
||||||
|
local str = string.rep(tab, tabCount)
|
||||||
|
if type(k) == 'number' then
|
||||||
|
str = str .. '[' .. k .. ']' .. '='
|
||||||
|
elseif type(k) == 'string' then
|
||||||
|
str = str .. '[\'' .. k .. '\']' .. '='
|
||||||
|
end
|
||||||
|
|
||||||
|
if type(value) == 'number' then
|
||||||
|
str = str .. value
|
||||||
|
elseif type(value) == 'string' then
|
||||||
|
str = str .. '\'' .. value .. '\''
|
||||||
|
elseif type(value) == 'table' then
|
||||||
|
str = str .. '{\n' .. tableConfigToString(value, tab, tabCount + 1) .. '\n' .. string.rep(tab, tabCount) .. '}'
|
||||||
|
end
|
||||||
|
table.insert(t, str)
|
||||||
|
end
|
||||||
|
return table.concat(t, ',\n')
|
||||||
|
end
|
||||||
|
|
||||||
|
function configToFile(targetTable, tableLen, targetPath)
|
||||||
|
local str = 'local monster = {\n' .. tableConfigToString(targetTable) .. '\n}\nlcoal config={\ndata=monster,count=' .. tableLen .. '\n}\nreturn config'
|
||||||
|
local luaFile, msg = io.open(targetPath, 'w')
|
||||||
|
if not luaFile then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
luaFile:write(str)
|
||||||
|
io.close(luaFile)
|
||||||
|
end
|
||||||
|
|
||||||
|
function dealMonster(targetPath, monsterList)
|
||||||
|
local monsterBase = require( 'monster_base')
|
||||||
|
local baseData = monsterBase.data
|
||||||
|
local monsterFullData = {}
|
||||||
|
local count = 0
|
||||||
|
local function handleMonsterGrow(name)
|
||||||
|
local monsterGrowConfig = require(name)
|
||||||
|
local growData = monsterGrowConfig.data
|
||||||
|
for k, v in pairs(growData) do
|
||||||
|
monsterFullData[k] = v
|
||||||
|
local data = baseData[v.monster_baseid]
|
||||||
|
if data then
|
||||||
|
monsterFullData[k].icon = data.icon
|
||||||
|
monsterFullData[k].model_id = data.model_id
|
||||||
|
else
|
||||||
|
Logger.logHighlight('not data monster_baseid = ' .. v.monster_baseid)
|
||||||
|
end
|
||||||
|
count = count + 1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
for _, name in ipairs(monsterList) do
|
||||||
|
handleMonsterGrow(name)
|
||||||
|
end
|
||||||
|
|
||||||
|
configToFile(monsterFullData, count, targetPath)
|
||||||
|
end
|
||||||
|
" + monsterList + @"
|
||||||
|
dealMonster('" + luaConfigPath + "/monster" + suffix.Substring(1) + "', monsterList)";
|
||||||
|
env.DoString(luaScriptString);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 60c594554d8cd4a2887b0fa1ff2978be
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
@ -0,0 +1,84 @@
|
|||||||
|
using System;
|
||||||
|
using System.IO;
|
||||||
|
using UnityEditor;
|
||||||
|
using UnityEngine;
|
||||||
|
using XLua;
|
||||||
|
using Debug = UnityEngine.Debug;
|
||||||
|
|
||||||
|
namespace BFEditor
|
||||||
|
{
|
||||||
|
public class ExportExcelWindow : EditorWindow
|
||||||
|
{
|
||||||
|
private string designExcelPath = "";
|
||||||
|
private bool designSuccFlag = false;
|
||||||
|
private bool skillSpecialSuccFlag = false;
|
||||||
|
private bool isDev = false;
|
||||||
|
|
||||||
|
public ExportExcelWindow()
|
||||||
|
{
|
||||||
|
this.titleContent = new GUIContent("导表工具");
|
||||||
|
}
|
||||||
|
|
||||||
|
void Awake()
|
||||||
|
{
|
||||||
|
var luaPath = Path.Combine(Application.dataPath, "Developer/lua/main.lua").Replace("\\", "/");
|
||||||
|
isDev = File.Exists(luaPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnEnable()
|
||||||
|
{
|
||||||
|
designExcelPath = ExportExcelTools.GetDesignExcelPath();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnGUI()
|
||||||
|
{
|
||||||
|
#region 设置Excel路径
|
||||||
|
GUILayout.Space(18);
|
||||||
|
GUILayout.BeginHorizontal();
|
||||||
|
GUILayout.Label("选择excel路径");
|
||||||
|
GUILayout.TextField(designExcelPath, GUILayout.Width(300));
|
||||||
|
if (GUILayout.Button("选择", GUILayout.Width(80)))
|
||||||
|
{
|
||||||
|
string openPath = EditorUtility.OpenFolderPanel("select excel path", designExcelPath, "");
|
||||||
|
if (openPath.CompareTo("") != 0){
|
||||||
|
designExcelPath = openPath;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
GUILayout.EndHorizontal();
|
||||||
|
GUILayout.Space(10);
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region 导出lua
|
||||||
|
GUILayout.BeginHorizontal();
|
||||||
|
GUILayout.Space(150);
|
||||||
|
if (GUILayout.Button("一键导表", GUILayout.Width(200), GUILayout.Height(40)))
|
||||||
|
{
|
||||||
|
bool succ = OnClickExport();
|
||||||
|
if (succ)
|
||||||
|
{
|
||||||
|
Close();
|
||||||
|
EditorUtility.DisplayDialog("成功", "导出成功!", "ok");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Close();
|
||||||
|
EditorUtility.DisplayDialog("失败", "导出失败!", "ok");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
GUILayout.EndHorizontal();
|
||||||
|
GUILayout.Space(30);
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool OnClickExport()
|
||||||
|
{
|
||||||
|
if (string.IsNullOrEmpty(designExcelPath) || !Directory.Exists(designExcelPath))
|
||||||
|
{
|
||||||
|
EditorUtility.DisplayDialog("错误", "excel路径不存在,请先设置正确路径", "ok");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
ExportExcelTools.SetDesignExcelPath(designExcelPath);
|
||||||
|
return ExportExcelTools.FastExportExcelToLua(isDev, designExcelPath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: eb1d652f69b014ee483413610f896973
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
132
Assets/Editor/BFOthersTools/ExportExcelTools/ToggleCaseWindow.cs
Normal file
132
Assets/Editor/BFOthersTools/ExportExcelTools/ToggleCaseWindow.cs
Normal file
@ -0,0 +1,132 @@
|
|||||||
|
using System;
|
||||||
|
using System.IO;
|
||||||
|
using UnityEditor;
|
||||||
|
using UnityEngine;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace BFEditor
|
||||||
|
{
|
||||||
|
public class ToggleCaseWindow : EditorWindow
|
||||||
|
{
|
||||||
|
private string folderPath = "";
|
||||||
|
|
||||||
|
//需要忽略的文件后缀
|
||||||
|
private Dictionary<string, bool> ignoreResSuffix = new Dictionary<string, bool>() {
|
||||||
|
{ ".meta", true },
|
||||||
|
{ ".ds_store", true },
|
||||||
|
};
|
||||||
|
|
||||||
|
public ToggleCaseWindow()
|
||||||
|
{
|
||||||
|
this.titleContent = new GUIContent("大小写转换");
|
||||||
|
}
|
||||||
|
|
||||||
|
void Awake()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnEnable()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnGUI()
|
||||||
|
{
|
||||||
|
#region 设置Excel路径
|
||||||
|
GUILayout.Space(18);
|
||||||
|
GUILayout.BeginHorizontal();
|
||||||
|
GUILayout.Label("需要转换的文件夹路径");
|
||||||
|
GUILayout.TextField(folderPath, GUILayout.Width(280));
|
||||||
|
if (GUILayout.Button("选择", GUILayout.Width(80)))
|
||||||
|
{
|
||||||
|
string openPath = EditorUtility.OpenFolderPanel("select excel path", "", "");
|
||||||
|
if (openPath.CompareTo("") != 0){
|
||||||
|
folderPath = openPath.Replace("\\", "/");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
GUILayout.EndHorizontal();
|
||||||
|
GUILayout.Space(10);
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region 导出lua
|
||||||
|
GUILayout.BeginHorizontal();
|
||||||
|
GUILayout.Space(150);
|
||||||
|
if (GUILayout.Button("一键转小写", GUILayout.Width(200), GUILayout.Height(40)))
|
||||||
|
{
|
||||||
|
bool succ = OnClickExport();
|
||||||
|
if (succ)
|
||||||
|
{
|
||||||
|
Close();
|
||||||
|
EditorUtility.DisplayDialog("成功", "转换成功!", "ok");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Close();
|
||||||
|
EditorUtility.DisplayDialog("失败", "转换失败!", "ok");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
GUILayout.EndHorizontal();
|
||||||
|
GUILayout.Space(30);
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool CheckIgnoreOrHidden(FileInfo fi)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (((fi.Attributes & FileAttributes.Hidden) > 0) || ((fi.Attributes & FileAttributes.System) > 0))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ignoreResSuffix.ContainsKey(fi.Extension.ToLower()))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool OnClickExport()
|
||||||
|
{
|
||||||
|
if (string.IsNullOrEmpty(folderPath) || !Directory.Exists(folderPath))
|
||||||
|
{
|
||||||
|
EditorUtility.DisplayDialog("错误", "路径不存在,请先设置正确路径", "ok");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
var outFolderPath = folderPath + "_out";
|
||||||
|
if (!Directory.Exists(outFolderPath))
|
||||||
|
{
|
||||||
|
Directory.CreateDirectory(outFolderPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
var dirInfo = new DirectoryInfo(folderPath);
|
||||||
|
var dirs = dirInfo.GetDirectories();
|
||||||
|
foreach (var subDirInfo in dirs)
|
||||||
|
{
|
||||||
|
var subDirPath = subDirInfo.FullName.Replace("\\", "/");;
|
||||||
|
var outSubDirPath = subDirPath.Replace(folderPath, outFolderPath);
|
||||||
|
if (!Directory.Exists(outSubDirPath))
|
||||||
|
{
|
||||||
|
Directory.CreateDirectory(outSubDirPath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var files = dirInfo.GetFiles("*.*", SearchOption.AllDirectories);
|
||||||
|
var assetFiles = new List<string>();
|
||||||
|
|
||||||
|
for (var i = 0; i < files.Length; ++i)
|
||||||
|
{
|
||||||
|
var fileInfo = files[i];
|
||||||
|
|
||||||
|
if (CheckIgnoreOrHidden(fileInfo))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
var relativePath = fileInfo.FullName.Substring(folderPath.Length + 1).ToLower();
|
||||||
|
var outFilePath = Path.Combine(outFolderPath, relativePath);
|
||||||
|
File.Copy(fileInfo.FullName, outFilePath, true);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: a060b3f5007cbcc43a657fa039ca572b
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
@ -0,0 +1,524 @@
|
|||||||
|
local skillConfigPath = ""
|
||||||
|
local subSkillConfigPath = ""
|
||||||
|
local buffConfigPath = ""
|
||||||
|
|
||||||
|
if isDeveloper then
|
||||||
|
skillConfigPath = 'Developer/lua/app/config/skill.lua'
|
||||||
|
subSkillConfigPath = 'Developer/lua/app/config/skillSub.lua'
|
||||||
|
buffConfigPath = 'Developer/lua/app/config/buff.lua'
|
||||||
|
else
|
||||||
|
skillConfigPath = 'Lua/app/config/skill.lua.bytes'
|
||||||
|
subSkillConfigPath = 'Lua/app/config/skillSub.lua.bytes'
|
||||||
|
buffConfigPath = 'Lua/app/config/buff.lua.bytes'
|
||||||
|
end
|
||||||
|
|
||||||
|
local pairsName = {
|
||||||
|
[1] = 'skillName',
|
||||||
|
[2] = 'desc',
|
||||||
|
[3] = 'desc2'
|
||||||
|
}
|
||||||
|
|
||||||
|
local skillConfig = require(skillConfigPath).data
|
||||||
|
local subSkillConfig = require(subSkillConfigPath).data
|
||||||
|
local buffConfig = require(buffConfigPath)
|
||||||
|
|
||||||
|
function getBuffIsPercent(type)
|
||||||
|
local data = buffConfig.keys.name[type]
|
||||||
|
if not data then
|
||||||
|
CS.UnityEngine.Debug.LogError("buff表中不存在类型" .. tostring(type))
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
|
return data.isPercent and data.isPercent == 2 or false
|
||||||
|
end
|
||||||
|
|
||||||
|
function reWrite(languageStr, str)
|
||||||
|
--配置表无序 只能按匹配
|
||||||
|
|
||||||
|
local skillDescConfigPath = ""
|
||||||
|
if isDeveloper then
|
||||||
|
skillDescConfigPath = 'Developer/lua/app/config/strings/' .. languageStr .. '/skill.lua'
|
||||||
|
else
|
||||||
|
skillDescConfigPath = 'Lua/app/config/strings/' .. languageStr .. '/skill.lua.bytes'
|
||||||
|
end
|
||||||
|
|
||||||
|
local skillDescConfig = require(skillDescConfigPath).data
|
||||||
|
local caCheTable = {}
|
||||||
|
local caCheRatioTable = {}
|
||||||
|
|
||||||
|
for skillid, data in pairs(skillDescConfig) do
|
||||||
|
for _, field in ipairs(pairsName) do
|
||||||
|
if data[field] then
|
||||||
|
--匹配规则并计算出数值记录下来
|
||||||
|
local matchResult = string.match(data[field], "{(.+)_(.)}")
|
||||||
|
if matchResult then
|
||||||
|
--计算并排序
|
||||||
|
local mainSkill = skillConfig[skillid]
|
||||||
|
if not mainSkill then
|
||||||
|
-- CS.UnityEngine.Debug.LogError("skill表中不存在技能" .. tostring(skillid))
|
||||||
|
return "Error"
|
||||||
|
end
|
||||||
|
|
||||||
|
local skillCacheData = {}
|
||||||
|
local skillRatioCacheData = {}
|
||||||
|
|
||||||
|
----------主技能技能效果 整体概率
|
||||||
|
local mainSkillEffects = mainSkill.effect
|
||||||
|
local mainSkillHasChange = false
|
||||||
|
local subSkillHasChange = false
|
||||||
|
|
||||||
|
if not mainSkillEffects then
|
||||||
|
-- CS.UnityEngine.Debug.LogWarning("主技能没有技能效果" .. tostring(skillid))
|
||||||
|
else
|
||||||
|
for _, mainSkillEffect in ipairs(mainSkillEffects) do
|
||||||
|
if mainSkillEffect.type ~= 'changeAtk' and mainSkillEffect.type ~= 'changeSkill' then
|
||||||
|
--CS.UnityEngine.Debug.Log("insert main SkillEffect")
|
||||||
|
table.insert(skillCacheData,{
|
||||||
|
effect = {
|
||||||
|
type = mainSkillEffect.type,
|
||||||
|
v = mainSkillEffect.num,
|
||||||
|
p = mainSkillEffect.ratio,
|
||||||
|
r = mainSkillEffect.round,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
else
|
||||||
|
mainSkillHasChange = true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
table.insert(skillRatioCacheData, mainSkill.skillRatio or 0)
|
||||||
|
|
||||||
|
-----------子技能技能效果 整体概率
|
||||||
|
local subSkills = nil
|
||||||
|
if mainSkill.skillSub then
|
||||||
|
subSkills = mainSkill.skillSub
|
||||||
|
for _, subSkillId in ipairs(subSkills) do
|
||||||
|
local subSkill = subSkillConfig[subSkillId]
|
||||||
|
if not subSkill then
|
||||||
|
-- CS.UnityEngine.Debug.LogError("subskill表中不存在技能" .. tostring(subSkillId))
|
||||||
|
return "Error"
|
||||||
|
end
|
||||||
|
--子技能技能效果 整体概率
|
||||||
|
local subSkillEffects = subSkill.effect
|
||||||
|
|
||||||
|
if not subSkillEffects then
|
||||||
|
-- CS.UnityEngine.Debug.LogWarning("子技能没有技能效果" .. tostring(skillid))
|
||||||
|
else
|
||||||
|
for _, subSkillEffect in ipairs(subSkillEffects) do
|
||||||
|
if subSkillEffect.type ~= 'changeAtk' and subSkillEffect.type ~= 'changeSkill' then
|
||||||
|
--CS.UnityEngine.Debug.Log("insert sub SkillEffect")
|
||||||
|
table.insert(skillCacheData,{
|
||||||
|
effect = {
|
||||||
|
type = subSkillEffect.type,
|
||||||
|
v = subSkillEffect.num,
|
||||||
|
p = subSkillEffect.ratio,
|
||||||
|
r = subSkillEffect.round,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
else
|
||||||
|
subSkillHasChange = true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
table.insert(skillRatioCacheData, subSkill.skillRatio or 0)
|
||||||
|
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local mainChangeAtkSkill = nil
|
||||||
|
local mainChangeSkillSkill = nil
|
||||||
|
local changeId = nil
|
||||||
|
local cacheChange = nil
|
||||||
|
|
||||||
|
if mainSkillHasChange then
|
||||||
|
---------主技能change技能
|
||||||
|
for _, mainSkillEffect in ipairs(mainSkillEffects) do
|
||||||
|
changeId = nil
|
||||||
|
if mainSkillEffect.type == 'changeAtk' then
|
||||||
|
changeId = mainSkillEffect.num
|
||||||
|
mainChangeAtkSkill = skillConfig[changeId]
|
||||||
|
cacheChange = mainChangeAtkSkill
|
||||||
|
if not mainChangeAtkSkill then
|
||||||
|
-- CS.UnityEngine.Debug.LogError("skill表中不存在技能" .. tostring(changeId))
|
||||||
|
return "Error"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if mainSkillEffect.type == 'changeSkill' then
|
||||||
|
changeId = mainSkillEffect.num
|
||||||
|
mainChangeSkillSkill = skillConfig[changeId]
|
||||||
|
cacheChange = mainChangeSkillSkill
|
||||||
|
if not mainChangeSkillSkill then
|
||||||
|
-- CS.UnityEngine.Debug.LogError("skill表中不存在技能" .. tostring(changeId))
|
||||||
|
return "Error"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if changeId then
|
||||||
|
local changeEffects = cacheChange.effect
|
||||||
|
if not changeEffects then
|
||||||
|
-- CS.UnityEngine.Debug.LogWarning("主机能chanage技能没有技能效果" .. tostring(skillid))
|
||||||
|
else
|
||||||
|
for _, changeEffect in ipairs(changeEffects) do
|
||||||
|
table.insert(skillCacheData,{
|
||||||
|
effect = {
|
||||||
|
type = changeEffect.type,
|
||||||
|
v = changeEffect.num,
|
||||||
|
p = changeEffect.ratio,
|
||||||
|
r = changeEffect.round,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
table.insert(skillRatioCacheData, cacheChange.skillRatio or 0)
|
||||||
|
|
||||||
|
---------主技能change技能的子技能
|
||||||
|
local changeFirstSubIds = cacheChange.skillSub
|
||||||
|
if changeFirstSubIds then
|
||||||
|
for _, changeFirstSubId in ipairs(changeFirstSubIds) do
|
||||||
|
local changeFirstSub = subSkillConfig[changeFirstSubId]
|
||||||
|
if not changeFirstSub then
|
||||||
|
-- CS.UnityEngine.Debug.LogError("subSkill表中不存在技能" .. tostring(changeFirstSubId))
|
||||||
|
return "Error"
|
||||||
|
end
|
||||||
|
|
||||||
|
local changeEffects = changeFirstSub.effect
|
||||||
|
if not changeEffects then
|
||||||
|
-- CS.UnityEngine.Debug.LogWarning("主机能chanage子技能没有技能效果" .. tostring(skillid))
|
||||||
|
else
|
||||||
|
for _, changeEffect in ipairs(changeEffects) do
|
||||||
|
table.insert(skillCacheData,{
|
||||||
|
effect = {
|
||||||
|
type = changeEffect.type,
|
||||||
|
v = changeEffect.num,
|
||||||
|
p = changeEffect.ratio,
|
||||||
|
r = changeEffect.round,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
table.insert(skillRatioCacheData, changeFirstSub.skillRatio or 0)
|
||||||
|
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
else
|
||||||
|
------------主技能isAct技能
|
||||||
|
if mainSkill.isAct then
|
||||||
|
local mainIsActSkill = skillConfig[mainSkill.isAct]
|
||||||
|
if not mainIsActSkill then
|
||||||
|
-- CS.UnityEngine.Debug.LogError("skill表中不存在技能" .. tostring(mainSkill.isAct))
|
||||||
|
return "Error"
|
||||||
|
end
|
||||||
|
|
||||||
|
local changeEffects = mainIsActSkill.effect
|
||||||
|
|
||||||
|
if not changeEffects then
|
||||||
|
-- CS.UnityEngine.Debug.LogWarning("主技能isAct技能没有技能效果" .. tostring(skillid))
|
||||||
|
else
|
||||||
|
for _, changeEffect in ipairs(changeEffects) do
|
||||||
|
table.insert(skillCacheData,{
|
||||||
|
effect = {
|
||||||
|
type = changeEffect.type,
|
||||||
|
v = changeEffect.num,
|
||||||
|
p = changeEffect.ratio,
|
||||||
|
r = changeEffect.round,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
table.insert(skillRatioCacheData, mainIsActSkill.skillRatio or 0)
|
||||||
|
|
||||||
|
-------主技能isAct技能的子技能
|
||||||
|
local mainIsActSkillSubSkillIds = mainIsActSkill.skillSub
|
||||||
|
if mainIsActSkillSubSkillIds then
|
||||||
|
for _, mainIsActSkillSubSkillId in ipairs(mainIsActSkillSubSkillIds) do
|
||||||
|
local mainIsActSkillSubSkill = subSkillConfig[mainIsActSkillSubSkillId]
|
||||||
|
if not mainIsActSkillSubSkill then
|
||||||
|
-- CS.UnityEngine.Debug.LogError("subskill表中不存在技能" .. tostring(mainIsActSkillSubSkillId))
|
||||||
|
return "Error"
|
||||||
|
end
|
||||||
|
|
||||||
|
local changeEffects = mainIsActSkillSubSkill.effect
|
||||||
|
if not changeEffects then
|
||||||
|
-- CS.UnityEngine.Debug.LogWarning("主技能isAct技能的子技能没有技能效果" .. tostring(skillid))
|
||||||
|
else
|
||||||
|
for _, changeEffect in ipairs(changeEffects) do
|
||||||
|
table.insert(skillCacheData,{
|
||||||
|
effect = {
|
||||||
|
type = changeEffect.type,
|
||||||
|
v = changeEffect.num,
|
||||||
|
p = changeEffect.ratio,
|
||||||
|
r = changeEffect.round,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
table.insert(skillRatioCacheData, mainIsActSkillSubSkill.skillRatio)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
----------------子技能相关
|
||||||
|
local subSkillChangeAtkSkill = nil
|
||||||
|
local subSkillChangeSkillSkill = nil
|
||||||
|
local changeId = nil
|
||||||
|
local cacheChange = nil
|
||||||
|
|
||||||
|
if subSkills then
|
||||||
|
for _, subSkillId in ipairs(subSkills) do
|
||||||
|
local subSkill = subSkillConfig[subSkillId]
|
||||||
|
if not subSkill then
|
||||||
|
-- CS.UnityEngine.Debug.LogError("subskill表中不存在技能" .. tostring(subSkillId))
|
||||||
|
return "Error"
|
||||||
|
end
|
||||||
|
|
||||||
|
---------子技能isAct技能
|
||||||
|
if subSkill.isAct then
|
||||||
|
local subSkillActSkill = skillConfig[subSkill.isAct]
|
||||||
|
if not subSkillActSkill then
|
||||||
|
-- CS.UnityEngine.Debug.LogError("skill表中不存在技能" .. tostring(subSkillId))
|
||||||
|
return "Error"
|
||||||
|
end
|
||||||
|
|
||||||
|
local changeEffects = subSkillActSkill.effect
|
||||||
|
if not changeEffects then
|
||||||
|
-- CS.UnityEngine.Debug.LogWarning("子技能isAct技能没有技能效果" .. tostring(skillid))
|
||||||
|
else
|
||||||
|
for _, changeEffect in ipairs(changeEffects) do
|
||||||
|
table.insert(skillCacheData,{
|
||||||
|
effect = {
|
||||||
|
type = changeEffect.type,
|
||||||
|
v = changeEffect.num,
|
||||||
|
p = changeEffect.ratio,
|
||||||
|
r = changeEffect.round,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
table.insert(skillRatioCacheData, subSkillActSkill.skillRatio or 0)
|
||||||
|
|
||||||
|
|
||||||
|
------------子技能isAct技能的子技能
|
||||||
|
local subIsActSkillSubSkillIds = subSkillActSkill.skillsub
|
||||||
|
if subIsActSkillSubSkillIds then
|
||||||
|
for _, subIsActSkillSubSkillId in ipairs(subIsActSkillSubSkillIds) do
|
||||||
|
local subIsActSkillSubSkill = subSkillConfig[subIsActSkillSubSkillId]
|
||||||
|
if not subIsActSkillSubSkill then
|
||||||
|
-- CS.UnityEngine.Debug.LogError("subskill表中不存在技能" .. tostring(subIsActSkillSubSkillId))
|
||||||
|
return "Error"
|
||||||
|
end
|
||||||
|
|
||||||
|
local changeEffects = subIsActSkillSubSkill.effect
|
||||||
|
if not changeEffects then
|
||||||
|
-- CS.UnityEngine.Debug.LogWarning("子技能isAct技能的子技能没有技能效果" .. tostring(skillid))
|
||||||
|
else
|
||||||
|
for _, changeEffect in ipairs(changeEffects) do
|
||||||
|
table.insert(skillCacheData,{
|
||||||
|
effect = {
|
||||||
|
type = changeEffect.type,
|
||||||
|
v = changeEffect.num,
|
||||||
|
p = changeEffect.ratio,
|
||||||
|
r = changeEffect.round,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
table.insert(skillRatioCacheData, subIsActSkillSubSkill.skillRatio or 0)
|
||||||
|
|
||||||
|
end
|
||||||
|
end
|
||||||
|
else
|
||||||
|
local subSkillEffects = subSkill.effect
|
||||||
|
if not subSkillEffects then
|
||||||
|
-- CS.UnityEngine.Debug.LogWarning("子技能没有技能效果" .. tostring(skillid))
|
||||||
|
else
|
||||||
|
----------子技能change技能
|
||||||
|
for _, subSkillEffect in ipairs(subSkillEffects) do
|
||||||
|
changeId = nil
|
||||||
|
if subSkillEffect.type == 'changeAtk' then
|
||||||
|
changeId = subSkillEffect.num
|
||||||
|
subSkillChangeAtkSkill = skillConfig[changeId]
|
||||||
|
cacheChange = subSkillChangeAtkSkill
|
||||||
|
if not subSkillChangeAtkSkill then
|
||||||
|
-- CS.UnityEngine.Debug.LogError("skill表中不存在技能" .. tostring(changeId))
|
||||||
|
return "Error"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if subSkillEffect.type == 'changeSkill' then
|
||||||
|
changeId = subSkillEffect.num
|
||||||
|
subSkillChangeSkillSkill = skillConfig[changeId]
|
||||||
|
cacheChange = subSkillChangeSkillSkill
|
||||||
|
if not subSkillChangeSkillSkill then
|
||||||
|
-- CS.UnityEngine.Debug.LogError("skill表中不存在技能" .. tostring(changeId))
|
||||||
|
return "Error"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if changeId then
|
||||||
|
local changeEffects = cacheChange.effect
|
||||||
|
if not changeEffects then
|
||||||
|
-- CS.UnityEngine.Debug.LogWarning("子技能change技能没有技能效果" .. tostring(skillid))
|
||||||
|
else
|
||||||
|
for _, changeEffect in ipairs(changeEffects) do
|
||||||
|
table.insert(skillCacheData,{
|
||||||
|
effect = {
|
||||||
|
type = changeEffect.type,
|
||||||
|
v = changeEffect.num,
|
||||||
|
p = changeEffect.ratio,
|
||||||
|
r = changeEffect.round,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
table.insert(skillRatioCacheData, cacheChange.skillRatio or 0)
|
||||||
|
|
||||||
|
---------子技能change技能的子技能
|
||||||
|
local subChangeFirstSubIds = cacheChange.skillSub
|
||||||
|
if subChangeFirstSubIds then
|
||||||
|
for _, subChangeFirstSubId in ipairs(subChangeFirstSubIds) do
|
||||||
|
local subChangeFirstSub = subSkillConfig[subChangeFirstSubId]
|
||||||
|
if not subChangeFirstSub then
|
||||||
|
-- CS.UnityEngine.Debug.LogError("subSkill表中不存在技能" .. tostring(subChangeFirstSubId))
|
||||||
|
return "Error"
|
||||||
|
end
|
||||||
|
|
||||||
|
local changeEffects = subChangeFirstSub.effect
|
||||||
|
if not changeEffects then
|
||||||
|
-- CS.UnityEngine.Debug.LogWarning("子技能change技能的子技能没有技能效果" .. tostring(skillid))
|
||||||
|
else
|
||||||
|
for _, changeEffect in ipairs(changeEffects) do
|
||||||
|
table.insert(skillCacheData,{
|
||||||
|
effect = {
|
||||||
|
type = changeEffect.type,
|
||||||
|
v = changeEffect.num,
|
||||||
|
p = changeEffect.ratio,
|
||||||
|
r = changeEffect.round,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
table.insert(skillRatioCacheData, subChangeFirstSub.skillRatio or 0)
|
||||||
|
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
--CS.UnityEngine.Debug.Log(tostring(skillid) .. "写入数据" .. #skillCacheData)
|
||||||
|
caCheTable[skillid] = skillCacheData
|
||||||
|
caCheRatioTable[skillid] = skillRatioCacheData
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
--匹配每个id然后替换内部字符串(保证原有顺序)
|
||||||
|
local result = string.gsub(str, "%[(%d+)%]=(%b{})", function (id, infoStr)
|
||||||
|
id = tonumber(id)
|
||||||
|
--CS.UnityEngine.Debug.LogError("id" .. tostring(id))
|
||||||
|
local returnStr = string.gsub(string.sub(infoStr, 2), "(%b{})",function(str)
|
||||||
|
local _flag = string.sub(str,2,-2)
|
||||||
|
local _index = string.find(_flag, '_')
|
||||||
|
local flag = string.sub(_flag,1 ,_index - 1)
|
||||||
|
local readFlag = string.sub(_flag,_index + 1)
|
||||||
|
local index = tonumber(flag)
|
||||||
|
|
||||||
|
if not caCheTable[id] then
|
||||||
|
CS.UnityEngine.Debug.LogError(tostring(id) .. "没有读取到数据 请对比多语言表和skill表" .. caCheTable[id])
|
||||||
|
return ""
|
||||||
|
end
|
||||||
|
|
||||||
|
--CS.UnityEngine.Debug.Log(flag .. " " .. readFlag)
|
||||||
|
|
||||||
|
if readFlag == 'v' then
|
||||||
|
if not index then
|
||||||
|
CS.UnityEngine.Debug.LogError(tostring(id) .. "{x_x}格式配置错误" .. " v")
|
||||||
|
return ""
|
||||||
|
end
|
||||||
|
|
||||||
|
if not caCheTable[id][index] then
|
||||||
|
CS.UnityEngine.Debug.LogError(tostring(id) .. "读取参数错误 或者 配置错误" .. "读取配置长度:" .. #caCheTable[id] .. "index: " .. index .. " v")
|
||||||
|
return ""
|
||||||
|
end
|
||||||
|
|
||||||
|
local isPercent = getBuffIsPercent(caCheTable[id][index].effect.type)
|
||||||
|
local num = math.abs(caCheTable[id][index].effect.v)
|
||||||
|
if isPercent then
|
||||||
|
num = math.floor(num / 10)
|
||||||
|
end
|
||||||
|
|
||||||
|
return tostring(num)
|
||||||
|
elseif readFlag == 'p' then
|
||||||
|
if string.sub(flag,1, 1) == "s" then
|
||||||
|
index = tonumber(string.sub(flag, 2))
|
||||||
|
if not index then
|
||||||
|
CS.UnityEngine.Debug.LogError(tostring(id) .. "{x_x}格式配置错误" .. " s")
|
||||||
|
return ""
|
||||||
|
end
|
||||||
|
|
||||||
|
if not caCheRatioTable[id][index] then
|
||||||
|
CS.UnityEngine.Debug.LogError(tostring(id) .. "读取参数错误 或者 配置错误" .. "读取配置长度:" .. #caCheRatioTable[id] .. "index: " .. index .. " p")
|
||||||
|
return ""
|
||||||
|
end
|
||||||
|
|
||||||
|
if not caCheRatioTable[id][index] then
|
||||||
|
CS.UnityEngine.Debug.LogError(tostring(id) .. "技能没有整体概率")
|
||||||
|
end
|
||||||
|
return math.floor((caCheRatioTable[id][index] or 0) / 10)
|
||||||
|
else
|
||||||
|
if not index then
|
||||||
|
CS.UnityEngine.Debug.LogError(tostring(id) .. "{x_x}格式配置错误" .. " s")
|
||||||
|
return ""
|
||||||
|
end
|
||||||
|
|
||||||
|
if not caCheTable[id][index] then
|
||||||
|
CS.UnityEngine.Debug.LogError(tostring(id) .. "读取参数错误 或者 配置错误" .. "读取配置长度:" .. #caCheTable[id] .. "index: " .. index .. " p")
|
||||||
|
return ""
|
||||||
|
end
|
||||||
|
|
||||||
|
return math.floor(caCheTable[id][index].effect.p / 10)
|
||||||
|
end
|
||||||
|
elseif readFlag == 'r' then
|
||||||
|
if not index then
|
||||||
|
CS.UnityEngine.Debug.LogError(tostring(id) .. "{x_x}格式配置错误" .. " r")
|
||||||
|
return ""
|
||||||
|
end
|
||||||
|
|
||||||
|
if not caCheTable[id][index] then
|
||||||
|
CS.UnityEngine.Debug.LogError(tostring(id) .. "读取参数错误 或者 配置错误" .. "读取配置长度:" .. #caCheTable[id] .. "index: " .. index .. " r")
|
||||||
|
return ""
|
||||||
|
end
|
||||||
|
|
||||||
|
return caCheTable[id][index].effect.r
|
||||||
|
else
|
||||||
|
CS.UnityEngine.Debug.LogError(tostring(id) .. "{x_x}格式配置错误" .. "后缀不是vpr")
|
||||||
|
return ""
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
|
||||||
|
return "[" .. tostring(id) .. "]={" .. returnStr
|
||||||
|
end)
|
||||||
|
|
||||||
|
return result
|
||||||
|
end
|
||||||
@ -0,0 +1,10 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 61cd7619fa40641459984f57ae4a5c9a
|
||||||
|
ScriptedImporter:
|
||||||
|
internalIDToNameTable: []
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
|
script: {fileID: 11500000, guid: 3b8b241bab4a4ac9a22fcce9c64f1242, type: 3}
|
||||||
8
Assets/Editor/BFOthersTools/GameSettingTools.meta
Normal file
8
Assets/Editor/BFOthersTools/GameSettingTools.meta
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 1a54160c0eb804f0d96dc3a001dfec79
|
||||||
|
folderAsset: yes
|
||||||
|
DefaultImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
@ -0,0 +1,32 @@
|
|||||||
|
using UnityEditor;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
namespace BFEditor
|
||||||
|
{
|
||||||
|
public class GameSettingWindow : EditorWindow {
|
||||||
|
// private bool NotchScreenSimulate = false;
|
||||||
|
|
||||||
|
private void Awake () {
|
||||||
|
// NotchScreenSimulate = PlayerPrefs.GetInt (BF.SafeAreaManager.NOTCH_SCREEN_SIMULATE, 0) == 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public GameSettingWindow () {
|
||||||
|
titleContent = new GUIContent ("游戏设置");
|
||||||
|
}
|
||||||
|
void OnGUI () {
|
||||||
|
// GUILayout.BeginHorizontal ("刘海屏模拟");
|
||||||
|
// bool isSimulate = EditorGUILayout.Toggle ("刘海屏模拟(Editor):", NotchScreenSimulate, GUILayout.Width (300));
|
||||||
|
// if (isSimulate != NotchScreenSimulate) {
|
||||||
|
// NotchScreenSimulate = isSimulate;
|
||||||
|
// PlayerPrefs.SetInt (BF.SafeAreaManager.NOTCH_SCREEN_SIMULATE, NotchScreenSimulate ? 1 : 0);
|
||||||
|
// Debug.Log ("Editor模式 刘海屏模拟是否开启:" + NotchScreenSimulate);
|
||||||
|
// }
|
||||||
|
// GUILayout.EndHorizontal ();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void ShowWindow () {
|
||||||
|
var window = GetWindow<GameSettingWindow> ();
|
||||||
|
window.Show ();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 1579ac829698449d7968ceb92f234af2
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
8
Assets/Editor/BFOthersTools/GameViewTools.meta
Normal file
8
Assets/Editor/BFOthersTools/GameViewTools.meta
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 32be2ef7dc03746e4a3fdd515faa1055
|
||||||
|
folderAsset: yes
|
||||||
|
DefaultImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
145
Assets/Editor/BFOthersTools/GameViewTools/GameViewEditor.cs
Normal file
145
Assets/Editor/BFOthersTools/GameViewTools/GameViewEditor.cs
Normal file
@ -0,0 +1,145 @@
|
|||||||
|
using System;
|
||||||
|
using System.Reflection;
|
||||||
|
using UnityEditor;
|
||||||
|
|
||||||
|
namespace BFEditor
|
||||||
|
{
|
||||||
|
public static class GameViewUtils
|
||||||
|
{
|
||||||
|
static object gameViewSizesInstance;
|
||||||
|
static MethodInfo getGroup;
|
||||||
|
|
||||||
|
static GameViewUtils()
|
||||||
|
{
|
||||||
|
var sizesType = typeof(Editor).Assembly.GetType("UnityEditor.GameViewSizes");
|
||||||
|
var singleType = typeof(ScriptableSingleton<>).MakeGenericType(sizesType);
|
||||||
|
var instanceProp = singleType.GetProperty("instance");
|
||||||
|
getGroup = sizesType.GetMethod("GetGroup");
|
||||||
|
gameViewSizesInstance = instanceProp.GetValue(null, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum GameViewSizeType
|
||||||
|
{
|
||||||
|
AspectRatio,
|
||||||
|
FixedResolution
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void SetSize(int index)
|
||||||
|
{
|
||||||
|
var gvWndType = typeof(Editor).Assembly.GetType("UnityEditor.GameView");
|
||||||
|
var selectedSizeIndexProp = gvWndType.GetProperty("selectedSizeIndex",
|
||||||
|
BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
|
||||||
|
var gvWnd = EditorWindow.GetWindow(gvWndType);
|
||||||
|
selectedSizeIndexProp.SetValue(gvWnd, index, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void AddCustomSize(int width, int height, string text = "")
|
||||||
|
{
|
||||||
|
AddCustomSize(GameViewSizeGroupType.Standalone, width, height, text);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void AddCustomSize(GameViewSizeGroupType sizeGroupType, int width, int height, string text)
|
||||||
|
{
|
||||||
|
AddCustomSize(GameViewSizeType.FixedResolution, sizeGroupType, width, height, text);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void AddCustomSize(GameViewSizeType viewSizeType, GameViewSizeGroupType sizeGroupType, int width, int height, string text)
|
||||||
|
{
|
||||||
|
var group = GetGroup(sizeGroupType);
|
||||||
|
var addCustomSize = getGroup.ReturnType.GetMethod("AddCustomSize");
|
||||||
|
var gvsType = typeof(Editor).Assembly.GetType("UnityEditor.GameViewSize");
|
||||||
|
var ctor = gvsType.GetConstructor(new Type[] { typeof(Editor).Assembly.GetType("UnityEditor.GameViewSizeType"),
|
||||||
|
typeof(int), typeof(int), typeof(string) });
|
||||||
|
var newGvsType = typeof(Editor).Assembly.GetType("UnityEditor.GameViewSizeType.FixedResolution");
|
||||||
|
if (viewSizeType == GameViewSizeType.AspectRatio)
|
||||||
|
newGvsType = typeof(Editor).Assembly.GetType("UnityEditor.GameViewSizeType.AspectRatio");
|
||||||
|
var newSize = ctor.Invoke(new object[] { newGvsType, width, height, text });
|
||||||
|
addCustomSize.Invoke(group, new object[] { newSize });
|
||||||
|
}
|
||||||
|
|
||||||
|
public static bool SizeExists(GameViewSizeGroupType sizeGroupType, string text)
|
||||||
|
{
|
||||||
|
return FindSize(sizeGroupType, text) != -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static bool SizeExists(int width, int height)
|
||||||
|
{
|
||||||
|
return SizeExists(GameViewSizeGroupType.Standalone, width, height);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static bool SizeExists(GameViewSizeGroupType sizeGroupType, int width, int height)
|
||||||
|
{
|
||||||
|
return FindSize(sizeGroupType, width, height) != -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int FindSize(GameViewSizeGroupType sizeGroupType, string text)
|
||||||
|
{
|
||||||
|
var group = GetGroup(sizeGroupType);
|
||||||
|
var getDisplayTexts = group.GetType().GetMethod("GetDisplayTexts");
|
||||||
|
var displayTexts = getDisplayTexts.Invoke(group, null) as string[];
|
||||||
|
for (int i = 0; i < displayTexts.Length; i++)
|
||||||
|
{
|
||||||
|
string display = displayTexts[i];
|
||||||
|
int pren = display.IndexOf('(');
|
||||||
|
if (pren != -1)
|
||||||
|
display = display.Substring(0, pren - 1);
|
||||||
|
if (display == text)
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int FindSize(int width, int height)
|
||||||
|
{
|
||||||
|
return FindSize(GameViewSizeGroupType.Standalone, width, height);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int FindSize(GameViewSizeGroupType sizeGroupType, int width, int height)
|
||||||
|
{
|
||||||
|
var group = GetGroup(sizeGroupType);
|
||||||
|
var groupType = group.GetType();
|
||||||
|
var getBuiltinCount = groupType.GetMethod("GetBuiltinCount");
|
||||||
|
var getCustomCount = groupType.GetMethod("GetCustomCount");
|
||||||
|
int sizesCount = (int)getBuiltinCount.Invoke(group, null) + (int)getCustomCount.Invoke(group, null);
|
||||||
|
var getGameViewSize = groupType.GetMethod("GetGameViewSize");
|
||||||
|
var gvsType = getGameViewSize.ReturnType;
|
||||||
|
var widthProp = gvsType.GetProperty("width");
|
||||||
|
var heightProp = gvsType.GetProperty("height");
|
||||||
|
var indexValue = new object[1];
|
||||||
|
for (int i = 0; i < sizesCount; i++)
|
||||||
|
{
|
||||||
|
indexValue[0] = i;
|
||||||
|
var size = getGameViewSize.Invoke(group, indexValue);
|
||||||
|
int sizeWidth = (int)widthProp.GetValue(size, null);
|
||||||
|
int sizeHeight = (int)heightProp.GetValue(size, null);
|
||||||
|
if (sizeWidth == width && sizeHeight == height)
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static object GetGroup(GameViewSizeGroupType type)
|
||||||
|
{
|
||||||
|
return getGroup.Invoke(gameViewSizesInstance, new object[] { (int)type });
|
||||||
|
}
|
||||||
|
|
||||||
|
public static GameViewSizeGroupType GetCurrentGroupType()
|
||||||
|
{
|
||||||
|
var getCurrentGroupTypeProp = gameViewSizesInstance.GetType().GetProperty("currentGroupType");
|
||||||
|
return (GameViewSizeGroupType)(int)getCurrentGroupTypeProp.GetValue(gameViewSizesInstance, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void GetCurrentGameViewSize(out int width, out int height)
|
||||||
|
{
|
||||||
|
var t = System.Type.GetType("UnityEditor.GameView,UnityEditor");
|
||||||
|
var getMainGameView = t.GetMethod("GetMainGameView", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Static);
|
||||||
|
var res = getMainGameView.Invoke(null, null);
|
||||||
|
var gameView = (UnityEditor.EditorWindow)res;
|
||||||
|
var prop = gameView.GetType().GetProperty("currentGameViewSize", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
|
||||||
|
var gvsize = prop.GetValue(gameView, new object[0] { });
|
||||||
|
var gvSizeType = gvsize.GetType();
|
||||||
|
height = (int)gvSizeType.GetProperty("height", System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance).GetValue(gvsize, new object[0] { });
|
||||||
|
width = (int)gvSizeType.GetProperty("width", System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance).GetValue(gvsize, new object[0] { });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 28b50fa1feeff4587a5083b06fc2c27b
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
107
Assets/Editor/BFOthersTools/OtherToolsMenu.cs
Normal file
107
Assets/Editor/BFOthersTools/OtherToolsMenu.cs
Normal file
@ -0,0 +1,107 @@
|
|||||||
|
using UnityEditor;
|
||||||
|
using System.IO;
|
||||||
|
using UnityEngine;
|
||||||
|
using BF;
|
||||||
|
|
||||||
|
namespace BFEditor
|
||||||
|
{
|
||||||
|
public static class OtherToolsMenu
|
||||||
|
{
|
||||||
|
[MenuItem("其他工具/账号/创建新号", false, 1)]
|
||||||
|
static public void ClearAccount()
|
||||||
|
{
|
||||||
|
BFLog.Log("创建新号 success!");
|
||||||
|
LocalData.SetInt("ACCOUNT", Random.Range(100000, 999999));
|
||||||
|
}
|
||||||
|
|
||||||
|
[MenuItem("其他工具/账号/切换账号", false, 2)]
|
||||||
|
static public void SelectAccont()
|
||||||
|
{
|
||||||
|
var window = (SelectAccontWindow)EditorWindow.GetWindowWithRect(typeof(SelectAccontWindow),
|
||||||
|
new Rect(Screen.width / 2, Screen.height / 2, 520, 750));
|
||||||
|
window.Show();
|
||||||
|
}
|
||||||
|
|
||||||
|
[MenuItem("其他工具/账号/清除数据(B5)", false, 3)]
|
||||||
|
static public void ClearGameData()
|
||||||
|
{
|
||||||
|
LocalData.SetString("LAST_LOGIN_INFO", "{}");
|
||||||
|
LocalData.SetString("SEND_QUEUE", "{}");
|
||||||
|
LocalData.SetString("SDK_UID", "");
|
||||||
|
LocalData.SetInt("LAST_MAIL_ID", 0);
|
||||||
|
BFLog.Log("清除数据成功 success!");
|
||||||
|
}
|
||||||
|
|
||||||
|
[MenuItem("其他工具/一键导表", false, 3)]
|
||||||
|
public static void ExportExcel()
|
||||||
|
{
|
||||||
|
var designExcelPath = ExportExcelTools.GetDesignExcelPath();
|
||||||
|
if (string.IsNullOrEmpty(designExcelPath) || !Directory.Exists(designExcelPath))
|
||||||
|
{
|
||||||
|
OpenClientExcelWindow();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var luaPath = Path.Combine(Application.dataPath, "Developer/lua/main.lua").Replace("\\", "/");
|
||||||
|
var isDev = File.Exists(luaPath);
|
||||||
|
|
||||||
|
EditorUtility.DisplayProgressBar("提示", "导表中", 1.0f);
|
||||||
|
bool succ = ExportExcelTools.FastExportExcelToLua(isDev, designExcelPath);
|
||||||
|
EditorUtility.ClearProgressBar();
|
||||||
|
if (succ)
|
||||||
|
{
|
||||||
|
EditorUtility.DisplayDialog("成功", "导出成功!", "ok");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
EditorUtility.DisplayDialog("失败", "导出失败!", "ok");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[MenuItem("其他工具/打开导表窗口", false, 4)]
|
||||||
|
public static void OpenClientExcelWindow()
|
||||||
|
{
|
||||||
|
var window = (ExportExcelWindow)EditorWindow.GetWindowWithRect(typeof(ExportExcelWindow),
|
||||||
|
new Rect(Screen.width / 2, Screen.height / 2, 500, 120), true);
|
||||||
|
window.Show();
|
||||||
|
}
|
||||||
|
|
||||||
|
[MenuItem("其他工具/生成pb配置", false, 5)]
|
||||||
|
static private void SetProtoGitPath()
|
||||||
|
{
|
||||||
|
SetProtoPathWindow.Init();
|
||||||
|
}
|
||||||
|
|
||||||
|
[MenuItem("其他工具/打开设置窗口", false, 6)]
|
||||||
|
static void OpenGameSettingMenu()
|
||||||
|
{
|
||||||
|
GameSettingWindow.ShowWindow();
|
||||||
|
}
|
||||||
|
|
||||||
|
[MenuItem("其他工具/批量大写转小写", false, 7)]
|
||||||
|
public static void OpenToggleCaseWindow()
|
||||||
|
{
|
||||||
|
var window = (ToggleCaseWindow)EditorWindow.GetWindowWithRect(typeof(ToggleCaseWindow),
|
||||||
|
new Rect(Screen.width / 2, Screen.height / 2, 500, 120), true);
|
||||||
|
window.Show();
|
||||||
|
}
|
||||||
|
|
||||||
|
[MenuItem("其他工具/截图", false, 8)]
|
||||||
|
public static void CaptureScreenshot()
|
||||||
|
{
|
||||||
|
var desktopDir = System.Environment.GetFolderPath(System.Environment.SpecialFolder.DesktopDirectory);
|
||||||
|
var path = System.IO.Path.Combine(desktopDir, "dz_screenshot_");
|
||||||
|
int index = 0;
|
||||||
|
while(true)
|
||||||
|
{
|
||||||
|
var screenshotPath = path + index.ToString() + ".png";
|
||||||
|
if (!File.Exists(screenshotPath))
|
||||||
|
{
|
||||||
|
UnityEngine.ScreenCapture.CaptureScreenshot(screenshotPath, 1);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
index++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
11
Assets/Editor/BFOthersTools/OtherToolsMenu.cs.meta
Normal file
11
Assets/Editor/BFOthersTools/OtherToolsMenu.cs.meta
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 69a27f872a3c94a48a03584d27a1d22b
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
8
Assets/Editor/BFOthersTools/Proto.meta
Normal file
8
Assets/Editor/BFOthersTools/Proto.meta
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 807a808622d8b48db998d49ca7687c87
|
||||||
|
folderAsset: yes
|
||||||
|
DefaultImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
173
Assets/Editor/BFOthersTools/Proto/GenProtoConfig.cs
Normal file
173
Assets/Editor/BFOthersTools/Proto/GenProtoConfig.cs
Normal file
@ -0,0 +1,173 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
using UnityEditor;
|
||||||
|
using UnityEngine;
|
||||||
|
using XLua;
|
||||||
|
using BF;
|
||||||
|
|
||||||
|
namespace BFEditor
|
||||||
|
{
|
||||||
|
public class GenProtoConfig
|
||||||
|
{
|
||||||
|
static private string ProtoToolDir = Application.dataPath + "/../Tools/proto";
|
||||||
|
static private string PbSaveDir = Application.dataPath + "/proto";
|
||||||
|
static private string LuaSaveDir = Application.dataPath + "/Developer/lua/app/proto/";
|
||||||
|
static private string MsgIdsProto = PbSaveDir + "/bf_msgids.bytes";
|
||||||
|
|
||||||
|
static public void GenProtoLuaConfig()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var protoPath = LocalData.GetProtoPath();
|
||||||
|
if (string.IsNullOrEmpty(protoPath) ||
|
||||||
|
!Directory.Exists(protoPath))
|
||||||
|
{
|
||||||
|
EditorUtility.DisplayDialog("提示", "没有正确配置Proto路径!", "确定");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
BFEditorUtils.RunCommond("python", ProtoToolDir + "/proto.py " + protoPath + " " + LuaSaveDir, ProtoToolDir,
|
||||||
|
(msg) =>
|
||||||
|
{
|
||||||
|
},
|
||||||
|
(err) =>
|
||||||
|
{
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
var dirInfo = new DirectoryInfo(protoPath);
|
||||||
|
var files = dirInfo.GetFiles("*.pb", SearchOption.AllDirectories);
|
||||||
|
for (var i = 0; i < files.Length; ++i)
|
||||||
|
{
|
||||||
|
var fileInfo = files[i];
|
||||||
|
|
||||||
|
var filePath = fileInfo.FullName;
|
||||||
|
|
||||||
|
var outPath = Path.Combine(PbSaveDir, filePath.Substring(protoPath.Length + 1)).Replace(".pb", ".bytes");
|
||||||
|
if (File.Exists(outPath))
|
||||||
|
{
|
||||||
|
var inMD5 = GameLaunchUtils.GetFileMD5(filePath);
|
||||||
|
var outMD5 = GameLaunchUtils.GetFileMD5(outPath);
|
||||||
|
if (inMD5.CompareTo(outMD5) == 0)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
File.Copy(filePath, outPath, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
// LuaEnv luaEnv = new LuaEnv();
|
||||||
|
// luaEnv.AddBuildin("pb", XLua.LuaDLL.Lua.LoadLuaProfobuf);
|
||||||
|
// luaEnv.DoString(@"allNames = {}");
|
||||||
|
// var pbFullName = MsgIdsProto;
|
||||||
|
// var pbPath = BF.Utils.GetAssetPathByFullPath(pbFullName);
|
||||||
|
// var luaText = CreateLuaString(pbPath);
|
||||||
|
// luaEnv.DoString(luaText);
|
||||||
|
// var luaDir = LuaSaveDir;
|
||||||
|
// if (!Directory.Exists(luaDir))
|
||||||
|
// Directory.CreateDirectory(luaDir);
|
||||||
|
// var luaPath = luaDir + "protomsgtype.lua";
|
||||||
|
// luaEnv.DoString(SaveLuaFile(luaPath));
|
||||||
|
// luaEnv.Dispose();
|
||||||
|
// AssetDatabase.ImportAsset(pbPath);
|
||||||
|
// AssetDatabase.Refresh();
|
||||||
|
// AssetDatabase.DeleteAsset(pbPath);
|
||||||
|
// Proto2MarkDown.Pb2Markdown();
|
||||||
|
EditorUtility.DisplayDialog("提示", "生成Proto配置成功!", "确定");
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static private string CreateLuaString(string protoPath)
|
||||||
|
{
|
||||||
|
var lua =
|
||||||
|
@"
|
||||||
|
local pb = require 'pb'
|
||||||
|
assert(pb.loadfile '" + protoPath + @"')
|
||||||
|
|
||||||
|
local function split(input, delimiter)
|
||||||
|
input = tostring(input)
|
||||||
|
delimiter = tostring(delimiter)
|
||||||
|
if (delimiter=='') then return false end
|
||||||
|
local pos,arr = 0, {}
|
||||||
|
-- for each divider found
|
||||||
|
for st,sp in function() return string.find(input, delimiter, pos, true) end do
|
||||||
|
table.insert(arr, string.sub(input, pos, st - 1))
|
||||||
|
pos = sp + 1
|
||||||
|
end
|
||||||
|
table.insert(arr, string.sub(input, pos))
|
||||||
|
return arr
|
||||||
|
end
|
||||||
|
|
||||||
|
local function unique(number)
|
||||||
|
for _,info in ipairs(allNames) do
|
||||||
|
if info.number == number then
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
|
||||||
|
for name, number, type in pb.fields 'MsgId' do
|
||||||
|
-- print(name, number)
|
||||||
|
if number > 0 and unique(number) then
|
||||||
|
table.insert(allNames, {number = number, name = name})
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
table.sort(allNames, function(a, b)
|
||||||
|
return a.number < b.number
|
||||||
|
end)
|
||||||
|
";
|
||||||
|
return lua;
|
||||||
|
}
|
||||||
|
|
||||||
|
static private string SaveLuaFile(string luaPath)
|
||||||
|
{
|
||||||
|
var lua =
|
||||||
|
@"
|
||||||
|
local output = 'local ProtoMsgType = {\n'
|
||||||
|
|
||||||
|
output = output .. ' FromMsgId = {\n'
|
||||||
|
for i, info in ipairs(allNames) do
|
||||||
|
output = output .. ' ' .. '[' .. info.number .. ']' .. ' = \'' .. info.name .. '\',\n'
|
||||||
|
end
|
||||||
|
output = output .. ' },\n'
|
||||||
|
|
||||||
|
output = output .. ' FromMsgToId = {\n'
|
||||||
|
for i, info in ipairs(allNames) do
|
||||||
|
output = output .. ' ' .. info.name .. ' = ' .. info.number .. ',\n'
|
||||||
|
end
|
||||||
|
output = output .. ' },\n'
|
||||||
|
|
||||||
|
output = output .. ' FromMsgEnum = {\n'
|
||||||
|
for i, info in ipairs(allNames) do
|
||||||
|
output = output .. ' ' .. 'req' .. info.name .. ' = \'' .. 'req' .. info.name .. '\',\n'
|
||||||
|
output = output .. ' ' .. 'rsp' .. info.name .. ' = \'' .. 'rsp' .. info.name .. '\',\n'
|
||||||
|
end
|
||||||
|
output = output .. ' },\n'
|
||||||
|
|
||||||
|
output = output .. '}\n\n'
|
||||||
|
output = output .. 'return ProtoMsgType'
|
||||||
|
|
||||||
|
local file = assert(io.open('" + luaPath + @"', 'w'))
|
||||||
|
file:write(output)
|
||||||
|
file:close()
|
||||||
|
|
||||||
|
-- print(output)
|
||||||
|
";
|
||||||
|
|
||||||
|
return lua;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
11
Assets/Editor/BFOthersTools/Proto/GenProtoConfig.cs.meta
Normal file
11
Assets/Editor/BFOthersTools/Proto/GenProtoConfig.cs.meta
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: b2e14ac9a8ffe44499a899210e24e80e
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
654
Assets/Editor/BFOthersTools/Proto/Proto2Markdown.cs
Normal file
654
Assets/Editor/BFOthersTools/Proto/Proto2Markdown.cs
Normal file
@ -0,0 +1,654 @@
|
|||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System;
|
||||||
|
using System.IO;
|
||||||
|
using BF;
|
||||||
|
|
||||||
|
namespace BFEditor
|
||||||
|
{
|
||||||
|
public class ProtoEnum
|
||||||
|
{
|
||||||
|
public string enumName = "";
|
||||||
|
public int enumNum = 0;
|
||||||
|
public int moduleId = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public class ProtoModule
|
||||||
|
{
|
||||||
|
public string moduleDesc = "";
|
||||||
|
public int moduleNum = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public class ProtoMessage
|
||||||
|
{
|
||||||
|
public string commentStr = "";
|
||||||
|
public string messageName = "";
|
||||||
|
public List<ProtoField> fields = new List<ProtoField>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public class ProtoStruct
|
||||||
|
{
|
||||||
|
public string typeName = "";
|
||||||
|
public List<ProtoField> fields = new List<ProtoField>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public class ProtoField
|
||||||
|
{
|
||||||
|
public string commentStr = "";
|
||||||
|
public string fieldName = "";
|
||||||
|
public string typeName = "";
|
||||||
|
public bool isRepeated = false;
|
||||||
|
|
||||||
|
public bool isMap = false;
|
||||||
|
public string keyTypeName = "";
|
||||||
|
public string valueTypeName = "";
|
||||||
|
}
|
||||||
|
|
||||||
|
public class Proto2MarkDown
|
||||||
|
{
|
||||||
|
const string COMMENT_CONST = "comment = ";
|
||||||
|
const string MESSAGE_NAME_CONST = "message_name = ";
|
||||||
|
const string MARKDOWN_FILE_NAME = "/bf_proto.md";
|
||||||
|
|
||||||
|
static string[] TYPE_KEYWORDS = new string[] { "uint32", "int32", "uint64", "int64", "string", "bool" };
|
||||||
|
|
||||||
|
static string MarkdownPath { get { return LocalData.GetProtoPath(); } }
|
||||||
|
|
||||||
|
static string MsgIdsProtoPath { get { return LocalData.GetProtoPath() + "/bf_msgids.proto"; } }
|
||||||
|
static string CommonProtoPath { get { return LocalData.GetProtoPath() + "/bf_comm.proto"; } }
|
||||||
|
static string LogicProtoPath { get { return LocalData.GetProtoPath() + "/bf_logic.proto"; } }
|
||||||
|
static string BattleProtoPath { get { return LocalData.GetProtoPath() + "/bf_battle.proto"; } }
|
||||||
|
static string protoMessageCommentStr = COMMENT_CONST;
|
||||||
|
static string protoStructTypeNameStr = "";
|
||||||
|
|
||||||
|
static StringBuilder sb = new StringBuilder();
|
||||||
|
|
||||||
|
static bool readingProtoEnum = false;
|
||||||
|
static bool readingProtoMessage = false;
|
||||||
|
static bool readingProtoStruct = false;
|
||||||
|
static List<ProtoEnum> protoEnums = new List<ProtoEnum>();
|
||||||
|
static List<ProtoModule> protoModules = new List<ProtoModule>();
|
||||||
|
static List<ProtoMessage> protoMessages = new List<ProtoMessage>();
|
||||||
|
static List<ProtoStruct> protoStructs = new List<ProtoStruct>();
|
||||||
|
static List<int> moduleIds = new List<int>();
|
||||||
|
|
||||||
|
public static bool Pb2Markdown()
|
||||||
|
{
|
||||||
|
protoEnums.Clear();
|
||||||
|
protoModules.Clear();
|
||||||
|
protoMessages.Clear();
|
||||||
|
protoStructs.Clear();
|
||||||
|
moduleIds.Clear();
|
||||||
|
|
||||||
|
if (string.IsNullOrEmpty(MsgIdsProtoPath) || string.IsNullOrEmpty(CommonProtoPath) ||
|
||||||
|
string.IsNullOrEmpty(LogicProtoPath) || string.IsNullOrEmpty(MarkdownPath) || string.IsNullOrEmpty(BattleProtoPath))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
ParsingEnum();
|
||||||
|
ParsingLogic();
|
||||||
|
ParsingCommon();
|
||||||
|
ParsingBattle();
|
||||||
|
SortEnum();
|
||||||
|
Export2Markdown();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ParsingEnum()
|
||||||
|
{
|
||||||
|
var reader = new StreamReader(new FileStream(MsgIdsProtoPath, FileMode.Open));
|
||||||
|
var logicLineStr = "";
|
||||||
|
while ((logicLineStr = reader.ReadLine()) != null)
|
||||||
|
{
|
||||||
|
if (logicLineStr == "")
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (logicLineStr == "enum MsgId")
|
||||||
|
{
|
||||||
|
readingProtoEnum = true;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (readingProtoEnum)
|
||||||
|
{
|
||||||
|
if (logicLineStr == "{")
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (logicLineStr == "}")
|
||||||
|
{
|
||||||
|
readingProtoEnum = false;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
ReadProtoEnum(logicLineStr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
reader.Close();
|
||||||
|
reader.Dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ParsingLogic()
|
||||||
|
{
|
||||||
|
var reader = new StreamReader(new FileStream(LogicProtoPath, FileMode.Open));
|
||||||
|
var logicLineStr = "";
|
||||||
|
while ((logicLineStr = reader.ReadLine()) != null)
|
||||||
|
{
|
||||||
|
if (logicLineStr == "")
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (logicLineStr.Replace(" ", "").Replace("\t", "").StartsWith("//") && logicLineStr.Contains("========"))
|
||||||
|
{
|
||||||
|
ReadProtoModule(logicLineStr);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (logicLineStr.Replace(" ", "").Replace("\t", "").StartsWith("//"))
|
||||||
|
{
|
||||||
|
protoMessageCommentStr = protoMessageCommentStr + logicLineStr.Replace("//", " ");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (logicLineStr.Replace(" ", "").Replace("\t", "").StartsWith("message"))
|
||||||
|
{
|
||||||
|
readingProtoMessage = true;
|
||||||
|
|
||||||
|
sb.AppendLine(protoMessageCommentStr);
|
||||||
|
protoMessageCommentStr = COMMENT_CONST;
|
||||||
|
string messageName = MESSAGE_NAME_CONST + logicLineStr.Replace(" ", "").Replace("\t", "").Replace("message", "").Replace("{", "");
|
||||||
|
sb.AppendLine(messageName);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (readingProtoMessage)
|
||||||
|
{
|
||||||
|
if (logicLineStr.Replace(" ", "").Replace("\t", "") == "}")
|
||||||
|
{
|
||||||
|
ReadProtoMessage(sb);
|
||||||
|
readingProtoMessage = false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
sb.AppendLine(logicLineStr);
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
reader.Close();
|
||||||
|
reader.Dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ReadProtoEnum(string enumStr)
|
||||||
|
{
|
||||||
|
enumStr = enumStr.Replace(" ", "").Replace("\t", "");
|
||||||
|
enumStr = enumStr.Replace(";", "");
|
||||||
|
var index = enumStr.IndexOf("//");
|
||||||
|
if (index > 0)
|
||||||
|
{
|
||||||
|
enumStr = enumStr.Remove(index, enumStr.Length - index);
|
||||||
|
}
|
||||||
|
|
||||||
|
var equalIndex = enumStr.IndexOf("=");
|
||||||
|
var name = enumStr.Substring(0, equalIndex);
|
||||||
|
var num = Int32.Parse(enumStr.Substring(equalIndex + 1, enumStr.Length - equalIndex - 1));
|
||||||
|
|
||||||
|
var pe = new ProtoEnum();
|
||||||
|
pe.enumName = name;
|
||||||
|
pe.enumNum = num;
|
||||||
|
var moduleKey = (num - (num % 1000)) / 1000;
|
||||||
|
pe.moduleId = moduleKey;
|
||||||
|
|
||||||
|
protoEnums.Add(pe);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ReadProtoModule(string moduleStr)
|
||||||
|
{
|
||||||
|
moduleStr = moduleStr.Replace(" ", "").Replace("\t", "");
|
||||||
|
moduleStr = moduleStr.Replace("=", "");
|
||||||
|
moduleStr = moduleStr.Replace("//", "");
|
||||||
|
|
||||||
|
var pm = new ProtoModule();
|
||||||
|
pm.moduleDesc = moduleStr;
|
||||||
|
var num = Int32.Parse(System.Text.RegularExpressions.Regex.Replace(moduleStr, @"[^0-9]+", ""));
|
||||||
|
pm.moduleNum = num;
|
||||||
|
moduleIds.Add(num);
|
||||||
|
protoModules.Add(pm);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ReadProtoMessage(StringBuilder sb)
|
||||||
|
{
|
||||||
|
var message = sb.ToString();
|
||||||
|
var lines = message.Split(new char[] { '\n' });
|
||||||
|
var pm = new ProtoMessage();
|
||||||
|
foreach (var line in lines)
|
||||||
|
{
|
||||||
|
if (line == "")
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (line.Contains(COMMENT_CONST))
|
||||||
|
{
|
||||||
|
pm.commentStr = line.Replace(COMMENT_CONST, "");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (line.Contains(MESSAGE_NAME_CONST))
|
||||||
|
{
|
||||||
|
pm.messageName = line.Replace(MESSAGE_NAME_CONST, "");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
var pf = GetProtoField(line);
|
||||||
|
pm.fields.Add(pf);
|
||||||
|
}
|
||||||
|
|
||||||
|
protoMessages.Add(pm);
|
||||||
|
sb.Clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void SortEnum()
|
||||||
|
{
|
||||||
|
protoEnums.Sort((x, y) => { return x.enumNum - y.enumNum; });
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ParsingCommon()
|
||||||
|
{
|
||||||
|
var reader = new StreamReader(new FileStream(CommonProtoPath, FileMode.Open));
|
||||||
|
var commonLineStr = "";
|
||||||
|
while ((commonLineStr = reader.ReadLine()) != null)
|
||||||
|
{
|
||||||
|
if (commonLineStr == "")
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (commonLineStr.Replace(" ", "").Replace("\t", "").StartsWith("message"))
|
||||||
|
{
|
||||||
|
protoStructTypeNameStr = commonLineStr.Replace(" ", "").Replace("\t", "").Replace("message", "").Replace("{", "");
|
||||||
|
readingProtoStruct = true;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (readingProtoStruct)
|
||||||
|
{
|
||||||
|
if (commonLineStr.Replace(" ", "").Replace("\t", "") == "}")
|
||||||
|
{
|
||||||
|
ReadProtoStruct(sb, protoStructTypeNameStr);
|
||||||
|
protoStructTypeNameStr = "";
|
||||||
|
readingProtoStruct = false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
sb.AppendLine(commonLineStr);
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
reader.Close();
|
||||||
|
reader.Dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ParsingBattle()
|
||||||
|
{
|
||||||
|
var reader = new StreamReader(new FileStream(BattleProtoPath, FileMode.Open));
|
||||||
|
var lineStr = "";
|
||||||
|
while ((lineStr = reader.ReadLine()) != null)
|
||||||
|
{
|
||||||
|
if (lineStr == "")
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (lineStr.Replace(" ", "").Replace("\t", "").StartsWith("message"))
|
||||||
|
{
|
||||||
|
protoStructTypeNameStr = lineStr.Replace(" ", "").Replace("\t", "").Replace("message", "").Replace("{", "");
|
||||||
|
readingProtoStruct = true;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (readingProtoStruct)
|
||||||
|
{
|
||||||
|
if (lineStr.Replace(" ", "").Replace("\t", "") == "}")
|
||||||
|
{
|
||||||
|
ReadProtoStruct(sb, protoStructTypeNameStr);
|
||||||
|
protoStructTypeNameStr = "";
|
||||||
|
readingProtoStruct = false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
sb.AppendLine(lineStr);
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
reader.Close();
|
||||||
|
reader.Dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ReadProtoStruct(StringBuilder sb, string structName)
|
||||||
|
{
|
||||||
|
var ps = new ProtoStruct();
|
||||||
|
ps.typeName = structName;
|
||||||
|
var message = sb.ToString();
|
||||||
|
var lines = message.Split(new char[] { '\n' });
|
||||||
|
foreach (var line in lines)
|
||||||
|
{
|
||||||
|
if (line == "")
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
ProtoField pf = GetProtoField(line);
|
||||||
|
ps.fields.Add(pf);
|
||||||
|
}
|
||||||
|
sb.Clear();
|
||||||
|
protoStructs.Add(ps);
|
||||||
|
}
|
||||||
|
|
||||||
|
static ProtoField GetProtoField(string fieldLine)
|
||||||
|
{
|
||||||
|
var pf = new ProtoField(); // 解析filed
|
||||||
|
if (fieldLine.Replace(" ", "").Replace("\t", "").StartsWith("repeated"))
|
||||||
|
{
|
||||||
|
pf.isRepeated = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fieldLine.Contains("//"))
|
||||||
|
{
|
||||||
|
var index1 = fieldLine.IndexOf("//");
|
||||||
|
var comment = fieldLine.Substring(index1, fieldLine.Length - index1);
|
||||||
|
pf.commentStr = comment;
|
||||||
|
}
|
||||||
|
|
||||||
|
var index2 = fieldLine.IndexOf("=");
|
||||||
|
var fieldStr = fieldLine.Remove(index2).Replace("repeated", "");
|
||||||
|
if (fieldStr.Replace(" ", "").Replace("\t", "").StartsWith("map<")) // map结构
|
||||||
|
{
|
||||||
|
pf.isMap = true;
|
||||||
|
|
||||||
|
var index3 = fieldStr.IndexOf(">") + 1;
|
||||||
|
var fieldName = fieldStr.Substring(index3, fieldStr.Length - index3).Replace(" ", "").Replace("\t", "");
|
||||||
|
pf.fieldName = fieldName;
|
||||||
|
|
||||||
|
var keyValueStr = fieldStr.Replace("map<", "").Replace(">", "").Replace(fieldName, "").Replace(" ", "").Replace("\t", "");
|
||||||
|
var index4 = keyValueStr.IndexOf(",");
|
||||||
|
var keyName = keyValueStr.Substring(0, index4);
|
||||||
|
pf.keyTypeName = keyName;
|
||||||
|
|
||||||
|
var vauleName = keyValueStr.Substring(index4 + 1, keyValueStr.Length - index4 - 1);
|
||||||
|
pf.valueTypeName = vauleName.Replace(" ", "").Replace("\t", "");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
while (fieldStr.Contains(" ")) // 这个处理不好
|
||||||
|
{
|
||||||
|
fieldStr = fieldStr.Replace(" ", " ");
|
||||||
|
}
|
||||||
|
|
||||||
|
var typeFiledNameStr = fieldStr.Split(new char[] { ' ' });
|
||||||
|
foreach (var item in typeFiledNameStr)
|
||||||
|
{
|
||||||
|
if (item == "")
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (pf.typeName == "")
|
||||||
|
{
|
||||||
|
pf.typeName = item.Replace(" ", "").Replace("\t", "");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
pf.fieldName = item;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return pf;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void Export2Markdown()
|
||||||
|
{
|
||||||
|
var sw = new StreamWriter(MarkdownPath + MARKDOWN_FILE_NAME, false);
|
||||||
|
WriteTitle(sw);
|
||||||
|
WriteProtoModule(sw);
|
||||||
|
WriteProtoEnum(sw);
|
||||||
|
WriteProtoMessage(sw);
|
||||||
|
WriteProtoStructs(sw);
|
||||||
|
sw.Close();
|
||||||
|
sw.Dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void WriteTitle(StreamWriter sw)
|
||||||
|
{
|
||||||
|
sw.WriteLine("# *BF协议文档*");
|
||||||
|
sw.WriteLine(" ");
|
||||||
|
sw.WriteLine("<I><B>Auto Generated By: </B></I>");
|
||||||
|
sw.WriteLine(" ");
|
||||||
|
sw.WriteLine("bf_logic.proto (协议描述文件)\n");
|
||||||
|
sw.WriteLine("bf_comm.proto、bf_battle.proto (结构体描述文件)\n");
|
||||||
|
sw.WriteLine("bf_msgids.proto(协议枚举描述文件)\n");
|
||||||
|
sw.WriteLine(" ");
|
||||||
|
sw.WriteLine("<I><B>文档分为四部分:</B></I>\n");
|
||||||
|
sw.WriteLine("[功能模块](#一)、[协议枚举](#二)、[消息内容](#三)、[自定义结构体](#四)");
|
||||||
|
sw.WriteLine(" ");
|
||||||
|
sw.WriteLine("req: 前端请求, rsp: 服务器应答");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void WriteProtoModule(StreamWriter sw)
|
||||||
|
{
|
||||||
|
sw.WriteLine(" ");
|
||||||
|
sw.WriteLine("## " + GetHtmlLink("top") + GetHtmlLink("一") + "第一部分 模块");
|
||||||
|
foreach (var item in protoModules)
|
||||||
|
{
|
||||||
|
sw.WriteLine(" - [" + "模块id: " + item.moduleNum + " // " + item.moduleDesc + "]" + "(#" + item.moduleNum + ")");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void WriteProtoEnum(StreamWriter sw)
|
||||||
|
{
|
||||||
|
sw.WriteLine(" ");
|
||||||
|
sw.WriteLine("## " + GetHtmlLink("二") + "第二部分 ProtoEnum");
|
||||||
|
|
||||||
|
var moduleId = protoEnums[0].moduleId;
|
||||||
|
sw.WriteLine("### " + GetHtmlLink(moduleId.ToString()) + "模块" + moduleId + " // " + GetModuleDesc(moduleId));
|
||||||
|
|
||||||
|
foreach (var item in protoEnums)
|
||||||
|
{
|
||||||
|
if (item.moduleId != moduleId)
|
||||||
|
{
|
||||||
|
moduleId = item.moduleId;
|
||||||
|
sw.WriteLine("### " + GetHtmlLink(moduleId.ToString()) + "模块" + moduleId + " // " + GetModuleDesc(moduleId));
|
||||||
|
}
|
||||||
|
sw.WriteLine("> - [" + item.enumName + " = " + item.enumNum + "]" + "(#" + item.enumName + ")");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static string GetModuleDesc(int key)
|
||||||
|
{
|
||||||
|
foreach (var item in protoModules)
|
||||||
|
{
|
||||||
|
if (item.moduleNum == key)
|
||||||
|
{
|
||||||
|
return item.moduleDesc;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
static void WriteProtoMessage(StreamWriter sw)
|
||||||
|
{
|
||||||
|
sw.WriteLine(" ");
|
||||||
|
sw.WriteLine("## " + GetHtmlLink("三") + "第三部分 ProtoMessage");
|
||||||
|
|
||||||
|
foreach (var item in protoEnums)
|
||||||
|
{
|
||||||
|
var rspPM = GetRspMessage(item.enumName);
|
||||||
|
var reqPM = GetReqMessage(item.enumName);
|
||||||
|
if (rspPM == null && reqPM == null)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
string comment = "";
|
||||||
|
if (reqPM != null && reqPM.commentStr != "")
|
||||||
|
{
|
||||||
|
comment = reqPM.commentStr;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
comment = rspPM.commentStr;
|
||||||
|
}
|
||||||
|
|
||||||
|
sw.WriteLine("## " + "__" + GetHtmlLink(item.enumName) + "消息 " + item.enumName + " //" + comment + "__");
|
||||||
|
|
||||||
|
WriteProtoMessage(sw, reqPM, "req : ");
|
||||||
|
sw.WriteLine(" ");
|
||||||
|
|
||||||
|
WriteProtoMessage(sw, rspPM, "rsp : ");
|
||||||
|
sw.WriteLine(" ");
|
||||||
|
|
||||||
|
DrawTopBtn(sw);
|
||||||
|
|
||||||
|
sw.WriteLine("<br>");
|
||||||
|
sw.WriteLine("<br>");
|
||||||
|
sw.WriteLine(" ");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static ProtoMessage GetRspMessage(string enumName)
|
||||||
|
{
|
||||||
|
const string RSP = "rsp";
|
||||||
|
foreach (var item in protoMessages)
|
||||||
|
{
|
||||||
|
if (item.messageName == RSP + enumName)
|
||||||
|
{
|
||||||
|
return item;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
static ProtoMessage GetReqMessage(string enumName)
|
||||||
|
{
|
||||||
|
const string REQ = "req";
|
||||||
|
foreach (var item in protoMessages)
|
||||||
|
{
|
||||||
|
if (item.messageName == REQ + enumName)
|
||||||
|
{
|
||||||
|
return item;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void WriteProtoMessage(StreamWriter sw, ProtoMessage pm, string title)
|
||||||
|
{
|
||||||
|
if (pm == null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
sw.WriteLine("### " + title);
|
||||||
|
sw.WriteLine(" ");
|
||||||
|
|
||||||
|
WriteTableTitle(sw);
|
||||||
|
|
||||||
|
foreach (var item in pm.fields)
|
||||||
|
{
|
||||||
|
WriteField(sw, item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void WriteTableTitle(StreamWriter sw)
|
||||||
|
{
|
||||||
|
sw.WriteLine("| repeated | 类型 | 字段名 | 注释 |");
|
||||||
|
sw.WriteLine("| :------------ | :------------ | :------------ | :------------ |");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void WriteField(StreamWriter sw, ProtoField pf)
|
||||||
|
{
|
||||||
|
var str = "| ";
|
||||||
|
if (pf.isRepeated)
|
||||||
|
{
|
||||||
|
str = str + "repeated |";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
str = str + " |";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pf.isMap)
|
||||||
|
{
|
||||||
|
str = str + "map< " + GetTypeMarkdownStr(pf.keyTypeName) + " , " + GetTypeMarkdownStr(pf.valueTypeName) + "> |";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
str = str + GetTypeMarkdownStr(pf.typeName) + " |";
|
||||||
|
}
|
||||||
|
|
||||||
|
str = str + pf.fieldName + " |";
|
||||||
|
str = str + pf.commentStr + " |";
|
||||||
|
sw.WriteLine(str);
|
||||||
|
}
|
||||||
|
|
||||||
|
static string GetTypeMarkdownStr(string typeName)
|
||||||
|
{
|
||||||
|
if (TYPE_KEYWORDS.Contains(typeName))
|
||||||
|
{
|
||||||
|
return typeName;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return "[" + typeName + "]" + "(#TYPE_" + typeName + ")";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void WriteProtoStructs(StreamWriter sw)
|
||||||
|
{
|
||||||
|
sw.WriteLine(" ");
|
||||||
|
sw.WriteLine("## " + GetHtmlLink("四") + "第四部分 结构体");
|
||||||
|
|
||||||
|
foreach (var item in protoStructs)
|
||||||
|
{
|
||||||
|
WriteStruct(sw, item);
|
||||||
|
sw.WriteLine(" ");
|
||||||
|
|
||||||
|
DrawTopBtn(sw);
|
||||||
|
|
||||||
|
sw.WriteLine("<br>");
|
||||||
|
sw.WriteLine(" ");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void WriteStruct(StreamWriter sw, ProtoStruct ps)
|
||||||
|
{
|
||||||
|
sw.WriteLine("### " + "__" + GetHtmlLink("TYPE_" + ps.typeName) + "结构体 " + ps.typeName + "__");
|
||||||
|
WriteTableTitle(sw);
|
||||||
|
|
||||||
|
foreach (var item in ps.fields)
|
||||||
|
{
|
||||||
|
WriteField(sw, item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static string GetHtmlLink(string name)
|
||||||
|
{
|
||||||
|
return "<a name = \"" + name + "\" />";
|
||||||
|
}
|
||||||
|
|
||||||
|
static void DrawTopBtn(StreamWriter sw)
|
||||||
|
{
|
||||||
|
sw.WriteLine("<p align=\"right\"><a href=\"#top\"><I><U>回到顶部</U></I></a></p>");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
11
Assets/Editor/BFOthersTools/Proto/Proto2Markdown.cs.meta
Normal file
11
Assets/Editor/BFOthersTools/Proto/Proto2Markdown.cs.meta
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 650672beb37524be48d29378a03dc403
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
51
Assets/Editor/BFOthersTools/Proto/SetProtoPathWindow.cs
Normal file
51
Assets/Editor/BFOthersTools/Proto/SetProtoPathWindow.cs
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
using System;
|
||||||
|
using BF;
|
||||||
|
using UnityEditor;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
namespace BFEditor
|
||||||
|
{
|
||||||
|
public class SetProtoPathWindow : EditorWindow
|
||||||
|
{
|
||||||
|
[SerializeField]
|
||||||
|
private string protoPath;
|
||||||
|
|
||||||
|
private SerializedObject serializedObject;
|
||||||
|
private SerializedProperty protoPathProperty;
|
||||||
|
|
||||||
|
static public void Init()
|
||||||
|
{
|
||||||
|
GetWindowWithRect<SetProtoPathWindow>(new Rect(Screen.width / 2, Screen.height / 2, 500, 120), true, "生成pb配置", true);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnEnable()
|
||||||
|
{
|
||||||
|
protoPath = LocalData.GetProtoPath();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnGUI()
|
||||||
|
{
|
||||||
|
GUILayout.Space(18);
|
||||||
|
GUILayout.BeginHorizontal();
|
||||||
|
GUILayout.Label("选择pb路径");
|
||||||
|
GUILayout.TextField(protoPath, GUILayout.Width(300));
|
||||||
|
if (GUILayout.Button("选择", GUILayout.Width(80)))
|
||||||
|
{
|
||||||
|
protoPath = EditorUtility.OpenFolderPanel("select pb path", Application.dataPath, "");
|
||||||
|
LocalData.SetProtoPath(protoPath);
|
||||||
|
}
|
||||||
|
GUILayout.EndHorizontal();
|
||||||
|
GUILayout.Space(10);
|
||||||
|
|
||||||
|
GUILayout.BeginHorizontal();
|
||||||
|
GUILayout.Space(190);
|
||||||
|
if (GUILayout.Button("生成", GUILayout.Width(110), GUILayout.Height(20)))
|
||||||
|
{
|
||||||
|
GenProtoConfig.GenProtoLuaConfig();
|
||||||
|
Close();
|
||||||
|
}
|
||||||
|
GUILayout.EndHorizontal();
|
||||||
|
GUILayout.Space(10);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
11
Assets/Editor/BFOthersTools/Proto/SetProtoPathWindow.cs.meta
Normal file
11
Assets/Editor/BFOthersTools/Proto/SetProtoPathWindow.cs.meta
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: ae69bc069d48f4c488fc99b1bb13515e
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
8
Assets/Editor/BFResourceTools.meta
Normal file
8
Assets/Editor/BFResourceTools.meta
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 12676a38fe8394ad1812c197c969e95f
|
||||||
|
folderAsset: yes
|
||||||
|
DefaultImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
@ -0,0 +1,8 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: cffea037edbd1470eba49e2f3ea704e6
|
||||||
|
folderAsset: yes
|
||||||
|
DefaultImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
@ -0,0 +1,115 @@
|
|||||||
|
using System;
|
||||||
|
using System.Linq;
|
||||||
|
using System.IO;
|
||||||
|
using UnityEngine;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
namespace BFEditor.Resource
|
||||||
|
{
|
||||||
|
public class DependenciesCheckTool
|
||||||
|
{
|
||||||
|
static bool checkedOver = true;
|
||||||
|
|
||||||
|
public static bool CheckedOver
|
||||||
|
{
|
||||||
|
get{return checkedOver;}
|
||||||
|
private set{}
|
||||||
|
}
|
||||||
|
|
||||||
|
static Dictionary<string, List<string>> abnormalDependenciesDic = new Dictionary<string, List<string>>();
|
||||||
|
|
||||||
|
public static Dictionary<string, List<string>> AbnormalDependenciesDic
|
||||||
|
{
|
||||||
|
get{return abnormalDependenciesDic;}
|
||||||
|
private set{}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static List<BaseDependenciesChecker> GetAllCheckers()
|
||||||
|
{
|
||||||
|
var result = new List<BaseDependenciesChecker>()
|
||||||
|
{
|
||||||
|
new AnimationDependenciesChecker(),
|
||||||
|
new AtlasDependenciesChecker(),
|
||||||
|
new BakedataDependenciesChecker(),
|
||||||
|
new EffectDependenciesChecker(),
|
||||||
|
new FirstDependenciesChecker(),
|
||||||
|
new FontDependenciesChecker(),
|
||||||
|
new LanguageDependenciesChecker(),
|
||||||
|
new LuaDependenciesChecker(),
|
||||||
|
new MaterialDependenciesChecker(),
|
||||||
|
new ModelDependenciesChecker(),
|
||||||
|
new ShaderDependenciesChecker(),
|
||||||
|
new ShakeDependenciesChecker(),
|
||||||
|
new SkyboxDependenciesChecker(),
|
||||||
|
new SoundDependenciesChecker(),
|
||||||
|
new SpineDependenciesChecker(),
|
||||||
|
new TextureDependenciesChecker(),
|
||||||
|
new TimelineDependenciesChecker(),
|
||||||
|
new VideoDependenciesChecker(),
|
||||||
|
new EffectPrefabDependenciesChecker(),
|
||||||
|
new TimelinePrefabDependenciesChecker(),
|
||||||
|
new SpritePrefabDependenciesChecker(),
|
||||||
|
new OtherPrefabDependenciesChecker(),
|
||||||
|
new ModelPrefabDependenciesChecker(),
|
||||||
|
new SpinePrefabDependenciesChecker(),
|
||||||
|
new CityPrefabDependenciesChecker(),
|
||||||
|
};
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
public static void Clear()
|
||||||
|
{
|
||||||
|
checkedOver = false;
|
||||||
|
abnormalDependenciesDic.Clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
static AssetBundleManifest GetManifest()
|
||||||
|
{
|
||||||
|
var streamPath = Path.Combine(Application.streamingAssetsPath, "asset_bundle_manifest.ab");
|
||||||
|
if (!File.Exists(streamPath))
|
||||||
|
{
|
||||||
|
Debug.LogError("文件不存在 " + streamPath);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
var assetBundle = AssetBundle.LoadFromFile(streamPath);
|
||||||
|
var manifest = assetBundle.LoadAsset<AssetBundleManifest>("AssetBundleManifest");
|
||||||
|
assetBundle.Unload(false);
|
||||||
|
return manifest;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Dictionary<string, List<string>> CheckDependenceies(Action<bool> checkOverAction = null, List<BaseDependenciesChecker> allCheckers = null)
|
||||||
|
{
|
||||||
|
if(allCheckers == null)
|
||||||
|
{
|
||||||
|
allCheckers = GetAllCheckers();
|
||||||
|
}
|
||||||
|
checkedOver = false;
|
||||||
|
abnormalDependenciesDic.Clear();
|
||||||
|
AssetBundleManifest manifest = GetManifest();
|
||||||
|
string[] allBundles = manifest.GetAllAssetBundles();
|
||||||
|
foreach(var bundle in allBundles)
|
||||||
|
{
|
||||||
|
List<string> abnormalDependencies = new List<string>();
|
||||||
|
string[] allDependencies = manifest.GetDirectDependencies(bundle);
|
||||||
|
foreach(BaseDependenciesChecker checker in allCheckers)
|
||||||
|
{
|
||||||
|
if(checker.Active && bundle.Contains(checker.GetCheckPathPrefix()))
|
||||||
|
{
|
||||||
|
abnormalDependencies = checker.GetAbnormalDenpendencies(bundle, allDependencies);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(abnormalDependencies.Count > 0)
|
||||||
|
{
|
||||||
|
abnormalDependenciesDic.Add(bundle, abnormalDependencies);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
checkedOver = true;
|
||||||
|
|
||||||
|
if(checkOverAction != null)
|
||||||
|
{
|
||||||
|
checkOverAction(abnormalDependenciesDic.Keys.Count <= 0);
|
||||||
|
}
|
||||||
|
return abnormalDependenciesDic;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 515c1de9b00c9426786aabdfd22cab0c
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
@ -0,0 +1,129 @@
|
|||||||
|
using System.IO;
|
||||||
|
using System;
|
||||||
|
using UnityEditor;
|
||||||
|
using UnityEngine;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Text.RegularExpressions;
|
||||||
|
|
||||||
|
namespace BFEditor.Resource
|
||||||
|
{
|
||||||
|
public class DependenciesCheckWindow : EditorWindow
|
||||||
|
{
|
||||||
|
Vector2 scrollPosition = new Vector2(100, 100);
|
||||||
|
Action<bool> checkOverAction;
|
||||||
|
List<BaseDependenciesChecker> allChekers = new List<BaseDependenciesChecker>();
|
||||||
|
DependenciesCheckWindow()
|
||||||
|
{
|
||||||
|
this.titleContent = new GUIContent("资源依赖检查");
|
||||||
|
|
||||||
|
DependenciesCheckTool.Clear();
|
||||||
|
foreach(var checker in DependenciesCheckTool.GetAllCheckers())
|
||||||
|
{
|
||||||
|
allChekers.Add(checker);
|
||||||
|
}
|
||||||
|
checkOverAction = (bool result) =>
|
||||||
|
{
|
||||||
|
if (result)
|
||||||
|
{
|
||||||
|
EditorUtility.DisplayDialog("提示", "检查完成,符合标准", "ok");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
void OnGUI()
|
||||||
|
{
|
||||||
|
DrawButton();
|
||||||
|
DrawResult();
|
||||||
|
}
|
||||||
|
|
||||||
|
void DrawButton()
|
||||||
|
{
|
||||||
|
int count = allChekers.Count;
|
||||||
|
int column = (int)Math.Ceiling(count / 6.0); //900 / 150 = 6
|
||||||
|
for(int i = 0; i < column; i++)
|
||||||
|
{
|
||||||
|
GUILayout.BeginHorizontal();
|
||||||
|
for(int j = 0; j < 6; j++)
|
||||||
|
{
|
||||||
|
int curIndex = i*6 + j;
|
||||||
|
if(curIndex < count)
|
||||||
|
{
|
||||||
|
allChekers[curIndex].Active = GUILayout.Toggle(allChekers[curIndex].Active, allChekers[curIndex].GetCheckerName(), GUILayout.Width(150));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
GUILayout.EndHorizontal();
|
||||||
|
}
|
||||||
|
GUILayout.Space(15);
|
||||||
|
var style = new GUIStyle(GUI.skin.button);
|
||||||
|
style.fontSize = 15;
|
||||||
|
style.alignment = TextAnchor.MiddleCenter;
|
||||||
|
GUILayout.BeginHorizontal();
|
||||||
|
if (GUILayout.Button("检查所选", style, GUILayout.Width(100), GUILayout.Height(26)))
|
||||||
|
{
|
||||||
|
CheckAll();
|
||||||
|
}
|
||||||
|
if (GUILayout.Button("全选", style, GUILayout.Width(100), GUILayout.Height(26)))
|
||||||
|
{
|
||||||
|
for(int i = 0; i < allChekers.Count; i++)
|
||||||
|
{
|
||||||
|
allChekers[i].Active = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (GUILayout.Button("取消全选", style, GUILayout.Width(100), GUILayout.Height(26)))
|
||||||
|
{
|
||||||
|
for(int i = 0; i < allChekers.Count; i++)
|
||||||
|
{
|
||||||
|
allChekers[i].Active = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
GUILayout.EndHorizontal();
|
||||||
|
GUILayout.Space(15);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CheckAll()
|
||||||
|
{
|
||||||
|
DependenciesCheckTool.CheckDependenceies(checkOverAction, allChekers);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DrawResult()
|
||||||
|
{
|
||||||
|
if(DependenciesCheckTool.CheckedOver)
|
||||||
|
{
|
||||||
|
GUILayout.BeginHorizontal();
|
||||||
|
GUILayout.Label("AB包", GUILayout.Width(450));
|
||||||
|
GUILayout.Label("不正常依赖", GUILayout.Width(450));
|
||||||
|
GUILayout.EndHorizontal();
|
||||||
|
scrollPosition = GUILayout.BeginScrollView(
|
||||||
|
scrollPosition, GUILayout.Width(900), GUILayout.Height(800));
|
||||||
|
Dictionary<string, List<string>> abnormalDependenciesDic = DependenciesCheckTool.AbnormalDependenciesDic;
|
||||||
|
foreach(string bundle in abnormalDependenciesDic.Keys)
|
||||||
|
{
|
||||||
|
GUILayout.BeginHorizontal();
|
||||||
|
GUILayout.TextField(bundle, GUILayout.Width(450));
|
||||||
|
GUILayout.BeginVertical();
|
||||||
|
foreach(string dependent in abnormalDependenciesDic[bundle])
|
||||||
|
{
|
||||||
|
GUILayout.TextField(dependent);
|
||||||
|
}
|
||||||
|
GUILayout.EndVertical();
|
||||||
|
GUILayout.EndHorizontal();
|
||||||
|
GUILayout.Label("", GUILayout.Width(100));
|
||||||
|
}
|
||||||
|
GUILayout.EndScrollView();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void OnDestroy()
|
||||||
|
{
|
||||||
|
DependenciesCheckTool.Clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void ShowDependenciesCheckWindow()
|
||||||
|
{
|
||||||
|
var window = (DependenciesCheckWindow)GetWindowWithRect(typeof(DependenciesCheckWindow),
|
||||||
|
new Rect(Screen.width / 2, Screen.height / 2, 900, 800));
|
||||||
|
window.Show();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: be22ae29ea89c48a4aef87591310355f
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
@ -0,0 +1,8 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: b685029cb42e8460d8f87b5c7c3c749a
|
||||||
|
folderAsset: yes
|
||||||
|
DefaultImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
@ -0,0 +1,26 @@
|
|||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using UnityEngine;
|
||||||
|
using UnityEditor;
|
||||||
|
|
||||||
|
namespace BFEditor.Resource
|
||||||
|
{
|
||||||
|
public class AnimationDependenciesChecker:BaseDependenciesChecker
|
||||||
|
{
|
||||||
|
public override string GetCheckerName()
|
||||||
|
{
|
||||||
|
return "animation";
|
||||||
|
}
|
||||||
|
public override string GetCheckPathPrefix()
|
||||||
|
{
|
||||||
|
return "arts/animations/";
|
||||||
|
}
|
||||||
|
public override string[] GetWhitePath()
|
||||||
|
{
|
||||||
|
string[] whitePath = {
|
||||||
|
"arts/shader"
|
||||||
|
};
|
||||||
|
return whitePath;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 0dfe73973c2db425ebcfc80e020b777b
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
@ -0,0 +1,19 @@
|
|||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using UnityEngine;
|
||||||
|
using UnityEditor;
|
||||||
|
|
||||||
|
namespace BFEditor.Resource
|
||||||
|
{
|
||||||
|
public class AtlasDependenciesChecker:BaseDependenciesChecker
|
||||||
|
{
|
||||||
|
public override string GetCheckerName()
|
||||||
|
{
|
||||||
|
return "atlas";
|
||||||
|
}
|
||||||
|
public override string GetCheckPathPrefix()
|
||||||
|
{
|
||||||
|
return "arts/textures/";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 163c9129f106c44a2871ef6d71360a52
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
@ -0,0 +1,19 @@
|
|||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using UnityEngine;
|
||||||
|
using UnityEditor;
|
||||||
|
|
||||||
|
namespace BFEditor.Resource
|
||||||
|
{
|
||||||
|
public class BakedataDependenciesChecker : BaseDependenciesChecker
|
||||||
|
{
|
||||||
|
public override string GetCheckerName()
|
||||||
|
{
|
||||||
|
return "bakedatas";
|
||||||
|
}
|
||||||
|
public override string GetCheckPathPrefix()
|
||||||
|
{
|
||||||
|
return "arts/bakedatas/";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 2e8683017a542454cb341262a3228d09
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
@ -0,0 +1,88 @@
|
|||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using UnityEngine;
|
||||||
|
using UnityEditor;
|
||||||
|
|
||||||
|
namespace BFEditor.Resource
|
||||||
|
{
|
||||||
|
public abstract class BaseDependenciesChecker
|
||||||
|
{
|
||||||
|
private bool active = true;
|
||||||
|
public bool Active{
|
||||||
|
get{return active;}
|
||||||
|
set{active = value;}
|
||||||
|
}
|
||||||
|
public List<string> GetAbnormalDenpendencies(string bundleName, string[] allDependencies)
|
||||||
|
{
|
||||||
|
// 第一次筛选
|
||||||
|
List<string> abnormalDependencies = new List<string>();
|
||||||
|
foreach(var dependent in allDependencies)
|
||||||
|
{
|
||||||
|
bool skip = false;
|
||||||
|
foreach(var whiteItem in GetWhitePath())
|
||||||
|
{
|
||||||
|
if(dependent.Contains(whiteItem))
|
||||||
|
{
|
||||||
|
skip = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(skip)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
abnormalDependencies.Add(dependent);
|
||||||
|
}
|
||||||
|
// 第二次筛选
|
||||||
|
List<string> subWhiteList = GetDetailWhitePath(bundleName);
|
||||||
|
for (var i = abnormalDependencies.Count - 1; i >= 0; i--)
|
||||||
|
{
|
||||||
|
foreach(var v in subWhiteList)
|
||||||
|
{
|
||||||
|
if(abnormalDependencies[i].Contains(v))
|
||||||
|
{
|
||||||
|
abnormalDependencies.RemoveAt(i);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
OnCheck(bundleName, ref abnormalDependencies);
|
||||||
|
return abnormalDependencies;
|
||||||
|
}
|
||||||
|
protected List<string> GetDetailWhitePath(string bundleName)
|
||||||
|
{
|
||||||
|
Dictionary<string, List<string>> detailWhiteDic = GetDetailWhiteDic();
|
||||||
|
List<string> subWhiteList = new List<string>();
|
||||||
|
foreach(var k in detailWhiteDic.Keys)
|
||||||
|
{
|
||||||
|
if(bundleName.Contains(k))
|
||||||
|
{
|
||||||
|
subWhiteList = detailWhiteDic[k];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return subWhiteList;
|
||||||
|
}
|
||||||
|
public abstract string GetCheckerName();
|
||||||
|
public abstract string GetCheckPathPrefix();
|
||||||
|
public virtual string[] GetWhitePath()
|
||||||
|
{
|
||||||
|
string[] whitePath = {
|
||||||
|
// "xxxxxxxx",
|
||||||
|
};
|
||||||
|
return whitePath;
|
||||||
|
}
|
||||||
|
protected virtual Dictionary<string, List<string>> GetDetailWhiteDic()
|
||||||
|
{
|
||||||
|
Dictionary<string, List<string>> detailWhiteDic = new Dictionary<string, List<string>>(){
|
||||||
|
// {"prefabs/effects/underground_palace",
|
||||||
|
// new List<string>(){
|
||||||
|
// "prefabs/effects/underground_palace"
|
||||||
|
// }
|
||||||
|
// },
|
||||||
|
};
|
||||||
|
return detailWhiteDic;
|
||||||
|
}
|
||||||
|
public virtual void OnCheck(string bundleName, ref List<string> allDependencies){}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 77fa6b6732d9c472a8b8644fe220d28f
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
@ -0,0 +1,32 @@
|
|||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using UnityEngine;
|
||||||
|
using UnityEditor;
|
||||||
|
|
||||||
|
namespace BFEditor.Resource
|
||||||
|
{
|
||||||
|
public class CityPrefabDependenciesChecker:BaseDependenciesChecker
|
||||||
|
{
|
||||||
|
public override string GetCheckerName()
|
||||||
|
{
|
||||||
|
return "city-prefab";
|
||||||
|
}
|
||||||
|
public override string GetCheckPathPrefix()
|
||||||
|
{
|
||||||
|
return "prefabs/city/";
|
||||||
|
}
|
||||||
|
public override string[] GetWhitePath()
|
||||||
|
{
|
||||||
|
string[] whitePath = {
|
||||||
|
"arts/animations/ui/city",
|
||||||
|
"arts/effects/ui",
|
||||||
|
"arts/materials.ab",
|
||||||
|
"arts/textures/ui/city_build.ab",
|
||||||
|
"arts/spines/",
|
||||||
|
"arts/textures/ui/common.ab",
|
||||||
|
"prefabs/effects/ui_effect/ui_citybox.prefab.ab"
|
||||||
|
};
|
||||||
|
return whitePath;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 69f05f71cd08d44029be100bf6213091
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
@ -0,0 +1,27 @@
|
|||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using UnityEngine;
|
||||||
|
using UnityEditor;
|
||||||
|
|
||||||
|
namespace BFEditor.Resource
|
||||||
|
{
|
||||||
|
public class EffectDependenciesChecker:BaseDependenciesChecker
|
||||||
|
{
|
||||||
|
public override string GetCheckerName()
|
||||||
|
{
|
||||||
|
return "effects";
|
||||||
|
}
|
||||||
|
public override string GetCheckPathPrefix()
|
||||||
|
{
|
||||||
|
return "arts/effects/";
|
||||||
|
}
|
||||||
|
public override string[] GetWhitePath()
|
||||||
|
{
|
||||||
|
string[] whitePath = {
|
||||||
|
"arts/shader",
|
||||||
|
"arts/effects/common/textures/"
|
||||||
|
};
|
||||||
|
return whitePath;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 700c8a9c522664901af6e320a1d1c659
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
@ -0,0 +1,85 @@
|
|||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using UnityEngine;
|
||||||
|
using UnityEditor;
|
||||||
|
|
||||||
|
namespace BFEditor.Resource
|
||||||
|
{
|
||||||
|
public class EffectPrefabDependenciesChecker:BaseDependenciesChecker
|
||||||
|
{
|
||||||
|
public override string GetCheckerName()
|
||||||
|
{
|
||||||
|
return "effect-prefab";
|
||||||
|
}
|
||||||
|
public override string GetCheckPathPrefix()
|
||||||
|
{
|
||||||
|
return "prefabs/effects/";
|
||||||
|
}
|
||||||
|
public override string[] GetWhitePath()
|
||||||
|
{
|
||||||
|
string[] whitePath = {
|
||||||
|
"arts/materials.ab",
|
||||||
|
"arts/textures/",
|
||||||
|
"arts/shader",
|
||||||
|
"arts/effects/common/",
|
||||||
|
};
|
||||||
|
return whitePath;
|
||||||
|
}
|
||||||
|
protected override Dictionary<string, List<string>> GetDetailWhiteDic()
|
||||||
|
{
|
||||||
|
Dictionary<string, List<string>> detailWhiteDic = new Dictionary<string, List<string>>(){
|
||||||
|
{"prefabs/effects/battle_effects/",
|
||||||
|
new List<string>(){
|
||||||
|
"arts/effects/ui/ui_battle.ab",
|
||||||
|
"arts/effects/battle"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{"prefabs/effects/ui",
|
||||||
|
new List<string>(){
|
||||||
|
"arts/effects/ui"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{"prefabs/effects/card_effects/",
|
||||||
|
new List<string>(){
|
||||||
|
"arts/effects/card_ui",
|
||||||
|
"arts/effects/card/"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{"prefabs/effects/underground_palace",
|
||||||
|
new List<string>(){
|
||||||
|
"arts/effects/underground_palace/",
|
||||||
|
"arts/models/maps/underground_palace"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{"prefabs/effects/city_build_effects/city_build_teardown",
|
||||||
|
new List<string>(){
|
||||||
|
"arts/effects/city_build/city_build_teardown",
|
||||||
|
}
|
||||||
|
},
|
||||||
|
};
|
||||||
|
return detailWhiteDic;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void OnCheck(string bundleName, ref List<string> abnormalDependencies)
|
||||||
|
{
|
||||||
|
List<string> dependencies = new List<string>();
|
||||||
|
string[] strs = bundleName.Split('/');
|
||||||
|
string name = strs[strs.Length - 1].Replace(".prefab.ab", string.Empty);
|
||||||
|
foreach(var dependent in abnormalDependencies)
|
||||||
|
{
|
||||||
|
if(dependent.Contains(name))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
strs = dependent.Split('/');
|
||||||
|
string dependentName = strs[strs.Length - 1].Replace(".ab", string.Empty);
|
||||||
|
if(name.Contains(dependentName))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
dependencies.Add(dependent);
|
||||||
|
}
|
||||||
|
abnormalDependencies = dependencies;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: afa3da188d9eb45a7a120eabbdb9c795
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
@ -0,0 +1,26 @@
|
|||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using UnityEngine;
|
||||||
|
using UnityEditor;
|
||||||
|
|
||||||
|
namespace BFEditor.Resource
|
||||||
|
{
|
||||||
|
public class FirstDependenciesChecker:BaseDependenciesChecker
|
||||||
|
{
|
||||||
|
public override string GetCheckerName()
|
||||||
|
{
|
||||||
|
return "first";
|
||||||
|
}
|
||||||
|
public override string GetCheckPathPrefix()
|
||||||
|
{
|
||||||
|
return "first/";
|
||||||
|
}
|
||||||
|
public override string[] GetWhitePath()
|
||||||
|
{
|
||||||
|
string[] whitePath = {
|
||||||
|
"arts/shaders.ab",
|
||||||
|
};
|
||||||
|
return whitePath;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 7c82727ddb650443ca5fdc8425851cdb
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
@ -0,0 +1,26 @@
|
|||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using UnityEngine;
|
||||||
|
using UnityEditor;
|
||||||
|
|
||||||
|
namespace BFEditor.Resource
|
||||||
|
{
|
||||||
|
public class FontDependenciesChecker:BaseDependenciesChecker
|
||||||
|
{
|
||||||
|
public override string GetCheckerName()
|
||||||
|
{
|
||||||
|
return "fonts";
|
||||||
|
}
|
||||||
|
public override string GetCheckPathPrefix()
|
||||||
|
{
|
||||||
|
return "arts/fonts/";
|
||||||
|
}
|
||||||
|
public override string[] GetWhitePath()
|
||||||
|
{
|
||||||
|
string[] whitePath = {
|
||||||
|
"arts/shader"
|
||||||
|
};
|
||||||
|
return whitePath;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: c3fe49f6cdc7a44d38ad732f7386f081
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
@ -0,0 +1,26 @@
|
|||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using UnityEngine;
|
||||||
|
using UnityEditor;
|
||||||
|
|
||||||
|
namespace BFEditor.Resource
|
||||||
|
{
|
||||||
|
public class LanguageDependenciesChecker:BaseDependenciesChecker
|
||||||
|
{
|
||||||
|
public override string GetCheckerName()
|
||||||
|
{
|
||||||
|
return "language";
|
||||||
|
}
|
||||||
|
public override string GetCheckPathPrefix()
|
||||||
|
{
|
||||||
|
return "arts/language/";
|
||||||
|
}
|
||||||
|
public override string[] GetWhitePath()
|
||||||
|
{
|
||||||
|
string[] whitePath = {
|
||||||
|
"arts/shader"
|
||||||
|
};
|
||||||
|
return whitePath;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user