提交 62a72d98 编写于 作者: L linxinfa

UnityXFramework

上级
此差异已折叠。
此差异已折叠。
此差异已折叠。
fileFormatVersion: 2
guid: d06de972e3ddd454e800bdc2880c1c2d
folderAsset: yes
timeCreated: 1494416338
licenseType: Pro
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:
fileFormatVersion: 2
guid: cbe5031e6dec8364a9d886e51d702749
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
using System.IO;
public class BuildApp : EditorWindow
{
[MenuItem("Build/打包APP")]
public static void ShowWin()
{
var win = GetWindow<BuildApp>();
win.Show();
}
private void Awake()
{
m_versionGUI = new VersionGUI();
m_versionGUI.Awake();
}
private void OnGUI()
{
m_versionGUI.DrawVersion();
DrawBuildApp();
}
private void DrawBuildApp()
{
if (GUILayout.Button("Build APP"))
{
// 生成原始lua全量文件的md5
BuildUtils.GenOriginalLuaFrameworkMD5File();
// 打AssetBundle
BuildAssetBundle.Build();
// 打包APP
BuildUtils.BuildApp();
}
if (GUILayout.Button("Build AssetBundle"))
{
// 打AssetBundle
BuildAssetBundle.Build();
}
}
private VersionGUI m_versionGUI;
}
fileFormatVersion: 2
guid: 4ca2aaaed15cc0f4c9e5d70018a6662d
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
using UnityEngine;
using UnityEditor;
public class BuildAssetBundle
{
public static void Build()
{
string targetPath = Application.streamingAssetsPath + "/res";
BuildUtils.BuildLuaBundle(targetPath);
GameLogger.LogGreen("BuildLuaBundle Done");
BuildUtils.BuildNormalCfgBundle(targetPath);
GameLogger.LogGreen("BuildNormalCfgBundle Done");
BuildUtils.BuildGameResBundle(targetPath);
GameLogger.LogGreen("BuildGameResBundle Done");
}
}
fileFormatVersion: 2
guid: 96f7130badd155d4595f0339d51bc37f
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
using System.IO;
using LitJson;
public class BuildUtils
{
/// <summary>
/// 递归遍历获取目标目录中的所有文件
/// </summary>
/// <param name="sourceDir">目标目录</param>
/// <param name="splitAssetPath">是否要切割目录,以Assets目录为根</param>
public static List<string> GetFiles(string sourceDir, bool splitAssetPath)
{
List<string> fileList = new List<string>();
string[] fs = Directory.GetFiles(sourceDir);
string[] ds = Directory.GetDirectories(sourceDir);
for (int i = 0, len = fs.Length; i < len; ++i)
{
var index = splitAssetPath ? fs[i].IndexOf("Assets") : 0;
fileList.Add(fs[i].Substring(index));
}
for (int i = 0, len = ds.Length; i < len; ++i)
{
fileList.AddRange(GetFiles(ds[i], splitAssetPath));
}
return fileList;
}
public static List<string> GetFiles(string[] sourceDirs, bool splitAssetPath)
{
List<string> fileList = new List<string>();
foreach (var sourceDir in sourceDirs)
{
fileList.AddRange(GetFiles(sourceDir, splitAssetPath));
}
return fileList;
}
/// <summary>
/// 根据哈希表构建AssetBundleBuild列表
/// </summary>
/// <param name="tb">哈希表,key为assetBundleName,value为目录</param>
/// <returns></returns>
public static AssetBundleBuild[] MakeAssetBundleBuildArray(Hashtable tb)
{
AssetBundleBuild[] buildArray = new AssetBundleBuild[tb.Count];
int index = 0;
foreach (string key in tb.Keys)
{
buildArray[index].assetBundleName = key;
List<string> fileList = new List<string>();
fileList = GetFiles(Application.dataPath + "/" + tb[key], true);
buildArray[index].assetNames = fileList.ToArray();
++index;
}
return buildArray;
}
/// <summary>
/// 打包常规配置表AssetBundle
/// </summary>
public static void BuildNormalCfgBundle(string targetPath)
{
Hashtable tb = new Hashtable();
tb["normal_cfg.bundle"] = "GameRes/Config";
AssetBundleBuild[] buildArray = BuildUtils.MakeAssetBundleBuildArray(tb);
BuildUtils.BuildBundles(buildArray, targetPath);
}
/// <summary>
/// 打包Lua的AssetBundle
/// </summary>
public static void BuildLuaBundle(string targetPath)
{
// 创建Lua的Bundle临时目录
var luabundleDir = BuildUtils.CreateTmpDir("luabundle");
// 将Lua代码拷贝到Bundle临时目录(做加密处理)
var luaFiles = BuildUtils.GetFiles(new string[] {
Application.dataPath + "/LuaFramework/Lua",
Application.dataPath + "/LuaFramework/ToLua/Lua",
}, true);
BuildUtils.CopyLuaToBundleDir(luaFiles, luabundleDir);
// 构建AssetBundleBuild列表
Hashtable tb = new Hashtable();
tb["lua.bundle"] = "luabundle";
AssetBundleBuild[] buildArray = MakeAssetBundleBuildArray(tb);
// 打包AssetBundle
BuildBundles(buildArray, targetPath);
// 删除Lua的Bundle临时目录
DeleteDir(luabundleDir);
AssetDatabase.Refresh();
}
/// <summary>
/// 打包游戏资源AssetBundle
/// </summary>
public static void BuildGameResBundle(string targetPath)
{
Hashtable tb = new Hashtable();
tb["baseres.bundle"] = "GameRes/BaseRes";
tb["uiprefabs.bundle"] = "GameRes/UIPrefabs";
tb["atlas.bundle"] = "GameRes/Atlas";
tb["effects.bundle"] = "GameRes/Effects";
tb["3d.bundle"] = "GameRes/3D";
tb["font.bundle"] = "GameRes/Font";
AssetBundleBuild[] buildArray = MakeAssetBundleBuildArray(tb);
BuildBundles(buildArray, targetPath);
}
/// <summary>
/// 打AssetBundle
/// </summary>
/// <param name="buildArray">AssetBundleBuild列表</param>
public static void BuildBundles(AssetBundleBuild[] buildArray, string targetPath)
{
if (!Directory.Exists(targetPath))
{
Directory.CreateDirectory(targetPath);
}
BuildPipeline.BuildAssetBundles(targetPath, buildArray, BuildAssetBundleOptions.ChunkBasedCompression, GetBuildTarget());
}
public static void BuildApp()
{
string[] scenes = new string[] { "Assets/Scenes/Main.unity" };
string appName = PlayerSettings.productName + "_" + VersionMgr.instance.appVersion + GetTargetPlatfromAppPostfix();
string outputPath = Application.dataPath + "/../Bin/";
if (!Directory.Exists(outputPath))
{
Directory.CreateDirectory(outputPath);
}
string appPath = Path.Combine(outputPath, appName);
// 根据你的需求设置各种版本号
// PlayerSettings.Android.bundleVersionCode
// PlayerSettings.bundleVersion
// PlayerSettings.iOS.buildNumber
BuildPipeline.BuildPlayer(scenes, appPath, GetBuildTarget(), BuildOptions.None);
GameLogger.Log("Build APP Done");
}
/// <summary>
/// 生成原始lua代码的md5
/// </summary>
public static void GenOriginalLuaFrameworkMD5File()
{
VersionMgr.instance.Init();
JsonData jd = GetOriginalLuaframeworkMD5Json();
var jsonStr = JsonMapper.ToJson(jd);
jsonStr = jsonStr.Replace(",", ",\n");
if (!Directory.Exists(BIN_PATH))
{
Directory.CreateDirectory(BIN_PATH);
}
using (StreamWriter sw = new StreamWriter(BIN_PATH + "LuaFrameworkFiles_" + VersionMgr.instance.appVersion + ".json"))
{
sw.Write(jsonStr);
}
GameLogger.Log("GenLuaframeworkMd5 Done");
}
public static JsonData GetOriginalLuaframeworkMD5Json()
{
var sourceDirs = new string[] {
Application.dataPath + "/LuaFramework/Lua",
Application.dataPath + "/LuaFramework/ToLua/Lua",
};
JsonData jd = new JsonData();
foreach (var sourceDir in sourceDirs)
{
List<string> fileList = new List<string>();
fileList = GetFiles(sourceDir, false);
foreach (var luaFile in fileList)
{
if (!luaFile.EndsWith(".lua")) continue;
var md5 = LuaFramework.Util.md5file(luaFile);
var key = luaFile.Substring(luaFile.IndexOf("Assets/"));
jd[key] = md5;
}
}
return jd;
}
/// <summary>
/// 创建临时目录
/// </summary>
/// <returns></returns>
public static string CreateTmpDir(string dirName)
{
var tmpDir = string.Format(Application.dataPath + "/{0}/", dirName);
if (Directory.Exists(tmpDir))
{
Directory.Delete(tmpDir, true);
}
Directory.CreateDirectory(tmpDir);
return tmpDir;
}
/// <summary>
/// 删除目录
/// </summary>
public static void DeleteDir(string targetDir)
{
if (Directory.Exists(targetDir))
{
Directory.Delete(targetDir, true);
}
AssetDatabase.Refresh();
}
/// <summary>
/// 拷贝Lua到目标目录,并做加密处理
/// </summary>
/// <param name="sourceDirs">源目录列表</param>
/// <param name="luabundleDir">母包目录</param>
public static void CopyLuaToBundleDir(List<string> luaFiles, string luabundleDir)
{
foreach (var luaFile in luaFiles)
{
if (luaFile.EndsWith(".meta")) continue;
var luaFileFullPath = Application.dataPath + "/../" + luaFile;
// 由于Build AssetBundle不识别.lua文件,所以拷贝一份到临时目录,统一加上.bytes结尾
var targetFile = luaFile.Replace("Assets/LuaFramework/Lua", "");
targetFile = targetFile.Replace("Assets/LuaFramework/ToLua/Lua", "");
targetFile = luabundleDir + targetFile + ".bytes";
var targetDir = Path.GetDirectoryName(targetFile);
if (!Directory.Exists(targetDir))
Directory.CreateDirectory(targetDir);
// 做下加密
byte[] bytes = File.ReadAllBytes(luaFileFullPath);
byte[] encryptBytes = AESEncrypt.Encrypt(bytes);
File.WriteAllBytes(targetFile, encryptBytes);
}
AssetDatabase.Refresh();
}
public void BuildLuaUpdateBundle(List<string> luaFileList)
{
}
/// <summary>
/// 获取当前平台
/// </summary>
public static BuildTarget GetBuildTarget()
{
#if UNITY_STANDALONE
return BuildTarget.StandaloneWindows;
#elif UNITY_ANDROID
return BuildTarget.Android;
#else
return BuildTarget.iOS;
#endif
}
public static string GetNameByPath(string path)
{
if(string.IsNullOrEmpty(path)) return string.Empty;
var name = string.Empty;
path = path.Replace("\\", "/");
int lastIndex = path.LastIndexOf("/");
if(lastIndex < 0) return string.Empty;
name = path.Remove(0, lastIndex + 1);
return name;
}
/// <summary>
/// 获取目标平台APP后缀
/// </summary>
/// <returns></returns>
public static string GetTargetPlatfromAppPostfix(bool useAAB = false)
{
#if UNITY_STANDALONE
return ".exe";
#elif UNITY_ANDROID
if(useAAB)
{
return ".aab";
}
else
{
return ".apk";
}
#else
return ".ipa";
#endif
}
public static string BIN_PATH
{
get { return Application.dataPath + "/../Bin/"; }
}
}
fileFormatVersion: 2
guid: 72b7450446dfba146b9e8dd101bc7318
timeCreated: 1494421258
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
/// <summary>
/// EditorSytleDef
/// </summary>
using UnityEngine;
using UnityEditor;
public class EditorStyleDef
{
public static GUIStyle labelStyleNormal
{
get
{
if (m_labelStyleNormal == null)
{
m_labelStyleNormal = new GUIStyle(EditorStyles.label);
m_labelStyleNormal.fontSize = 12;
m_labelStyleNormal.normal.textColor = Color.white;
}
return m_labelStyleNormal;
}
}
public static GUIStyle labelStyleBlue
{
get
{
if (m_labelStyleBlue == null)
{
m_labelStyleBlue = new GUIStyle(labelStyleNormal);
Texture2D tex = CreateTexture2D(new Color(35 / 255f, 55 / 255f, 75 / 255f));
m_labelStyleBlue.normal.background = tex;
m_labelStyleBlue.normal.textColor = Color.white;
}
return m_labelStyleBlue;
}
}
public static GUIStyle labelSytleGreen
{
get
{
if (m_labelStyleYellow == null)
{
m_labelStyleYellow = new GUIStyle(labelStyleNormal);
Texture2D tex = CreateTexture2D(new Color(185f / 255f, 1, 144 / 255f));
m_labelStyleYellow.normal.background = tex;
m_labelStyleYellow.normal.textColor = Color.black;
m_labelStyleYellow.fontStyle = FontStyle.Bold;
}
return m_labelStyleYellow;
}
}
public static GUIStyle labelSytleYellow
{
get
{
if (m_labelStyleGreen == null)
{
m_labelStyleGreen = new GUIStyle(labelStyleNormal);
Texture2D tex = CreateTexture2D(Color.yellow);
m_labelStyleGreen.normal.background = tex;
m_labelStyleGreen.normal.textColor = Color.black;
}
return m_labelStyleGreen;
}
}
public static GUIStyle labelSytleGray
{
get
{
if (m_labelSytleGray == null)
{
m_labelSytleGray = new GUIStyle(labelStyleNormal);
Texture2D tex = CreateTexture2D(Color.gray);
m_labelSytleGray.normal.background = tex;
m_labelSytleGray.normal.textColor = Color.black;
m_labelSytleGray.wordWrap = true;
}
return m_labelSytleGray;
}
}
private static Texture2D CreateTexture2D(Color color)
{
Texture2D tex = new Texture2D(1, 1);
tex.SetPixel(0, 0, color);
tex.wrapMode = TextureWrapMode.Repeat;
tex.Apply();
return tex;
}
public static GUIStyle boxStyleGrayBlue
{
get
{
if (m_boxStyleGrayBlue == null)
{
m_boxStyleGrayBlue = new GUIStyle(EditorStyles.helpBox);
Texture2D tex = CreateTexture2D(new Color(35 / 255f, 55 / 255f, 75 / 255f));
m_boxStyleGrayBlue.normal.background = tex;
}
return m_boxStyleGrayBlue;
}
}
public static GUIStyle boxStyleGrayYellow
{
get
{
if (m_boxStyleGrayYellow == null)
{
m_boxStyleGrayYellow = new GUIStyle(EditorStyles.helpBox);
Texture2D tex = CreateTexture2D(new Color(17 / 255f, 30 / 255f, 41 / 255f));
m_boxStyleGrayYellow.normal.background = tex;
}
return m_boxStyleGrayYellow;
}
}
public static GUIStyle textAreaNormal
{
get
{
if (null == m_textAreaNormal)
{
m_textAreaNormal = new GUIStyle(EditorStyles.textArea);
m_textAreaNormal.wordWrap = true;
}
return m_textAreaNormal;
}
}
public static GUIStyle numberField
{
get
{
if(null == m_numberField)
{
m_numberField = new GUIStyle(EditorStyles.numberField);
m_numberField.alignment = TextAnchor.MiddleLeft;
m_numberField.overflow = new RectOffset(130, 0, 0, 0);
m_numberField.padding = new RectOffset(-130, 0, 0, 0);
}
return m_numberField;
}
}
private static GUIStyle m_labelStyleNormal;
private static GUIStyle m_labelStyleBlue;
private static GUIStyle m_labelStyleGreen;
private static GUIStyle m_labelStyleYellow;
private static GUIStyle m_labelSytleGray;
private static GUIStyle m_boxStyleGrayBlue;
private static GUIStyle m_boxStyleGrayYellow;
private static GUIStyle m_textAreaNormal;
private static GUIStyle m_numberField;
}
fileFormatVersion: 2
guid: bc0bbeda71627844ca3f6999e8cef59d
timeCreated: 1497338886
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
using System;
using UnityEditor;
using UnityEngine;
using System.Collections.Generic;
using System.IO;
using System.Threading;
using System.Text;
static class EdtUtil
{
/// <summary>
/// 运行shell命令
/// </summary>
/// <param name="cmd">命令(exe的文件名)</param>
/// <param name="args">命令的参数</param>
/// <returns>string[] res[0]命令的stdout输出, res[1]命令的stderr输出</returns>
public static string[] RunCmd(string cmd, string args)
{
string[] res = new string[2];
var p = CreateCmdProcess(cmd, args);
res[0] = p.StandardOutput.ReadToEnd();
res[1] = p.StandardError.ReadToEnd();
p.Close();
return res;
}
/// <summary>
/// 运行shell命令,不返回stderr版本
/// </summary>
/// <param name="cmd">命令(exe的文件名)</param>
/// <param name="args">命令的参数</param>
/// <returns>命令的stdout输出</returns>
public static string RunCmdNoErr(string cmd, string args)
{
var p = CreateCmdProcess(cmd, args);
var res = p.StandardOutput.ReadToEnd();
p.Close();
return res;
}
public static string RunCmdNoErr(string cmd, string args, string[] input)
{
var p = CreateCmdProcess(cmd, args);
//p.StandardOutput.ReadToEnd();
if (input != null && input.Length > 0)
{
for(int i = 0; i < input.Length; i++)
p.StandardInput.WriteLine(input[i]);
}
var res = p.StandardOutput.ReadToEnd();
p.Close();
return res;
}
/// <summary>
/// 打开文件夹
/// </summary>
/// <param name="absPath">文件夹的绝对路径</param>
public static void OpenFolderInExplorer(string absPath)
{
#if UNITY_EDITOR
if (Application.platform == RuntimePlatform.WindowsEditor)
RunCmdNoErr("explorer.exe", absPath);
else if (Application.platform == RuntimePlatform.OSXEditor)
RunCmdNoErr("open", absPath.Replace("\\", "/"));
#endif
}
/// <summary>
/// 打开文件夹 并定位文件
/// </summary>
/// <param name="fileAbsPath">文件的绝对路径</param>
public static void OpenFolderInExplorerReveals(string fileAbsPath)
{
#if UNITY_EDITOR
if (Application.platform == RuntimePlatform.WindowsEditor)
{
var args = string.Format("/select,\"{0}\"", fileAbsPath);
RunCmdNoErr("explorer.exe", args);
}
else if (Application.platform == RuntimePlatform.OSXEditor)
{
fileAbsPath = fileAbsPath.Replace("\\", "/");
var args = string.Format("-R \"{0}\"", fileAbsPath);
RunCmdNoErr("open", args);
}
#endif
}
/// <summary>
/// 一个路径的上层文件夹
/// </summary>
/// <param name="path">路径</param>
/// <returns>路径的上层</returns>
public static string PathParent(string path)
{
if (string.IsNullOrEmpty(path))
return "";
int lastStartIndex = path.Length - 1;
char lastchar = path[lastStartIndex];
if (lastchar == '\\' || lastchar == '/')
lastStartIndex--;
if (lastStartIndex < 0)
return path;
int idx = path.LastIndexOf('/', lastStartIndex);
int idx2 = path.LastIndexOf('\\', lastStartIndex);
if (idx < idx2)
idx = idx2;
if (idx == -1)
{
if (lastchar == '\\' || lastchar == '/')
path = path.Substring(0, lastStartIndex+1);
return path;
}
if (idx == 0)
return path.Substring(0, 1);
return path.Substring(0, idx);
}
/// <summary>
/// 取得Application.dataPath的上层文件夹
/// </summary>
public static string GetDataPathParent()
{
const string kAssets = "Assets";
var dataPath = Application.dataPath;
if (!dataPath.EndsWith(kAssets))
throw new System.Exception("Application.dataPath is not EndsWith \"Assets\" ");
return dataPath.Substring(0, dataPath.Length - kAssets.Length - 1);
}
/// <summary>
/// 计算文件的md5值
/// </summary>
/// <param name="filename">文件名</param>
/// <returns>文件的md5</returns>
public static string GetFileMd5(string filename)
{
var file = new System.IO.FileStream(filename, System.IO.FileMode.Open);
var md5 = new System.Security.Cryptography.MD5CryptoServiceProvider();
byte[] hash = md5.ComputeHash(file);
file.Close();
return BitConverter.ToString(hash).Replace("-", "");
}
private static readonly char[] kNewLineSplit = new char[] { '\n' };
public static Dictionary<string, string> ParseKeyValCfg(string txt, string split = ":", bool needTrim = false)
{
if (string.IsNullOrEmpty(txt))
return null;
txt = txt.Replace("\r\n", "\n");
string[] lines = txt.Split(kNewLineSplit, StringSplitOptions.RemoveEmptyEntries);
return ParseKeyValCfg(lines, split, needTrim);
}
public static Dictionary<string, string> ParseKeyValCfg(string[] lines, string split=":", bool needTrim = false)
{
if (lines == null || lines.Length == 0)
return null;
if (string.IsNullOrEmpty(split))
return null;
Dictionary<string, string> tab = new Dictionary<string, string>();
for(int i = 0,count = lines.Length; i < count; i++)
{
string line = lines[i];
if (string.IsNullOrEmpty(line))
continue;
int idx = line.IndexOf(split);
if (idx < 0)
continue;
string k = idx == 0 ? "" : line.Substring(0, idx);
string v = line.Substring(idx + split.Length);
if (needTrim)
{
k = k.Trim();
v = v.Trim();
}
tab.Add(k, v);
}
return tab;
}
private static System.Diagnostics.Process CreateCmdProcess(string cmd, string args)
{
var pStartInfo = new System.Diagnostics.ProcessStartInfo(cmd);
pStartInfo.Arguments = args;
pStartInfo.CreateNoWindow = false;
pStartInfo.UseShellExecute = false;
pStartInfo.RedirectStandardError = true;
pStartInfo.RedirectStandardInput = true;
pStartInfo.RedirectStandardOutput = true;
pStartInfo.StandardErrorEncoding = System.Text.UTF8Encoding.UTF8;
pStartInfo.StandardOutputEncoding = System.Text.UTF8Encoding.UTF8;
return System.Diagnostics.Process.Start(pStartInfo);
}
/// <summary>
/// 拿文件夹里指定后缀的全部文件
/// </summary>
/// <param name="absPath">文件夹绝对路径</param>
/// <param name="extensions">后缀名</param>
/// <returns></returns>
public static List<string> GetFiles(string absPath, string extensions)
{
List<string> list = new List<string>();
GetFiles(absPath, extensions, list);
return list;
}
private static void GetFiles(string absPath, string extensions, List<string> list)
{
string[] folders = Directory.GetDirectories(absPath);
for (int i = 0, len = folders.Length; i < len; i++)
{
GetFiles(folders[i], extensions, list);
}
string[] files = Directory.GetFiles(absPath);
for (int i = 0, len = files.Length; i < len; i++)
{
string file = files[i];
if (file.EndsWith(extensions))
{
list.Add(file);
}
}
}
public static string GetFileName(string fileAbsPath)
{
int idx = fileAbsPath.LastIndexOf('\\') + 1;
if (idx <= 0)
{
idx = fileAbsPath.LastIndexOf('/') + 1;
}
if (idx >= 0)
{
return fileAbsPath.Substring(idx, fileAbsPath.Length - idx);
}
return fileAbsPath;
}
/// <summary>
/// 获取文件夹上层路径
/// </summary>
/// <returns></returns>
public static string GetFolderParent(string folderPath)
{
int idx = folderPath.LastIndexOf('\\') + 1;
if (idx <= 0)
{
idx = folderPath.LastIndexOf('/') + 1;
}
if (idx >= 0)
{
return folderPath.Substring(0, idx);
}
return folderPath;
}
public static void Xml2Excel(string xmlPath, string excelPath)
{
// 转换成Excel
string projectDir = Directory.GetCurrentDirectory();
int lastIndex1 = projectDir.LastIndexOf('\\');
int lastIndex2 = projectDir.LastIndexOf('\\', lastIndex1 - 1, lastIndex1);
string rootDir = projectDir.Substring(0, lastIndex2);
excelPath = rootDir + "/doc/" + excelPath;
//xmlPath = Path.Combine(projectDir, xmlPath);
string programPath = rootDir + @"\tool\xml2excel\Xml2Excel.exe";
if (!File.Exists(programPath))
{
EditorUtility.DisplayDialog("错误", "找不到Xml2Excel.exe!", "确定");
return;
}
if(!File.Exists(xmlPath) || !File.Exists(excelPath))
{
GameLogger.LogError(xmlPath + "\n" + excelPath);
return;
}
Thread thread = new Thread(() => Xml2Excel(programPath, xmlPath, excelPath));
thread.Start();
}
private static void Xml2Excel(string programPath, string xmlPath, string excelPath)
{
try
{
string cmd = string.Format("{0} {1} {2} {3}", programPath, xmlPath, excelPath, true);
System.Diagnostics.Process p = new System.Diagnostics.Process();
p.StartInfo.FileName = "cmd.exe";
p.StartInfo.Arguments = "/c" + cmd;
p.StartInfo.UseShellExecute = false;
p.StartInfo.RedirectStandardInput = true;
p.StartInfo.RedirectStandardOutput = true;
p.StartInfo.RedirectStandardError = false;
p.StartInfo.CreateNoWindow = true;
p.StartInfo.StandardOutputEncoding = Encoding.GetEncoding(936);
p.Start();
string output = p.StandardOutput.ReadToEnd();
p.WaitForExit();
p.Close();
if (!string.IsNullOrEmpty(output))
{
GameLogger.LogError("Xml2Excel Console:\n" + output);
}
}
catch (Exception e)
{
GameLogger.LogError(e.ToString());
}
finally
{
File.Delete(xmlPath);
}
}
private static void GenXml2ExcelScript(string xmlPath, string excelPath, Dictionary<string, string> colNames, string tempPythonFile)
{
var sb = new StringBuilder();
sb.AppendLine("#-*- coding: UTF-8 -*- ");
sb.AppendLine("from excelpy.xml2excel import xml2excel");
if (colNames == null || colNames.Count == 0)
{
sb.AppendFormat("xml2excel(u\"{0}\", u\"{1}\")", xmlPath, excelPath);
sb.AppendLine();
}
else
{
sb.AppendLine("col_names = {}");
foreach (KeyValuePair<string, string> pair in colNames)
{
sb.AppendFormat("col_names[\"{0}\"] = u\"{1}\"", pair.Key, pair.Value);
sb.AppendLine();
}
sb.AppendFormat("xml2excel(u\"{0}\", u\"{1}\", col_names)", xmlPath, excelPath);
sb.AppendLine();
}
var txt = sb.ToString();
File.WriteAllText(tempPythonFile, txt);
}
}// end class EdtUtil
fileFormatVersion: 2
guid: ddcce01064655774dbc994ff1e2d58c4
timeCreated: 1494421344
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
public class FastOpenTools
{
[MenuItem("Tools/命令/打开I18配置 &i")]
public static void OpenI18NCfg()
{
OpenFileOrDirectory("/GameRes/Config/i18nAppStrings.bytes");
}
[MenuItem("Tools/命令/打开资源配置 &r")]
public static void OpenResCfg()
{
OpenFileOrDirectory("/GameRes/Config/resources.bytes");
}
public static void OpenFileOrDirectory(string uri, string workingDir = "")
{
var path = Application.dataPath + uri;
path = path.Replace("/", "\\");
EdtUtil.OpenFolderInExplorer(path);
}
}
fileFormatVersion: 2
guid: 9d5db5daf49e00f4eb00e7221c2f5403
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
fileFormatVersion: 2
guid: ff88a6b81e56bd646b522cf1ff093064
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
using System.Linq;
public class PrefabBinderEditor : EditorWindow
{
private GameObject m_prefabBinderObj;
private PrefabBinder m_slot;
private List<PrefabBinder.Item> m_itemList;
private List<PrefabBinder.Item> m_searchMatchItemList = new List<PrefabBinder.Item>();
private Vector2 m_scrollViewPos;
private List<Component> m_comList = new List<Component>();
private string m_itemName;
private string m_itemNameSearch;
private string m_selectedItemName;
private string m_lockBtnName;
private Object m_itemObj;
private bool m_lock;
private string m_componentStr;
enum ItemOption
{
AddItem,
RemoveItem,
ClearItems,
SearchItems
}
private GUIStyle m_labelSytleYellow;
private GUIStyle m_labelStyleNormal;
[MenuItem("Tools/Aux/PrefabBinder工具")]
public static void ShowWindow()
{
var window = GetWindow<PrefabBinderEditor>();
window.titleContent = new GUIContent("PrefabBinder", AssetPreview.GetMiniTypeThumbnail(typeof(UnityEngine.EventSystems.EventSystem)), "decent");
window.Init();
}
[MenuItem("GameObject/PrefabBinder Window", priority = 0)]
public static void PrefabBinderWindow()
{
if (Selection.activeGameObject.GetComponent<PrefabBinder>())
ShowWindow();
else
Debug.LogError("no PrefabBinder on this GameObject");
}
void Awake()
{
m_labelStyleNormal = new GUIStyle(EditorStyles.miniButton);
m_labelStyleNormal.fontSize = 12;
m_labelStyleNormal.normal.textColor = Color.white;
m_labelSytleYellow = new GUIStyle(EditorStyles.miniButton);
m_labelSytleYellow.fontSize = 12;
m_labelSytleYellow.normal.textColor = Color.yellow;
}
void OnEnable()
{
EditorApplication.update += Repaint;
}
void OnDisable()
{
EditorApplication.update -= Repaint;
}
void Init()
{
m_itemList = new List<PrefabBinder.Item>();
m_comList = new List<Component>();
m_lockBtnName = "锁定item组件列表";
m_componentStr = string.Empty;
m_lock = false;
if (Selection.activeGameObject.GetComponent<PrefabBinder>())
{
m_prefabBinderObj = Selection.activeGameObject;
OnRefreshBtnClicked();
}
}
void OnGUI()
{
BeginBox(new Rect(0, 0, 3 * Screen.width / 7f, Screen.height));
DrawSearchBtn();
DrawSearchItemList();
EndBox();
BeginBox(new Rect(3 * Screen.width / 7f + 2, 0, 2 * Screen.width / 7f, Screen.height));
DrawLockBtn();
GUILayout.Space(2);
DrawComponentList();
EndBox();
BeginBox(new Rect(5 * Screen.width / 7f + 4, 0, 2 * Screen.width / 7f - 4, Screen.height));
DrawPrefabBinderField();
GUILayout.Space(2);
DrawItemField();
EndBox();
}
private void DrawSearchBtn()
{
GUILayout.BeginHorizontal();
string before = m_itemNameSearch;
string after = EditorGUILayout.TextField("", before, "SearchTextField");
if (before != after) m_itemNameSearch = after;
if (GUILayout.Button("", "SearchCancelButton"))
{
m_itemNameSearch = "";
GUIUtility.keyboardControl = 0;
}
ComponentOperation(m_slot, ItemOption.SearchItems, after);
GUILayout.EndHorizontal();
}
private void DrawPrefabBinderField()
{
EditorGUILayout.BeginHorizontal(EditorStyles.toolbar);
GUILayout.Label("binder");
var oldObj = m_prefabBinderObj;
m_prefabBinderObj = EditorGUILayout.ObjectField(m_prefabBinderObj, typeof(GameObject), true) as GameObject;
EditorGUILayout.EndHorizontal();
if (!m_prefabBinderObj)
{
EditorGUILayout.HelpBox("Select a PrefabBinder Object", MessageType.Warning);
}
else if (oldObj != m_prefabBinderObj)
{
m_slot = m_prefabBinderObj.GetComponent<PrefabBinder>();
}
}
private void BeginBox(Rect rect)
{
rect.height -= 20;
GUILayout.BeginArea(rect);
GUILayout.Box("", GUILayout.Width(rect.width), GUILayout.Height(rect.height));
GUILayout.EndArea();
GUILayout.BeginArea(rect);
}
private void EndBox()
{
GUILayout.EndArea();
}
private void DrawSearchItemList()
{
if (null == m_prefabBinderObj || null == m_slot)
m_searchMatchItemList.Clear();
m_scrollViewPos = EditorGUILayout.BeginScrollView(m_scrollViewPos);
foreach (var item in m_searchMatchItemList)
{
GUILayout.BeginHorizontal();
item.name = EditorGUILayout.TextField(item.name);
item.obj = EditorGUILayout.ObjectField(item.obj, typeof(GameObject), true);
if (GUILayout.Button("-", GUILayout.Width(20)))
{
m_itemList.Remove(item);
m_slot.items = m_itemList.ToArray();
GUILayout.EndHorizontal();
break;
}
GUILayout.EndHorizontal();
}
EditorGUILayout.EndScrollView();
}
private void DrawItemField()
{
EditorGUILayout.BeginVertical();
GUILayout.Label(string.IsNullOrEmpty(m_componentStr) ? "null" : m_componentStr);
m_itemName = EditorGUILayout.TextField(m_itemName);
if (GUILayout.Button(new GUIContent("Add Item", "添加item"), GUILayout.Height(80)))
{
ComponentOperation(m_slot, ItemOption.AddItem);
}
if (GUILayout.Button(new GUIContent("Delete Item", "删除指定的item")))
{
if (m_prefabBinderObj != null)
{
if (string.IsNullOrEmpty(m_itemName))
Debug.LogWarning("请输入要删除的项目名称");
else
ComponentOperation(m_slot, ItemOption.RemoveItem);
}
}
if (GUILayout.Button(new GUIContent("Refresh", "刷新")))
{
OnRefreshBtnClicked();
}
ItemTip();
}
private void OnRefreshBtnClicked()
{
if (null != m_prefabBinderObj)
m_slot = m_prefabBinderObj.GetComponent<PrefabBinder>();
if (null == m_slot)
{
m_itemList.Clear();
m_comList.Clear();
}
}
private void DrawLockBtn()
{
if (GUILayout.Button(new GUIContent(m_lockBtnName, m_lockBtnName), EditorStyles.toolbarButton))
{
m_lock = !m_lock;
if (m_lock == false)
m_lockBtnName = "锁定item组件列表";
else
m_lockBtnName = "解锁item组件列表";
}
}
private void DrawComponentList()
{
var go = Selection.activeObject as GameObject; //获取选中对象
if (go && m_lock == false)
{
Component[] components = go.GetComponents<Component>();
m_comList.Clear();
m_comList.AddRange(components);
m_selectedItemName = go.name;
}
if (go == null)
{
m_comList.Clear();
m_selectedItemName = "无选中对象";
}
if (go && GUILayout.Button("GameObject", "GameObject" == m_componentStr ? m_labelSytleYellow : m_labelStyleNormal))
{
m_itemObj = go;
m_componentStr = "GameObject";
}
foreach (var com in m_comList)
{
GUILayout.Space(2);
var comType = com.GetType().ToString();
comType = comType.Replace("UnityEngine.UI.", "");
comType = comType.Replace("UnityEngine.", "");
if (GUILayout.Button(comType, comType == m_componentStr ? m_labelSytleYellow : m_labelStyleNormal))
{
m_itemObj = com;
m_componentStr = comType;
}
}
EditorGUILayout.EndVertical();
}
#region private method
private void ComponentOperation(PrefabBinder slot, ItemOption option, string name = " ")
{
if (null == slot) return;
PrefabBinder.Item item = new PrefabBinder.Item();
switch (option)
{
case ItemOption.AddItem:
AddItem(item, slot);
break;
case ItemOption.RemoveItem:
RemoveItem(item, slot);
break;
case ItemOption.ClearItems:
ClearItem(item, slot);
break;
case ItemOption.SearchItems:
SearchItem(item, slot, name);
break;
}
slot.items = m_itemList.ToArray();
}
private void AddItem(PrefabBinder.Item item, PrefabBinder Ps)
{
item.name = m_itemName;
item.obj = m_itemObj;
m_itemList = Ps.items.ToList();
List<string> nameList = new List<string>();
foreach (var iL in m_itemList)
{
nameList.Add(iL.name);
}
if (!string.IsNullOrEmpty(m_itemName) && m_itemObj != null)
{
if (nameList.Contains(m_itemName))
{
Debug.LogError("重复元素");
m_itemList.Add(item);
}
else
m_itemList.Add(item);
}
}
private void RemoveItem(PrefabBinder.Item item, PrefabBinder Ps)
{
item.name = m_itemName;
m_itemList = Ps.items.ToList();
for (int i = 0; i < m_itemList.Count; i++)
{
if (m_itemList[i].name.ToLower() == item.name.ToLower())
{
m_itemList.Remove(m_itemList[i]);
break;
}
}
}
private void ClearItem(PrefabBinder.Item item, PrefabBinder Ps)
{
item.name = m_itemName;
item.obj = m_itemObj;
m_itemList = Ps.items.ToList();
for (int i = 0; i < m_itemList.Count; i++)
{
if (m_itemList[i].obj == null || string.IsNullOrEmpty(m_itemList[i].name))
{
m_itemList.Remove(m_itemList[i]);
}
}
}
private void SearchItem(PrefabBinder.Item item, PrefabBinder slot, string name)
{
m_itemList = slot.items.ToList();
m_searchMatchItemList.Clear();
foreach (var o in m_itemList)
{
if (string.IsNullOrEmpty(name))
{
m_searchMatchItemList.Add(o);
}
else
{
if (o.name.ToLower().Contains(name.ToLower()))
{
m_searchMatchItemList.Add(o);
}
else if (null != o.obj)
{
var objName = o.obj.name;
if (objName.ToLower().Contains(name.ToLower()))
{
m_searchMatchItemList.Add(o);
}
}
}
}
}
private void ItemTip()
{
if (string.IsNullOrEmpty(m_itemName) || m_itemObj == null)
{
string msg = string.Empty;
if (m_itemObj == null)
{
msg = "请选择项目组件";
}
else if (string.IsNullOrEmpty(m_itemName))
{
msg = "请输入要添加的项的名字";
}
EditorGUILayout.HelpBox(msg, MessageType.Warning);
EditorGUILayout.Space();
}
}
#endregion
}
fileFormatVersion: 2
guid: 0d7b7b9e5e7dac649951a00ef7fd24db
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
using UnityEngine;
using UnityEditor;
[CustomEditor(typeof(PrefabBinder), true)]
public class PrefabBinderInspector : Editor
{
void Awake()
{
btnStyle = new GUIStyle(EditorStyles.miniButton);
btnStyle.fontSize = 12;
btnStyle.normal.textColor = Color.green;
}
public override void OnInspectorGUI()
{
if (GUILayout.Button("打开PrefabBinder编辑器", btnStyle))
{
PrefabBinderEditor.ShowWindow();
}
base.OnInspectorGUI();
}
private GUIStyle btnStyle;
}
fileFormatVersion: 2
guid: 27b632dd057183f408f3c78f222e6c28
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
using UnityEditor;
using UnityEngine;
using System.Xml;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
public enum OperType
{
Add,
Update,
Delete
}
public enum ResEditorErrorCode
{
Ok = -1,
DescriptionNull = 1,
ObjNull,
ResExist,
PathError,
ArgsError,
DuplicateID,
UnknowError
}
public class ResConfigEditor : EditorWindow
{
[MenuItem("Tools/Aux/资源添加编辑器 &g")]
static void Init()
{
ResConfigEditor window = (ResConfigEditor)EditorWindow.GetWindow(typeof(ResConfigEditor));
window.minSize = new Vector2(500f, 600f);
window.Show();
s_manager = new ResConfigManager();
}
void OnDestroy()
{
}
void OnGUI()
{
GUILayout.Label("资源配置", EditorStyles.boldLabel);
EditorGUILayout.BeginVertical();
if (m_curObj != m_lastObj)
{
m_lastObj = m_curObj;
m_operType = s_manager.exist(m_curObj.name) ? OperType.Update : OperType.Add;
string path = AssetDatabase.GetAssetPath(m_curObj);
if (!ResConfigManager.isPathRight(path)) m_errorCode = ResEditorErrorCode.PathError;
if (m_operType == OperType.Update)
{
string filePath;
XmlElement element;
s_manager.getResourceElement(m_curObj, out filePath, out element);
m_resID = int.Parse(element.Attributes["id"].Value);
m_description = element.Attributes["desc"].Value;
}
else if (m_operType == OperType.Add)
{
m_resID = -1;
m_description = "";
}
}
m_curObj = EditorGUILayout.ObjectField("资源对象", m_curObj, typeof(Object), false, m_option);
m_operType = (OperType)EditorGUILayout.EnumPopup("操作类型", m_operType);
if (m_operType == OperType.Add || m_operType == OperType.Update)
{
m_description = EditorGUILayout.TextField("资源描述", m_description, m_option);
EditorGUILayout.SelectableLabel("自动生成的资源ID:" + m_resID.ToString(), m_option);
if (m_operType == OperType.Add && GUILayout.Button("Add"))
{
m_errorCode = s_manager.append(m_curObj, m_description, m_arg, out m_resID);
}
if (m_operType == OperType.Update && GUILayout.Button("Update"))
{
m_errorCode = s_manager.update(m_curObj, m_description, m_arg);
}
}
else
{
m_resourceName = EditorGUILayout.TextField("资源名称", m_resourceName, m_option);
if (GUILayout.Button("Delete"))
{
s_manager.delete(m_curObj, m_resourceName);
}
}
EditorGUILayout.EndVertical();
EditorGUILayout.BeginVertical();
EditorGUILayout.Space();
EditorGUILayout.Space();
EditorGUILayout.Space();
EditorGUILayout.SelectableLabel(ResConfigManager.getTipsByID(m_errorCode), m_option);
EditorGUILayout.EndVertical();
}
private static ResConfigManager s_manager;
private Object m_curObj = null, m_lastObj = null;
private OperType m_operType = OperType.Add;
private string m_resourceName = string.Empty;
private string m_description = string.Empty;
private int m_resID = -1;
private ResEditorErrorCode m_errorCode = ResEditorErrorCode.Ok;
private float m_arg = 1f;
GUILayoutOption[] m_option = new GUILayoutOption[] { GUILayout.Width(300), GUILayout.Height(16) };
}
public class ResConfigManager
{
public ResConfigManager()
{
initResourceConf();
}
public ResEditorErrorCode append(Object obj, string description, float arg, out int resourceID)
{
resourceID = -1;
if (string.IsNullOrEmpty(description))
{
return ResEditorErrorCode.DescriptionNull;
}
if (obj == null)
{
return ResEditorErrorCode.ObjNull;
}
if (exist(obj.name)) return ResEditorErrorCode.ResExist;
string path = AssetDatabase.GetAssetPath(obj);
if (!isPathRight(path)) return ResEditorErrorCode.PathError;
var ret = ResEditorErrorCode.Ok;
resourceID = appendResourceConf("resources", s_itemMap1, path, description);
if (path.EndsWith(".ogg") || path.EndsWith(".wav"))
{
var fname = Path.GetFileName(path);
ret = appendAudioConf(fname, resourceID, (float)arg);
}
return ret;
}
public ResEditorErrorCode getResourceConfigItem(string name, out ResConfigItem cfg)
{
cfg = null;
foreach (ResConfigItem item in s_itemMap1.Values)
{
if (item != null && name.Equals(item.name))
{
cfg = item;
return ResEditorErrorCode.Ok;
}
}
return ResEditorErrorCode.ObjNull;
}
public ResEditorErrorCode getResourceConfigItem(int id, out ResConfigItem cfg)
{
cfg = null;
if (s_itemMap1.TryGetValue(id, out cfg))
{
return ResEditorErrorCode.Ok;
}
return ResEditorErrorCode.ObjNull;
}
private XmlDocument getResourceElement(string name, out string filePath, out XmlElement item)
{
filePath = ResourcePathBuilder.BuildEssentialConfigPath("resources");
XmlDocument doc = getConfElementByName(name, filePath, out item);
return doc;
}
public XmlDocument getResourceElement(Object obj, out string filePath, out XmlElement item)
{
return getResourceElement(obj.name, out filePath, out item);
}
public ResEditorErrorCode update(Object obj, string description, float arg)
{
XmlDocument doc = null;
XmlElement item = null;
string filePath = string.Empty;
doc = getResourceElement(obj, out filePath, out item);
if (doc == null || item == null) return ResEditorErrorCode.ObjNull;
string sourcepath = AssetDatabase.GetAssetPath(obj);
string path;
path = sourcepath.Replace("Assets/GameRes/", "");
item.SetAttribute("editorPath", path);
item.SetAttribute("version", System.DateTime.Now.ToShortDateString());
item.SetAttribute("desc", description);
StreamWriter sw = new StreamWriter(filePath, false, new UTF8Encoding(false));
doc.Save(sw);
sw.Close();
if (path.EndsWith(".ogg") || path.EndsWith(".wav"))
{
string fname = Path.GetFileName(path);
int resid = int.Parse(item.GetAttribute("id"));
updateAudioConf(fname, resid, arg);
}
int resourceID = int.Parse(item.Attributes["id"].Value);
if (s_itemMap1.ContainsKey(resourceID))
{
ResConfigItem cfg = s_itemMap1[resourceID];
cfg.path = path;
cfg.desc = description;
}
return ResEditorErrorCode.Ok;
}
private XmlDocument getConfElementByName(string objName, string filePath, out XmlElement element)
{
element = null;
XmlDocument doc = XMLUtil.getXMLFromFile(filePath);
XmlNodeList nodeList = doc.GetElementsByTagName("item");
if (nodeList != null)
{
for (int i = 0; i < nodeList.Count; ++i)
{
string editorPath = nodeList[i].Attributes["editorPath"].Value;
int index1 = editorPath.LastIndexOf('/');
if (index1 == -1) continue;
string tempPath = editorPath.Remove(0, index1 + 1);
int index2 = tempPath.LastIndexOf('.');
if (index2 == -1) continue;
string tempName = tempPath.Remove(index2, tempPath.Length - index2);
if (objName.Equals(tempName))
{
element = (XmlElement)nodeList[i];
break;
}
}
}
return doc;
}
public ResEditorErrorCode delete(Object obj, string name)
{
int resourceID = -1;
ResEditorErrorCode errorCode = ResEditorErrorCode.UnknowError;
errorCode = deleteResouceConf(obj != null ? obj.name : name, out resourceID);
if (errorCode == ResEditorErrorCode.Ok)
{
if (obj.name.EndsWith(".ogg") || obj.name.EndsWith(".wav"))
{
errorCode = deleteItemInConf("audioConfig", "items", "audio", "id", resourceID);
}
}
return errorCode;
}
private ResEditorErrorCode deleteResouceConf(string name, out int resourceID)
{
resourceID = -1;
if (string.IsNullOrEmpty(name)) return ResEditorErrorCode.ArgsError;
string filePath = string.Empty;
XmlElement element = null;
XmlDocument doc = getResourceElement(name, out filePath, out element);
resourceID = int.Parse(element.Attributes["id"].Value);
XmlNode items = doc.SelectSingleNode("items");
items.RemoveChild(element);
StreamWriter sw = new StreamWriter(filePath, false, new UTF8Encoding(false));
doc.Save(sw);
sw.Close();
if (s_itemMap1.ContainsKey(resourceID))
s_itemMap1.Remove(resourceID);
AssetDatabase.Refresh();
return ResEditorErrorCode.Ok;
}
private ResEditorErrorCode deleteItemInConf(string fileName, string rootItem, string item, string resIDArrtibute, int resourceID)
{
if (resourceID == -1)
{
GameLogger.LogError("resourceID error.");
return ResEditorErrorCode.ArgsError;
}
string filePath = ResourcePathBuilder.BuildEssentialConfigPath(fileName);
XmlDocument doc = XMLUtil.getXMLFromFile(filePath);
XmlNode rootNode = doc.SelectSingleNode(rootItem);
XmlNodeList items = doc.GetElementsByTagName(item);
XmlNode childNode = null;
foreach (XmlNode node in items)
{
int tempResourceID = int.Parse(node.Attributes[resIDArrtibute].Value);
if (tempResourceID == resourceID)
{
childNode = node;
break;
}
}
childNode = rootNode.RemoveChild(childNode);
if (childNode == null)
GameLogger.LogError("remove error ...");
StreamWriter sw = new StreamWriter(filePath, false, new UTF8Encoding(false));
doc.Save(sw);
sw.Close();
AssetDatabase.Refresh();
return ResEditorErrorCode.Ok;
}
private int appendResourceConf(string resourceConf, Dictionary<int, ResConfigItem> map1,
string sourcepath, string description)
{
int id = map1.Count > 0 ? map1.Keys.Max() + 1 : 1;
string filePath = ResourcePathBuilder.BuildEssentialConfigPath(resourceConf);
XmlDocument doc = XMLUtil.getXMLFromFile(filePath);
XmlNode rootNode = doc.SelectSingleNode("items");
XmlElement item = doc.CreateElement("item");
rootNode.AppendChild(item);
item.SetAttribute("id", id.ToString());
string path = sourcepath.Replace("Assets/GameRes/", "");
item.SetAttribute("editorPath", path);
item.SetAttribute("version", System.DateTime.Now.ToShortDateString());
item.SetAttribute("desc", description);
StreamWriter sw = new StreamWriter(filePath, false, new UTF8Encoding(false));
doc.Save(sw);
sw.Close();
AssetDatabase.Refresh();
map1.Add(id, new ResConfigItem(id, sourcepath, description));
return id;
}
private bool isDuplicate(XmlDocument doc, string item, string attribute, int id)
{
XmlNodeList list = doc.GetElementsByTagName(item);
foreach (XmlNode node in list)
{
int tempid = int.Parse(node.Attributes[attribute].Value);
if (tempid == id)
return true;
}
return false;
}
private ResEditorErrorCode appendAudioConf(string fname, int resID, float volume)
{
string filePath = ResourcePathBuilder.BuildEssentialConfigPath("audioConfig");
XmlDocument doc = XMLUtil.getXMLFromFile(filePath);
if (isDuplicate(doc, "audio", "id", resID))
return ResEditorErrorCode.DuplicateID;
XmlNode rootNode = doc.SelectSingleNode("items");
XmlElement item = doc.CreateElement("audio");
rootNode.AppendChild(item);
item.SetAttribute("id", resID.ToString());
item.SetAttribute("name", fname);
item.SetAttribute("volume", volume.ToString());
AssetDatabase.Refresh();
StreamWriter sw = new StreamWriter(filePath, false, new UTF8Encoding(false));
doc.Save(sw);
sw.Close();
return ResEditorErrorCode.Ok;
}
private ResEditorErrorCode updateAudioConf(string fname, int resID, float volume)
{
string filePath = ResourcePathBuilder.BuildEssentialConfigPath("audioConfig");
XmlDocument doc = XMLUtil.getXMLFromFile(filePath);
if (isDuplicate(doc, "audio", "id", resID))
return ResEditorErrorCode.DuplicateID;
XmlNode rootNode = doc.SelectSingleNode("items");
XmlNodeList audioNodes = rootNode.SelectNodes("audio");
bool isUpdate = false;
for (int i = 0, count = audioNodes.Count; i < count; ++i)
{
XmlNode audionode = audioNodes[i];
if (audionode.Attributes["id"].Value == resID.ToString() && audionode.Attributes["name"].Value == fname)
{
audionode.Attributes["id"].Value = resID.ToString();
audionode.Attributes["name"].Value = fname;
audionode.Attributes["volume"].Value = volume.ToString();
isUpdate = true;
break;
}
}
if (!isUpdate)
{
Debug.LogWarning(string.Format("资源编辑器更新音效时,没有在audioCoinfig.bytes文件中找到音效{0},所以在这里添加此音效!", fname));
XmlElement item = doc.CreateElement("audio");
rootNode.AppendChild(item);
item.SetAttribute("id", resID.ToString());
item.SetAttribute("name", fname);
item.SetAttribute("volume", volume.ToString());
}
AssetDatabase.Refresh();
StreamWriter sw = new StreamWriter(filePath, false, new UTF8Encoding(false));
doc.Save(sw);
sw.Close();
return ResEditorErrorCode.Ok;
}
public bool exist(string name)
{
foreach (ResConfigItem item in s_itemMap1.Values)
{
if (item != null && name.Equals(item.name))
return true;
}
return false;
}
public bool ExistResourceConfigItem(string path, out ResConfigItem configItem)
{
foreach (ResConfigItem item in s_itemMap1.Values)
{
if (item != null && path.Equals(item.path))
{
configItem = item;
return true;
}
}
configItem = null;
return false;
}
private static string joinIntArray(int[] values)
{
StringBuilder sb = new StringBuilder();
if (values != null)
{
foreach (int value in values)
{
if (sb.Length > 0) sb.Append(",");
sb.Append(value);
}
}
return sb.ToString();
}
private static void initResourceConf()
{
s_itemMap1 = new Dictionary<int, ResConfigItem>();
initResourceConf("resources", s_itemMap1);
}
private static void initResourceConf(string fileName, Dictionary<int, ResConfigItem> map)
{
string filePath = ResourcePathBuilder.BuildEssentialConfigPath(fileName);
XmlDocument doc = XMLUtil.getXMLFromFile(filePath);
XmlNodeList nodeList = doc.GetElementsByTagName("item");
if (nodeList == null || nodeList.Count == 0) return;
for (int i = 0; i < nodeList.Count; ++i)
{
XmlNode currentNode = nodeList.Item(i);
int id = XmlConvert.ToInt32(currentNode.Attributes["id"].Value);
string editorPath = currentNode.Attributes["editorPath"].Value;
string description = currentNode.Attributes["desc"] != null ? currentNode.Attributes["desc"].Value : "请填写资源描述,便于维护.";
map.Add(id, new ResConfigItem(id, editorPath, description));
}
}
public static bool isPathRight(string path)
{
return path.Contains("GameRes");
}
public static string getTipsByID(ResEditorErrorCode code)
{
switch (code)
{
case ResEditorErrorCode.Ok:
return "这是游戏资源配置编辑器。";
case ResEditorErrorCode.DescriptionNull:
return "资源描述不能为空!";
case ResEditorErrorCode.ObjNull:
return "请将需要添加的资源拖放到资源对象项。";
case ResEditorErrorCode.ResExist:
return "同名资源已存在,需要进行更新操作?";
case ResEditorErrorCode.PathError:
return "资源放置的路径不正确,不清楚请问程序猿。";
case ResEditorErrorCode.ArgsError:
return "参数错误。";
case ResEditorErrorCode.DuplicateID:
return "ID重复!!!";
default:
return "sorry, 未知错误";
}
}
private static Dictionary<int, ResConfigItem> s_itemMap1;
}
public class ResConfigItem
{
public ResConfigItem(int resourceID, string resourcePath,
string resourceDescription = null)
{
this.id = resourceID;
this.path = resourcePath;
this.desc = resourceDescription;
parseName();
}
private void parseName()
{
int index0 = this.path.LastIndexOf(".");
int index1 = this.path.LastIndexOf("/");
if (index0 == -1 && index1 != -1)
{
this.name = this.path.Substring(index1 + 1, this.path.Length - index1 - 1);
}
else
{
this.name = this.path.Substring(index1 + 1, index0 - index1 - 1);
}
}
public int id;
public string path;
public string desc;
public string name;
}
\ No newline at end of file
fileFormatVersion: 2
guid: b4287f453704c9e4799bd1d4d53f9059
timeCreated: 1494418139
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
using System.IO;
using UnityEngine.U2D;
using System.Text;
public class SpriteAtlasTools
{
[MenuItem("Tools/命令/生成精灵映射配置")]
private static void GenSpriteAtlasCfg()
{
ResourceManager.instance.Init();
var fs = Directory.GetFiles(Application.dataPath + "/GameRes/Atlas/");
Dictionary<string, int> sprite2atlasId = new Dictionary<string, int>();
StringBuilder sbr = new StringBuilder();
sbr.AppendLine("<?xml version=\"1.0\" encoding=\"utf-8\"?>");
sbr.AppendLine("<items>");
foreach(var f in fs)
{
if(!f.EndsWith(".spriteatlas")) continue;
var atlasFileName = Path.GetFileName(f);
var assetPath = f.Replace(Application.dataPath , "Assets/");
var uri = f.Replace(Application.dataPath + "/GameRes/", "");
var atals = AssetDatabase.LoadAssetAtPath<SpriteAtlas>(assetPath);
var resId = ResourceManager.instance.Uri2Id(uri);
Sprite[] sprites = new Sprite[atals.spriteCount];
atals.GetSprites(sprites);
foreach(var sprite in sprites)
{
var key = sprite.texture.name;
if(sprite2atlasId.ContainsKey(key))
GameLogger.LogError("精灵名重复, key: " + key);
else
{
sprite2atlasId.Add(sprite.texture.name, resId);
sbr.AppendLine(string.Format(" <item name=\"{0}\" atlas=\"{1}\" resId=\"{2}\"/>", key, atlasFileName, resId));
}
}
}
sbr.AppendLine("</items>");
// 保存配置
// GameLogger.Log(sbr.ToString());
SaveXmlCfg(sbr.ToString(), Application.dataPath + "/GameRes/Config/sprite2atlas.bytes");
}
private static void SaveXmlCfg(string txt, string path)
{
using(FileStream s = new FileStream(path, FileMode.OpenOrCreate))
{
StreamWriter writer = new StreamWriter(s);
writer.Write(txt);
writer.Close();
}
GameLogger.LogGreen("gen sprite2atlas cfg done, path: " + path);
}
}
fileFormatVersion: 2
guid: 3a88235d6182ae74d938826962358f2d
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
using UnityEngine;
using UnityEditor;
using LitJson;
using System.IO;
public class VersionGUI
{
public void Awake()
{
VersionMgr.instance.Init();
m_appVersion = VersionMgr.instance.appVersion;
}
public void DrawVersion()
{
GUILayout.BeginHorizontal();
m_appVersion = EditorGUILayout.TextField("version", m_appVersion);
JsonData jd = new JsonData();
jd["app_version"] = m_appVersion;
jd["res_version"] = m_appVersion;
if (GUILayout.Button("Save"))
{
using (StreamWriter sw = new StreamWriter(Application.dataPath + "/Resources/version.bytes"))
{
sw.Write(jd.ToJson());
}
AssetDatabase.Refresh();
Debug.Log("Save Version OK: " + m_appVersion);
VersionMgr.instance.DeleteCacheResVersion();
VersionMgr.instance.Init();
}
GUILayout.EndHorizontal();
}
private string m_appVersion;
}
fileFormatVersion: 2
guid: 8eff6dbc499f7f0489139f67c1f95d77
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
fileFormatVersion: 2
guid: 51aafd12ff335134c8e207283767c2f0
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
fileFormatVersion: 2
guid: 464a9ccd9239e2749b8a778b403fb565
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!1 &3779815630173574891
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 4704078714790945495}
- component: {fileID: 7359251799582786276}
- component: {fileID: 5653311627500096122}
- component: {fileID: 7922772586812536456}
m_Layer: 0
m_Name: Cube
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!4 &4704078714790945495
Transform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 3779815630173574891}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 4.8899016, y: 0.34013844, z: 104.42119}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children: []
m_Father: {fileID: 0}
m_RootOrder: 0
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!33 &7359251799582786276
MeshFilter:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 3779815630173574891}
m_Mesh: {fileID: 10202, guid: 0000000000000000e000000000000000, type: 0}
--- !u!23 &5653311627500096122
MeshRenderer:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 3779815630173574891}
m_Enabled: 1
m_CastShadows: 1
m_ReceiveShadows: 1
m_DynamicOccludee: 1
m_StaticShadowCaster: 0
m_MotionVectors: 1
m_LightProbeUsage: 1
m_ReflectionProbeUsage: 1
m_RayTracingMode: 2
m_RayTraceProcedural: 0
m_RenderingLayerMask: 1
m_RendererPriority: 0
m_Materials:
- {fileID: 10303, guid: 0000000000000000f000000000000000, type: 0}
m_StaticBatchInfo:
firstSubMesh: 0
subMeshCount: 0
m_StaticBatchRoot: {fileID: 0}
m_ProbeAnchor: {fileID: 0}
m_LightProbeVolumeOverride: {fileID: 0}
m_ScaleInLightmap: 1
m_ReceiveGI: 1
m_PreserveUVs: 0
m_IgnoreNormalsForChartDetection: 0
m_ImportantGI: 0
m_StitchLightmapSeams: 1
m_SelectedEditorRenderState: 3
m_MinimumChartSize: 4
m_AutoUVMaxDistance: 0.5
m_AutoUVMaxAngle: 89
m_LightmapParameters: {fileID: 0}
m_SortingLayerID: 0
m_SortingLayer: 0
m_SortingOrder: 0
m_AdditionalVertexStreams: {fileID: 0}
--- !u!65 &7922772586812536456
BoxCollider:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 3779815630173574891}
m_Material: {fileID: 0}
m_IsTrigger: 0
m_Enabled: 1
serializedVersion: 2
m_Size: {x: 1, y: 1, z: 1}
m_Center: {x: 0, y: 0, z: 0}
fileFormatVersion: 2
guid: 6126e6a4f5c87ef4786839b283a8df4a
PrefabImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
fileFormatVersion: 2
guid: 2b98b7c6958a42b4da65f698c60d81c7
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!687078895 &4343727234628468602
SpriteAtlas:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_Name: CommonUI
m_EditorData:
serializedVersion: 2
textureSettings:
serializedVersion: 2
anisoLevel: 1
compressionQuality: 50
maxTextureSize: 2048
textureCompression: 0
filterMode: 1
generateMipMaps: 0
readable: 0
crunchedCompression: 0
sRGB: 1
platformSettings: []
packingSettings:
serializedVersion: 2
padding: 4
blockOffset: 1
allowAlphaSplitting: 0
enableRotation: 1
enableTightPacking: 1
enableAlphaDilation: 0
secondaryTextureSettings: {}
variantMultiplier: 1
packables:
- {fileID: 102900000, guid: fa25a5bc8ed8c0b4fab93c4af1a61e1c, type: 3}
bindAsDefault: 1
isAtlasV2: 0
cachedData: {fileID: 0}
m_MasterAtlas: {fileID: 0}
m_PackedSprites:
- {fileID: 21300000, guid: 415a9e33391ce0c44bd7592d6494dcbf, type: 3}
- {fileID: 21300000, guid: 79b1714b9b9e8384f922c158c1b4b321, type: 3}
- {fileID: 21300000, guid: fc68c4ac18be2d2409dac34387396666, type: 3}
m_PackedSpriteNamesToIndex:
- framebg
- frame
- btn
m_RenderDataMap: {}
m_Tag: CommonUI
m_IsVariant: 0
fileFormatVersion: 2
guid: 43a538e8cf82e1441894e825d682f5b1
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 4343727234628468602
userData:
assetBundleName:
assetBundleVariant:
fileFormatVersion: 2
guid: 58f10602111b5294da59da617407ccab
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
fileFormatVersion: 2
guid: cd7b9e444905cde46965ed4f8db120a1
AudioImporter:
externalObjects: {}
serializedVersion: 6
defaultSettings:
loadType: 0
sampleRateSetting: 0
sampleRateOverride: 44100
compressionFormat: 1
quality: 1
conversionMode: 0
platformSettingOverrides: {}
forceToMono: 0
normalize: 1
preloadAudioData: 1
loadInBackground: 0
ambisonic: 0
3D: 1
userData:
assetBundleName:
assetBundleVariant:
fileFormatVersion: 2
guid: 2ee2382862c28ca41a84f5394e738d25
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!1 &1752661164713176635
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 8876070423238677405}
- component: {fileID: 5728883518745875144}
- component: {fileID: 2075083043615025143}
m_Layer: 5
m_Name: RawImage
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!224 &8876070423238677405
RectTransform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1752661164713176635}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children: []
m_Father: {fileID: 6950564264706902045}
m_RootOrder: 0
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0}
m_AnchorMax: {x: 1, y: 1}
m_AnchoredPosition: {x: 0, y: 0}
m_SizeDelta: {x: 0, y: 0}
m_Pivot: {x: 0.5, y: 0.5}
--- !u!222 &5728883518745875144
CanvasRenderer:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1752661164713176635}
m_CullTransparentMesh: 1
--- !u!114 &2075083043615025143
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1752661164713176635}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 1344c3c82d62a2a41a3576d8abb8e3ea, type: 3}
m_Name:
m_EditorClassIdentifier:
m_Material: {fileID: 0}
m_Color: {r: 1, g: 1, b: 1, a: 1}
m_RaycastTarget: 1
m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0}
m_Maskable: 1
m_OnCullStateChanged:
m_PersistentCalls:
m_Calls: []
m_Texture: {fileID: 2800000, guid: a322c50833325fa469079ac1a3cbb188, type: 3}
m_UVRect:
serializedVersion: 2
x: 0
y: 0
width: 1
height: 1
--- !u!1 &2235309103711344579
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 6950564264706902045}
- component: {fileID: 3899680468884421878}
- component: {fileID: 6284585954419973819}
m_Layer: 5
m_Name: TestPanel
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!224 &6950564264706902045
RectTransform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 2235309103711344579}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children:
- {fileID: 8876070423238677405}
m_Father: {fileID: 0}
m_RootOrder: 0
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0}
m_AnchorMax: {x: 1, y: 1}
m_AnchoredPosition: {x: 0, y: 0}
m_SizeDelta: {x: 0, y: 0}
m_Pivot: {x: 0.5, y: 0.5}
--- !u!222 &3899680468884421878
CanvasRenderer:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 2235309103711344579}
m_CullTransparentMesh: 1
--- !u!114 &6284585954419973819
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 2235309103711344579}
m_Enabled: 0
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3}
m_Name:
m_EditorClassIdentifier:
m_Material: {fileID: 0}
m_Color: {r: 1, g: 1, b: 1, a: 0.392}
m_RaycastTarget: 1
m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0}
m_Maskable: 1
m_OnCullStateChanged:
m_PersistentCalls:
m_Calls: []
m_Sprite: {fileID: 10907, guid: 0000000000000000f000000000000000, type: 0}
m_Type: 1
m_PreserveAspect: 0
m_FillCenter: 1
m_FillMethod: 4
m_FillAmount: 1
m_FillClockwise: 1
m_FillOrigin: 0
m_UseSpriteMesh: 0
m_PixelsPerUnitMultiplier: 1
fileFormatVersion: 2
guid: 236427918458785468859e58cabe08f9
PrefabImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
fileFormatVersion: 2
guid: 6749548d6322bd8499f25778b385dd24
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
<?xml version="1.0" encoding="utf-8"?>
<items>
<item id="6" name="bg.wav" volume="1" />
</items>
\ No newline at end of file
fileFormatVersion: 2
guid: ca4065d24afeda2419dfeecade19ec95
timeCreated: 1494937370
licenseType: Pro
TextScriptImporter:
userData:
assetBundleName:
assetBundleVariant:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<item key="1" value="你好Unity,我是I18" />
</resources>
\ No newline at end of file
fileFormatVersion: 2
guid: 842003ba86b568843a0aa08f5cee09c3
timeCreated: 1496649557
licenseType: Pro
TextScriptImporter:
userData:
assetBundleName:
assetBundleVariant:
<?xml version="1.0" encoding="utf-8"?>
<items>
<item id="1" editorPath="Font/fz_CuoYuan.prefab" version="2021/10/15" desc="粗圆字体" />
<item id="2" editorPath="Font/fz_ZhunYuan.prefab" version="2021/10/15" desc="细圆字体" />
<item id="3" editorPath="UIPrefabs/LoginPanel.prefab" version="2021/10/15" desc="测试界面" />
<item id="4" editorPath="Effects/Particle System.prefab" version="2021/10/15" desc="粒子" />
<item id="5" editorPath="Atlas/CommonUI.spriteatlas" version="2021/10/15" desc="图集" />
<item id="6" editorPath="Audios/bg.wav" version="2021/10/15" desc="背景音乐" />
<item id="7" editorPath="3D/Cube.prefab" version="2021/10/15" desc="Cube" />
<item id="8" editorPath="BaseRes/TestPanel.prefab" version="2021/10/15" desc="测试界面" />
</items>
\ No newline at end of file
fileFormatVersion: 2
guid: e129108de049b0c44aa9f77a5d8f5ea0
timeCreated: 1494419087
licenseType: Pro
TextScriptImporter:
userData:
assetBundleName:
assetBundleVariant:
<?xml version="1.0" encoding="utf-8"?>
<items>
<item name="framebg" atlas="CommonUI.spriteatlas" resId="5"/>
<item name="frame" atlas="CommonUI.spriteatlas" resId="5"/>
<item name="btn" atlas="CommonUI.spriteatlas" resId="5"/>
</items>
fileFormatVersion: 2
guid: 4d4f2a91693b7b24da3933eec8dac3b1
TextScriptImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
fileFormatVersion: 2
guid: 1f4ca90ceb5fcde40a03a4613a338445
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
此差异已折叠。
fileFormatVersion: 2
guid: 834550a46c42e5844b53acb151a497aa
PrefabImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
fileFormatVersion: 2
guid: eef5e9aa288db0840971ac8bed7b6b37
folderAsset: yes
timeCreated: 1494417354
licenseType: Pro
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:
此差异已折叠。
fileFormatVersion: 2
guid: 6797f7019bb73da4faf167c561c4a0ae
timeCreated: 1494417389
licenseType: Pro
NativeFormatImporter:
userData:
assetBundleName:
assetBundleVariant:
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
skynet @ 0ae839b2
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册