diff options
Diffstat (limited to 'Client/Assets/Scripts/XEditor')
69 files changed, 19034 insertions, 0 deletions
diff --git a/Client/Assets/Scripts/XEditor/AssetModify.cs b/Client/Assets/Scripts/XEditor/AssetModify.cs new file mode 100644 index 00000000..b6ab0cbe --- /dev/null +++ b/Client/Assets/Scripts/XEditor/AssetModify.cs @@ -0,0 +1,11389 @@ +#if UNITY_EDITOR
+using System.Collections.Generic;
+using System.IO;
+using UnityEditor;
+using UnityEngine;
+using XUtliPoolLib;
+using System;
+using System.Text;
+using System.Reflection;
+using UnityEditor.SceneManagement;
+using System.Xml.Serialization;
+
+namespace XEditor
+{
+ public enum ETextureCompress
+ {
+ Compress,
+ TrueColor,
+ RGB16
+ }
+ public enum ETextureSize
+ {
+ Original,
+ Half,
+ Quarter,
+ X32,
+ X64,
+ X128,
+ X256,
+ X512,
+ }
+
+
+ public class AssetModify : EditorWindow
+ {
+ public delegate void EnumAssetPreprocessCallback(string path);
+
+ public delegate bool EnumAssetImportCallback<T, I>(T obj, I assetImporter, string path)
+ where T : UnityEngine.Object where I : UnityEditor.AssetImporter;
+
+ public delegate void EnumAssetCallback<T>(T obj, string path)
+ where T : UnityEngine.Object;
+
+ public class ObjectInfo
+ {
+ public UnityEngine.Object obj = null;
+ public string path = "";
+ }
+ public interface IAssetLoadCallback
+ {
+ bool verbose { get; }
+ List<ObjectInfo> GetObjects(string dir);
+
+ void PreProcess(string path);
+ bool Process(UnityEngine.Object asset, string path);
+ void PostProcess(string path);
+ }
+ public class BaseAssetLoadCallback<T> where T : UnityEngine.Object
+ {
+ public bool is_verbose = true;
+ public string extFilter = "";
+ public string extFilter1 = "";
+ protected List<ObjectInfo> m_Objects = new List<ObjectInfo>();
+ private static string assetsRoot = "Assets/";
+ public BaseAssetLoadCallback(string ext)
+ {
+ extFilter = ext;
+ }
+ public BaseAssetLoadCallback(string ext, string ext1)
+ {
+ extFilter = ext;
+ extFilter1 = ext1;
+ }
+
+ public bool verbose { get { return is_verbose; } }
+ private void GetObjectsInfolder(FileInfo[] files)
+ {
+ for (int i = 0; i < files.Length; ++i)
+ {
+ FileInfo file = files[i];
+ string fileName = file.FullName.Replace("\\", "/");
+ int index = fileName.IndexOf(assetsRoot);
+ fileName = fileName.Substring(index);
+ ObjectInfo oi = new ObjectInfo();
+ oi.path = fileName;
+ oi.obj = AssetDatabase.LoadAssetAtPath<T>(fileName);
+ m_Objects.Add(oi);
+ }
+
+ }
+ private void GetObjectsInfolder(string path)
+ {
+ DirectoryInfo di = new DirectoryInfo(path);
+ FileInfo[] files = di.GetFiles(extFilter, SearchOption.AllDirectories);
+ GetObjectsInfolder(files);
+ if (!string.IsNullOrEmpty(extFilter1))
+ {
+ files = di.GetFiles(extFilter1, SearchOption.AllDirectories);
+ GetObjectsInfolder(files);
+ }
+
+ }
+
+ private void GetObjectsInfolder(UnityEditor.DefaultAsset folder)
+ {
+ string path = AssetDatabase.GetAssetPath(folder);
+ GetObjectsInfolder(path);
+ }
+
+ public List<ObjectInfo> GetObjects(string dir)
+ {
+ m_Objects.Clear();
+ if(string.IsNullOrEmpty(dir))
+ {
+ UnityEngine.Object[] objs = Selection.GetFiltered(typeof(UnityEngine.Object), SelectionMode.Assets);
+ for (int i = 0; i < objs.Length; ++i)
+ {
+ UnityEngine.Object obj = objs[i];
+ if (obj is UnityEditor.DefaultAsset)
+ {
+ GetObjectsInfolder(obj as UnityEditor.DefaultAsset);
+ }
+ else
+ {
+ if (obj is T)
+ {
+ string path = AssetDatabase.GetAssetPath(obj);
+ ObjectInfo oi = new ObjectInfo();
+ oi.obj = obj;
+ oi.path = path;
+ m_Objects.Add(oi);
+ }
+ }
+ }
+ }
+ else
+ {
+ GetObjectsInfolder(dir);
+ }
+ return m_Objects;
+ }
+ }
+
+ public class AssetLoadCallback<T, I> : BaseAssetLoadCallback<T>, IAssetLoadCallback
+ where T : UnityEngine.Object where I : UnityEditor.AssetImporter
+ {
+ public EnumAssetPreprocessCallback preprocess = null;
+ public EnumAssetImportCallback<T, I> cb = null;
+
+ public AssetLoadCallback(string ext)
+ :base(ext)
+ {
+ }
+ public AssetLoadCallback(string ext, string ext1)
+ : base(ext, ext1)
+ {
+ }
+
+ public virtual void PreProcess(string path)
+ {
+ if (preprocess != null)
+ {
+ preprocess(path);
+ }
+ }
+ public virtual bool Process(UnityEngine.Object asset, string path)
+ {
+ T obj = asset as T;
+ if (cb != null && obj != null)
+ {
+ I assetImporter = AssetImporter.GetAtPath(path) as I;
+ return cb(obj, assetImporter, path);
+ }
+ return false;
+ }
+
+ public virtual void PostProcess(string path)
+ {
+ AssetDatabase.ImportAsset(path, ImportAssetOptions.ForceUpdate);
+ }
+ }
+ public class AssetLoadCallback<T> : BaseAssetLoadCallback<T>, IAssetLoadCallback where T : UnityEngine.Object
+ {
+ public EnumAssetCallback<T> cb = null;
+ public AssetLoadCallback(string ext)
+ : base(ext)
+ {
+ }
+ public AssetLoadCallback(string ext, string ext1)
+ : base(ext, ext1)
+ {
+ }
+ public virtual void PreProcess(string path)
+ {
+
+ }
+ public virtual bool Process(UnityEngine.Object asset, string path)
+ {
+ T obj = asset as T;
+ if (cb != null && obj != null)
+ {
+ cb(obj, path);
+ }
+ return false;
+ }
+
+ public virtual void PostProcess(string path)
+ {
+ }
+ }
+
+ public delegate bool EnumFbxCallback<GameObject, ModelImporter>(GameObject fbx, ModelImporter modelImporter, string path);
+ public delegate bool EnumTex2DCallback<Texture2D, TextureImporter>(Texture2D tex, TextureImporter textureImporter, string path);
+
+ private static AssetLoadCallback<GameObject, ModelImporter> enumFbx = new AssetLoadCallback<GameObject, ModelImporter>("*.fbx");
+ public static AssetLoadCallback<Texture2D, TextureImporter> enumTex2D = new AssetLoadCallback<Texture2D, TextureImporter>("*.png", "*.tga");
+
+ public delegate void EnumPrefabCallback<GameObject>(GameObject prefab, string path);
+ public delegate void EnumTxtCallback<TextAsset>(TextAsset txt, string path);
+ public delegate void EnumMaterialCallback<Material>(Material mat, string path);
+ public delegate void EnumMeshCallback<Mesh>(Mesh mesh, string path);
+ public delegate void EnumAnimationCallback<AnimationClip>(AnimationClip animClip, string path);
+ public delegate void EnumBytesCallback<TextAsset>(TextAsset bytes, string path);
+
+ private static AssetLoadCallback<GameObject> enumPrefab = new AssetLoadCallback<GameObject>("*.prefab");
+ private static AssetLoadCallback<TextAsset> enumTxt = new AssetLoadCallback<TextAsset>("*.bytes", "*.txt");
+ private static AssetLoadCallback<Material> enumMat = new AssetLoadCallback<Material>("*.mat");
+ private static AssetLoadCallback<Mesh> enumMesh = new AssetLoadCallback<Mesh>("*.asset");
+ private static AssetLoadCallback<AnimationClip> enumAnimationClip = new AssetLoadCallback<AnimationClip>("*.anim");
+
+ public static T CreateOrReplaceAsset<T>(T asset, string path) where T : UnityEngine.Object
+ {
+ T existingAsset = null;
+ if (asset is Texture2D)
+ {
+ Texture2D tex = asset as Texture2D;
+ byte[] png = tex.EncodeToPNG();
+ path = path.ToLower();
+ if (path.EndsWith(".tga"))
+ {
+ path = path.Replace(".tga", ".png");
+ }
+ File.WriteAllBytes(path, png);
+ existingAsset = AssetDatabase.LoadAssetAtPath<T>(path);
+ }
+ else
+ {
+ existingAsset = AssetDatabase.LoadAssetAtPath<T>(path);
+
+ if (existingAsset == null)
+ {
+ if (asset is Texture2D)
+ {
+ Texture2D tex = asset as Texture2D;
+ byte[] png = tex.EncodeToPNG();
+ path = path.ToLower();
+ if (path.EndsWith(".tga"))
+ {
+ path = path.Replace(".tga", ".png");
+ }
+ File.WriteAllBytes(path, png);
+ existingAsset = AssetDatabase.LoadAssetAtPath<T>(path);
+ }
+ else
+ {
+ AssetDatabase.CreateAsset(asset, path);
+ AssetDatabase.SaveAssets();
+ existingAsset = asset;
+ }
+
+ }
+ else
+ {
+ EditorUtility.CopySerializedIfDifferent(asset, existingAsset);
+ }
+
+ }
+
+ return existingAsset;
+ }
+
+ public static void CreateOrReplacePrefab(GameObject prefab, string path)
+ {
+ GameObject go = AssetDatabase.LoadAssetAtPath<GameObject>(path);
+
+ if (go == null)
+ {
+ PrefabUtility.CreatePrefab(path, prefab, ReplacePrefabOptions.ReplaceNameBased);
+ }
+ else
+ {
+ PrefabUtility.ReplacePrefab(prefab, go);
+ }
+ }
+ public static void ProcessRender(Renderer render, bool on = false)
+ {
+ render.lightProbeUsage = UnityEngine.Rendering.LightProbeUsage.Off;
+ render.shadowCastingMode = on ? UnityEngine.Rendering.ShadowCastingMode.On : UnityEngine.Rendering.ShadowCastingMode.Off;
+ render.receiveShadows = on;
+ render.reflectionProbeUsage = UnityEngine.Rendering.ReflectionProbeUsage.Off;
+ render.motionVectorGenerationMode = MotionVectorGenerationMode.ForceNoMotion;
+ }
+ public static void ProcessSkinMesh(SkinnedMeshRenderer smr)
+ {
+ ProcessRender(smr);
+ smr.skinnedMotionVectors = false;
+ smr.updateWhenOffscreen = false;
+ }
+
+ public static int ReplaceAvatar(Avatar avatar, out Avatar newAvatar)
+ {
+ newAvatar = avatar;
+ string path = AssetDatabase.GetAssetPath(avatar);
+ path = path.ToLower();
+ if (path.EndsWith(".fbx"))
+ {
+ int index = path.LastIndexOf("/");
+ if (index >= 0)
+ {
+ string dir = path.Substring(0, index);
+ string name = path.Substring(index + 1);
+ index = name.LastIndexOf(".");
+ name = name.Substring(0, index);
+ string avatarPath = string.Format("{0}/{1}_avatar.asset", dir, name);
+ if (avatarPath != path)
+ {
+ newAvatar = AssetDatabase.LoadAssetAtPath<Avatar>(avatarPath);
+ if (newAvatar == null || avatar == newAvatar)
+ {
+ return -1;
+ }
+ else
+ {
+ return 1;
+ }
+ }
+ }
+ }
+ return 0;
+ }
+ public static bool CheckRender(Renderer render)
+ {
+ return render.shadowCastingMode == UnityEngine.Rendering.ShadowCastingMode.Off &&
+ render.receiveShadows == false &&
+ render.reflectionProbeUsage == UnityEngine.Rendering.ReflectionProbeUsage.Off &&
+ render.motionVectorGenerationMode == MotionVectorGenerationMode.ForceNoMotion &&
+ render.lightProbeUsage == UnityEngine.Rendering.LightProbeUsage.Off;
+ }
+ public static bool CheckSkinMesh(SkinnedMeshRenderer smr)
+ {
+ return CheckRender(smr) &&
+ smr.skinnedMotionVectors == false &&
+ smr.updateWhenOffscreen == false;
+ }
+
+ public static void GetGameObjectComponent<T>(GameObject go, List<T> lst) where T : Component
+ {
+ T com = go.GetComponent<T>();
+ if (com != null)
+ {
+ lst.Add(com);
+ }
+ Transform t = go.transform;
+ for (int i = 0; i < t.childCount; ++i)
+ {
+ Transform child = t.GetChild(i);
+ GetGameObjectComponent<T>(child.gameObject, lst);
+ }
+ }
+
+ public static void EnumAsset<T>(IAssetLoadCallback cb, string title, string dir = "") where T : UnityEngine.Object
+ {
+ if (cb != null)
+ {
+ List<ObjectInfo> objInfoLst = cb.GetObjects(dir);
+ for (int i = 0; i < objInfoLst.Count; ++i)
+ {
+ ObjectInfo oi = objInfoLst[i];
+ T asset = oi.obj as T;
+ if (asset != null)
+ {
+ cb.PreProcess(oi.path);
+ if (cb.Process(asset, oi.path))
+ {
+ cb.PostProcess(oi.path);
+ }
+ }
+ if (cb.verbose)
+ EditorUtility.DisplayProgressBar(string.Format("{0}-{1}/{2}", title, i, objInfoLst.Count), oi.path, (float)i / objInfoLst.Count);
+ }
+ }
+
+ AssetDatabase.Refresh();
+ if (cb.verbose)
+ {
+ EditorUtility.ClearProgressBar();
+ EditorUtility.DisplayDialog("Finish", "All assets processed finish", "OK");
+ }
+ }
+
+ #region texture
+ private static int scaleSize = 2;
+ private static TextureImporterPlatformSettings tips = null;
+ public static int GetSize(int srcSize, ETextureSize size)
+ {
+ switch (size)
+ {
+ case ETextureSize.Original:
+ return srcSize;
+ case ETextureSize.Half:
+ return srcSize / 2;
+ case ETextureSize.Quarter:
+ return srcSize / 4;
+ case ETextureSize.X32:
+ return 32;
+ case ETextureSize.X64:
+ return 64;
+ case ETextureSize.X128:
+ return 128;
+ case ETextureSize.X256:
+ return 256;
+ case ETextureSize.X512:
+ return 512;
+ }
+ return srcSize;
+ }
+ public static void MakeTexReadable(Texture2D tex, TextureImporter texImporter, bool readable)
+ {
+ texImporter.isReadable = readable;
+ string path = AssetDatabase.GetAssetPath(tex);
+ AssetDatabase.ImportAsset(path, ImportAssetOptions.ForceUpdate);
+ }
+
+ public static bool HasAlpha(Texture2D tex, TextureImporter texImporter, bool forceConvert = false)
+ {
+ if (forceConvert)
+ {
+ texImporter.isReadable = true;
+ SetTexImportSetting(texImporter, "", 1024, TextureImporterFormat.RGBA32);
+ string path = AssetDatabase.GetAssetPath(tex);
+ AssetDatabase.ImportAsset(path, ImportAssetOptions.ForceUpdate);
+
+ }
+ if (texImporter.isReadable)
+ {
+ Color[] colors = tex.GetPixels();
+ for (int j = 0; j < colors.Length; j++)
+ if (colors[j].a < 1f)
+ {
+ return true;
+ }
+ return false;
+ }
+ return texImporter.DoesSourceTextureHaveAlpha();
+ }
+ public static void GetTexFormat(bool isAtlas, string userData, out ETextureCompress format, out ETextureSize size)
+ {
+ format = ETextureCompress.Compress;
+ size = isAtlas ? ETextureSize.Original : ETextureSize.Half;
+ if (!string.IsNullOrEmpty(userData))
+ {
+ string[] str = userData.Split(' ');
+ if (str.Length > 0)
+ {
+ try
+ {
+ format = (ETextureCompress)int.Parse(str[0]);
+ }
+ catch (Exception)
+ {
+
+ }
+ }
+ if (str.Length > 1)
+ {
+ try
+ {
+ size = (ETextureSize)int.Parse(str[1]);
+ }
+ catch (Exception)
+ {
+
+ }
+ }
+ }
+ }
+ public static string GetCurrentPlatformName()
+ {
+#if UNITY_ANDROID
+ return "Android";
+#elif UNITY_IOS
+ return "iPhone";
+#else
+ return "Standalone";
+#endif
+ }
+ public static void SetTexImportSetting(TextureImporter texImporter, string platform, int size, TextureImporterFormat format, bool overrideOpt = true)
+ {
+ if (tips == null)
+ {
+ tips = new TextureImporterPlatformSettings();
+ }
+ if (string.IsNullOrEmpty(platform))
+ {
+ tips.name = GetCurrentPlatformName();
+ }
+ else
+ {
+ tips.name = platform;
+ }
+
+ tips.overridden = overrideOpt;
+ tips.maxTextureSize = size;
+ tips.format = format;
+ texImporter.SetPlatformTextureSettings(tips);
+ }
+
+ [MenuItem(@"Assets/Tool/Texture/Compress", false, 0)]
+ private static void Compress()
+ {
+ Rect wr = new Rect(0, 0, 300, 400);
+ TextureCommonCompress window = (TextureCommonCompress)EditorWindow.GetWindowWithRect(typeof(TextureCommonCompress), wr, true, "压缩贴图");
+ window.Show();
+ }
+
+ public static Texture2D MakeAlphaRTex(string alphaTexPath, int size, Texture2D src)
+ {
+ Texture2D alphaTex = new Texture2D(src.width, src.height, TextureFormat.ARGB32, false);
+ for (int y = 0, ymax = src.height; y < ymax; ++y)
+ {
+ for (int x = 0, xmax = src.width; x < xmax; ++x)
+ {
+ Color c0 = src.GetPixel(x, y);
+ Color a = new Color(c0.a, 1, 1, 1);
+ alphaTex.SetPixel(x, y, a);
+ }
+ }
+
+ byte[] bytes = alphaTex.EncodeToPNG();
+
+ File.WriteAllBytes(alphaTexPath, bytes);
+ AssetDatabase.ImportAsset(alphaTexPath, ImportAssetOptions.ForceUpdate);
+
+ TextureImporter alphaTextureImporter = AssetImporter.GetAtPath(alphaTexPath) as TextureImporter;
+ if (alphaTextureImporter != null)
+ {
+ int alphaSize = size;
+ alphaTextureImporter.textureType = TextureImporterType.Default;
+ alphaTextureImporter.anisoLevel = 0;
+ alphaTextureImporter.mipmapEnabled = false;
+ alphaTextureImporter.isReadable = false;
+ alphaTextureImporter.npotScale = TextureImporterNPOTScale.ToNearest;
+ SetTexImportSetting(alphaTextureImporter, BuildTarget.Android.ToString(), alphaSize, TextureImporterFormat.ETC_RGB4);
+ SetTexImportSetting(alphaTextureImporter, "iPhone", alphaSize, TextureImporterFormat.PVRTC_RGB4);
+ AssetDatabase.ImportAsset(alphaTexPath, ImportAssetOptions.ForceUpdate);
+ }
+ return AssetDatabase.LoadAssetAtPath(alphaTexPath, typeof(Texture2D)) as Texture2D;
+ }
+
+ public static Texture2D ConvertTexRtex(Texture2D src)
+ {
+ string texPath = AssetDatabase.GetAssetPath(src);
+ int index = texPath.LastIndexOf('.');
+ string alphaTexPath = texPath.Substring(0, index) + "_A.png";
+ int size = src.width > src.height ? src.width : src.height;
+ TextureImporter texImporter = AssetImporter.GetAtPath(texPath) as TextureImporter;
+
+ texImporter.textureType = TextureImporterType.Default;
+ texImporter.anisoLevel = 0;
+ texImporter.mipmapEnabled = src.width > 256 && src.height > 256;
+ texImporter.npotScale = TextureImporterNPOTScale.ToNearest;
+ texImporter.wrapMode = TextureWrapMode.Repeat;
+ texImporter.filterMode = FilterMode.Bilinear;
+ SetTexImportSetting(texImporter, BuildTarget.Android.ToString(), size, TextureImporterFormat.RGBA32);
+ SetTexImportSetting(texImporter, "iPhone", size, TextureImporterFormat.RGBA32);
+ SetTexImportSetting(texImporter, "Standalone", size, TextureImporterFormat.RGBA32);
+ texImporter.isReadable = true;
+ AssetDatabase.ImportAsset(texPath, ImportAssetOptions.ForceUpdate);
+ Texture2D alphaTex = null;
+ if (HasAlpha(src, texImporter))
+ {
+ alphaTex = MakeAlphaRTex(alphaTexPath, size / scaleSize, src);
+ }
+ SetTexImportSetting(texImporter, BuildTarget.Android.ToString(), size, TextureImporterFormat.ETC_RGB4);
+ SetTexImportSetting(texImporter, "iPhone", size, TextureImporterFormat.PVRTC_RGB4);
+ if (alphaTex != null)
+ {
+ SetTexImportSetting(texImporter, "Standalone", size, TextureImporterFormat.DXT5);
+ }
+ else
+ {
+ SetTexImportSetting(texImporter, "Standalone", size, TextureImporterFormat.DXT1);
+ }
+ texImporter.isReadable = false;
+ AssetDatabase.ImportAsset(texPath, ImportAssetOptions.ForceUpdate);
+ return alphaTex;
+ }
+
+ public static void DefaultCompressTex(Texture2D src, string path, bool disableMipmap, bool forceSquare)
+ {
+ TextureImporter textureImporter = AssetImporter.GetAtPath(path) as TextureImporter;
+ isSeperateAlpha = !path.StartsWith("Assets/Effect");
+ isForceSquare = forceSquare;
+ isDisableMipmap = disableMipmap;
+ _DefaultCompress(src, textureImporter, path);
+ isDisableMipmap = false;
+ AssetDatabase.ImportAsset(path, ImportAssetOptions.ForceUpdate);
+ }
+ public static void EnableMipmap(Texture2D src, string path, bool enable)
+ {
+ TextureImporter textureImporter = AssetImporter.GetAtPath(path) as TextureImporter;
+ if (textureImporter.mipmapEnabled)
+ {
+ textureImporter.mipmapEnabled = enable;
+ AssetDatabase.ImportAsset(path, ImportAssetOptions.ForceUpdate);
+ }
+ }
+ static bool isSeperateAlpha = true;
+ static bool isDisableMipmap = false;
+ static bool isForceSquare = false;
+ public static bool _DefaultCompress(Texture2D tex, TextureImporter textureImporter, string path)
+ {
+ if (path.IndexOf("_A.") >= 0 || path.IndexOf("_NRM.") >= 0)
+ return false;
+ int size = tex.width > tex.height ? tex.width : tex.height;
+ textureImporter.textureType = TextureImporterType.Default;
+ textureImporter.anisoLevel = 0;
+ textureImporter.mipmapEnabled = isDisableMipmap ? false : tex.height > 256 && tex.height > 256;
+ textureImporter.npotScale = TextureImporterNPOTScale.ToNearest;
+ textureImporter.wrapMode = TextureWrapMode.Repeat;
+ textureImporter.filterMode = FilterMode.Bilinear;
+ SetTexImportSetting(textureImporter, BuildTarget.Android.ToString(), size, TextureImporterFormat.RGBA32);
+ int iosSize = size;
+ if (isForceSquare)
+ {
+ iosSize = tex.width > tex.height ? tex.height : tex.width;
+ }
+ SetTexImportSetting(textureImporter, "iPhone", iosSize, TextureImporterFormat.RGBA32);
+ textureImporter.isReadable = true;
+ AssetDatabase.ImportAsset(path, ImportAssetOptions.ForceUpdate);
+ bool hasAlpha = false;
+ if (HasAlpha(tex, textureImporter))
+ {
+ hasAlpha = true;
+ if (isSeperateAlpha)
+ {
+ int extIndex = path.LastIndexOf(".");
+ if (extIndex >= 0)
+ {
+ string alphaTexPath = path.Substring(0, extIndex) + "_A.png";
+ MakeAlphaRTex(alphaTexPath, size / 2, tex);
+ }
+ }
+
+ }
+ if (isSeperateAlpha || !hasAlpha)
+ {
+ SetTexImportSetting(textureImporter, "Standalone", size, TextureImporterFormat.DXT1);
+ SetTexImportSetting(textureImporter, BuildTarget.Android.ToString(), size, TextureImporterFormat.ETC_RGB4);
+ if (tex.width / tex.height >= 4 || tex.height / tex.width >= 4)
+ {
+ SetTexImportSetting(textureImporter, "iPhone", size, TextureImporterFormat.RGB16);
+ }
+ else
+ {
+ SetTexImportSetting(textureImporter, "iPhone", iosSize, TextureImporterFormat.PVRTC_RGB4);
+ }
+
+ }
+ else
+ {
+ SetTexImportSetting(textureImporter, "Standalone", size, TextureImporterFormat.DXT5);
+ SetTexImportSetting(textureImporter, BuildTarget.Android.ToString(), size, TextureImporterFormat.RGBA16);
+ if (tex.width / tex.height >= 4 || tex.height / tex.width >= 4)
+ {
+ SetTexImportSetting(textureImporter, "iPhone", size, TextureImporterFormat.RGB16);
+ }
+ else
+ {
+ SetTexImportSetting(textureImporter, "iPhone", size, TextureImporterFormat.PVRTC_RGBA4);
+ }
+
+ }
+ textureImporter.isReadable = false;
+ return true;
+ }
+
+ public static void DefaultCompress(Texture2D tex, TextureImporter textureImporter, string path, bool mipmap)
+ {
+ if (path.IndexOf("_A.") >= 0 || path.IndexOf("_NRM.") >= 0)
+ return;
+ int size = tex.width > tex.height ? tex.width : tex.height;
+ textureImporter.textureType = TextureImporterType.Default;
+ textureImporter.anisoLevel = 0;
+ textureImporter.mipmapEnabled = tex.height > 256 && tex.height > 256 && mipmap;
+ textureImporter.npotScale = TextureImporterNPOTScale.ToNearest;
+ textureImporter.wrapMode = TextureWrapMode.Clamp;
+ textureImporter.filterMode = FilterMode.Bilinear;
+ SetTexImportSetting(textureImporter, BuildTarget.Android.ToString(), size, TextureImporterFormat.RGBA32);
+ SetTexImportSetting(textureImporter, "iPhone", size, TextureImporterFormat.RGBA32);
+ textureImporter.isReadable = true;
+ AssetDatabase.ImportAsset(path, ImportAssetOptions.ForceUpdate);
+ bool hasAlpha = false;
+ if (HasAlpha(tex, textureImporter))
+ {
+ hasAlpha = true;
+ if (isSeperateAlpha)
+ {
+ int extIndex = path.LastIndexOf(".");
+ if (extIndex >= 0)
+ {
+ string alphaTexPath = path.Substring(0, extIndex) + "_A.png";
+ MakeAlphaRTex(alphaTexPath, size / 2, tex);
+ }
+ }
+
+ }
+ if (isSeperateAlpha || !hasAlpha)
+ {
+ SetTexImportSetting(textureImporter, "Standalone", size, TextureImporterFormat.DXT1);
+ SetTexImportSetting(textureImporter, BuildTarget.Android.ToString(), size, TextureImporterFormat.ETC_RGB4);
+ SetTexImportSetting(textureImporter, "iPhone", size, TextureImporterFormat.PVRTC_RGB4);
+ }
+ else
+ {
+ SetTexImportSetting(textureImporter, "Standalone", size, TextureImporterFormat.DXT5);
+ SetTexImportSetting(textureImporter, BuildTarget.Android.ToString(), size, TextureImporterFormat.RGBA16);
+ SetTexImportSetting(textureImporter, "iPhone", size, TextureImporterFormat.PVRTC_RGBA4);
+ }
+ textureImporter.isReadable = false;
+ AssetDatabase.ImportAsset(path, ImportAssetOptions.ForceUpdate);
+ }
+ [MenuItem(@"Assets/Tool/Texture/DefaultCompress %1", false, 0)]
+ private static void DefaultCompress()
+ {
+ isSeperateAlpha = true;
+ enumTex2D.cb = _DefaultCompress;
+ EnumAsset<Texture2D>(enumTex2D, "DefaultCompress");
+ }
+ [MenuItem(@"Assets/Tool/Texture/DefaultCompressNoSeperate %5", false, 0)]
+ private static void DefaultCompressNoSeperate()
+ {
+ isSeperateAlpha = false;
+ enumTex2D.cb = _DefaultCompress;
+ EnumAsset<Texture2D>(enumTex2D, "DefaultCompressNoSeperate");
+ }
+ [MenuItem(@"Assets/Tool/Texture/TextureCombine", false, 0)]
+ private static void CombineTex()
+ {
+ Rect wr = new Rect(0, 0, 800, 800);
+ TextureCombine window = (TextureCombine)EditorWindow.GetWindowWithRect(typeof(TextureCombine), wr, true, "合并贴图");
+ window.Show();
+ }
+
+ private static bool _SplitTex(Texture2D tex, TextureImporter textureImporter, string path)
+ {
+ TextureCombine.SplitTexture(tex, textureImporter, true);
+ return false;
+ }
+
+ [MenuItem(@"Assets/Tool/Texture/SplitTex", false, 0)]
+ public static void SplitTex()
+ {
+ enumTex2D.cb = _SplitTex;
+ EnumAsset<Texture2D>(enumTex2D, "SplitTex");
+ }
+
+ [MenuItem(@"Assets/Tool/Texture/ShadowTex", false, 0)]
+ public static void ShadowTex()
+ {
+ int width = 32;
+ int height = 32;
+ Color[] edgeColor = new Color[]
+ { Color.white,
+ new Color(0.8f, 0.8f, 0.8f, 0.8f),
+ new Color(0.6f, 0.6f, 0.6f, 0.6f),
+ new Color(0.4f, 0.4f, 0.4f, 0.4f),
+ new Color(0.2f, 0.2f, 0.2f, 0.2f)
+ };
+ Texture2D tex = new Texture2D(width, height, TextureFormat.RGBA32, false);
+
+ for (int y = 0; y < height; ++y)
+ {
+ for (int x = 0; x < width; ++x)
+ {
+ bool inColorRange = false;
+ for (int i = 0; i < edgeColor.Length; ++i)
+ {
+ if(x == i || x == width - 1 - i || y == i || y == height - 1 - i)
+ {
+ tex.SetPixel(x, y, edgeColor[i]);
+ inColorRange = true;
+ break;
+ }
+ }
+ if(!inColorRange)
+ {
+ tex.SetPixel(x, y, Color.black);
+ }
+ }
+ }
+
+ CreateOrReplaceAsset<Texture2D>(tex, "Assets/Resources/Shader/Shadow/ShadowMask.png");
+ AssetDatabase.Refresh();
+ }
+
+ private static bool _Find2ValueAlphaTex(Texture2D tex, TextureImporter textureImporter, string path)
+ {
+ textureImporter.isReadable = true;
+ TextureImporterPlatformSettings tips = textureImporter.GetPlatformTextureSettings(GetCurrentPlatformName());
+ TextureImporterFormat format = tips.format;
+ SetTexImportSetting(textureImporter, "", tips.maxTextureSize, TextureImporterFormat.RGBA32);
+ textureImporter.isReadable = true;
+ AssetDatabase.ImportAsset(path, ImportAssetOptions.ForceUpdate);
+
+ if (textureImporter.isReadable)
+ {
+ bool not2Value = false;
+ Color[] colors = tex.GetPixels();
+ for (int j = 0; j < colors.Length; j++)
+ {
+ float a = colors[j].a;
+ if (a < 0.99f && a > 0.09)
+ {
+ not2Value = true;
+ break;
+ }
+ }
+ if (!not2Value)
+ {
+ Debug.LogWarning("2 value tex:" + path);
+ }
+ }
+ textureImporter.isReadable = false;
+ SetTexImportSetting(textureImporter, "", tips.maxTextureSize, format);
+ return true;
+ }
+
+ [MenuItem(@"Assets/Tool/Texture/Find2ValueAlphaTex", false, 0)]
+ public static void Find2ValueAlphaTex()
+ {
+#if UNITY_ANDROID
+ enumTex2D.cb = _Find2ValueAlphaTex;
+ EnumAsset<Texture2D>(enumTex2D, "Find2ValueAlphaTex");
+
+#else
+ Debug.LogError("Only supported in android platform");
+#endif
+ }
+ #endregion texture
+ #region UI
+
+ private static bool onlyAtlas = false;
+
+ public struct ConvertInfo
+ {
+ public bool mipmap;
+ public bool isAlpha;
+ public Texture2D srcTex;
+ public TextureImporter textureImporter;
+ public string path;
+ public string name;
+ public string resourcePath;
+ public string alphaResourcePath;
+ public string alphaTexPath;
+ public ETextureCompress srcFormat;
+ public ETextureSize alphaSize;
+ public bool isAtlas;
+ }
+
+ //public struct TexProcessInfo
+ //{
+ // public string name;
+ // public string path;
+ // public TextureImporter textureImporter;
+ // public bool halfSize;
+ //}
+
+
+ private static bool GetTexPath(ref ConvertInfo ci)
+ {
+ ci.isAlpha = ci.path.IndexOf("_A.png") >= 0;
+ if (ci.isAlpha)
+ return false;
+ ci.name = ci.path;
+ ci.alphaResourcePath = ci.path;
+ ci.alphaTexPath = ci.path;
+ int extIndex = ci.name.LastIndexOf(".");
+ if (extIndex >= 0)
+ {
+ ci.name = ci.name.Substring(0, extIndex);
+ string relativePath = "Assets/Resources/";
+ ci.name = ci.name.Substring(relativePath.Length);
+ ci.resourcePath = ci.name;
+
+ int nameIndex = ci.name.LastIndexOf("/");
+ if (nameIndex >= 0)
+ {
+ ci.name = ci.name.Substring(nameIndex + 1);
+ }
+ if (!ci.isAlpha)
+ {
+ if (ci.path.StartsWith("Assets/Resources/atlas/UI"))
+ {
+ ci.alphaResourcePath = "atlas/UI/Alpha/" + ci.name + "_A";
+ ci.alphaTexPath = "Assets/Resources/atlas/UI/Alpha/" + ci.name + "_A.png";
+ }
+ else
+ {
+ ci.alphaResourcePath = ci.resourcePath + "_A";
+ ci.alphaTexPath = ci.path.Replace(".png", "_A.png");
+ }
+ }
+ return true;
+ }
+ return false;
+ }
+
+ private static void _ProcessTexture(ref ConvertInfo ci, bool import, bool isUI = false)
+ {
+ ci.textureImporter.textureType = TextureImporterType.Default;
+ ci.textureImporter.anisoLevel = 0;
+ ci.textureImporter.mipmapEnabled = ci.mipmap;
+ ci.textureImporter.npotScale = TextureImporterNPOTScale.ToNearest;
+ ci.textureImporter.wrapMode = TextureWrapMode.Clamp;
+ ci.textureImporter.filterMode = FilterMode.Bilinear;
+ ci.textureImporter.isReadable = false;
+ int srcSize = 1024;
+ if (ci.srcTex != null)
+ {
+ srcSize = ci.srcTex.width > ci.srcTex.height ? ci.srcTex.width : ci.srcTex.height;
+ }
+ //XUITextureImporterData data = ci.dataSet.Find(ci.name);
+ //if (data != null)
+ {
+ if (ci.isAlpha)
+ {
+ int size = GetSize(srcSize, ci.alphaSize);
+ SetTexImportSetting(ci.textureImporter, BuildTarget.Android.ToString(), size, TextureImporterFormat.Alpha8);
+ SetTexImportSetting(ci.textureImporter, "iPhone", size, TextureImporterFormat.Alpha8);
+ SetTexImportSetting(ci.textureImporter, "Standalone", size, TextureImporterFormat.Alpha8);
+ }
+ else
+ {
+ if (ci.srcFormat == ETextureCompress.TrueColor)
+ {
+ SetTexImportSetting(ci.textureImporter, BuildTarget.Android.ToString(), srcSize, TextureImporterFormat.RGB24);
+ SetTexImportSetting(ci.textureImporter, "iPhone", srcSize, TextureImporterFormat.RGB24);
+ //SetTexImportSetting(ci.textureImporter, BuildTarget.StandaloneWindows.ToString(), srcSize, TextureImporterFormat.RGB24);
+ }
+ else if (ci.srcFormat == ETextureCompress.RGB16)
+ {
+ SetTexImportSetting(ci.textureImporter, BuildTarget.Android.ToString(), srcSize, TextureImporterFormat.RGB16);
+ SetTexImportSetting(ci.textureImporter, "iPhone", srcSize, TextureImporterFormat.RGB16);
+ //SetTexImportSetting(ci.textureImporter, BuildTarget.StandaloneWindows.ToString(), srcSize, TextureImporterFormat.RGB16);
+ }
+ else
+ {
+ SetTexImportSetting(ci.textureImporter, BuildTarget.Android.ToString(), srcSize, TextureImporterFormat.ETC_RGB4);
+ if (ci.srcTex.width / ci.srcTex.height >= 4 || ci.srcTex.height / ci.srcTex.width >= 4)
+ {
+ SetTexImportSetting(ci.textureImporter, "iPhone", srcSize, TextureImporterFormat.RGB16);
+ }
+ else
+ {
+ SetTexImportSetting(ci.textureImporter, "iPhone", srcSize, TextureImporterFormat.PVRTC_RGB4);
+ }
+
+ // ci.textureImporter.SetPlatformTextureSettings("Standalone", srcSize, TextureImporterFormat.DXT1);
+ }
+ if (isUI)
+ {
+ SetTexImportSetting(ci.textureImporter, "Standalone", 4096, TextureImporterFormat.RGBA32);
+ }
+ }
+ }
+
+ if (import)
+ {
+ AssetDatabase.ImportAsset(ci.path, ImportAssetOptions.ForceUpdate);
+ }
+ }
+
+ private static void _ProcessAlpha(ref ConvertInfo ci, bool halfSize)
+ {
+ File.Copy(ci.path, ci.alphaTexPath, true);
+
+ AssetDatabase.ImportAsset(ci.alphaTexPath, ImportAssetOptions.ForceUpdate);
+ ci.name = ci.name + "_A";
+ ci.path = ci.alphaTexPath;
+ ci.isAlpha = true;
+ ci.mipmap = false;
+ ci.textureImporter = AssetImporter.GetAtPath(ci.alphaTexPath) as TextureImporter;
+ _ProcessTexture(ref ci, halfSize);
+ }
+
+ private static void _CompressAtlas(ConvertInfo ci, Texture2D aTex, GameObject atlas, Material mat)
+ {
+ int size = ci.srcTex.width > ci.srcTex.height ? ci.srcTex.height : ci.srcTex.width;
+ if (size >= 512)
+ {
+ Texture2D newTex = null;
+ string texResPath = "Assets/Resources/" + ci.resourcePath;
+ if (ci.srcFormat != ETextureCompress.Compress && aTex.width != ci.srcTex.width / 2)
+ {
+ newTex = MakeCompressTexture(texResPath + "Half.png", ci.srcTex, false);
+ }
+ else
+ {
+ return;
+ }
+
+ Texture2D newAlphaTex = MakeCompressTexture(texResPath + "Half_A.png", aTex, true);
+
+
+ Material newMat = null;
+ if (mat.shader.name == "Custom/UI/Additive")
+ {
+ newMat = new Material(Shader.Find("Custom/UI/Additive"));
+ }
+ else
+ {
+ newMat = new Material(Shader.Find("Custom/UI/SeparateColorAlpha"));
+ }
+ newMat.mainTexture = newTex;
+ newMat.SetTexture("_Mask", newAlphaTex);
+ newMat = CreateOrReplaceAsset<Material>(newMat, "Assets/Resources/" + ci.resourcePath + "Half.mat");
+
+ GameObject newAtlas = GameObject.Instantiate(atlas) as GameObject;
+ UIAtlas a = newAtlas.GetComponent<UIAtlas>();
+ a.spriteMaterial = newMat;
+ PrefabUtility.CreatePrefab("Assets/Resources/" + ci.resourcePath + "Half.prefab", newAtlas, ReplacePrefabOptions.ReplaceNameBased);
+ GameObject.DestroyImmediate(newAtlas);
+ }
+ }
+ private static Texture2D MakeCompressTexture(string desTex, Texture src, bool isAlpha, int scale = 1, bool mipmap = false)
+ {
+ if (isAlpha)
+ {
+ TextureCombine.ScaleTexture(src, desTex, src.width / 2, src.height / 2, "Custom/Editor/TexScaleAlpha");
+ }
+ else
+ TextureCombine.ScaleTexture(src, desTex, src.width / scale, src.height / scale, "Custom/Editor/TexScale");
+
+ TextureImporter newTexImporter = AssetImporter.GetAtPath(desTex) as TextureImporter;
+ Texture2D newTex = AssetDatabase.LoadAssetAtPath(desTex, typeof(Texture)) as Texture2D;
+
+ ConvertInfo newTexCI = new ConvertInfo();
+ newTexCI.isAlpha = isAlpha;
+ newTexCI.srcTex = newTex;
+ newTexCI.textureImporter = newTexImporter;
+ newTexCI.path = desTex;
+ newTexCI.srcFormat = ETextureCompress.Compress;
+ newTexCI.alphaSize = ETextureSize.Original;
+ newTexCI.mipmap = mipmap;
+ _ProcessTexture(ref newTexCI, true);
+ return newTex;
+ }
+
+ private static Texture2D MakeHalfTexture(string desTex, Texture2D src, bool mipmap = false)
+ {
+ TextureCombine.ScaleTexture(src, desTex, src.width / 2, src.height / 2, "Custom/Effect/TexScale");
+
+ TextureImporter newTexImporter = AssetImporter.GetAtPath(desTex) as TextureImporter;
+
+ Texture2D newTex = AssetDatabase.LoadAssetAtPath(desTex, typeof(Texture)) as Texture2D;
+
+ int srcSize = newTex.width > newTex.height ? newTex.width : newTex.height; ;
+
+ newTexImporter.textureType = TextureImporterType.Default;
+ newTexImporter.anisoLevel = src.anisoLevel;
+ newTexImporter.mipmapEnabled = (src.mipmapCount > 1);
+ newTexImporter.npotScale = TextureImporterNPOTScale.ToNearest;
+ newTexImporter.wrapMode = src.wrapMode;
+ newTexImporter.filterMode = src.filterMode;
+ newTexImporter.isReadable = false;
+ SetTexImportSetting(newTexImporter, BuildTarget.Android.ToString(), srcSize, (TextureImporterFormat)src.format);
+ SetTexImportSetting(newTexImporter, "iPhone", srcSize, (TextureImporterFormat)src.format);
+
+ AssetDatabase.ImportAsset(desTex, ImportAssetOptions.ForceUpdate);
+
+ return newTex;
+ }
+
+ public static bool _CompressSeparateAlpha(Texture2D tex, TextureImporter textureImporter, string path)
+ {
+ if (path.IndexOf("_A.png") >= 0 || path.IndexOf("Half.png") >= 0)
+ return false;
+ ConvertInfo ci = new ConvertInfo();
+ ci.srcTex = tex;
+ ci.textureImporter = textureImporter;
+ ci.path = path;
+
+ //ci.dataSet = dataSet;
+ if (GetTexPath(ref ci))
+ {
+ Material mat = Resources.Load(ci.resourcePath, typeof(Material)) as Material;
+ GameObject atlas = Resources.Load(ci.resourcePath, typeof(GameObject)) as GameObject;
+ bool isAtlas = mat != null && atlas != null;
+ GetTexFormat(mat != null, textureImporter.userData, out ci.srcFormat, out ci.alphaSize);
+ ci.isAtlas = isAtlas;
+ if (isAtlas)
+ {
+ Texture2D aTex = null;
+ //atlas
+ if (mat.shader.name == "Custom/UI/RGBA" ||
+ mat.shader.name == "Custom/UI/SeparateColorAlpha" ||
+ mat.shader.name == "Custom/UI/Additive" ||
+ mat.shader.name == "Unlit/Separate Alpha Colored Mask")
+ {
+ ci.alphaResourcePath = ci.resourcePath + "_A";
+
+ int index = ci.path.LastIndexOf(".");
+ if (index >= 0)
+ {
+ ci.alphaTexPath = ci.path.Substring(0, index);
+ }
+ else
+ {
+ ci.alphaTexPath = ci.path;
+ }
+ ci.alphaTexPath += "_A.png";
+ _ProcessTexture(ref ci, true, true);
+ _ProcessAlpha(ref ci, true);
+ if (mat.shader.name != "Custom/UI/Additive")
+ mat.shader = Shader.Find("Custom/UI/SeparateColorAlpha");
+
+ mat.SetTexture("_MainTex", ci.srcTex);
+ aTex = Resources.Load(ci.alphaResourcePath, typeof(Texture)) as Texture2D;
+ mat.SetTexture("_Mask", aTex);
+ }
+ else
+ {
+ if (mat.shader.name == "Custom/UI/WhiteAnim")
+ ci.isAlpha = false;
+ _ProcessTexture(ref ci, true, true);
+ }
+ //_CompressAtlas(ci, aTex, atlas, mat);
+ }
+ else if (!onlyAtlas)
+ {
+ if (!HasAlpha(tex, ci.textureImporter, true))
+ {
+ AssetDatabase.DeleteAsset(ci.alphaTexPath);
+ _ProcessTexture(ref ci, true, true);
+ }
+ else
+ {
+ _ProcessTexture(ref ci, true, true);
+ _ProcessAlpha(ref ci, true);
+ }
+ }
+ }
+ return false;
+ }
+
+ [MenuItem(@"Assets/Tool/UI/Compress&SeparateAlpha", false, 0)]
+ public static void CompressSeparateAlpha()
+ {
+ enumTex2D.cb = _CompressSeparateAlpha;
+ EnumAsset<Texture2D>(enumTex2D, "CompressSeparateAlpha");
+ }
+ public static bool _CompressAtlas(Texture2D tex, TextureImporter textureImporter, string path)
+ {
+ if (path.IndexOf("_A.png") >= 0 || path.IndexOf("Half.png") >= 0)
+ return false;
+ ConvertInfo ci = new ConvertInfo();
+ ci.srcTex = tex;
+ ci.textureImporter = textureImporter;
+ ci.path = path;
+
+ //ci.dataSet = dataSet;
+ if (GetTexPath(ref ci))
+ {
+ Material mat = Resources.Load(ci.resourcePath, typeof(Material)) as Material;
+ GameObject atlas = Resources.Load(ci.resourcePath, typeof(GameObject)) as GameObject;
+ bool isAtlas = mat != null && atlas != null;
+ GetTexFormat(mat != null, textureImporter.userData, out ci.srcFormat, out ci.alphaSize);
+ if (isAtlas)
+ {
+ ci.alphaResourcePath = ci.resourcePath + "_A";
+ Texture2D aTex = Resources.Load(ci.alphaResourcePath, typeof(Texture)) as Texture2D;
+ _CompressAtlas(ci, aTex, atlas, mat);
+ }
+ }
+ return false;
+ }
+
+ [MenuItem(@"Assets/Tool/UI/CompressAtlas", false, 0)]
+ public static void CompressAtlas()
+ {
+ enumTex2D.cb = _CompressAtlas;
+ EnumAsset<Texture2D>(enumTex2D, "CompressAtlas");
+ }
+
+ public static void CompressSeparateAlpha(TextureImporter textureImporter)
+ {
+ Texture2D tex = AssetDatabase.LoadAssetAtPath(textureImporter.assetPath, typeof(Texture2D)) as Texture2D;
+ if (tex != null)
+ {
+ _CompressSeparateAlpha(tex, textureImporter, textureImporter.assetPath);
+ }
+ }
+
+ [MenuItem(@"Assets/Tool/UI/SeparateAlpha", false, 0)]
+ private static void SeparateAlpha()
+ {
+ onlyAtlas = true;
+ enumTex2D.cb = _CompressSeparateAlpha;
+ EnumAsset<Texture2D>(enumTex2D, "SeparateAlpha");
+ onlyAtlas = false;
+ }
+
+ [MenuItem(@"Assets/Tool/UI/Compress&SeparateAlphaHere", false, 0)]
+ private static void CompressSeparateAlphaHere()
+ {
+ enumTex2D.cb = _CompressSeparateAlpha;
+ EnumAsset<Texture2D>(enumTex2D, "CompressSeparateAlphaHere");
+ }
+
+ //[MenuItem(@"Assets/Tool/UI/SeparateAlphaHere")]
+ //private static void SeparateAlphaHere()
+ //{
+ // XImageImporterSet dataSet = XDataIO<XImageImporterSet>.singleton.DeserializeData("Assets/Editor/ResImporter/ImporterData/Image/ResourceImportXML.xml");
+ // if (dataSet == null)
+ // dataSet = new XImageImporterSet();
+ // else
+ // {
+ // dataSet.Init();
+ // }
+ // inCommonAlphaFolder = false;
+ // onlyAtlas = true;
+ // EnumTextures(_CompressSeparateAlpha, "SeparateAlphaHere", dataSet);
+ // onlyAtlas = false;
+ //}
+
+ [MenuItem(@"Assets/Tool/UI/CheckUISameName", false, 0)]
+ private static void CheckUIName()
+ {
+ Dictionary<string, List<string>> names = new Dictionary<string, List<string>>();
+ UnityEngine.Object[] textures = Selection.GetFiltered(typeof(Texture), SelectionMode.DeepAssets);
+ if (textures != null)
+ {
+ for (int i = 0; i < textures.Length; ++i)
+ {
+ Texture2D tex = textures[i] as Texture2D;
+ if (tex != null)
+ {
+ List<string> list;
+ string name = tex.name.ToLower();
+ if (!names.TryGetValue(name, out list))
+ {
+ list = new List<string>();
+ names.Add(name, list);
+ }
+ list.Add(AssetDatabase.GetAssetPath(tex));
+ }
+ }
+ }
+ foreach (KeyValuePair<string, List<string>> name in names)
+ {
+ if (name.Value.Count > 1)
+ {
+ Debug.LogWarning(string.Format("======Same Name Tex:{0}======", name.Key));
+ foreach (string path in name.Value)
+ {
+ Debug.LogWarning(path);
+ }
+ }
+ }
+ }
+
+ //private static bool _ReplaceUIMat(Material material, string path)
+ //{
+ // if (material.shader.name == "Unlit/Transparent Colored")
+ // {
+ // material.shader = Shader.Find("Unlit/Separate Alpha Colored");
+ // }
+ // if (material.shader.name == "Unlit/Separate Alpha Colored")
+ // {
+ // string alphaResourcePath = "atlas/UI/Alpha/" + material.name + "_A";
+ // Texture2D aTex = Resources.Load(alphaResourcePath, typeof(Texture)) as Texture2D;
+ // material.SetTexture("_Mask", aTex);
+ // }
+ // return false;
+ //}
+
+ //[MenuItem(@"Assets/Tool/UI/ReplaceUIMat")]
+ //private static void ReplaceUIMat()
+ //{
+ // EnumMaterial(_ReplaceUIMat, "ReplaceUIMat");
+ //}
+
+ //[MenuItem(@"Assets/Tool/UI/GenerateAtlasAlpha")]
+ //private static void GenerateAtlasAlpha()
+ //{
+ // XImageImporterSet dataSet = XDataIO<XImageImporterSet>.singleton.DeserializeData("Assets/Editor/ResImporter/ImporterData/Image/ResourceImportXML.xml");
+ // if (dataSet == null)
+ // dataSet = new XImageImporterSet();
+ // else
+ // {
+ // dataSet.Init();
+ // }
+ // inCommonAlphaFolder = true;
+ // onlyAtlas = true;
+ // EnumTextures(_CompressSeparateAlpha, "SeparateAlpha", dataSet);
+ // onlyAtlas = false;
+ //}
+
+ public static void SeparateTexture(string[] files, bool isHighQuality = false)
+ {
+ //XImageImporterSet dataSet = XDataIO<XImageImporterSet>.singleton.DeserializeData("Assets/Editor/ResImporter/ImporterData/Image/ResourceImportXML.xml");
+ //if (dataSet == null)
+ // dataSet = new XImageImporterSet();
+ //else
+ //{
+ // dataSet.Init();
+ //}
+ int i = 0;
+ foreach (string strPath in files)
+ {
+ string strTempPath = strPath.Replace(@"\", "/");
+ strTempPath = strTempPath.Substring(strTempPath.IndexOf("Assets"));
+ UnityEngine.Object obj = AssetDatabase.LoadAssetAtPath(@strTempPath, typeof(UnityEngine.Object));
+ Texture2D tex = obj as Texture2D;
+ if (tex != null)
+ {
+ string path = AssetDatabase.GetAssetPath(tex);
+ TextureImporter textureImporter = AssetImporter.GetAtPath(path) as TextureImporter;
+ _CompressSeparateAlpha(tex, textureImporter, path);
+ EditorUtility.DisplayProgressBar(i.ToString(), tex.name, 1.0f * i / files.Length);
+ }
+ ++i;
+ }
+ EditorUtility.ClearProgressBar();
+ }
+
+
+ //public static bool PreCheckImportUITexture(ref ConvertInfo ci)
+ //{
+ // if (manulConvert || atlasProcess)
+ // {
+ // return false;
+ // }
+
+ // if (GetTexPath(ref ci))
+ // {
+ // Material mat = Resources.Load(ci.resourcePath, typeof(Material)) as Material;
+ // if (mat == null)
+ // {
+ // ci.srcTex = Resources.Load(ci.resourcePath, typeof(Texture2D)) as Texture2D;
+ // if (!ci.isAlpha)
+ // {
+ // if (ci.srcTex != null)
+ // {
+ // lastRGBTex.SrcSize = ci.srcTex.width > ci.srcTex.height ? ci.srcTex.width : ci.srcTex.height;
+ // lastRGBTex.SrcName = ci.name;
+ // }
+ // else
+ // {
+ // lastRGBTex.SrcSize = 1024;
+ // }
+ // }
+ // ci.dataSet = XDataIO<XImageImporterSet>.singleton.DeserializeData("Assets/Editor/ResImporter/ImporterData/Image/ResourceImportXML.xml");
+ // if (ci.dataSet == null)
+ // ci.dataSet = new XImageImporterSet();
+ // else
+ // {
+ // ci.dataSet.Init();
+ // }
+ // return true;
+ // }
+ // }
+ // lastRGBTex.SrcSize = -1;
+ // return false;
+ //}
+
+ //public static void PreImportUITexture(ref ConvertInfo ci)
+ //{
+ // if (ci.isAlpha)
+ // {
+ // _ProcessTexture(ref ci, true, false);
+ // lastRGBTex.SrcSize = -1;
+ // }
+ // else
+ // {
+ // _ProcessTexture(ref ci, false, false);
+ // if (!ci.textureImporter.DoesSourceTextureHaveAlpha())
+ // {
+ // AssetDatabase.DeleteAsset(ci.alphaTexPath);
+ // }
+ // else
+ // {
+ // File.Copy(ci.path, ci.alphaTexPath, true);
+ // AssetDatabase.ImportAsset(ci.alphaTexPath, ImportAssetOptions.ForceSynchronousImport);
+ // }
+ // }
+ //}
+
+ public static bool atlasProcess = false;
+ //public static void PostImportUIAtlas(Texture2D tex)
+ //{
+ // atlasProcess = true;
+ // string path = AssetDatabase.GetAssetPath(tex.GetInstanceID());
+ // TextureImporter textureImporter = AssetImporter.GetAtPath(path) as TextureImporter;
+ // if (path.IndexOf("_A.png") >= 0)
+ // {
+ // atlasProcess = false;
+ // return;
+ // }
+
+ // ConvertInfo ci = new ConvertInfo();
+ // ci.srcTex = tex;
+ // ci.textureImporter = textureImporter;
+ // ci.path = path;
+ // //ci.dataSet = XDataIO<XImageImporterSet>.singleton.DeserializeData("Assets/Editor/ResImporter/ImporterData/Image/ResourceImportXML.xml");
+ // //if (ci.dataSet == null)
+ // // ci.dataSet = new XImageImporterSet();
+ // //else
+ // //{
+ // // ci.dataSet.Init();
+ // //}
+ // if (GetTexPath(ref ci))
+ // {
+ // Material mat = Resources.Load(ci.resourcePath, typeof(Material)) as Material;
+ // if (mat != null)
+ // {
+ // //atlas
+ // if (mat.shader.name == "Unlit/Transparent Colored" ||
+ // mat.shader.name == "Unlit/Separate Alpha Colored" ||
+ // mat.shader.name == "Unlit/Particles/Additive" ||
+ // mat.shader.name == "Unlit/Separate Alpha Colored Mask")
+ // {
+ // _ProcessTexture(ref ci, false);
+ // _ProcessAlpha(ref ci, false);
+
+ // mat.shader = Shader.Find("Unlit/Separate Alpha Colored");
+
+ // mat.SetTexture("_MainTex", ci.srcTex);
+ // Texture2D aTex = Resources.Load(ci.alphaResourcePath, typeof(Texture)) as Texture2D;
+ // mat.SetTexture("_Mask", aTex);
+ // }
+ // else
+ // {
+ // _ProcessTexture(ref ci, false);
+ // }
+ // }
+ // }
+ // atlasProcess = false;
+ //}
+
+
+ [MenuItem(@"Assets/Tool/UI/FindAtlas&Texture", false, 0)]
+ public static void FindAtlasTexture()
+ {
+ Rect wr = new Rect(0, 0, 600, 800);
+ TextureStatis window = (TextureStatis)EditorWindow.GetWindowWithRect(typeof(TextureStatis), wr, true, "查找贴图");
+ window.ScanGameObject();
+ window.Show();
+ }
+
+ private static Dictionary<int, List<AlphaTexTask>> atlasTasks = new Dictionary<int, List<AlphaTexTask>>();
+ private static Dictionary<int, List<AlphaTexTask>> texTasks = new Dictionary<int, List<AlphaTexTask>>();
+ public class AlphaTexTask
+ {
+ public Texture2D srcTex;
+ public Material mat;
+ public AlphaTexTask(Texture2D t, Material m)
+ {
+ srcTex = t;
+ mat = m;
+ }
+ }
+
+ private static void InitAlphaTask()
+ {
+ atlasTasks[1024] = new List<AlphaTexTask>();
+ atlasTasks[512] = new List<AlphaTexTask>();
+ atlasTasks[256] = new List<AlphaTexTask>();
+ atlasTasks[128] = new List<AlphaTexTask>();
+ atlasTasks[64] = new List<AlphaTexTask>();
+ atlasTasks[32] = new List<AlphaTexTask>();
+
+ texTasks[1024] = new List<AlphaTexTask>();
+ texTasks[512] = new List<AlphaTexTask>();
+ texTasks[256] = new List<AlphaTexTask>();
+ texTasks[128] = new List<AlphaTexTask>();
+ texTasks[64] = new List<AlphaTexTask>();
+ texTasks[32] = new List<AlphaTexTask>();
+ }
+
+ private static Shader alphaMask = Shader.Find("Unlit/Separate Alpha Colored Mask");
+ private static void CombineAlphaTex(int size,
+ AlphaTexTask task0,
+ AlphaTexTask task1,
+ AlphaTexTask task2,
+ AlphaTexTask task3)
+ {
+ string name = "";
+ if (task0.srcTex != null)
+ {
+ name = task0.srcTex.name;
+ }
+ if (task1 != null && task1.srcTex != null)
+ {
+ name += "_" + task1.srcTex.name;
+ }
+ if (task2 != null && task2.srcTex != null)
+ {
+ name += "_" + task2.srcTex.name;
+ }
+ if (task3 != null && task3.srcTex != null)
+ {
+ name += "_" + task3.srcTex.name;
+ }
+ Texture2D tex = new Texture2D(size, size, TextureFormat.ARGB32, false);
+ for (int y = 0, ymax = size; y < ymax; ++y)
+ {
+ for (int x = 0, xmax = size; x < xmax; ++x)
+ {
+ Color c0 = Color.black;
+ Color c1 = Color.black;
+ Color c2 = Color.black;
+ Color c3 = Color.black;
+ if (task0.srcTex != null)
+ {
+ c0 = task0.srcTex.GetPixel(x, y);
+ }
+ if (task1 != null && task1.srcTex != null)
+ {
+ c1 = task1.srcTex.GetPixel(x, y);
+ }
+ if (task2 != null && task2.srcTex != null)
+ {
+ c2 = task2.srcTex.GetPixel(x, y);
+ }
+ if (task3 != null && task3.srcTex != null)
+ {
+ c3 = task3.srcTex.GetPixel(x, y);
+ }
+ Color a = new Color(c0.a, c1.a, c2.a, c3.a);
+ tex.SetPixel(x, y, a);
+ }
+ }
+
+ byte[] bytes = tex.EncodeToPNG();
+ string alphaTexPath = "Assets/Resources/atlas/UI/Alpha/" + name + "_A.png";
+ File.WriteAllBytes(alphaTexPath, bytes);
+ AssetDatabase.ImportAsset(alphaTexPath, ImportAssetOptions.ForceUpdate);
+ TextureImporter alphaTextureImporter = AssetImporter.GetAtPath(alphaTexPath) as TextureImporter;
+ if (alphaTextureImporter != null)
+ {
+ alphaTextureImporter.textureType = TextureImporterType.Default;
+ alphaTextureImporter.anisoLevel = 0;
+ alphaTextureImporter.mipmapEnabled = false;
+ alphaTextureImporter.isReadable = false;
+ alphaTextureImporter.npotScale = TextureImporterNPOTScale.ToLarger;
+ alphaTextureImporter.wrapMode = TextureWrapMode.Clamp;
+ SetTexImportSetting(alphaTextureImporter, BuildTarget.Android.ToString(), size, TextureImporterFormat.RGBA16);
+ SetTexImportSetting(alphaTextureImporter, "iPhone", size, TextureImporterFormat.RGBA16);
+ AssetDatabase.ImportAsset(alphaTexPath, ImportAssetOptions.ForceUpdate);
+
+ UnityEngine.Object obj = AssetDatabase.LoadAssetAtPath(alphaTexPath, typeof(UnityEngine.Object));
+ Texture2D newTex = obj as Texture2D;
+ if (newTex != null)
+ {
+ if (task0.mat != null)
+ {
+ task0.mat.shader = alphaMask;
+ task0.mat.SetTexture("_Mask", newTex);
+ task0.mat.SetVector("_Channel", new Vector4(1, 0, 0, 0));
+ }
+ if (task1 != null && task1.mat != null)
+ {
+ task1.mat.shader = alphaMask;
+ task1.mat.SetTexture("_Mask", newTex);
+ task1.mat.SetVector("_Channel", new Vector4(0, 1, 0, 0));
+ }
+ if (task2 != null && task2.mat != null)
+ {
+ task2.mat.shader = alphaMask;
+ task2.mat.SetTexture("_Mask", newTex);
+ task2.mat.SetVector("_Channel", new Vector4(0, 0, 1, 0));
+ }
+ if (task3 != null && task3.mat != null)
+ {
+ task3.mat.shader = alphaMask;
+ task3.mat.SetTexture("_Mask", newTex);
+ task3.mat.SetVector("_Channel", new Vector4(0, 0, 0, 1));
+ }
+ }
+
+ }
+ if (task0.srcTex != null)
+ {
+ string path = AssetDatabase.GetAssetPath(task0.srcTex);
+ TextureImporter srcImporter = AssetImporter.GetAtPath(path) as TextureImporter;
+ if (srcImporter != null)
+ {
+ srcImporter.isReadable = false;
+ SetTexImportSetting(srcImporter, BuildTarget.Android.ToString(), size, TextureImporterFormat.ETC_RGB4);
+ SetTexImportSetting(srcImporter, "iPhone", size, TextureImporterFormat.PVRTC_RGB4);
+ AssetDatabase.ImportAsset(path, ImportAssetOptions.ForceUpdate);
+ }
+ }
+ if (task1 != null && task1.srcTex != null)
+ {
+ string path = AssetDatabase.GetAssetPath(task1.srcTex);
+ TextureImporter srcImporter = AssetImporter.GetAtPath(path) as TextureImporter;
+ if (srcImporter != null)
+ {
+ srcImporter.isReadable = false;
+ SetTexImportSetting(srcImporter, BuildTarget.Android.ToString(), size, TextureImporterFormat.ETC_RGB4);
+ SetTexImportSetting(srcImporter, "iPhone", size, TextureImporterFormat.PVRTC_RGB4);
+ AssetDatabase.ImportAsset(path, ImportAssetOptions.ForceUpdate);
+ }
+ }
+ if (task2 != null && task2.srcTex != null)
+ {
+ string path = AssetDatabase.GetAssetPath(task2.srcTex);
+ TextureImporter srcImporter = AssetImporter.GetAtPath(path) as TextureImporter;
+ if (srcImporter != null)
+ {
+ srcImporter.isReadable = false;
+ SetTexImportSetting(srcImporter, BuildTarget.Android.ToString(), size, TextureImporterFormat.ETC_RGB4);
+ SetTexImportSetting(srcImporter, "iPhone", size, TextureImporterFormat.PVRTC_RGB4);
+ AssetDatabase.ImportAsset(path, ImportAssetOptions.ForceUpdate);
+ }
+ }
+ if (task3 != null && task3.srcTex != null)
+ {
+ string path = AssetDatabase.GetAssetPath(task3.srcTex);
+ TextureImporter srcImporter = AssetImporter.GetAtPath(path) as TextureImporter;
+ if (srcImporter != null)
+ {
+ srcImporter.isReadable = false;
+ SetTexImportSetting(srcImporter, BuildTarget.Android.ToString(), size, TextureImporterFormat.ETC_RGB4);
+ SetTexImportSetting(srcImporter, "iPhone", size, TextureImporterFormat.PVRTC_RGB4);
+ AssetDatabase.ImportAsset(path, ImportAssetOptions.ForceUpdate);
+ }
+ }
+ }
+
+
+ private static int SortByName(AlphaTexTask a, AlphaTexTask b)
+ {
+ if (a.srcTex != null && b.srcTex != null)
+ {
+ return string.Compare(a.srcTex.name, b.srcTex.name);
+ }
+ if (a.srcTex != null && b.srcTex == null)
+ {
+ return 1;
+ }
+ if (a.srcTex == null && b.srcTex != null)
+ {
+ return -1;
+ }
+ return 1;
+ }
+ private static void PostProcessAlpha()
+ {
+ foreach (KeyValuePair<int, List<AlphaTexTask>> pair in atlasTasks)
+ {
+ int size = pair.Key;
+ List<AlphaTexTask> list = pair.Value;
+ list.Sort(SortByName);
+ for (int i = 0, imax = list.Count; i < imax; i += 4)
+ {
+ AlphaTexTask task0 = list[i];
+ AlphaTexTask task1 = null;
+ AlphaTexTask task2 = null;
+ AlphaTexTask task3 = null;
+ if ((i + 1) < imax)
+ {
+ task1 = list[i + 1];
+ }
+ if ((i + 2) < imax)
+ {
+ task2 = list[i + 2];
+ }
+ if ((i + 3) < imax)
+ {
+ task3 = list[i + 3];
+ }
+ CombineAlphaTex(size, task0, task1, task2, task3);
+ }
+ }
+ }
+ private static void PreConvertTex2Mobile(Texture2D srcTex, TextureImporter textureImporter, string path)
+ {
+ int srcSize = srcTex.width > srcTex.height ? srcTex.width : srcTex.height;
+ textureImporter.textureType = TextureImporterType.Default;
+ textureImporter.anisoLevel = 0;
+ textureImporter.mipmapEnabled = false;
+ textureImporter.isReadable = true;
+ textureImporter.npotScale = TextureImporterNPOTScale.ToNearest;
+ textureImporter.wrapMode = TextureWrapMode.Clamp;
+ textureImporter.filterMode = FilterMode.Bilinear;
+ SetTexImportSetting(textureImporter, BuildTarget.Android.ToString(), srcSize, TextureImporterFormat.RGBA32);
+ SetTexImportSetting(textureImporter, "iPhone", srcSize, TextureImporterFormat.RGBA32);
+ AssetDatabase.ImportAsset(path, ImportAssetOptions.ForceUpdate);
+ }
+ private static void _ProcessAtlasAlpha(Texture2D srcTex, Material mat, string path, string alphaTexPath)
+ {
+ int srcSize = srcTex.width > srcTex.height ? srcTex.width : srcTex.height;
+ int size = srcSize;
+
+ List<AlphaTexTask> taskList = null;
+ if (mat != null)
+ {
+ if (atlasTasks.TryGetValue(size, out taskList))
+ {
+ taskList.Add(new AlphaTexTask(srcTex, mat));
+ }
+ }
+ else
+ {
+ if (texTasks.TryGetValue(size, out taskList))
+ {
+ taskList.Add(new AlphaTexTask(srcTex, mat));
+ }
+ }
+ }
+
+ private static bool _CombineAlpha(Texture2D tex, TextureImporter textureImporter, string path)
+ {
+ if (path.IndexOf("_A.png") >= 0)
+ return false;
+ int extIndex = path.LastIndexOf(".");
+ //1.check mat first
+ string matPath = path;
+ if (extIndex >= 0)
+ {
+ matPath = path.Substring(0, extIndex);
+ string relativePath = "Assets/Resources/";
+ matPath = matPath.Substring(relativePath.Length);
+
+ //string alphaResourcePath = inCommonAlphaFolder ? "atlas/UI/Alpha/" + tex.name + "_A" : matPath + "_A";
+ string alphaTexPath = "Assets/Resources/atlas/UI/Alpha/" + tex.name + "_A.png";
+
+
+ Material mat = Resources.Load(matPath, typeof(Material)) as Material;
+ if (mat != null)
+ {
+ //atlas
+ if (mat.shader.name == "Custom/UI/RGBA" ||
+ mat.shader.name == "Custom/UI/SeparateColorAlpha")
+ {
+ PreConvertTex2Mobile(tex, textureImporter, path);
+ _ProcessAtlasAlpha(tex, mat, path, alphaTexPath);
+ }
+ else if (mat.shader.name == "Custom/UI/Additive")
+ {
+ PreConvertTex2Mobile(tex, textureImporter, path);
+ _ProcessAtlasAlpha(tex, mat, path, alphaTexPath);
+ }
+ else
+ {
+ }
+ }
+ }
+ return false;
+ }
+
+
+ //[MenuItem(@"Assets/Tool/UI/CombineAlpha")]
+ //private static void CombineAlpha()
+ //{
+ // InitAlphaTask();
+ // XImageImporterSet dataSet = XDataIO<XImageImporterSet>.singleton.DeserializeData("Assets/Editor/ResImporter/ImporterData/Image/ResourceImportXML.xml");
+ // if (dataSet == null)
+ // dataSet = new XImageImporterSet();
+ // else
+ // {
+ // dataSet.Init();
+ // }
+ // inCommonAlphaFolder = true;
+ // EnumTextures(_CombineAlpha, "CombineAlpha", dataSet, PostProcessAlpha);
+ //}
+ #endregion UI
+ #region fbx
+
+ private static bool _MakeFbxReadOnly(GameObject fbx, ModelImporter modelImporter, string path)
+ {
+ bool change = modelImporter.isReadable == false;
+ modelImporter.isReadable = false;
+ if(modelImporter.meshCompression == ModelImporterMeshCompression.Low|| modelImporter.meshCompression == ModelImporterMeshCompression.Off)
+ {
+ if (path.ToLower().Contains("_bandpose"))
+ Debug.LogError(path);
+ }
+ return false;
+ }
+
+ [MenuItem(@"Assets/Tool/Fbx/MakeFbxReadOnly", false, 0)]
+ private static void MakeFbxReadOnly()
+ {
+ enumFbx.cb = _MakeFbxReadOnly;
+ EnumAsset<GameObject>(enumFbx, "MakeFbxReadOnly");
+ }
+ //private static void CheckMeshVertex(Mesh mesh)
+ //{
+ // List<Vector3> newPos = ListPool<Vector3>.Get();
+ // List<Vector2> newUV = ListPool<Vector2>.Get();
+ // List<Vector2> newUV2 = ListPool<Vector2>.Get();
+ // Vector3[] pos = mesh.vertices;
+ // Vector2[] uv = mesh.uv;
+ // Vector2[] uv2 = mesh.uv2;
+ // int index = 0;
+ // Vector3 invalidPos = new Vector3(-100001, -100000, -100000);
+ // while(index< pos.Length)
+ // {
+ // Vector3 posStart = pos[index];
+ // if (posStart.x > -100000)
+ // {
+ // for (int i = index + 1; i < pos.Length; ++i)
+ // {
+ // Vector3 p = pos[i] - posStart;
+ // p.x = Mathf.Abs(p.x);
+ // p.y = Mathf.Abs(p.y);
+ // p.z = Mathf.Abs(p.z);
+ // if (p.x < 0.01f && p.y < 0.01f && p.z < 0.01f)
+ // {
+ // pos[i] = invalidPos;
+ // newUV.Add(uv[i]);
+ // newUV2.Add(uv2[i]);
+ // newPos.Add(posStart);
+ // index++;
+ // break;
+ // }
+ // }
+ // }
+ // else
+ // {
+ // index++;
+ // }
+ // }
+ // if(newPos.Count%4==0)
+ // {
+ // List<int> newIndex = ListPool<int>.Get();
+ // for (int i = 0; i < newPos.Count; i += 4)
+ // {
+ // Vector3 p0 = newPos[i];
+ // Vector3 p1 = newPos[i + 1];
+ // Vector3 p2 = newPos[i + 2];
+ // Vector3 p3 = newPos[i + 3];
+ // newIndex.Add(i);
+ // newIndex.Add(i + 1);
+ // newIndex.Add(i + 2);
+
+ // newIndex.Add(i + 1);
+ // newIndex.Add(i + 0);
+ // newIndex.Add(i + 3);
+ // }
+ // mesh.triangles = newIndex.ToArray();
+ // mesh.vertices = newPos.ToArray();
+ // mesh.uv = newUV.ToArray();
+ // mesh.uv2 = newUV2.ToArray();
+ // ListPool<int>.Release(newIndex);
+ // }
+
+ // ListPool<Vector3>.Release(newPos);
+
+
+ //}
+
+
+ public class ExportInfo
+ {
+ public bool needNormal = false;
+ public bool needColor = false;
+ public bool needExportAnim = true;
+ public bool needUV2 = false;
+ public bool notNeedExportMesh = false;
+ public ModelImporterMeshCompression compress = ModelImporterMeshCompression.Medium;
+ public ModelImporterTangents tangents = ModelImporterTangents.None;
+ }
+
+ public static ExportInfo fbxExportInfo = new ExportInfo();
+ public static void PreExportMeshAvatar(ModelImporterMeshCompression compress, ModelImporterTangents tangents)
+ {
+ fbxExportInfo.compress = compress;
+ fbxExportInfo.tangents = tangents;
+ }
+
+ public static void PreExportMeshAvatar(string path)
+ {
+ string lowPath = path.ToLower();
+ bool needNormal = lowPath.Contains("_normal");
+ bool needColor = lowPath.Contains("_color");
+ bool isCreature = lowPath.StartsWith("assets/creatures/");
+ bool isEffect = lowPath.StartsWith("assets/effect/");
+ bool isSene = lowPath.StartsWith("assets/xscene/");
+ bool isEuip = lowPath.StartsWith("assets/equipment/") &&
+ !lowPath.StartsWith("assets/equipment/tail/") &&
+ !lowPath.StartsWith("assets/equipment/wing/") &&
+ !lowPath.StartsWith("assets/equipment/spirit/") &&
+ !lowPath.StartsWith("assets/equipment/else/");
+
+ fbxExportInfo.needNormal = needNormal;
+ fbxExportInfo.needColor = needColor|| isEffect;
+ fbxExportInfo.needExportAnim = !isCreature;
+ fbxExportInfo.needUV2 = isEffect|| isSene;
+ fbxExportInfo.notNeedExportMesh = isEuip;
+ fbxExportInfo.compress = ModelImporterMeshCompression.Medium;
+ }
+
+ private static bool _ExportMeshAvatar(GameObject fbx, ModelImporter modelImporter, string path)
+ {
+ if (fbx == null)
+ return false;
+ PreExportMeshAvatar(path);
+ string name = fbx.name.ToLower();
+ GameObject go = GameObject.Instantiate(fbx) as GameObject;
+ int index = path.LastIndexOf("/");
+ if (index >= 0)
+ {
+ string dir = path.Substring(0, index);
+ if (name.EndsWith("_bandpose"))
+ {
+ name = name.Replace("_bandpose", "");
+ }
+ bool hasSkin = false;
+ List<Renderer> renderLst = ListPool<Renderer>.Get();
+ go.GetComponentsInChildren<Renderer>(true, renderLst);
+ for (int i = 0; i < renderLst.Count; ++i)
+ {
+ Renderer render = renderLst[i];
+ Mesh mesh = null;
+ Shader shader = render.sharedMaterial != null ? render.sharedMaterial.shader : null;
+ if (render is SkinnedMeshRenderer)
+ {
+ SkinnedMeshRenderer smr = render as SkinnedMeshRenderer;
+ mesh = smr.sharedMesh;
+ hasSkin = true;
+ }
+ else if (render is MeshRenderer)
+ {
+ MeshFilter mf = render.GetComponent<MeshFilter>();
+ mesh = mf.sharedMesh;
+
+ }
+ if (mesh != null && !fbxExportInfo.notNeedExportMesh)
+ {
+ string newMeshName = string.Format("{0}_{1}", name, i);
+ string meshPath = string.Format("{0}/{1}.asset", dir, newMeshName);
+ Mesh newMesh = UnityEngine.Object.Instantiate<Mesh>(mesh);
+ newMesh.name = newMeshName;
+ if (!hasSkin && !fbxExportInfo.needNormal)
+ {
+ newMesh.normals = null;
+ }
+ if (!fbxExportInfo.needUV2 && !hasSkin)
+ {
+ if (!(shader != null && shader.name.EndsWith("UV2")))
+ newMesh.uv2 = null;
+ }
+ if (!fbxExportInfo.needColor)
+ {
+ newMesh.colors = null;
+ }
+ newMesh.tangents = null;
+ newMesh.uv3 = null;
+ newMesh.uv4 = null;
+
+ newMesh.UploadMeshData(true);
+ MeshUtility.SetMeshCompression(newMesh, fbxExportInfo.compress);
+ MeshUtility.Optimize(newMesh);
+ CreateOrReplaceAsset<Mesh>(newMesh, meshPath);
+ }
+ }
+ ListPool<Renderer>.Release(renderLst);
+ if (hasSkin)
+ {
+ Animator ator = go.GetComponent<Animator>();
+ if (ator != null && ator.avatar != null)
+ {
+ string avatarPath = dir + "/" + fbx.name + "_avatar.asset";
+ Avatar avatar = UnityEngine.Object.Instantiate<Avatar>(ator.avatar);
+ avatar.name = fbx.name + "_avatar";
+ CreateOrReplaceAsset<Avatar>(avatar, avatarPath);
+ }
+ }
+ if (fbxExportInfo.needExportAnim)
+ {
+ UnityEngine.Object[] allObjects = AssetDatabase.LoadAllAssetsAtPath(path);
+ int animIndex = 0;
+ for (int i = 0; i < allObjects.Length; ++i)
+ {
+ AnimationClip anim = allObjects[i] as AnimationClip;
+ if (anim != null && !anim.name.StartsWith("__preview"))
+ {
+ string newAnimName = string.Format("{0}_{1}", name, animIndex++);
+ string animPath = string.Format("{0}/{1}.anim", dir, newAnimName);
+ AnimationClip newClip = new AnimationClip();
+ EditorUtility.CopySerialized(anim, newClip);
+ newClip.name = newAnimName;
+ CreateOrReplaceAsset<AnimationClip>(newClip, animPath);
+ }
+ }
+ }
+
+ }
+
+ GameObject.DestroyImmediate(go);
+ return false;
+ }
+
+
+
+
+ //[MenuItem(@"Assets/Tool/Fbx/FindBandpose", false, 0)]
+ //private static void FindBandpose()
+ //{
+ // string path = "Folder\tfbx\r\n";
+ // DirectoryInfo di = new DirectoryInfo("Assets/Creatures");
+ // DirectoryInfo[] subDirs = di.GetDirectories("*.*", SearchOption.TopDirectoryOnly);
+ // foreach (DirectoryInfo subDir in subDirs)
+ // {
+ // FileInfo[] files = subDir.GetFiles("*_bandpose.fbx", SearchOption.TopDirectoryOnly);
+ // if (files.Length > 1)
+ // {
+ // path += subDir.FullName + "\t";
+ // foreach (FileInfo file in files)
+ // {
+ // path += file.Name + "|";
+ // }
+ // path += "\r\n";
+ // }
+ // else if (files.Length == 0)
+ // {
+ // Debug.LogError(subDir.FullName);
+ // }
+ // }
+ // File.WriteAllText("Assets/Resources/a.txt", path);
+ //}
+ public static void ExportMeshAvatar(ModelImporter modelimporter, string path, GameObject fbx)
+ {
+ if (fbx == null)
+ fbx = AssetDatabase.LoadAssetAtPath<GameObject>(path);
+ _ExportMeshAvatar(fbx, modelimporter, path);
+ }
+
+
+ static string targetAnimFolder = "Animation";
+ //static void CopyClip(string importedPath, string assetname)
+ //{
+ // //AnimationClip src = AssetDatabase.LoadAssetAtPath(importedPath, typeof(AnimationClip)) as AnimationClip;
+ // Object[] allObjects = AssetDatabase.LoadAllAssetsAtPath(importedPath);
+
+ // int index = assetname.IndexOf('_');
+ // int index2 = assetname.Substring(index + 1).IndexOf('_');
+ // string folder = assetname.Substring(0, index + index2 + 1);
+ // string targetPath = "Assets/Resources/" + targetFolder + "/" + folder;
+
+ // if (Directory.Exists(targetPath) == false)
+ // {
+ // AssetDatabase.CreateFolder("Assets/Resources/" + targetFolder, folder);
+ // }
+
+ // string staticTargetPath = "Assets/Resources/" + targetFolder + "/" + folder;
+
+ // foreach (Object o in allObjects)
+ // {
+ // AnimationClip oClip = o as AnimationClip;
+
+ // if (oClip == null || oClip.name.StartsWith("__preview__Take 001")) continue;
+
+ // //if(oClip.name != name) continue;
+ // string copyPath = targetPath + "/" + oClip.name + ".anim";
+ // string staticPath = staticTargetPath + "/" + oClip.name + ".anim";
+ // if (File.Exists(staticPath))
+ // copyPath = staticPath;
+
+ // AnimationClip newClip = new AnimationClip();
+
+ // EditorUtility.CopySerialized(oClip, newClip);
+
+ // AssetDatabase.CreateAsset(newClip, copyPath);
+
+ // //XEditor.AssetModify._ReduceKeyFrame(newClip, "");
+
+ // }
+ // AssetDatabase.SaveAssets();
+ // AssetDatabase.Refresh();
+ //}
+ private static bool _ExtractAnimationClipFromFBX(GameObject fbx, ModelImporter modelImporter, string path)
+ {
+ if (modelImporter.animationCompression != ModelImporterAnimationCompression.Optimal)
+ {
+ modelImporter.animationCompression = ModelImporterAnimationCompression.Optimal;
+ AssetDatabase.ImportAsset(path, ImportAssetOptions.ForceUpdate);
+ }
+
+
+ int index = fbx.name.IndexOf('_');
+ if(index>=0)
+ {
+ index = fbx.name.IndexOf('_', index + 1);
+ if(index >= 0)
+ {
+ string folderName = fbx.name.Substring(0, index);
+ string targetPath = "Assets/Resources/" + targetAnimFolder + "/" + folderName;
+
+ if (!Directory.Exists(targetPath))
+ {
+ AssetDatabase.CreateFolder("Assets/Resources/" + targetAnimFolder, folderName);
+ }
+ UnityEngine.Object[] allObjects = AssetDatabase.LoadAllAssetsAtPath(path);
+ for (int i = 0; i < allObjects.Length; ++i)
+ {
+ AnimationClip anim = allObjects[i] as AnimationClip;
+ if (anim != null && !anim.name.StartsWith("__preview"))
+ {
+
+ if (string.IsNullOrEmpty(anim.name))
+ {
+ Debug.LogError(path);
+ }
+ else
+ {
+ AnimationClip newClip = new AnimationClip();
+ EditorUtility.CopySerialized(anim, newClip);
+ newClip.name = anim.name;
+ string newClipPath = targetPath + "/" + anim.name + ".anim";
+ _ReduceKeyFrame(newClip, newClipPath);
+ CreateOrReplaceAsset<AnimationClip>(newClip, newClipPath);
+ }
+ }
+ }
+ }
+
+ }
+
+ return false;
+ }
+
+ [MenuItem("Assets/ExtractFBX")]
+ private static void ExtractAnimationClipFromFBX()
+ {
+ if (!Directory.Exists("Assets/Resources/" + targetAnimFolder))
+ {
+ AssetDatabase.CreateFolder("Assets/Resources", targetAnimFolder);
+ }
+
+ enumFbx.cb = _ExtractAnimationClipFromFBX;
+ EnumAsset<GameObject>(enumFbx, "ExtractAnimationClipFromFBX");
+
+ }
+
+ #endregion fbx
+ #region curve
+ [MenuItem(@"Assets/Tool/Curve/Scan", false, 0)]
+ private static void ScanCurve()
+ {
+ UnityEngine.Object[] curves = Selection.GetFiltered(typeof(TextAsset), SelectionMode.DeepAssets);
+
+ if (curves != null)
+ {
+ using (FileStream desStream = new FileStream("Assets/Resources/Curves.bytes", FileMode.Create))
+ {
+ int count = curves.Length;
+ BinaryWriter writer = new BinaryWriter(desStream);
+ writer.Write(count);
+ for (int i = 0; i < curves.Length; ++i)
+ {
+ UnityEngine.Object curve = curves[i];
+ string path = AssetDatabase.GetAssetPath(curve);
+ path = path.Replace("Assets/Resources/Server/", "");
+ writer.Write(path);
+ EditorUtility.DisplayProgressBar(string.Format("{0}-{1}/{2}", path, i, curves.Length), path, (float)i / curves.Length);
+ }
+ }
+
+ }
+ EditorUtility.ClearProgressBar();
+ EditorUtility.DisplayDialog("Finish", "All gameobjects processed finish", "OK");
+ }
+
+ [MenuItem(@"Assets/Tool/Curve/Read", false, 0)]
+ private static void ReadCurve()
+ {
+ UnityEngine.Object[] curves = Selection.GetFiltered(typeof(TextAsset), SelectionMode.DeepAssets);
+
+ if (curves != null)
+ {
+ using (FileStream desStream = new FileStream("Assets/Resources/Curves.bytes", FileMode.Open))
+ {
+ BinaryReader reader = new BinaryReader(desStream);
+ int count = reader.ReadInt32();
+ for (int i = 0; i < count; ++i)
+ {
+ string path = reader.ReadString();
+ Debug.Log(path);
+ EditorUtility.DisplayProgressBar(string.Format("{0}-{1}/{2}", path, i, curves.Length), path, (float)i / curves.Length);
+ }
+ }
+
+ }
+ EditorUtility.ClearProgressBar();
+ EditorUtility.DisplayDialog("Finish", "All gameobjects processed finish", "OK");
+ }
+ #endregion
+ #region animation
+
+ private static bool ComputerKeyDerivative(Keyframe preKey,Keyframe midKey, Keyframe currentKey)
+ {
+ float ddx0 = (midKey.value - preKey.value);
+ float ddx1 = (currentKey.value - midKey.value);
+ float derivativeValue = Mathf.Abs(ddx1 - ddx0);
+
+ float ddxInTangent0 = midKey.inTangent - preKey.inTangent;
+ float ddxInTangent1 = currentKey.inTangent - midKey.inTangent;
+ float derivativeInTangent = Mathf.Abs(ddxInTangent1 - ddxInTangent0);
+
+ float ddxOutTangent0 = midKey.outTangent - preKey.outTangent;
+ float ddxOutTangent1 = currentKey.outTangent - midKey.outTangent;
+ float derivativeOutTangent = Mathf.Abs(ddxOutTangent1 - ddxOutTangent0);
+
+ return derivativeValue < 0.01f &&
+ derivativeInTangent < 0.01f &&
+ derivativeOutTangent < 0.01f;
+ }
+
+ public static void _ReduceKeyFrame(AnimationClip animClip, string path)
+ {
+ errorLog = "";
+ int reduceCurveCount = 0;
+ bool isMount = path.Contains("_Mount_");
+ List<int> removeIndex = ListPool<int>.Get();
+ EditorCurveBinding[] curveBinding = AnimationUtility.GetCurveBindings(animClip);
+ for (int i = 0; i < curveBinding.Length; ++i)
+ {
+ var binding = curveBinding[i];
+ AnimationCurve curve = AnimationUtility.GetEditorCurve(animClip, binding);
+ if (curve.keys.Length > 1)
+ {
+ removeIndex.Clear();
+ bool scale = binding.propertyName.StartsWith("m_LocalScale");
+ bool pos = binding.propertyName.StartsWith("m_LocalPosition");
+
+ Keyframe[] keys = new Keyframe[curve.keys.Length];
+ for (int j = 0; j < curve.keys.Length; ++j)
+ {
+ Keyframe key = curve.keys[j];
+ if (scale || pos)
+ {
+ key.value = (float)Math.Round(key.value, 4);
+ }
+ else
+ {
+ key.value = key.value;
+ }
+ key.inTangent = (float)Math.Round(key.inTangent, 3);
+ key.outTangent = (float)Math.Round(key.outTangent, 3);
+ keys[j] = key;
+ }
+
+ Keyframe preKey = keys[0];
+ Keyframe midKey = keys[1];
+
+ float defaultValue = scale ? 1 : 0;
+ bool isDefaultValue = Mathf.Abs(preKey.value - defaultValue) < 0.01f&& Mathf.Abs(midKey.value - defaultValue) < 0.01f;
+
+ for (int j = 2; j < keys.Length; ++j)
+ {
+ Keyframe key = keys[j];
+ if (ComputerKeyDerivative(preKey, midKey, key))
+ {
+ removeIndex.Add(j - 1);
+ }
+
+
+ float defaultError = Mathf.Abs(key.value - defaultValue);
+ float defaultErrorPercent = scale ? defaultError / defaultValue : defaultError;
+ if (defaultErrorPercent > 0.01f)
+ isDefaultValue = false;
+
+ preKey = midKey;
+ midKey = key;
+ }
+ curve.keys = keys;
+
+ if (isDefaultValue)
+ {
+ if (isMount && pos && binding.propertyName == "m_LocalPosition.z" && !binding.path.Contains("/"))
+ {
+ Debug.Log("not opt curve" + binding.path);
+ }
+ else
+ {
+ AnimationUtility.SetEditorCurve(animClip, binding, null);
+ reduceCurveCount++;
+ if (!(pos || scale))
+ {
+ errorLog += string.Format("{0}:{1}\r\n", binding.path, binding.propertyName);
+ }
+ }
+ }
+ else
+ {
+ for (int j = removeIndex.Count - 1; j >= 0; --j)
+ {
+ curve.RemoveKey(removeIndex[j]);
+ }
+ if (removeIndex.Count > 0)
+ reduceCurveCount++;
+
+ AnimationUtility.SetEditorCurve(animClip, binding, curve);
+ }
+
+ }
+ else
+ {
+ AnimationUtility.SetEditorCurve(animClip, binding, null);
+ }
+ }
+ if (reduceCurveCount > 0)
+ {
+ Debug.LogWarning(string.Format("{0} reduceCurveCount/total:{1}/{2}\r\n{3}", path, reduceCurveCount, curveBinding.Length, errorLog));
+ }
+ ListPool<int>.Release(removeIndex);
+ }
+
+ [MenuItem(@"Assets/Tool/Animation/ReduceKeyFrame", false, 0)]
+ private static void ReduceKeyFrame()
+ {
+ enumAnimationClip.cb = _ReduceKeyFrame;
+ EnumAsset<AnimationClip>(enumAnimationClip, "ReduceKeyFrame");
+ }
+
+ private static void _ConvertAnimation2Legacy(AnimationClip animClip, string path)
+ {
+ bool loop = animClip.isLooping;
+ animClip.legacy = true;
+ if (loop)
+ animClip.wrapMode = WrapMode.Loop;
+ }
+
+ [MenuItem(@"Assets/Tool/Animation/ConvertAnimator2Legacy", false, 0)]
+ private static void ConvertAnimation2Legacy()
+ {
+ enumAnimationClip.cb = _ConvertAnimation2Legacy;
+ EnumAsset<AnimationClip>(enumAnimationClip, "ConvertAnimation2Legacy");
+ }
+ static AssetBundleBuild[] testAnimBundle = new AssetBundleBuild[1];
+ static string[] testAnimBundlePath = new string[1];
+ private static void _TestAnimBundle(AnimationClip animClip, string path)
+ {
+ AssetBundleBuild abb;
+ abb.assetBundleName = animClip.name;
+ abb.assetBundleVariant = "";
+ testAnimBundlePath[0] = path;
+ abb.assetNames = testAnimBundlePath;
+ testAnimBundle[0] = abb;
+ BuildPipeline.BuildAssetBundles("Assets/Test", testAnimBundle, BuildAssetBundleOptions.DeterministicAssetBundle | BuildAssetBundleOptions.UncompressedAssetBundle, EditorUserBuildSettings.activeBuildTarget);
+ }
+
+ [MenuItem(@"Assets/Tool/Animation/TestAnimBundle", false, 0)]
+ private static void TestAnimBundle()
+ {
+ enumAnimationClip.cb = _TestAnimBundle;
+ EnumAsset<AnimationClip>(enumAnimationClip, "TestAnimBundle");
+ }
+
+ [MenuItem(@"Assets/Tool/Animation/RefreshAnim", false, 0)]
+ private static void RefreshAnim()
+ {
+ using (FileStream desStream = new FileStream(@"Assets/Resources/anim.bytes", FileMode.Open))
+ {
+ BinaryReader sr = new BinaryReader(desStream);
+ int count = sr.ReadInt32();
+ for (int i = 0; i < count; ++i)
+ {
+ string path = sr.ReadString();
+ bool loopPose = sr.ReadBoolean();
+ //int index = path.LastIndexOf("/");
+ //string dir = path.Substring(0, index);
+ //string animName = path.Substring(index + 1).Replace(".anim", ".fbx");
+ //index = dir.LastIndexOf("/");
+ //string dirName = dir.Substring(index + 1);
+ //string fbxPath = string.Format("Assets/Creatures/{0}/{1}", dirName, animName);
+ AnimationClip animClip = AssetDatabase.LoadAssetAtPath<AnimationClip>(path);
+ SerializedObject serializedClip = new SerializedObject(animClip);
+ SerializedProperty sp = serializedClip.FindProperty("m_AnimationClipSettings");
+ if (sp != null)
+ {
+ SerializedProperty subsp0 = sp.FindPropertyRelative("m_LoopTime");
+ if (subsp0 != null)
+ {
+ subsp0.boolValue = true;
+ }
+ SerializedProperty subsp1 = sp.FindPropertyRelative("m_LoopBlend");
+ if (subsp1 != null)
+ {
+ subsp1.boolValue = loopPose;
+ }
+ }
+ serializedClip.ApplyModifiedProperties();
+ EditorUtility.DisplayProgressBar(string.Format("RefreshAnim-{0}/{1}", i, count), path, (float)i / count);
+ //ModelImporter modelImporter = AssetImporter.GetAtPath(fbxPath) as ModelImporter;
+ //if (modelImporter != null)
+ //{
+ // ModelImporterClipAnimation[] clipAnimations = modelImporter.clipAnimations;
+ // for (int j = 0; j < clipAnimations.Length; ++j)
+ // {
+ // ModelImporterClipAnimation mica = clipAnimations[j];
+ // mica.loop = true;
+ // mica.loopTime = true;
+ // mica.loopPose = loopPose;
+ // }
+ // modelImporter.clipAnimations = clipAnimations;
+ // modelImporter.animationCompression = ModelImporterAnimationCompression.KeyframeReductionAndCompression;
+ // AssetDatabase.ImportAsset(path, ImportAssetOptions.ForceUpdate);
+
+ //}
+ }
+ EditorUtility.ClearProgressBar();
+ AssetDatabase.SaveAssets();
+ AssetDatabase.Refresh();
+ EditorUtility.DisplayDialog("Finish", "All assets processed finish", "OK");
+ }
+ }
+ //public static string relativeRoot = "Assets/Animation/";
+ //private static string platform = "Android";
+ ////private static BuildTarget target = BuildTarget.Android;
+
+ //private static void _BuildBundle(AnimationClip clip, string path)
+ //{
+ // string relativeDir = path.Substring(relativeRoot.Length);
+ // int index = relativeDir.LastIndexOf("/");
+ // relativeDir = relativeDir.Substring(0, index);
+ // string targetDir = string.Format("Assets/AssetBundle/{0}/Animation/{1}", platform, relativeDir);
+ // if (!Directory.Exists(targetDir))
+ // {
+ // Directory.CreateDirectory(targetDir);
+ // }
+ // string targetPath = string.Format("{0}/{1}.bundle", targetDir, clip.name);
+
+ // BuildPipeline.BuildAssetBundle(clip,
+ // null,
+ // targetPath,
+ // BuildAssetBundleOptions.UncompressedAssetBundle |
+ // BuildAssetBundleOptions.CompleteAssets |
+ // BuildAssetBundleOptions.DeterministicAssetBundle,
+ // EditorUserBuildSettings.activeBuildTarget);
+ //}
+
+ //[MenuItem(@"Assets/Tool/Animation/BuildBundleAndroid")]
+ //private static void BuildBundleAndroid()
+ //{
+ // platform = "Android";
+ // EnumAnimation(_BuildBundle, "BuildBundleAndroid");
+ //}
+
+ //[MenuItem(@"Assets/Tool/Animation/BuildBundleIOS")]
+ //private static void BuildBundleIOS()
+ //{
+ // platform = "IOS";
+ // EnumAnimation(_BuildBundle, "BuildBundleIOS");
+ //}
+ //[MenuItem(@"Assets/Tool/Animation/BuildBundlePC")]
+ //private static void BuildBundlePC()
+ //{
+ // platform = "PC";
+ // EnumAnimation(_BuildBundle, "BuildBundlePC");
+ //}
+ //public static void BuildBundle()
+ //{
+ // if (EditorUserBuildSettings.activeBuildTarget == BuildTarget.Android)
+ // {
+ // platform = "Android";
+ // }
+ // else if (EditorUserBuildSettings.activeBuildTarget == BuildTarget.iPhone)
+ // {
+ // platform = "IOS";
+ // }
+ // else if (EditorUserBuildSettings.activeBuildTarget == BuildTarget.StandaloneWindows)
+ // {
+ // platform = "PC";
+
+ // }
+ // else
+ // {
+ // return;
+ // }
+ // DirectoryInfo animDir = new DirectoryInfo(AssetModify.relativeRoot);
+ // FileInfo[] files = animDir.GetFiles("*.anim", SearchOption.AllDirectories);
+ // if (files != null)
+ // {
+ // FileInfo root = new FileInfo(Application.dataPath);
+ // string rootPath = root.FullName.Replace("\\", "/");
+ // int index = rootPath.LastIndexOf("/");
+ // rootPath = rootPath.Substring(0, index + 1);
+ // for (int i = 0, imax = files.Length; i < imax; ++i)
+ // {
+ // FileInfo file = files[i];
+ // string clipPath = file.FullName.Replace("\\", "/");
+ // string relativePath = clipPath.Substring(rootPath.Length);
+ // AnimationClip clip = AssetDatabase.LoadAssetAtPath(relativePath, typeof(AnimationClip)) as AnimationClip;
+ // if (clip != null)
+ // {
+ // _BuildBundle(clip, relativePath);
+ // EditorUtility.DisplayProgressBar(string.Format("Build Anim Bundle-{0}/{1}", i, imax), relativePath, (float)i / imax);
+ // }
+ // }
+ // EditorUtility.ClearProgressBar();
+ // }
+ //}
+ //private static void CreateDir(DirectoryInfo di, string parentDirName)
+ //{
+ // DirectoryInfo[] subdirs = di.GetDirectories("*.*", SearchOption.TopDirectoryOnly);
+ // if (subdirs != null)
+ // {
+ // for (int i = 0, imax = subdirs.Length; i < imax; ++i)
+ // {
+ // DirectoryInfo subdir = subdirs[i];
+ // string desDir = parentDirName + subdir.Name;
+ // if (!Directory.Exists(desDir))
+ // {
+ // Directory.CreateDirectory(desDir);
+ // //AssetDatabase.CreateFolder(parentDirName, subdir.Name);
+ // //AssetDatabase.Refresh();
+ // }
+ // CreateDir(subdir, parentDirName + "/" + subdir.Name + "/");
+ // }
+ // }
+ //}
+
+ //public static void CopyBundle()
+ //{
+ // string srcABRoot = "";
+ // string desABRoot = "";
+ // if (EditorUserBuildSettings.activeBuildTarget == BuildTarget.iPhone)
+ // {
+ // srcABRoot = "Assets/AssetBundle/IOS/Animation/";
+ // desABRoot = "Assets/StreamingAssets/IOS/Animation/";
+ // }
+ // else if (EditorUserBuildSettings.activeBuildTarget == BuildTarget.Android)
+ // {
+ // srcABRoot = "Assets/AssetBundle/Android/Animation/";
+ // desABRoot = "Assets/StreamingAssets/Android/Animation/";
+
+ // }
+ // else if (EditorUserBuildSettings.activeBuildTarget == BuildTarget.StandaloneWindows)
+ // {
+ // srcABRoot = "Assets/AssetBundle/PC/Animation/";
+ // desABRoot = "Assets/StreamingAssets/PC/Animation/";
+ // }
+ // else
+ // {
+ // return;
+ // }
+ // if (!Directory.Exists(desABRoot))
+ // {
+ // Directory.CreateDirectory(desABRoot);
+ // }
+ // AssetDatabase.Refresh();
+ // DirectoryInfo animDir = new DirectoryInfo(AssetModify.relativeRoot);
+ // CreateDir(animDir, desABRoot);
+ // AssetDatabase.Refresh();
+ // FileInfo[] files = animDir.GetFiles("*.anim", SearchOption.AllDirectories);
+ // if (files != null)
+ // {
+ // for (int i = 0, imax = files.Length; i < imax; ++i)
+ // {
+ // FileInfo file = files[i];
+ // string relativePath = file.FullName.Substring(animDir.FullName.Length);
+ // string relativeABPath = relativePath.Replace(".anim", ".bundle");
+ // string srcPath = srcABRoot + relativeABPath;
+ // string desPath = desABRoot + relativeABPath;
+ // if (File.Exists(srcPath))
+ // {
+ // try
+ // {
+ // File.Copy(srcPath, desPath, true);
+ // }
+ // catch (Exception e)
+ // {
+ // Debug.Log(e.Message);
+ // }
+ // }
+ // else
+ // {
+ // UnityEngine.Object clip = AssetDatabase.LoadAssetAtPath(relativePath, typeof(AnimationClip));
+ // BuildPipeline.BuildAssetBundle(clip,
+ // null,
+ // desPath,
+ // BuildAssetBundleOptions.UncompressedAssetBundle |
+ // BuildAssetBundleOptions.CompleteAssets |
+ // BuildAssetBundleOptions.DeterministicAssetBundle,
+ // EditorUserBuildSettings.activeBuildTarget);
+ // }
+ // EditorUtility.DisplayProgressBar(string.Format("Copy Anim Bundle-{0}/{1}", i, imax), desPath, (float)i / imax);
+ // }
+ // //string staticAnimationDir = "Assets/Resources/StaticAnimation/Main_Camera";
+ // //DirectoryInfo staticCameraDir = new DirectoryInfo(staticAnimationDir);
+ // //for()
+ // AssetDatabase.SaveAssets();
+ // AssetDatabase.Refresh();
+ // EditorUtility.ClearProgressBar();
+ // }
+ //}
+
+ //public static void DeleteBundle()
+ //{
+ // string desABRoot = "Assets/StreamingAssets/";
+ // if (EditorUserBuildSettings.activeBuildTarget == BuildTarget.iPhone)
+ // {
+ // desABRoot += "IOS/Animation";
+ // }
+ // else if (EditorUserBuildSettings.activeBuildTarget == BuildTarget.Android)
+ // {
+ // desABRoot += "Android/Animation";
+ // }
+ // else if (EditorUserBuildSettings.activeBuildTarget == BuildTarget.StandaloneWindows)
+ // {
+ // desABRoot += "PC/Animation";
+ // }
+ // else
+ // {
+ // return;
+ // }
+ // AssetDatabase.DeleteAsset(desABRoot);
+
+ // AssetDatabase.SaveAssets();
+ // AssetDatabase.Refresh();
+ //}
+ #endregion animation
+ #region Material
+
+ private static void _Cutoff2RMat(Material mat, string path)
+ {
+ if (mat.shader.name.Contains("CutoutDiffuse") ||
+ mat.shader.name.Contains("TransparentDiffuse"))
+ {
+ Texture2D tex = mat.mainTexture as Texture2D;
+ if (tex != null)
+ {
+ Texture2D alphaTex = ConvertTexRtex(tex);
+ if (mat.shader.name.Contains("RimLight/CutoutDiffuse"))
+ mat.shader = Shader.Find("Custom/RimLight/CutoutDiffuseMaskR");
+ else if (mat.shader.name.Contains("CutoutDiffuse") && mat.shader.name.Contains("NoLight"))
+ mat.shader = Shader.Find("Custom/Common/CutoutDiffuseMaskRNoLight");
+ else if (mat.shader.name.Contains("CutoutDiffuse"))
+ mat.shader = Shader.Find("Custom/Common/CutoutDiffuseMaskR");
+ else if (mat.shader.name.Contains("Common/TransparentDiffuse") && mat.shader.name.Contains("NoLight"))
+ mat.shader = Shader.Find("Custom/Common/TransparentDiffuseMaskRNoLight");
+ else if (mat.shader.name.Contains("Common/TransparentDiffuse"))
+ mat.shader = Shader.Find("Custom/Common/TransparentDiffuseMaskR");
+ else if (mat.shader.name.Contains("Transparent/Cutout/Diffuse"))
+ mat.shader = Shader.Find("Custom/Scene/CutoutDiffuseMaskLM");
+ mat.SetTexture("_Mask", alphaTex);
+
+ }
+ }
+ }
+
+ [MenuItem(@"Assets/Tool/Material/Cutoff2RMat2 %2", false, 0)]
+ private static void Cutoff2RMat2()
+ {
+ enumMat.cb = _Cutoff2RMat;
+ EnumAsset<Material>(enumMat, "Cutoff2RMat");
+ }
+
+ [MenuItem(@"Assets/Tool/Material/Cutoff2RMat", false, 0)]
+ private static void Cutoff2RMat()
+ {
+ scaleSize = 1;
+ enumMat.cb = _Cutoff2RMat;
+ EnumAsset<Material>(enumMat, "Cutoff2RMat");
+ scaleSize = 2;
+ }
+
+ private static HashSet<string> matName = new HashSet<string>();
+ private static Dictionary<string, List<string>> matTexName = new Dictionary<string, List<string>>();
+ private static void _FindSameMat(Material mat, string path)
+ {
+ if (matName.Contains(mat.name))
+ {
+ Debug.Log(string.Format("Same Mat:{0}", mat.name));
+ }
+ else
+ {
+ matName.Add(mat.name);
+ }
+ Texture tex = mat.mainTexture;
+ if (tex != null)
+ {
+ List<string> matList = null;
+ if (matTexName.TryGetValue(tex.name, out matList))
+ {
+ matList.Add(mat.name);
+ }
+ else
+ {
+ matList = new List<string>();
+ matList.Add(mat.name);
+ matTexName.Add(tex.name, matList);
+ }
+ }
+ }
+
+ [MenuItem(@"Assets/Tool/Material/FindSameMat", false, 0)]
+ private static void FindSameMat()
+ {
+ matName.Clear();
+ matTexName.Clear();
+ enumMat.cb = _FindSameMat;
+ EnumAsset<Material>(enumMat, "FindSameMat");
+ foreach (KeyValuePair<string, List<string>> kvp in matTexName)
+ {
+ if (kvp.Value.Count > 1)
+ {
+ Debug.Log(string.Format("Tex:{0}----------------------", kvp.Key));
+ foreach (string mat in kvp.Value)
+ {
+ Debug.Log(string.Format("Mat:{0}", mat));
+ }
+ }
+ }
+ matName.Clear();
+ matTexName.Clear();
+ }
+
+ //private static void _FixMat(Material mat, string path)
+ //{
+ // //if (mat.shader==null||mat.shader.name.Contains("Hidden/InternalErrorShader"))
+ // //{
+ // // mat.shader = Shader.Find("Unlit/Texture");
+ // //}
+ //}
+
+ //[MenuItem(@"Assets/Tool/Material/FixMat", false, 0)]
+ //private static void FixMat()
+ //{
+ // enumMat.cb = _FixMat;
+ // EnumAsset<Material>(enumMat, "FixMat");
+ //}
+
+
+
+ private static List<ShaderValue> shaderValue = new List<ShaderValue>();
+ private static void _ClearMat(Material mat, string path)
+ {
+ shaderValue.Clear();
+ ShaderValue.GetShaderValue(mat, shaderValue);
+ Material emptyMat = new Material(mat.shader);
+ mat.CopyPropertiesFromMaterial(emptyMat);
+ UnityEngine.Object.DestroyImmediate(emptyMat);
+ for (int i = 0; i < shaderValue.Count; ++i)
+ {
+ ShaderValue sv = shaderValue[i];
+ sv.SetValue(mat);
+ }
+ string name = mat.shader.name;
+ if (name == "Custom/RimLight/Diffuse" ||
+ name == "Custom/Common/Diffuse" ||
+ name == "Custom/RimLight/CutoutDiffuseMaskR" ||
+ name == "Custom/Common/CutoutDiffuseMaskR")
+ {
+ mat.SetColor("_Color", new Color(1, 1, 1, 1));
+ }
+ if (!mat.name.EndsWith("_RQ"))
+ mat.renderQueue = -1;
+ }
+
+
+ [MenuItem(@"Assets/Tool/Material/ClearMat", false, 0)]
+ private static void ClearMat()
+ {
+ enumMat.cb = _ClearMat;
+ EnumAsset<Material>(enumMat, "ClearMat");
+ AssetDatabase.SaveAssets();
+ }
+ [MenuItem(@"Assets/Tool/Material/FindUnusedShader", false, 0)]
+ private static void FindUnusedShader()
+ {
+ DirectoryInfo di = new DirectoryInfo("Assets/Resources/Shader");
+ FileInfo[] files = di.GetFiles("*.shader", SearchOption.AllDirectories);
+ Dictionary<Shader, int> shaderUse = new Dictionary<Shader, int>();
+ for (int i = 0; i < files.Length; ++i)
+ {
+ string path = files[i].FullName;
+ path = path.Replace("\\","/");
+ int index = path.IndexOf("Assets/Resources/");
+ path = path.Substring(index);
+ Shader shader = AssetDatabase.LoadAssetAtPath<Shader>(path);
+ if (!shaderUse.ContainsKey(shader))
+ shaderUse.Add(shader, 0);
+ }
+ di = new DirectoryInfo("Assets/");
+ files = di.GetFiles("*.mat", SearchOption.AllDirectories);
+ for (int i = 0; i < files.Length; ++i)
+ {
+ string path = files[i].FullName;
+ path = path.Replace("\\", "/");
+ int index = path.IndexOf("Assets/");
+ path = path.Substring(index);
+ Material mat = AssetDatabase.LoadAssetAtPath<Material>(path);
+ if (mat != null)
+ {
+ int count = 0;
+ if (shaderUse.TryGetValue(mat.shader, out count))
+ {
+ count++;
+ shaderUse[mat.shader] = count;
+ }
+ else
+ {
+ Debug.LogError(string.Format("Not custum shader:{0}", mat.shader.name));
+ }
+ }
+ }
+ var it = shaderUse.GetEnumerator();
+ while (it.MoveNext())
+ {
+ if (it.Current.Value == 0)
+ {
+ Debug.LogError(string.Format("No use shader:{0}", it.Current.Key.name));
+ }
+ }
+ }
+
+ private static void _FindMat(Material mat, string path)
+ {
+ if (mat.shader.name == "Mobile/Diffuse")
+ {
+ mat.shader = Shader.Find("Custom/Scene/DiffuseLM");
+ }
+ }
+
+ [MenuItem(@"Assets/Tool/Material/FindMat", false, 0)]
+ private static void FindMat()
+ {
+ enumMat.cb = _FindMat;
+ EnumAsset<Material>(enumMat, "FindMat");
+ }
+ public static void GetMatTex(Material mat, List<Texture> lst)
+ {
+ if (mat != null)
+ {
+ Shader shader = mat.shader;
+ int count = ShaderUtil.GetPropertyCount(shader);
+ for (int i = 0; i < count; ++i)
+ {
+ string name = ShaderUtil.GetPropertyName(shader, i);
+ ShaderUtil.ShaderPropertyType type = ShaderUtil.GetPropertyType(shader, i);
+ switch (type)
+ {
+ case ShaderUtil.ShaderPropertyType.TexEnv:
+ Texture tex = mat.GetTexture(name);
+ if (tex != null)
+ lst.Add(tex);
+ break;
+ }
+ }
+ }
+
+ }
+
+ #endregion Material
+ #region scene
+
+ private delegate bool EnumSceneCallback(UnityEngine.SceneManagement.Scene scene);
+ private static void EnumAllScene(EnumSceneCallback cb, string title)
+ {
+ if (cb != null)
+ {
+ EditorBuildSettingsScene[] scenes = EditorBuildSettings.scenes;
+ for (int i = 0; i < scenes.Length; ++i)
+ {
+ EditorBuildSettingsScene scene = scenes[i];
+ EditorUtility.DisplayProgressBar(string.Format("{0}-{1}/{2}", title, i, scenes.Length), scene.path, (float)i / scenes.Length);
+ UnityEngine.SceneManagement.Scene s = EditorSceneManager.OpenScene(scene.path);
+
+ bool save = cb(s);
+ if (save)
+ {
+ EditorSceneManager.SaveScene(s);
+ }
+ }
+ }
+ AssetDatabase.Refresh();
+ AssetDatabase.SaveAssets();
+ EditorUtility.ClearProgressBar();
+ EditorUtility.DisplayDialog("Finish", "All scenes processed finish", "OK");
+ }
+
+ public static void Process45colliders()
+ {
+ GameObject colliders = GameObject.Find("45collider");
+ if (colliders != null)
+ {
+ for (int i = 0, imax = colliders.transform.childCount; i < imax; ++i)
+ {
+ Transform child = colliders.transform.GetChild(i);
+ XColliderModelLinker modleLink = child.GetComponent<XColliderModelLinker>();
+ if (modleLink != null && modleLink.Models.Count > 0)
+ {
+ XColliderRenderLinker renderLink = child.gameObject.GetComponent<XColliderRenderLinker>();
+ if (renderLink == null)
+ {
+ renderLink = child.gameObject.AddComponent<XColliderRenderLinker>();
+ }
+ if (renderLink != null)
+ {
+ List<Renderer> tmp = new List<Renderer>();
+ for (int j = 0, jmax = modleLink.Models.Count; j < jmax; ++j)
+ {
+ Renderer r = modleLink.Models[j].GetComponent<Renderer>();
+ if (r != null && !tmp.Contains(r))
+ {
+ tmp.Add(r);
+ }
+ }
+ if (tmp.Count > 0)
+ {
+ renderLink.renders = tmp.ToArray();
+ }
+ else
+ renderLink.renders = null;
+ }
+ UnityEngine.Object.DestroyImmediate(modleLink);
+ }
+ }
+ }
+ }
+
+
+ private static HashSet<Material> processedMat = new HashSet<Material>();
+ private static void _PrcessSceneMat(Material mat, bool recover)
+ {
+ if (!processedMat.Contains(mat) && mat.shader != null)
+ {
+ if (mat.shader.name.Contains("Transparent/Cutout/Diffuse") ||
+ mat.shader.name.Contains("CutoutDiffuseMaskLM_VMove") ||
+ mat.shader.name == "Custom/Scene/CutoutDiffuseMaskLM")
+ {
+ Texture2D tex = mat.mainTexture as Texture2D;
+ if (tex != null)
+ {
+ if (recover)
+ {
+ string texPath = AssetDatabase.GetAssetPath(tex);
+ int size = tex.width > tex.height ? tex.width : tex.height;
+ TextureImporter texImporter = AssetImporter.GetAtPath(texPath) as TextureImporter;
+ texImporter.textureType = TextureImporterType.Default;
+ texImporter.anisoLevel = 0;
+ texImporter.mipmapEnabled = tex.width > 256 && tex.height > 256;
+ texImporter.npotScale = TextureImporterNPOTScale.ToNearest;
+ texImporter.wrapMode = TextureWrapMode.Repeat;
+ texImporter.filterMode = FilterMode.Bilinear;
+ //SetTexImportSetting(texImporter, BuildTarget.Android.ToString(), size, TextureImporterFormat.RGBA16);
+ //SetTexImportSetting(texImporter, "iPhone", size, TextureImporterFormat.RGBA16);
+ SetTexImportSetting(texImporter, "Standalone", size, TextureImporterFormat.RGBA32);
+ texImporter.isReadable = false;
+ AssetDatabase.ImportAsset(texPath, ImportAssetOptions.ForceUpdate);
+ mat.shader = Shader.Find("Legacy Shaders/Transparent/Cutout/Diffuse");
+ }
+ else
+ {
+ Texture2D alphaTex = ConvertTexRtex(tex);
+
+ mat.shader = Shader.Find("Custom/Scene/CutoutDiffuseMaskLM");
+ mat.SetTexture("_Mask", alphaTex);
+ }
+
+ }
+ processedMat.Add(mat);
+ }
+ }
+
+ }
+
+ private static void _HalfSceneMatTex(Material mat, string path)
+ {
+ if (!processedMat.Contains(mat) && mat.shader != null)
+ {
+ processedMat.Add(mat);
+ Texture2D tex = mat.mainTexture as Texture2D;
+ string texturePath = AssetDatabase.GetAssetPath(tex);
+ texturePath = texturePath.Replace("Half", "");
+ Texture2D fullTex = AssetDatabase.LoadAssetAtPath(texturePath, typeof(Texture2D)) as Texture2D;
+ int index = texturePath.LastIndexOf(".");
+ if (index > 0)
+ {
+ string ext = texturePath.Substring(index);
+ string halfTexturePath = texturePath.Substring(0, index) + "Half" + ext;
+ Texture2D halfTex = AssetDatabase.LoadAssetAtPath(halfTexturePath, typeof(Texture2D)) as Texture2D;
+ if (halfTex == null)
+ halfTex = MakeHalfTexture(halfTexturePath, fullTex, true);
+ mat.mainTexture = halfTex;
+ }
+ else
+ {
+ return;
+ }
+ }
+ }
+
+ [MenuItem(@"Assets/Tool/Scene/HalfSceneMatTex", false, 0)]
+ private static void HalfSceneMatTex()
+ {
+ processedMat.Clear();
+ enumMat.cb = _HalfSceneMatTex;
+ EnumAsset<Material>(enumMat, "HalfMatTex");
+ processedMat.Clear();
+ }
+
+ private static void _PrcessSceneMat(Material mat, string path)
+ {
+ bool cutout = mat.HasProperty("_Cutoff");
+ bool isTransparent = mat.renderQueue >= 3000;
+ if (cutout || isTransparent)
+ {
+ Texture2D tex = mat.mainTexture as Texture2D;
+ if (tex != null)
+ {
+ Texture2D alphaTex = ConvertTexRtex(tex);
+ if (cutout && mat.shader != Shader.Find("Custom/Scene/CutoutDiffuseMaskLM_VMove"))
+ mat.shader = Shader.Find("Custom/Scene/CutoutDiffuseMaskLM");
+ mat.SetTexture("_Mask", alphaTex);
+ }
+ }
+ }
+
+ [MenuItem(@"Assets/Tool/Scene/PrcessSceneMat", false, 0)]
+ public static void PrcessSceneMat()
+ {
+ enumMat.cb = _PrcessSceneMat;
+ EnumAsset<Material>(enumMat, "PrcessSceneMat");
+ AssetDatabase.SaveAssets();
+ }
+
+ private static void ProcessSceneObject(Transform t, bool bake)
+ {
+ int flag = (int)GameObjectUtility.GetStaticEditorFlags(t.gameObject);
+ if ((flag & (int)StaticEditorFlags.LightmapStatic) != 0)
+ {
+ Renderer render = t.GetComponent<Renderer>();
+ if (render != null)
+ {
+ if (render is SkinnedMeshRenderer)
+ {
+ SkinnedMeshRenderer smr = render as SkinnedMeshRenderer;
+ smr.skinnedMotionVectors = false;
+ smr.updateWhenOffscreen = false;
+ }
+ else
+ {
+ render.lightProbeUsage = UnityEngine.Rendering.LightProbeUsage.Off;
+ render.shadowCastingMode = bake ? UnityEngine.Rendering.ShadowCastingMode.On : UnityEngine.Rendering.ShadowCastingMode.Off;
+ render.receiveShadows = bake;
+ render.reflectionProbeUsage = bake ? UnityEngine.Rendering.ReflectionProbeUsage.BlendProbesAndSkybox : UnityEngine.Rendering.ReflectionProbeUsage.Off;
+ render.motionVectorGenerationMode = MotionVectorGenerationMode.ForceNoMotion;
+ }
+ MeshFilter mf = t.GetComponent<MeshFilter>();
+ if (mf != null && mf.sharedMesh != null)
+ {
+ Mesh mesh = mf.sharedMesh;
+ string assetPath = AssetDatabase.GetAssetPath(mesh).ToLower();
+ if (bake)
+ {
+ if (assetPath.EndsWith(".asset"))
+ {
+ bool find = false;
+ int index = assetPath.LastIndexOf("_");
+ string fbxPath = assetPath.Substring(0, index) + ".fbx";
+ string indexStr = assetPath.Substring(index + 1).Replace(".asset", "");
+ int meshIndex = -1;
+ int.TryParse(indexStr, out meshIndex);
+ if (meshIndex >= 0)
+ {
+ GameObject fbx = AssetDatabase.LoadAssetAtPath<GameObject>(fbxPath);
+ if (fbx != null)
+ {
+ GameObject fbxObj = GameObject.Instantiate<GameObject>(fbx);
+ List<Renderer> renderLst = ListPool<Renderer>.Get();
+ fbxObj.GetComponentsInChildren<Renderer>(true, renderLst);
+ if (meshIndex < renderLst.Count)
+ {
+ Renderer r = renderLst[meshIndex];
+ if (r is MeshRenderer)
+ {
+ MeshFilter fbxMf = r.GetComponent<MeshFilter>();
+ if (fbxMf != null && fbxMf.sharedMesh != null)
+ {
+ mf.sharedMesh = fbxMf.sharedMesh;
+ find = true;
+ }
+ }
+ }
+ ListPool<Renderer>.Release(renderLst);
+ GameObject.DestroyImmediate(fbxObj);
+ }
+ }
+
+ if (!find)
+ {
+ Debug.LogError("fbx mesh not found:" + t.name);
+ }
+ }
+ }
+ else if (assetPath.EndsWith(".fbx"))
+ {
+
+ Mesh newMesh = null;
+ int result = FindMesh(mesh, false, out newMesh);
+ if (result == 1)
+ {
+ mf.sharedMesh = newMesh;
+ }
+ else if (result == -1)
+ {
+ Debug.LogError("mesh not found:" + t.name);
+ }
+ }
+ }
+ }
+ }
+ for (int i = t.childCount - 1; i >= 0; --i)
+ {
+ Transform child = t.GetChild(i);
+ ProcessSceneObject(child, bake);
+ }
+ }
+
+ //private static HashSet<Mesh> processedMesh = new HashSet<Mesh>();
+ //private static void InnerProcessMat(Transform t,bool bake,bool processMesh, bool processMat)
+ //{
+ // InnerProcessSceneObject(t, bake);
+ // MeshRenderer meshRender = t.GetComponent<MeshRenderer>();
+ // if (meshRender != null && meshRender.enabled)
+ // {
+ // if(processMat)
+ // {
+ // for (int i = 0, imax = meshRender.sharedMaterials.Length; i < imax; ++i)
+ // {
+ // Material mat = meshRender.sharedMaterials[i];
+ // if (mat != null)
+ // _PrcessSceneMat(mat, bake);
+ // else
+ // {
+ // Debug.LogError("Null mat:" + meshRender.name);
+ // }
+ // }
+ // }
+ // }
+ // if(processMesh)
+ // {
+ // MeshFilter mf = t.GetComponent<MeshFilter>();
+ // if (mf != null && mf.sharedMesh != null)
+ // {
+ // Mesh m = mf.sharedMesh;
+ // if (!processedMesh.Contains(m))
+ // {
+ // string modelPath = AssetDatabase.GetAssetPath(m);
+ // ModelImporter modelImporter = AssetImporter.GetAtPath(modelPath) as ModelImporter;
+ // if (modelImporter != null)
+ // {
+ // AssetDatabase.ImportAsset(modelPath, ImportAssetOptions.ForceUpdate);
+ // }
+ // }
+ // }
+ // }
+
+ // for (int i = t.childCount - 1; i >= 0; --i)
+ // {
+ // Transform child = t.GetChild(i);
+ // InnerProcessMat(child, bake, processMesh, processMat);
+ // }
+ //}
+ //private static void _MaterialInFolder2Original(Material mat, string path)
+ //{
+ // _PrcessSceneMat(mat, true);
+ //}
+ //private static bool _MeshInFolderImport(GameObject fbx, ModelImporter modelImporter, string path)
+ //{
+ // if (modelImporter == null)
+ // return false;
+ // AssetDatabase.ImportAsset(path, ImportAssetOptions.ForceSynchronousImport | ImportAssetOptions.ImportRecursive);
+ // return false;
+ //}
+ //[MenuItem(@"Assets/Tool/Scene/恢复目录中的材质到烘焙状态")]
+ //private static void MeshMaterialInFolder2Original()
+ //{
+ // bAccordingSettings = false;
+ // enumFbx.cb = _MeshInFolderImport;
+ // EnumAsset<GameObject>(enumFbx, "MeshInFolder2Original");
+ // bAccordingSettings = true;
+
+ // processedMat.Clear();
+ // enumMat.cb = _MaterialInFolder2Original;
+ // EnumAsset<Material>(enumMat, "MaterialInFolder2Original");
+ // processedMat.Clear();
+ //}
+
+ //private static void _MaterialInFolder2Compress(Material mat, string path)
+ //{
+ // _PrcessSceneMat(mat, false);
+ //}
+
+ //[MenuItem(@"Assets/Tool/Scene/转换目录中的材质转到运行状态")]
+ //private static void MaterialInFolder2Compress()
+ //{
+ // bAccordingSettings = true;
+ // enumFbx.cb = _MeshInFolderImport;
+ // EnumAsset<GameObject>(enumFbx, "MeshInFolder2Compress");
+
+ // processedMat.Clear();
+ // enumMat.cb = _MaterialInFolder2Compress;
+ // EnumAsset<Material>(enumMat, "MaterialInFolder2Compress");
+ // processedMat.Clear();
+ //}
+
+ [MenuItem(@"GameObject/Scene/准备烘焙", false, 0)]
+ public static void PrepareBake()
+ {
+ UnityEngine.SceneManagement.Scene s = EditorSceneManager.GetActiveScene();
+ GameObject[] roots = s.GetRootGameObjects();
+ for (int i = 0, imax = roots.Length; i < imax; ++i)
+ {
+ Transform t = roots[i].transform;
+ ProcessSceneObject(t, true);
+ }
+ UnityEngine.Object[] terrains = UnityEngine.Object.FindObjectsOfType(typeof(Terrain));
+ if (terrains != null)
+ {
+ for (int j = 0, imax = terrains.Length; j < imax; ++j)
+ {
+ Terrain terrain = terrains[j] as Terrain;
+ terrain.materialType = Terrain.MaterialType.BuiltInLegacyDiffuse;
+ terrain.Flush();
+ }
+ }
+ EditorUtility.DisplayDialog("Finish", "processed finish", "OK");
+ }
+ [MenuItem(@"GameObject/Scene/结束烘焙", false, 0)]
+ public static void EndBake()
+ {
+ UnityEngine.SceneManagement.Scene s = EditorSceneManager.GetActiveScene();
+ GameObject[] roots = s.GetRootGameObjects();
+ for (int i = 0, imax = roots.Length; i < imax; ++i)
+ {
+ Transform t = roots[i].transform;
+ ProcessSceneObject(t, false);
+ }
+ FixCurrentScene();
+ EditorUtility.DisplayDialog("Finish", "processed finish", "OK");
+ }
+
+ //[MenuItem(@"Assets/Tool/Scene/恢复场景中选中的fbx和材质到烘焙状态")]
+ //private static void SelectMeshMaterial2Original()
+ //{
+ // processedMat.Clear();
+ // processedMesh.Clear();
+ // bAccordingSettings = false;
+ // UnityEngine.SceneManagement.Scene s = EditorSceneManager.GetActiveScene();
+ // GameObject[] roots = s.GetRootGameObjects();
+ // for (int i = 0, imax = roots.Length; i < imax; ++i)
+ // {
+ // Transform t = roots[i].transform;
+ // InnerProcessMat(t, true, true, true);
+ // }
+ // processedMat.Clear();
+ // processedMesh.Clear();
+ // bAccordingSettings = true;
+ // EditorUtility.DisplayDialog("Finish", "processed finish", "OK");
+ //}
+ //[MenuItem(@"Assets/Tool/Scene/转换场景中选中的fbx和材质转到运行状态")]
+ //private static void SelectMeshMaterial2Compress()
+ //{
+ // processedMat.Clear();
+ // processedMesh.Clear();
+ // bAccordingSettings = true;
+ // UnityEngine.SceneManagement.Scene s = EditorSceneManager.GetActiveScene();
+ // GameObject[] roots = s.GetRootGameObjects();
+ // for (int i = 0, imax = roots.Length; i < imax; ++i)
+ // {
+ // Transform t = roots[i].transform;
+ // InnerProcessMat(t, false, true, true);
+ // }
+ // processedMat.Clear();
+ // processedMesh.Clear();
+ // bAccordingSettings = true;
+ // EditorUtility.DisplayDialog("Finish", "processed finish", "OK");
+ //}
+
+ private static bool InnerProcessSceneObject(Transform t)
+ {
+ bool change = false;
+ Renderer render = t.GetComponent<Renderer>();
+ if (render != null && t.gameObject.layer == 9 && render.sharedMaterial.shader.name == "Custom/Scene/DiffuseLM")
+ {
+ render.sharedMaterial.shader = Shader.Find("Custom/Scene/DiffuseTerrainLM");
+ }
+ //Animator animator = t.GetComponent<Animator>();
+ //if (animator != null && render != null)
+ //{
+ // errorLog += t.name + ":无用animator\r\n";
+ // if (needFix)
+ // UnityEngine.Object.DestroyImmediate(animator);
+ //}
+ //bool hasMesh = false;
+ //Mesh mesh = null;
+ //MeshFilter mf = null;
+ //if (render != null)
+ //{
+ // PrefabType prefabType = PrefabUtility.GetPrefabType(render.gameObject);
+ // if (prefabType == PrefabType.MissingPrefabInstance)
+ // {
+ // PrefabUtility.DisconnectPrefabInstance(render.gameObject);
+ // }
+ // {
+
+ // SkinnedMeshRenderer smr = null;
+ // ParticleSystemRenderer psr = null;
+ // change = render.lightProbeUsage != UnityEngine.Rendering.LightProbeUsage.Off ||
+ // render.shadowCastingMode != UnityEngine.Rendering.ShadowCastingMode.Off ||
+ // render.receiveShadows ||
+ // render.reflectionProbeUsage != UnityEngine.Rendering.ReflectionProbeUsage.Off ||
+ // render.motionVectorGenerationMode != MotionVectorGenerationMode.ForceNoMotion;
+ // if (render is SkinnedMeshRenderer)
+ // {
+ // smr = render as SkinnedMeshRenderer;
+ // change |= smr.skinnedMotionVectors ||
+ // smr.updateWhenOffscreen;
+ // mesh = smr.sharedMesh;
+ // hasMesh = true;
+ // }
+ // else if (render is MeshRenderer)
+ // {
+ // mf = render.GetComponent<MeshFilter>();
+ // if (mf != null)
+ // mesh = mf.sharedMesh;
+ // hasMesh = true;
+ // }
+ // else if (render is ParticleSystemRenderer)
+ // {
+ // psr = render as ParticleSystemRenderer;
+ // if (psr.renderMode == ParticleSystemRenderMode.Mesh)
+ // {
+ // mesh = psr.mesh;
+ // hasMesh = true;
+ // }
+ // else if (psr.mesh != null)
+ // {
+ // errorLog += t.name + ":Particle未优化\r\n";
+ // if (needFix)
+ // {
+ // psr.mesh = null;
+ // change = true;
+ // }
+ // }
+ // }
+ // if (change)
+ // {
+ // errorLog += t.name + ":render未优化\r\n";
+ // if (needFix)
+ // {
+ // render.lightProbeUsage = UnityEngine.Rendering.LightProbeUsage.Off;
+ // render.shadowCastingMode = UnityEngine.Rendering.ShadowCastingMode.Off;
+ // render.receiveShadows = false;
+ // render.reflectionProbeUsage = UnityEngine.Rendering.ReflectionProbeUsage.Off;
+ // render.motionVectorGenerationMode = MotionVectorGenerationMode.ForceNoMotion;
+ // if (smr != null)
+ // {
+ // smr.skinnedMotionVectors = false;
+ // smr.updateWhenOffscreen = false;
+ // }
+ // }
+ // }
+ // if (mesh != null)
+ // {
+ // Mesh newMesh = null;
+ // int result = FindMesh(mesh, false, out newMesh);
+ // if (result == 1)
+ // {
+ // errorLog += t.name + ":mesh未优化\r\n";
+ // if (needFix)
+ // {
+ // if (smr != null)
+ // {
+ // smr.sharedMesh = newMesh;
+ // }
+ // else if (mf != null)
+ // {
+ // mf.sharedMesh = newMesh;
+ // }
+ // else if (psr != null)
+ // {
+ // psr.mesh = newMesh;
+ // }
+ // change = true;
+ // }
+ // }
+ // else if (result == -1)
+ // {
+ // errorLog += t.name + ":mesh没有找到mesh\r\n";
+ // }
+ // }
+ // else if (hasMesh)
+ // {
+ // errorLog += t.name + ":mesh为空\r\n";
+ // if (needFix)
+ // {
+ // if (smr != null)
+ // {
+ // GameObject.DestroyImmediate(smr);
+ // }
+ // else if (mf != null)
+ // {
+ // GameObject.DestroyImmediate(mf);
+ // GameObject.DestroyImmediate(render);
+ // }
+ // else if (psr != null)
+ // {
+ // GameObject.DestroyImmediate(psr);
+ // }
+ // change = true;
+ // }
+ // }
+ // }
+ //}
+
+ //MeshCollider mc = t.GetComponent<MeshCollider>();
+ //if (mc != null)
+ //{
+ // if (hasMesh && mesh == null)
+ // {
+ // if (needFix)
+ // GameObject.DestroyImmediate(mc);
+ // }
+ // else if (render != null && !render.enabled)
+ // {
+ // if (needFix)
+ // {
+ // GameObject.DestroyImmediate(render);
+ // if(mf!=null)
+ // {
+ // GameObject.DestroyImmediate(mf);
+ // }
+ // }
+
+ // }
+ // else
+ // {
+ // mesh = mc.sharedMesh;
+ // if (mesh != null)
+ // {
+ // Mesh newMesh = null;
+ // int result = FindMesh(mesh, false, out newMesh);
+ // if (result == 1)
+ // {
+ // errorLog += t.name + ":meshcollider未优化\r\n";
+ // if (needFix)
+ // {
+ // mc.sharedMesh = newMesh;
+ // change = true;
+ // }
+ // }
+ // else if (result == -1)
+ // {
+ // errorLog += t.name + ":meshcollider没有找到mesh\r\n";
+ // }
+ // }
+ // }
+
+ //}
+ for (int i = t.childCount - 1; i >= 0; --i)
+ {
+ Transform child = t.GetChild(i);
+ change |= InnerProcessSceneObject(child);
+ }
+ return change;
+ }
+
+
+ private static bool _FixScene(UnityEngine.SceneManagement.Scene scene)
+ {
+ bool change = false;
+ errorLog = "";
+ //GameObject camera = GameObject.Find("Main Camera");
+ //if (camera != null)
+ //{
+ // FxPro fxPro = camera.GetComponent<FxPro>();
+ // if (fxPro != null && fxPro.enabled)
+ // {
+ // errorLog += "fxPro未优化\r\n";
+ // if (needFix)
+ // fxPro.enabled = false;
+ // change = true;
+ // }
+ // FMOD_Listener fmod_Listener = camera.GetComponent<FMOD_Listener>();
+ // if (fmod_Listener != null)
+ // {
+ // errorLog += "FMOD_Listener未优化\r\n";
+ // if (needFix)
+ // UnityEngine.Object.DestroyImmediate(fmod_Listener);
+ // change = true;
+ // }
+ //}
+
+
+ //UnityEngine.Object[] terrains = UnityEngine.Object.FindObjectsOfType(typeof(Terrain));
+ //if (terrains != null)
+ //{
+ // GameObject lightGo = GameObject.Find("MainLight");
+ // if(lightGo != null)
+ // {
+ // Light light = lightGo.GetComponent<Light>();
+ // if(light!=null)
+ // {
+ // light.shadows = LightShadows.None;
+ // lightGo.layer = 9;
+ // }
+ // }
+ // for (int j = 0, imax = terrains.Length; j < imax; ++j)
+ // {
+ // Terrain terrain = terrains[j] as Terrain;
+ // if (needFix)
+ // {
+ // terrain.materialType = Terrain.MaterialType.Custom;
+ // string terrainMat = "Assets/XScene/TerrainTextures/Custom_Terrain_Diffuse.mat";
+ // if(terrain.terrainData.alphamapLayers > 4)
+ // terrainMat = "Assets/XScene/TerrainTextures/Custom_Terrain_Diffuse8.mat";
+ // terrain.materialTemplate = AssetDatabase.LoadAssetAtPath<Material>(terrainMat);
+ // terrain.bakeLightProbesForTrees = false;
+ // terrain.collectDetailPatches = false;
+ // if (terrain.basemapDistance < 1000)
+ // {
+ // terrain.basemapDistance = 1000;
+ // change = true;
+ // }
+ // else if (terrain.basemapDistance > 1000)
+ // {
+ // terrain.basemapDistance = 1000;
+ // change = true;
+ // }
+ // else
+ // {
+ // terrain.basemapDistance = 1001;
+ // change = true;
+ // }
+ // if (terrain.terrainData.baseMapResolution > 16)
+ // {
+ // terrain.terrainData.baseMapResolution = 16;
+ // terrain.Flush();
+ // change = true;
+ // }
+ // }
+ // }
+ //}
+ GameObject[] roots = scene.GetRootGameObjects();
+
+ for (int j = 0, imax = roots.Length; j < imax; ++j)
+ {
+ Transform t = roots[j].transform;
+ change |= InnerProcessSceneObject(t);
+ }
+ if (errorLog != "")
+ {
+ Debug.LogError(errorLog + ":" + scene.name);
+ }
+ return change && needFix;
+ }
+
+ [MenuItem(@"Assets/Tool/Scene/FixScene", false, 0)]
+ private static void FixScene()
+ {
+ needFix = true;
+ EnumAllScene(_FixScene, "FixScene");
+ needFix = true;
+ }
+
+ [MenuItem(@"Assets/Tool/Scene/ScanScene", false, 0)]
+ private static void ScanScene()
+ {
+ needFix = false;
+ EnumAllScene(_FixScene, "ScanScene");
+ needFix = true;
+ }
+
+ [MenuItem(@"GameObject/Scene/FixCurrentScene", false, 0)]
+ private static void FixCurrentScene()
+ {
+ UnityEngine.SceneManagement.Scene s = EditorSceneManager.GetActiveScene();
+ bool change = _FixScene(s);
+ if (change)
+ EditorSceneManager.SaveScene(s);
+ }
+ private static void _InnerFindSceneMat(Transform t, ref int cutOutCount, ref int totalCount)
+ {
+ Renderer render = t.GetComponent<Renderer>();
+ if (render != null)
+ {
+ if(!(render is ParticleSystemRenderer))
+ {
+ Material[] mats = render.sharedMaterials;
+ if (mats != null)
+ {
+ for (int i = 0; i < mats.Length; ++i)
+ {
+ Material mat = mats[i];
+ if (mat != null)
+ {
+ if (mat.renderQueue > 2000)
+ cutOutCount++;
+ }
+ totalCount++;
+ }
+ }
+ }
+
+ }
+ for (int i = t.childCount - 1; i >= 0; --i)
+ {
+ Transform child = t.GetChild(i);
+ _InnerFindSceneMat(child,ref cutOutCount, ref totalCount);
+ }
+ }
+ private static bool _FindSceneMat(UnityEngine.SceneManagement.Scene scene)
+ {
+ GameObject sceneObj = GameObject.Find("Scene");
+ if(sceneObj!=null)
+ {
+ int totalCount = 0;
+ int cutOutCount = 0;
+ _InnerFindSceneMat(sceneObj.transform, ref cutOutCount, ref totalCount);
+ string str = string.Format("{0}:{1}/{2}({3:P})\r\n", scene.name, cutOutCount, totalCount, (float)cutOutCount / totalCount);
+ errorLog += str;
+ Debug.LogError(str);
+ }
+ return false;
+ }
+ [MenuItem(@"GameObject/Scene/FindSceneMat", false, 0)]
+ private static void FindSceneMat()
+ {
+ UnityEngine.SceneManagement.Scene s = EditorSceneManager.GetActiveScene();
+ _FindSceneMat(s);
+
+ }
+ [MenuItem(@"Assets/Tool/Scene/ScanSceneMat", false, 0)]
+ private static void ScanSceneMat()
+ {
+ errorLog = "";
+ EnumAllScene(_FindSceneMat, "ScanSceneMat");
+ File.WriteAllText("Assets/XScene/CutoutMat.txt",errorLog);
+ }
+
+ //class MeshCombineInfo
+ //{
+ // public Mesh mesh;
+ // public Matrix4x4 matrix;
+ // public MeshFilter mf;
+ //}
+ //private static void _CollectMatMesh(Transform child, Dictionary<Material, List<MeshCombineInfo>> matMesh)
+ //{
+ // int flag = (int)GameObjectUtility.GetStaticEditorFlags(child.gameObject);
+ // if ((flag & (int)StaticEditorFlags.BatchingStatic) != 0)
+ // {
+ // MeshRenderer mr = child.GetComponent<MeshRenderer>();
+ // if (mr != null)
+ // {
+ // Material mat = mr.sharedMaterial;
+ // if (mat != null)
+ // {
+ // MeshFilter mf = child.GetComponent<MeshFilter>();
+ // if (mf != null)
+ // {
+ // Mesh mesh = mf.sharedMesh;
+ // if (mesh != null && mesh.isReadable)
+ // {
+ // List<MeshCombineInfo> meshList = null;
+ // if (!matMesh.TryGetValue(mat, out meshList))
+ // {
+ // meshList = new List<MeshCombineInfo>();
+ // matMesh.Add(mat, meshList);
+ // }
+ // MeshCombineInfo mci = new MeshCombineInfo();
+ // mci.mesh = mesh;
+ // mci.matrix = child.localToWorldMatrix;
+ // mci.mf = mf;
+ // meshList.Add(mci);
+ // }
+ // }
+ // }
+ // }
+ // }
+
+ // for (int i = 0; i < child.childCount; ++i)
+ // {
+ // Transform grandChild = child.GetChild(i);
+ // _CollectMatMesh(grandChild, matMesh);
+ // }
+ //}
+ //class MeshCombineInfo
+ //{
+ // public Mesh mesh;
+ // public MeshFilter mf;
+ //}
+ //private static void _CollectMatMesh(Transform child, Dictionary<Mesh, List<MeshFilter>> meshs)
+ //{
+ // int flag = (int)GameObjectUtility.GetStaticEditorFlags(child.gameObject);
+ // if ((flag & (int)StaticEditorFlags.BatchingStatic) != 0)
+ // {
+ // MeshRenderer mr = child.GetComponent<MeshRenderer>();
+ // if (mr != null)
+ // {
+ // Material mat = mr.sharedMaterial;
+ // if (mat != null)
+ // {
+ // MeshFilter mf = child.GetComponent<MeshFilter>();
+ // if (mf != null)
+ // {
+ // Mesh mesh = mf.sharedMesh;
+ // if (mesh != null && mesh.name.StartsWith("Combined Mesh"))
+ // {
+ // List<MeshFilter> meshList = null;
+ // if (!meshs.TryGetValue(mesh, out meshList))
+ // {
+ // meshList = new List<MeshFilter>();
+ // meshs.Add(mesh, meshList);
+ // }
+ // meshList.Add(mf);
+ // }
+ // }
+ // }
+ // }
+ // }
+
+ // for (int i = 0; i < child.childCount; ++i)
+ // {
+ // Transform grandChild = child.GetChild(i);
+ // _CollectMatMesh(grandChild, meshs);
+ // }
+ //}
+
+ //[MenuItem(@"GameObject/Scene/BakeSceneMesh", false, 0)]
+ //private static void BakeSceneMesh()
+ //{
+ // //Dictionary<Material, List<MeshCombineInfo>> matMesh = new Dictionary<Material, List<MeshCombineInfo>>();
+ // Dictionary<Mesh, List<MeshFilter>> meshs = new Dictionary<Mesh, List<MeshFilter>>();
+ // UnityEngine.SceneManagement.Scene s = EditorSceneManager.GetActiveScene();
+ // GameObject go = GameObject.Find("Scene");
+ // if(go!=null)
+ // {
+ // Transform t = go.transform;
+ // for(int i=0;i<t.childCount;++i)
+ // {
+ // Transform child = t.GetChild(i);
+ // _CollectMatMesh(child, meshs);
+ // }
+ // }
+ // int index = s.path.LastIndexOf("/");
+ // string sceneDir = s.path.Substring(0, index);
+ // var it = meshs.GetEnumerator();
+ // int meshIndex = 0;
+ // while (it.MoveNext())
+ // {
+ // Mesh mesh = it.Current.Key;
+ // string Path = string.Format("{0}/BakedMesh_{1}.asset", sceneDir, meshIndex++);
+ // CreateOrReplaceAsset<Mesh>(mesh, Path);
+ // List<MeshFilter> meshList = it.Current.Value;
+ // for (int i = 0; i < meshList.Count; ++i)
+ // {
+ // MeshFilter mf = meshList[i];
+ // mf.sharedMesh = mesh;
+ // }
+ // }
+ // //List<CombineInstance> ciList = new List<CombineInstance>();
+ // //var it = matMesh.GetEnumerator();
+ // //while(it.MoveNext())
+ // //{
+ // // List<MeshCombineInfo> meshList = it.Current.Value;
+ // // if(meshList.Count>10)
+ // // {
+ // // ciList.Clear();
+ // // int vertexCount = 0;
+ // // int combineIndex = 0;
+ // // for (int i = 0; i < meshList.Count; ++i)
+ // // {
+ // // MeshCombineInfo mci = meshList[i];
+ // // if (vertexCount + mci.mesh.vertexCount > 60000)
+ // // {
+ // // Mesh newMesh = new Mesh();
+ // // newMesh.CombineMeshes(ciList.ToArray(), true, true);
+ // // string path = string.Format("{0}/{1}_{2}.asset", sceneDir, it.Current.Key.name, combineIndex++);
+ // // CreateOrReplaceAsset<Mesh>(newMesh, path);
+ // // ciList.Clear();
+ // // }
+ // // CombineInstance ci = new CombineInstance();
+ // // ci.mesh = mci.mesh;
+ // // //ci.transform = mci.matrix;
+ // // ciList.Add(ci);
+ // // }
+ // // Mesh lastMesh = new Mesh();
+ // // lastMesh.CombineMeshes(ciList.ToArray(), true, false);
+ // // string lastPath = string.Format("{0}/{1}.asset", sceneDir, it.Current.Key.name, combineIndex);
+ // // CreateOrReplaceAsset<Mesh>(lastMesh, lastPath);
+ // // for (int i = 0; i < meshList.Count; ++i)
+ // // {
+ // // MeshCombineInfo mci = meshList[i];
+ // // mci.mf.sharedMesh = lastMesh;
+ // // }
+ // // }
+
+ // //}
+ //}
+
+ //private static bool ReplaceSceneMesh(Transform t,string sceneName)
+ //{
+ // if (!t.gameObject.activeSelf)
+ // return false;
+ // Renderer render = t.GetComponent<Renderer>();
+ // bool hasMesh = false;
+ // Mesh mesh = null;
+ // if (render != null)
+ // {
+ // MeshFilter mf = null;
+ // SkinnedMeshRenderer smr = null;
+ // if (render is SkinnedMeshRenderer)
+ // {
+ // smr = render as SkinnedMeshRenderer;
+ // hasMesh = true;
+ // }
+ // else if (render is MeshRenderer)
+ // {
+ // mf = render.GetComponent<MeshFilter>();
+ // if (mf != null)
+ // mesh = mf.sharedMesh;
+ // hasMesh = true;
+ // }
+ // if (mesh != null)
+ // {
+ // Mesh newMesh = null;
+ // int result = FindMesh(mesh, false, out newMesh);
+ // if (newMesh != null)
+ // {
+ // string path = AssetDatabase.GetAssetPath(newMesh);
+ // path = path.Replace("XScene", "XSceneIOS");
+ // newMesh = AssetDatabase.LoadAssetAtPath<Mesh>(path);
+ // }
+ // if (newMesh == null)
+ // {
+ // Debug.LogError(string.Format("Mesh not found:{0} scene:{1}", t.name, sceneName));
+ // }
+ // if (smr != null)
+ // {
+ // smr.sharedMesh = newMesh;
+ // }
+ // else if (mf != null)
+ // {
+ // mf.sharedMesh = newMesh;
+ // }
+ // }
+ // }
+
+ // MeshCollider mc = t.GetComponent<MeshCollider>();
+ // if (mc != null)
+ // {
+ // if (hasMesh && mesh == null)
+ // {
+ // }
+ // else
+ // {
+ // mesh = mc.sharedMesh;
+ // if (mesh != null)
+ // {
+ // Mesh newMesh = null;
+ // int result = FindMesh(mesh, false, out newMesh);
+ // if (newMesh != null)
+ // {
+ // string path = AssetDatabase.GetAssetPath(newMesh);
+ // path = path.Replace("XScene", "XSceneIOS");
+ // newMesh = AssetDatabase.LoadAssetAtPath<Mesh>(path);
+ // }
+ // if (newMesh == null)
+ // {
+ // Debug.LogError(string.Format("Collider Mesh not found:{0} scene:{1}", t.name, sceneName));
+ // }
+ // mc.sharedMesh = newMesh;
+ // }
+ // }
+
+ // }
+ // List<GameObject> notVisibleNode = new List<GameObject>();
+ // for (int i = t.childCount - 1; i >= 0; --i)
+ // {
+ // Transform child = t.GetChild(i);
+ // bool isVisible = ReplaceSceneMesh(child, sceneName);
+ // if(!isVisible)
+ // {
+ // notVisibleNode.Add(child.gameObject);
+ // }
+ // }
+ // for (int i = 0; i < notVisibleNode.Count; ++i)
+ // {
+ // GameObject.DestroyImmediate(notVisibleNode[i]);
+ // }
+ // return true;
+ //}
+ //private static bool _GenIOSSene(UnityEngine.SceneManagement.Scene scene)
+ //{
+ // GameObject[] roots = scene.GetRootGameObjects();
+
+ // for (int j = 0, imax = roots.Length; j < imax; ++j)
+ // {
+ // Transform t = roots[j].transform;
+ // if(t.name=="Scene")
+ // {
+ // ReplaceSceneMesh(t, scene.name);
+ // }
+ // }
+ // return true;
+ //}
+ //private static void CreateDir(string path)
+ //{
+ // if (Directory.Exists(path))
+ // return;
+ // int index = path.LastIndexOf("/");
+ // string newDirPath = path.Substring(0, index);
+ // CreateDir(newDirPath);
+ // Directory.CreateDirectory(path);
+
+ //}
+ //private static void _CopyMesh(Mesh mesh, string path)
+ //{
+ // //string newPath = path.Replace("xscene", "XSceneIOS");
+ // //int index = newPath.LastIndexOf("/");
+ // //string newDirPath = newPath.Substring(0, index);
+ // //CreateDir(newDirPath);
+ // string data = File.ReadAllText(path);
+ // data = data.Replace("m_IsReadable: 1", "m_IsReadable: 0");
+ // File.WriteAllText(path, data);
+
+ //}
+
+ //[MenuItem(@"Assets/Tool/Scene/GenIOSSene", false, 0)]
+ //private static void GenIOSSene()
+ //{
+ // enumMesh.cb = _CopyMesh;
+ // EnumAsset<Mesh>(enumMesh, "CopyMesh", "Assets/XScene");
+
+ // //EditorBuildSettingsScene[] scenes = EditorBuildSettings.scenes;
+ // //for (int i = 0; i < scenes.Length; ++i)
+ // //{
+ // // EditorBuildSettingsScene scene = scenes[i];
+ // // EditorUtility.DisplayProgressBar(string.Format("{0}-{1}/{2}", "GenIOSSene", i, scenes.Length), scene.path, (float)i / scenes.Length);
+ // // UnityEngine.SceneManagement.Scene s = EditorSceneManager.OpenScene(scene.path);
+
+ // // _GenIOSSene(s);
+ // // EditorSceneManager.SaveScene(s, "Assets/XSceneIOS/" + s.name + ".unity");
+ // //}
+ // //AssetDatabase.Refresh();
+ // //AssetDatabase.SaveAssets();
+ // //EditorUtility.ClearProgressBar();
+ // //EditorUtility.DisplayDialog("Finish", "All scenes processed finish", "OK");
+ //}
+
+ //public static void RemoveLightmapBakeThing(string scenePath)
+ //{
+ // if (EditorApplication.OpenScene(scenePath))
+ // {
+ // GameObject scene = GameObject.Find(@"Scene");
+ // if (scene != null)
+ // {
+ // List<GameObject> lst = new List<GameObject>();
+ // for (int i = 0, imax = scene.transform.childCount; i < imax; ++i)
+ // {
+ // Transform t = scene.transform.GetChild(i);
+ // if (!t.gameObject.activeSelf)
+ // {
+ // lst.Add(t.gameObject);
+ // }
+ // }
+ // for (int i = 0, imax = lst.Count; i < imax; ++i)
+ // {
+ // GameObject.DestroyImmediate(lst[i]);
+ // }
+ // if (lst.Count > 0)
+ // EditorApplication.SaveScene(scenePath);
+ // }
+
+
+ // }
+ //}
+
+ //public static void RemoveLightmapBakeThing(string[] scenes)
+ //{
+ // foreach (string scenePath in scenes)
+ // {
+ // RemoveLightmapBakeThing(scenePath);
+ // }
+ //}
+ #endregion
+ #region prefab
+ private static Mesh CompareMesh(Mesh srcMesh, Mesh mesh, string dir, string name, int i)
+ {
+ if (srcMesh != null && srcMesh.name == mesh.name)
+ {
+ string newMeshPath = string.Format("{0}/{1}_{2}.asset", dir, name, i);
+ return AssetDatabase.LoadAssetAtPath<Mesh>(newMeshPath);
+ }
+ return null;
+ }
+ private static int FindMesh(Mesh mesh, bool isSkin, out Mesh newMesh)
+ {
+ newMesh = mesh;
+ string meshPath = AssetDatabase.GetAssetPath(mesh);
+ int index = meshPath.LastIndexOf(".");
+ if (index > 0)
+ {
+ int dirindex = meshPath.LastIndexOf("/");
+ string dir = meshPath;
+ if (dirindex >= 0)
+ {
+ dir = meshPath.Substring(0, dirindex);
+ }
+ string ext = meshPath.Substring(index).ToLower();
+ if (ext == ".fbx")
+ {
+ GameObject fbx = AssetDatabase.LoadAssetAtPath<GameObject>(meshPath);
+ string name = fbx.name.ToLower();
+ if (name.EndsWith("_bandpose"))
+ {
+ name = name.Replace("_bandpose", "");
+ }
+ GameObject go = GameObject.Instantiate(fbx) as GameObject;
+ List<Renderer> renderLst = ListPool<Renderer>.Get();
+ go.GetComponentsInChildren<Renderer>(true, renderLst);
+ for (int i = 0; i < renderLst.Count; ++i)
+ {
+ Renderer render = renderLst[i];
+ Mesh srcMesh = null;
+ if (isSkin)
+ {
+ if (render is SkinnedMeshRenderer)
+ {
+ SkinnedMeshRenderer smr = render as SkinnedMeshRenderer;
+ srcMesh = smr.sharedMesh;
+ }
+ }
+ else
+ {
+ if (render is MeshRenderer)
+ {
+ MeshFilter mf = render.GetComponent<MeshFilter>();
+ srcMesh = mf.sharedMesh;
+ }
+ }
+ if (srcMesh != null)
+ {
+ Mesh findMesh = CompareMesh(srcMesh, mesh, dir, name, i);
+ if (findMesh != null)
+ {
+ newMesh = findMesh;
+ break;
+ }
+ }
+ }
+ ListPool<Renderer>.Release(renderLst);
+ GameObject.DestroyImmediate(go);
+ if (newMesh == mesh)
+ {
+ return -1;
+ }
+ else
+ {
+ return 1;
+ }
+ }
+ }
+ return 0;
+ }
+
+ private static int FindAvatar(Avatar avatar, out Avatar newAvatar)
+ {
+ newAvatar = avatar;
+ string avatarPath = AssetDatabase.GetAssetPath(avatar);
+ int index = avatarPath.LastIndexOf(".");
+ if (index > 0)
+ {
+ int dirindex = avatarPath.LastIndexOf("/");
+ string dir = avatarPath;
+ if (dirindex >= 0)
+ {
+ dir = avatarPath.Substring(0, dirindex);
+ }
+ string ext = avatarPath.Substring(index).ToLower();
+ if (ext == ".fbx")
+ {
+ GameObject fbx = AssetDatabase.LoadAssetAtPath<GameObject>(avatarPath);
+ string name = fbx.name.ToLower();
+ if (name.EndsWith("_bandpose"))
+ {
+ name = name.Replace("_bandpose", "");
+ }
+ GameObject go = GameObject.Instantiate(fbx) as GameObject;
+
+ GameObject.DestroyImmediate(go);
+ if (newAvatar == avatar)
+ {
+ return -1;
+ }
+ else
+ {
+ return 1;
+ }
+ }
+ }
+ return 0;
+ }
+
+ private static bool needFix = true;
+ private static string errorLog = "";
+ public static void FixPrefab(string path, GameObject go = null, bool isPrefab = false)
+ {
+ if (go == null && isPrefab)
+ return;
+ if (go == null)
+ go = AssetDatabase.LoadAssetAtPath<GameObject>(path);
+ if (go == null)
+ return;
+ path = path.ToLower();
+ bool isFx = path.StartsWith("assets/resources/prefabs/bullets") || path.StartsWith("assets/resources/effects");
+ errorLog = "";
+ GameObject prefab = isPrefab ? go : GameObject.Instantiate(go) as GameObject;
+ prefab.name = go.name;
+ Animator ator = prefab.GetComponentInChildren<Animator>();
+
+ List<Renderer> renderLst = ListPool<Renderer>.Get();
+ prefab.GetComponentsInChildren<Renderer>(true, renderLst);
+ bool change = false;
+ bool hasSkin = false;
+ for (int i = 0; i < renderLst.Count; ++i)
+ {
+ Renderer render = renderLst[i];
+ if (render != null)
+ {
+ MeshFilter mf = null;
+ SkinnedMeshRenderer smr = null;
+ ParticleSystemRenderer psr = null;
+ Mesh mesh = null;
+ if (!render.gameObject.activeSelf)
+ {
+ errorLog += render.name + ":render被影藏\r\n";
+ }
+ if (!CheckRender(render))
+ {
+ errorLog += render.name + ":mesh设置错误\r\n";
+ if (needFix)
+ {
+ ProcessRender(render);
+ change = true;
+ }
+ }
+ if (render is SkinnedMeshRenderer)
+ {
+ hasSkin = true;
+ smr = render as SkinnedMeshRenderer;
+ mesh = smr.sharedMesh;
+ if (!CheckSkinMesh(smr))
+ {
+ errorLog += render.name + ":skinmesh设置错误\r\n";
+ if (needFix)
+ {
+ ProcessSkinMesh(smr);
+ change = true;
+ }
+ }
+ }
+ else if (render is MeshRenderer)
+ {
+ mf = render.GetComponent<MeshFilter>();
+ if (mf != null)
+ mesh = mf.sharedMesh;
+ }
+ else if (render is ParticleSystemRenderer)
+ {
+ psr = render as ParticleSystemRenderer;
+
+ ParticleSystem ps = render.GetComponent<ParticleSystem>();
+ if (ps != null)
+ {
+ var main = ps.main;
+ var startSize = main.startSize;
+ var startSizeZ = main.startSizeZ;
+ startSizeZ.mode = startSize.mode;
+ if (startSize.constantMin != startSizeZ.constantMin ||
+ startSize.constantMax != startSizeZ.constantMax)
+ {
+ bool scaleError = false;
+ if (startSize.constantMin > startSize.constantMax)
+ {
+ scaleError = true;
+ errorLog += render.name + ":Particle Min>Max未设置\r\n";
+ }
+ else
+ {
+ errorLog += render.name + ":ParticleScale未设置\r\n";
+ }
+ if (needFix)
+ {
+ if (scaleError)
+ {
+ startSizeZ.constantMin = startSize.constantMax;
+ startSizeZ.constantMax = startSize.constantMin;
+ main.startSize = startSizeZ;
+ }
+ else
+ {
+ startSizeZ.constantMin = startSize.constantMin;
+ startSizeZ.constantMax = startSize.constantMax;
+ }
+
+ main.startSizeZ = startSizeZ;
+ change = true;
+ }
+ }
+ }
+
+ if (psr.renderMode == ParticleSystemRenderMode.Mesh)
+ {
+ mesh = psr.mesh;
+ }
+ else if (psr.mesh != null)
+ {
+ errorLog += render.name + ":Particle未优化\r\n";
+ if (needFix)
+ {
+ psr.mesh = null;
+ change = true;
+ }
+ }
+ }
+
+ if (mesh != null)
+ {
+ Mesh newMesh = null;
+ int result = FindMesh(mesh, smr!=null, out newMesh);
+ if (result == 1)
+ {
+ errorLog += render.name + ":mesh未优化\r\n";
+ if (needFix)
+ {
+ if (smr != null)
+ {
+ smr.sharedMesh = newMesh;
+ }
+ else if (mf != null)
+ {
+ mf.sharedMesh = newMesh;
+ }
+ else if (psr != null)
+ {
+ psr.mesh = newMesh;
+ }
+ change = true;
+ }
+ }
+ else if (result == -1)
+ {
+ errorLog += render.name + ":mesh没有找到mesh\r\n";
+ }
+ }
+ MeshCollider mc = render.GetComponent<MeshCollider>();
+ if (mc != null)
+ {
+ mesh = mc.sharedMesh;
+ if (mesh != null)
+ {
+ Mesh newMesh = null;
+ int result = FindMesh(mesh, false, out newMesh);
+ if (result == 1)
+ {
+ errorLog += render.name + "meshcollider未优化\r\n";
+ if (needFix)
+ {
+ mc.sharedMesh = newMesh;
+ change = true;
+ }
+ }
+ else if (result == -1)
+ {
+ errorLog += render.name + "meshcollider没有找到mesh\r\n";
+ }
+ }
+ }
+ }
+ }
+ if (!isFx && renderLst.Count > 1)
+ {
+ Debug.LogWarning(string.Format("Too many draw call:{0} {1}", renderLst.Count, path));
+ }
+ ListPool<Renderer>.Release(renderLst);
+ if (ator != null)
+ {
+ if (ator.avatar != null)
+ {
+ if (hasSkin)
+ {
+ Avatar newAvatar = null;
+ int result = ReplaceAvatar(ator.avatar, out newAvatar);
+ if (result == 1)
+ {
+ errorLog += ator.name + ":avatar没有优化\r\n";
+ if (needFix && newAvatar != null)
+ {
+ ator.avatar = newAvatar;
+ change = true;
+ }
+
+ }
+ else if (result == -1)
+ {
+ errorLog += ator.name + ":avatar没有找到avatar\r\n";
+ }
+ }
+ else
+ {
+ errorLog += ator.name + ":avatar可以为空\r\n";
+ if (needFix)
+ {
+ ator.avatar = null;
+ change = true;
+ }
+ }
+ }
+ else if (hasSkin)
+ {
+ if (ator.runtimeAnimatorController != null)
+ {
+ string name = ator.runtimeAnimatorController.name;
+ if (name == "XAnimator" ||
+ name == "XCamera" ||
+ name == "XMinorAnimator")
+ errorLog += "avatar空\r\n";
+ }
+ else
+ {
+ errorLog += "avatarController空\r\n";
+ }
+ }
+
+ }
+ BoxCollider box = prefab.GetComponent<BoxCollider>();
+ if (box != null && ator != null)
+ {
+ Rigidbody rb = prefab.GetComponent<Rigidbody>();
+ if (rb == null)
+ {
+ errorLog += "Rigidbody没有优化\r\n";
+ if (needFix)
+ {
+ rb = prefab.AddComponent<Rigidbody>();
+ change = true;
+ }
+
+ }
+ if (rb != null && (rb.useGravity != false || rb.isKinematic != true))
+ {
+ errorLog += "Rigidbody设置错误\r\n";
+ if (needFix)
+ {
+
+ rb.useGravity = false;
+ rb.isKinematic = true;
+ change = true;
+ }
+ }
+
+ }
+
+
+ if (change && needFix&& !isPrefab)
+ PrefabUtility.ReplacePrefab(prefab, go, ReplacePrefabOptions.ReplaceNameBased);
+ if (errorLog != "")
+ {
+ Debug.LogError(errorLog + ":" + path);
+ }
+ if (!isPrefab)
+ GameObject.DestroyImmediate(prefab);
+ }
+ private static void _FixPrefab(GameObject go, string path)
+ {
+ FixPrefab(path, go);
+ }
+
+ [MenuItem(@"Assets/FixPrefab", false, 0)]
+ private static void FixPrefab()
+ {
+ enumPrefab.cb = _FixPrefab;
+ EnumAsset<GameObject>(enumPrefab, "FixPrefab");
+ }
+
+ private static void _CheckPrefab(GameObject go, string path)
+ {
+ FixPrefab(path, go);
+ }
+ [MenuItem(@"Assets/CheckPrefab", false, 0)]
+ private static void CheckPrefab()
+ {
+ needFix = false;
+ enumPrefab.cb = _CheckPrefab;
+ EnumAsset<GameObject>(enumPrefab, "CheckPrefab");
+ needFix = true;
+ }
+
+ [MenuItem(@"Assets/DisconnectPrefab", false, 0)]
+ private static void DisconnectPrefab()
+ {
+ GameObject go = Selection.activeGameObject;
+ if (go != null)
+ {
+ PrefabUtility.DisconnectPrefabInstance(go);
+ PrefabUtility.CreatePrefab("Assets/TMPPrefab.prefab", go, ReplacePrefabOptions.ConnectToPrefab);
+ AssetDatabase.DeleteAsset("Assets/TMPPrefab.prefab");
+ }
+
+ }
+ [MenuItem(@"Assets/Tool/Prefab/SetPetTag", false, 0)]
+ private static void SetPetTag()
+ {
+ TextAsset ta0 = Resources.Load<TextAsset>(@"Table/PetInfo");
+ TextAsset ta1 = Resources.Load<TextAsset>(@"Table/XEntityPresentation");
+ if (ta0 != null && ta1 != null)
+ {
+ CVSReader.Init();
+ XBinaryReader.Init();
+ XBinaryReader piReader = XBinaryReader.Get();
+ piReader.Init(ta0);
+ PetInfoTable pi = new PetInfoTable();
+ pi.ReadFile(piReader);
+ XBinaryReader.Return(piReader);
+
+ XBinaryReader presentReader = XBinaryReader.Get();
+ presentReader.Init(ta1);
+ XEntityPresentation ep = new XEntityPresentation();
+ ep.ReadFile(presentReader);
+ XBinaryReader.Return(presentReader);
+
+ for (int i = 0; i < pi.Table.Length; ++i)
+ {
+ uint present_id = pi.Table[i].presentID;
+ XEntityPresentation.RowData row = ep.GetByPresentID(present_id);
+ if (row != null)
+ {
+ string path = "Prefabs/" + row.Prefab;
+ GameObject go = Resources.Load<GameObject>(path);
+ if (go != null)
+ {
+ bool change = false;
+ List<Renderer> renderLst = ListPool<Renderer>.Get();
+ GameObject mount = GameObject.Instantiate<GameObject>(go);
+ mount.GetComponentsInChildren<Renderer>(renderLst);
+ for (int j = 0; j < renderLst.Count; ++j)
+ {
+ Renderer render = renderLst[j];
+ if (render.sharedMaterial.renderQueue >= 3000 || render is ParticleSystemRenderer)
+ {
+ if (render.gameObject.tag != "Mount_BindedRes")
+ {
+ render.gameObject.tag = "Mount_BindedRes";
+ change = true;
+ }
+ }
+ else
+ {
+ if (render.gameObject.tag != "Mount")
+ {
+ render.gameObject.tag = "Mount";
+ change = true;
+ }
+ }
+ }
+ ListPool<Renderer>.Release(renderLst);
+ if (change)
+ PrefabUtility.ReplacePrefab(mount, go, ReplacePrefabOptions.ReplaceNameBased);
+ GameObject.DestroyImmediate(mount);
+ }
+ }
+ }
+ }
+
+ }
+
+ private static void AddCCPrefab(BuffTable buff, XEntityStatistics entityStatistics, XEntityPresentation entityPresentation, HashSet<string> transformPrefab)
+ {
+ for (int i = 0; i < buff.Table.Length; ++i)
+ {
+ BuffTable.RowData row = buff.Table[i];
+ if (row.BuffState != null)
+ {
+ for (int j = 0; j < row.BuffState.Length; ++j)
+ {
+ byte buffState = row.BuffState[j];
+ if (buffState == 9)
+ {
+ //变身
+ int statisticsID = Math.Abs(row.StateParam);
+ XEntityStatistics.RowData data = entityStatistics.GetByID((uint)statisticsID);
+ if (data != null)
+ {
+ XEntityPresentation.RowData present_data = entityPresentation.GetByPresentID(data.PresentID);
+ if (present_data != null)
+ {
+ transformPrefab.Add(present_data.Prefab.ToLower());
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ [MenuItem(@"Assets/Tool/Prefab/RefreshCharacterController", false, 0)]
+ private static void RefreshCharacterController()
+ {
+ TextAsset ta0 = Resources.Load<TextAsset>(@"Table/BuffList");
+ TextAsset ta1 = Resources.Load<TextAsset>(@"Table/BuffListPVP");
+ TextAsset ta2 = Resources.Load<TextAsset>(@"Table/XEntityStatistics");
+ TextAsset ta3 = Resources.Load<TextAsset>(@"Table/XEntityPresentation");
+ if (ta0 != null && ta1 != null)
+ {
+
+ CVSReader.Init();
+ XBinaryReader.Init();
+
+ XBinaryReader buffReader = XBinaryReader.Get();
+ buffReader.Init(ta0);
+ BuffTable buff = new BuffTable();
+ buff.ReadFile(buffReader);
+ XBinaryReader.Return(buffReader);
+
+ XBinaryReader buffPvPReader = XBinaryReader.Get();
+ buffPvPReader.Init(ta1);
+ BuffTable buffPvP = new BuffTable();
+ buffPvP.ReadFile(buffPvPReader);
+ XBinaryReader.Return(buffPvPReader);
+
+ XBinaryReader XEntityStatisticsPReader = XBinaryReader.Get();
+ XEntityStatisticsPReader.Init(ta2);
+ XEntityStatistics entityStatistics = new XEntityStatistics();
+ entityStatistics.ReadFile(XEntityStatisticsPReader);
+ XBinaryReader.Return(XEntityStatisticsPReader);
+
+ XBinaryReader XEntityPresentationReader = XBinaryReader.Get();
+ XEntityPresentationReader.Init(ta3);
+ XEntityPresentation entityPresentation = new XEntityPresentation();
+ entityPresentation.ReadFile(XEntityPresentationReader);
+ XBinaryReader.Return(XEntityPresentationReader);
+
+ HashSet<string> transformPrefab = new HashSet<string>();
+ AddCCPrefab(buff, entityStatistics, entityPresentation, transformPrefab);
+ AddCCPrefab(buffPvP, entityStatistics, entityPresentation, transformPrefab);
+
+ DirectoryInfo di = new DirectoryInfo("Assets/Resources/Prefabs");
+ FileInfo[] files = di.GetFiles("*.prefab", SearchOption.TopDirectoryOnly);
+ for (int i = 0; i < files.Length; ++i)
+ {
+ string path = files[i].FullName.Replace("\\", "/");
+ int index = path.IndexOf("Assets/Resources/Prefabs/");
+ path = path.Substring(index);
+ GameObject prefab = AssetDatabase.LoadAssetAtPath<GameObject>(path);
+ if (prefab.name.StartsWith("Mount_"))
+ {
+ CharacterController cc = prefab.GetComponent<CharacterController>();
+ if (cc == null)
+ {
+ Debug.LogError("miss CharacterController prefab:" + prefab.name);
+ }
+ }
+ else
+ {
+ index = path.LastIndexOf("/");
+ string name = path.Substring(index + 1);
+ name = name.Replace(".prefab", "").ToLower();
+ CharacterController cc = prefab.GetComponent<CharacterController>();
+ if (transformPrefab.Contains(name))
+ {
+ if (cc == null)
+ Debug.LogError("miss CharacterController prefab:" + name);
+ }
+ else
+ {
+ if (cc != null && (!name.StartsWith("player") && !name.StartsWith("zj")))
+ {
+ GameObject.DestroyImmediate(cc, true);
+ Debug.LogError("not need CharacterController prefab:" + name);
+ }
+
+ }
+ }
+
+ }
+ AssetDatabase.Refresh();
+ }
+
+ }
+ #endregion
+ #region equip
+ [MenuItem(@"Assets/Tool/Creatures/OptmizeCreatures", false, 0)]
+ private static void OptmizeGameObject()
+ {
+ Rect wr = new Rect(0, 0, 600, 800);
+ SelectBones window = (SelectBones)EditorWindow.GetWindowWithRect(typeof(SelectBones), wr, true, "隐藏骨骼");
+ window.Init();
+ window.Show();
+ }
+ [MenuItem(@"Assets/Tool/Equipment/OptmizeEquipment", false, 0)]
+ private static void OptmizeEquipGameObject()
+ {
+ Rect wr = new Rect(0, 0, 600, 800);
+ SelectEquipBones window = (SelectEquipBones)EditorWindow.GetWindowWithRect(typeof(SelectEquipBones), wr, true, "隐藏骨骼");
+ window.Init();
+ window.Show();
+ }
+
+ public static int GetUVOffset(int profession, string meshName, CombineConfig config, int depth = 0)
+ {
+ int index = meshName.LastIndexOf("_");
+ if (index >= 0)
+ {
+ string name = meshName.Substring(index).ToLower();
+ if (name.StartsWith(config.BodyString))
+ {
+ return (int)EPartType.EUpperBody;
+ }
+ if (name.StartsWith(config.LegString))
+ {
+ return (int)EPartType.ELowerBody;
+ }
+ if (name.StartsWith(config.GloveString))
+ {
+ return (int)EPartType.EGloves;
+ }
+ if (name.StartsWith(config.BootString))
+ {
+ return (int)EPartType.EBoots;
+ }
+ if (name.StartsWith(config.HeadString) ||
+ name.StartsWith(config.FaceString))
+ {
+ return (int)EPartType.EFace;
+ }
+ if (name.StartsWith(config.HairString))
+ {
+ return (int)EPartType.EHair;
+ }
+ if (name.StartsWith(config.HelmetString) ||
+ name.StartsWith("_helmat"))
+ {
+ return (int)EPartType.EHeadgear;
+ }
+ if (name.StartsWith(config.SecondaryWeapon[profession]))
+ {
+ return (int)EPartType.ESecondaryWeapon;
+ }
+ if (depth < 3)
+ {
+ depth++;
+ return GetUVOffset(profession, meshName.Substring(0, index), config, depth);
+ }
+ return -1;
+ }
+ else
+ {
+ return -1;
+ }
+
+ }
+ private static void ReCalculateUV(Mesh mesh, int uvOffsetX)
+ {
+ if (uvOffsetX >= 0)
+ {
+ Vector2[] uv = mesh.uv;
+ for (int i = 0, imax = mesh.uv.Length; i < imax; ++i)
+ {
+ //计算新uv
+ Vector2 tmp = uv[i];
+ tmp.x = tmp.x - Mathf.Floor(tmp.x);
+ tmp.x += uvOffsetX;
+ tmp.y = tmp.y - Mathf.Floor(tmp.y);
+ uv[i] = tmp;
+ }
+ mesh.uv = uv;
+ }
+ }
+ private static void ProcessMeshAsset(Mesh mesh, Material mat, int profession, string saveRootPath, string dirName, string srcMeshName, string meshName, string fbxDir,bool export = true)
+ {
+ Texture2D tex = mat.mainTexture as Texture2D;
+ int uvOffsetX = GetUVOffset(profession, srcMeshName, s_CombineConfig);
+ if (uvOffsetX >= 0)
+ {
+ if (export)
+ ReCalculateUV(mesh, uvOffsetX);
+ }
+ else
+ {
+ XDebug.singleton.AddErrorLog(string.Format("Find UV Error:{0} {1}", meshName, dirName));
+ }
+ if (export)
+ {
+ mesh.uv2 = null;
+ mesh.uv3 = null;
+ mesh.uv4 = null;
+ mesh.colors = null;
+ mesh.colors32 = null;
+ mesh.tangents = null;
+ }
+
+ string newMeshPath = "Equipments/" + dirName + "/" + meshName;
+ string meshPath = saveRootPath + meshName + ".asset";
+ string prefix = s_CombineConfig.EquipPrefix[profession];
+ if (tex == null)
+ {
+ Debug.LogError("null tex:" + meshName);
+ AddPart(newMeshPath, newMeshPath, "", "", false, false, false, prefix);
+ }
+ else
+ {
+ if (export)
+ {
+ MeshUtility.Optimize(mesh);
+ CreateOrReplaceAsset<Mesh>(mesh, meshPath);
+ }
+
+ PartTexInfo partTexInfo = null;
+ bool shareTex = false;
+ if (!usedTex.TryGetValue(tex.GetHashCode(), out partTexInfo))
+ {
+ string srcTexPath = AssetDatabase.GetAssetPath(tex);
+ int index = srcTexPath.LastIndexOf("/");
+ string srcTexDir = srcTexPath.Substring(0, index);
+ if (srcTexDir.ToLower() != fbxDir.ToLower())
+ {
+ //共享贴图的逻辑
+ int srcTexProfession = GetProfession(srcTexPath.ToLower());
+ string srcprefix = s_CombineConfig.EquipPrefix[srcTexProfession];
+ string partSuffix = s_CombineConfig.PartSuffix[uvOffsetX];
+ string srcTexName = saveRootPath + srcprefix + partSuffix + ".tga";
+ if (File.Exists(srcTexName))
+ {
+ //Debug.LogWarning(string.Format("Src Tex already exist:{0} {1}", srcTexName, meshPath));
+ partTexInfo = new PartTexInfo();
+ partTexInfo.texPath = "Equipments/" + dirName + "/" + srcprefix + partSuffix;
+ partTexInfo.isAlpha = File.Exists(saveRootPath + srcprefix + partSuffix + "_A.png");
+ shareTex = true;
+ }
+ else
+ {
+ Debug.LogError(string.Format("Src Tex not exist:{0} {1}", srcTexName, meshPath));
+ return;
+ }
+ }
+ else
+ {
+ bool isAlpha = false;
+ if(export)
+ {
+ string targetTexPath = saveRootPath + meshName + ".tga";
+ AssetDatabase.CopyAsset(srcTexPath, targetTexPath);
+ Texture2D mainTex = AssetDatabase.LoadAssetAtPath<Texture2D>(targetTexPath);
+ Texture2D alphaTex = null;
+ if (mat.renderQueue > 2000)
+ {
+ alphaTex = ConvertTexRtex(mainTex);
+ }
+ DefaultCompressTex(AssetDatabase.LoadAssetAtPath<Texture2D>(targetTexPath), targetTexPath, true, true);
+ isAlpha = alphaTex != null;
+ }
+ else
+ {
+ isAlpha = File.Exists(saveRootPath + meshName + "_A.png");
+ }
+ partTexInfo = new PartTexInfo();
+ partTexInfo.texPath = newMeshPath;
+ partTexInfo.isAlpha = isAlpha;
+ usedTex.Add(tex.GetHashCode(), partTexInfo);
+ }
+ }
+
+ AddPart(newMeshPath, newMeshPath, "", partTexInfo.texPath, tex.width == 1024, partTexInfo.isAlpha, shareTex, prefix);
+ }
+ }
+
+ private static void SaveSkinWeaponAsset(SkinnedMeshRenderer smr, Mesh mesh, string saveRootPath, int profession)
+ {
+ string prefix = s_CombineConfig.EquipPrefix[profession];
+ mesh.name = prefix + "weapon";
+ string weaponMeshPath = saveRootPath + prefix + "weapon.asset";
+
+ Material mat = smr.sharedMaterial;
+ if (mat.shader != null && mat.shader.name.EndsWith("UV2"))
+ {
+
+ }
+ else
+ {
+ mesh.uv2 = null;
+ }
+
+ mesh.uv3 = null;
+ mesh.uv4 = null;
+ mesh.colors = null;
+ mesh.colors32 = null;
+ mesh.tangents = null;
+ MeshUtility.Optimize(mesh);
+ mesh.UploadMeshData(true);
+
+ Mesh loadMesh = CreateOrReplaceAsset<Mesh>(mesh, weaponMeshPath);
+
+ GameObject weaponGo = new GameObject(mesh.name);
+ SkinnedMeshRenderer newSmr = weaponGo.AddComponent<SkinnedMeshRenderer>();
+ newSmr.sharedMesh = loadMesh;
+ ProcessSkinMesh(newSmr);
+ newSmr.sharedMaterial = smr.sharedMaterial;
+ newSmr.localBounds = mesh.bounds;
+ newSmr.gameObject.layer = LayerMask.NameToLayer("Role");
+ DefaultCompressTex(newSmr.sharedMaterial.mainTexture as Texture2D, AssetDatabase.GetAssetPath(newSmr.sharedMaterial.mainTexture), true, true);
+ string weaponPath = weaponMeshPath.Replace(".asset", ".prefab");
+ CreateOrReplacePrefab(weaponGo, weaponPath);
+ GameObject.DestroyImmediate(weaponGo);
+ }
+ public static string MakeEquipDir(string name, int profession)
+ {
+ string prefix = s_CombineConfig.EquipPrefix[profession];
+ name = name.ToLower();
+ if (name.StartsWith("player_") || name.StartsWith("cl_normal02_"))
+ {
+ return "Player";
+ }
+ else if (name.StartsWith(prefix) && (name.EndsWith("_bandpose") || name.EndsWith("_onepart_bandpose")))
+ {
+ name = name.Substring(prefix.Length);
+ int index = -1;
+ if (name.EndsWith("_onepart_bandpose"))
+ {
+ index = name.LastIndexOf("_onepart_bandpose");
+ }
+ else
+ {
+ index = name.LastIndexOf("_bandpose");
+ }
+ name = name.Substring(0, index);
+ return name;
+ }
+ else
+ {
+ Debug.LogError("name not correct:" + name);
+ return "";
+ }
+ }
+ public static string MakeEquipName(string name, int profession, string dirName)
+ {
+ string prefix = s_CombineConfig.EquipPrefix[profession];
+ string replacePrefix = s_CombineConfig.EquipPrefixReplace[profession];
+ name = name.ToLower();
+ if (name.Contains("_helmat"))
+ name = name.Replace("_helmat", s_CombineConfig.HelmetString);
+
+ int partIndex = GetUVOffset(profession, name, s_CombineConfig);
+ if (partIndex < 0)
+ {
+ Debug.LogError("error part:" + name);
+ return "";
+ }
+
+ string partSuffix = s_CombineConfig.PartSuffix[partIndex];
+ string defaultName = prefix + partSuffix;
+ if (partIndex == (int)EPartType.EFace && name.Contains(s_CombineConfig.HeadString))
+ {
+ name = name.Replace(s_CombineConfig.HeadString, s_CombineConfig.FaceString);
+ }
+ if (partIndex == 6)
+ {
+ return defaultName;
+ }
+
+
+ if (name.StartsWith(replacePrefix))
+ {
+ if (dirName == "Player")
+ {
+ name = name.Replace(replacePrefix, prefix);
+ }
+ else
+ {
+ name = defaultName;
+ }
+
+ return name;
+ }
+ return defaultName;
+ }
+
+ public static string MakeWeaponName(int profession)
+ {
+ string prefix = s_CombineConfig.EquipPrefix[profession];
+ return prefix + "weapon";
+ }
+ public static int GetProfession(string path)
+ {
+ path = path.ToLower();
+ int profession = -1;
+ for (int i = 0; i < s_CombineConfig.EquipFolderName.Length; ++i)
+ {
+ if (path.Contains(s_CombineConfig.EquipFolderName[i]))
+ {
+ profession = i;
+ break;
+ }
+ }
+ return profession;
+ }
+ private static CombineConfig s_CombineConfig = null;
+ public static void InitCombineConfig()
+ {
+ s_CombineConfig = CombineConfig.GetConfig();
+ }
+ public class PartTexInfo
+ {
+ public string texPath = "";
+ public bool isAlpha = false;
+ }
+ public static Dictionary<int, PartTexInfo> usedTex = new Dictionary<int, PartTexInfo>();
+
+ private static bool _SaveSkinAsset(GameObject fbx, ModelImporter modelImporter, string path)
+ {
+ if (modelImporter == null)
+ return false;
+ int profession = GetProfession(path);
+ if (profession < 0)
+ {
+ modelImporter.isReadable = false;
+ return true;
+ }
+ string dirName = MakeEquipDir(fbx.name, profession);
+ if (string.IsNullOrEmpty(dirName))
+ {
+ return false;
+ }
+ int pathIndex = path.LastIndexOf("/");
+ string fbxDir = path.Substring(0, pathIndex);
+ string saveRootPath = "Assets/Resources/Equipments/" + dirName + "/";
+ if (!Directory.Exists(saveRootPath))
+ {
+ Directory.CreateDirectory(saveRootPath);
+ }
+ modelImporter.isReadable = true;
+ AssetDatabase.ImportAsset(path, ImportAssetOptions.ForceUpdate);
+ usedTex.Clear();
+ GameObject go = GameObject.Instantiate(fbx) as GameObject;
+ List<SkinnedMeshRenderer> smrList = ListPool<SkinnedMeshRenderer>.Get();
+ go.GetComponentsInChildren<SkinnedMeshRenderer>(true, smrList);
+
+ foreach (SkinnedMeshRenderer smr in smrList)
+ {
+ Mesh mesh = UnityEngine.Object.Instantiate(smr.sharedMesh) as Mesh;
+ mesh.name = smr.sharedMesh.name;
+
+ if (smr.sharedMesh.name.EndsWith("weapon"))
+ {
+ SaveSkinWeaponAsset(smr, mesh, saveRootPath, profession);
+ }
+ else
+ {
+ string meshName = MakeEquipName(mesh.name, profession, dirName);
+ if (string.IsNullOrEmpty(meshName))
+ {
+ continue;
+ }
+ mesh.name = meshName;
+ string meshPath = saveRootPath + meshName + ".asset";
+
+ ProcessMeshAsset(mesh, smr.sharedMaterial, profession, saveRootPath, dirName, smr.sharedMesh.name, meshName, fbxDir);
+ }
+ }
+ ListPool<SkinnedMeshRenderer>.Release(smrList);
+ modelImporter.isReadable = false;
+ AssetDatabase.ImportAsset(path, ImportAssetOptions.ForceUpdate);
+ List<MeshFilter> meshList = ListPool<MeshFilter>.Get();
+ go.GetComponentsInChildren<MeshFilter>(meshList);
+ string prefix = s_CombineConfig.EquipPrefix[profession];
+
+ foreach (MeshFilter mf in meshList)
+ {
+ Mesh mesh = UnityEngine.Object.Instantiate(mf.sharedMesh) as Mesh;
+ MeshRenderer mr = mf.GetComponent<MeshRenderer>();
+ if (mr != null)
+ {
+ Material mat = mr.sharedMaterial;
+ if (mat.shader != null && mat.shader.name.EndsWith("UV2"))
+ {
+
+ }
+ else
+ {
+ mesh.uv2 = null;
+ }
+ }
+
+
+ mesh.uv3 = null;
+ mesh.uv4 = null;
+ mesh.colors = null;
+ mesh.colors32 = null;
+ mesh.tangents = null;
+ mesh.name = prefix + "weapon";
+ mesh.UploadMeshData(true);
+ string weaponMeshPath = saveRootPath + prefix + "weapon.asset";
+ Mesh loadMesh = CreateOrReplaceAsset<Mesh>(mesh, weaponMeshPath);
+ mf.sharedMesh = loadMesh;
+ DefaultCompressTex(mr.sharedMaterial.mainTexture as Texture2D, AssetDatabase.GetAssetPath(mr.sharedMaterial.mainTexture), true, true);
+ ProcessRender(mr);
+ mr.gameObject.layer = LayerMask.NameToLayer("Role");
+ CreateOrReplacePrefab(mr.gameObject, saveRootPath + mesh.name + ".prefab");
+ }
+ ListPool<MeshFilter>.Release(meshList);
+ GameObject.DestroyImmediate(go);
+ return false;
+ }
+
+ public static XMeshPartList s_meshPartLis = new XMeshPartList();
+ public static void LoadMeshPartInfo()
+ {
+ s_meshPartLis.Load();
+ if (s_meshPartLis.meshPartsInfo == null)
+ s_meshPartLis.meshPartsInfo = new Dictionary<uint, byte>();
+ if (s_meshPartLis.replaceMeshPartsInfo == null)
+ s_meshPartLis.replaceMeshPartsInfo = new Dictionary<uint, string>();
+ if (s_meshPartLis.replaceTexPartsInfo == null)
+ s_meshPartLis.replaceTexPartsInfo = new Dictionary<uint, string>();
+
+ }
+ [MenuItem(@"Assets/Tool/Equipment/SaveSkinAsset %3", false, 0)]
+ private static void SaveSkinAsset()
+ {
+ s_CombineConfig = CombineConfig.GetConfig();
+ LoadMeshPartInfo();
+ enumFbx.cb = _SaveSkinAsset;
+ EnumAsset<GameObject>(enumFbx, "SaveSkinAsset");
+ SaveEquipInfo();
+ AssetDatabase.SaveAssets();
+ AssetDatabase.Refresh();
+ }
+ private static bool _ExportEquipAvatar(GameObject fbx, ModelImporter modelImporter, string path)
+ {
+ AssetModify.PreExportMeshAvatar(modelImporter.meshCompression, ModelImporterTangents.None);
+ AssetModify.ExportMeshAvatar(modelImporter, path, null);
+ return false;
+ }
+ [MenuItem(@"Assets/Tool/Equipment/ExportEquipAvata", false, 0)]
+ private static void ExportMeshAvatar()
+ {
+ enumFbx.cb = _ExportEquipAvatar;
+ EnumAsset<GameObject>(enumFbx, "ExportEquipAvata");
+ enumFbx.preprocess = null;
+ }
+ private static void _RefreshConfig(GameObject fbx, string path)
+ {
+ int profession = GetProfession(path);
+ if (profession < 0)
+ {
+ return;
+ }
+ string dirName = MakeEquipDir(fbx.name, profession);
+ if (string.IsNullOrEmpty(dirName))
+ {
+ return;
+ }
+
+ int pathIndex = path.LastIndexOf("/");
+ string fbxDir = path.Substring(0, pathIndex);
+ string saveRootPath = "Assets/Resources/Equipments/" + dirName + "/";
+ if (!Directory.Exists(saveRootPath))
+ {
+ return;
+ }
+ usedTex.Clear();
+ GameObject go = GameObject.Instantiate(fbx) as GameObject;
+ List<SkinnedMeshRenderer> smrList = ListPool<SkinnedMeshRenderer>.Get();
+ go.GetComponentsInChildren<SkinnedMeshRenderer>(true, smrList);
+
+ foreach (SkinnedMeshRenderer smr in smrList)
+ {
+ Mesh mesh = smr.sharedMesh;
+ if (!smr.sharedMesh.name.ToLower().EndsWith("weapon") && smr.sharedMaterial != null)
+ {
+ string meshName = MakeEquipName(mesh.name, profession, dirName);
+ if (string.IsNullOrEmpty(meshName))
+ {
+ continue;
+ }
+ ProcessMeshAsset(mesh, smr.sharedMaterial, profession, saveRootPath, dirName, smr.sharedMesh.name, meshName, fbxDir, false);
+ //string meshPath = saveRootPath + meshName + ".asset";
+ //if (File.Exists(meshPath))
+ //{
+ // string newMeshPath = "Equipments/" + dirName + "/" + meshName;
+
+ // Texture2D tex = smr.sharedMaterial.mainTexture as Texture2D;
+ // int uvOffsetX = GetUVOffset(profession, smr.sharedMesh.name, s_CombineConfig);
+ // if (uvOffsetX < 0)
+ // {
+ // Debug.LogError(string.Format("Find UV Error:{0} {1}", meshName, dirName));
+ // }
+
+ // if (tex == null)
+ // {
+ // Debug.LogError("null tex:" + path);
+ // AddPart(newMeshPath, newMeshPath, "", "", false, false, false);
+ // }
+ // else
+ // {
+ // bool shareTex = false;
+ // PartTexInfo partTexInfo = null;
+ // if (usedTex.TryGetValue(tex.GetHashCode(), out partTexInfo))
+ // {
+ // Debug.LogWarning(string.Format("Share tex with:{0} {1}", partTexInfo.texPath, meshPath));
+ // }
+ // else
+ // {
+ // string srcTexPath = AssetDatabase.GetAssetPath(tex);
+ // int index = srcTexPath.LastIndexOf("/");
+ // string srcTexDir = srcTexPath.Substring(0, index).ToLower();
+ // if (srcTexDir != fbxDir)
+ // {
+ // int srcTexProfession = GetProfession(srcTexPath.ToLower());
+ // string prefix = s_CombineConfig.EquipPrefix[srcTexProfession];
+ // string partSuffix = s_CombineConfig.PartSuffix[uvOffsetX];
+ // string srcTexName = saveRootPath + prefix + partSuffix + ".tga";
+ // if (File.Exists(srcTexName))
+ // {
+ // Debug.LogWarning(string.Format("Src Tex already exist:{0} {1}", srcTexName, meshPath));
+ // partTexInfo = new PartTexInfo();
+ // partTexInfo.texPath = "Equipments/" + dirName + "/" + prefix + partSuffix;
+ // partTexInfo.isAlpha = File.Exists(saveRootPath + prefix + partSuffix + "_A.png");
+ // shareTex = true;
+ // }
+ // else
+ // {
+ // Debug.LogError(string.Format("Src Tex not exist:{0} {1}", srcTexName, meshPath));
+ // continue;
+ // }
+ // }
+ // else
+ // {
+ // string targetAlphaTexPath = saveRootPath + meshName + "_A.png";
+ // partTexInfo = new PartTexInfo();
+ // partTexInfo.texPath = newMeshPath;
+ // partTexInfo.isAlpha = File.Exists(targetAlphaTexPath);
+ // usedTex.Add(tex.GetHashCode(), partTexInfo);
+ // }
+ // }
+
+ // AddPart(newMeshPath, newMeshPath, "", partTexInfo.texPath, tex.width == 1024, partTexInfo.isAlpha, shareTex);
+ // }
+ //}
+ }
+ }
+ ListPool<SkinnedMeshRenderer>.Release(smrList);
+ GameObject.DestroyImmediate(go);
+ }
+ private static void _RefreshExtraConfig(GameObject fbx, string path)
+ {
+ GameObject go = GameObject.Instantiate(fbx) as GameObject;
+ ReplaceEquip re = go.GetComponent<ReplaceEquip>();
+ if (re != null)
+ {
+ re.Process(false);
+ }
+ GameObject.DestroyImmediate(go);
+ }
+ [MenuItem(@"Assets/Tool/Equipment/RefreshConfig", false, 0)]
+ private static void RefreshConfig()
+ {
+ s_CombineConfig = CombineConfig.GetConfig();
+ s_meshPartLis.meshPartsInfo = new Dictionary<uint, byte>();
+ s_meshPartLis.replaceMeshPartsInfo = new Dictionary<uint, string>();
+ s_meshPartLis.replaceTexPartsInfo = new Dictionary<uint, string>();
+
+ List<EquipPathInfo> meshParts = new List<EquipPathInfo>();
+ foreach (string equipFolderName in s_CombineConfig.EquipFolderName)
+ {
+ string path = "Assets/Equipment" + equipFolderName;
+ DirectoryInfo di = new DirectoryInfo(path);
+ FileInfo[] files = di.GetFiles("*.fbx", SearchOption.TopDirectoryOnly);
+ for (int i = 0; i < files.Length; ++i)
+ {
+ FileInfo fi = files[i];
+ string filename = fi.FullName;
+ filename = filename.Replace("\\", "/");
+ int index = filename.IndexOf("Assets/Equipment/");
+ filename = filename.Substring(index);
+ EditorUtility.DisplayProgressBar(string.Format("{0}-{1}/{2}", "Process Fbx", i, files.Length), filename, (float)i / files.Length);
+
+ GameObject fbx = AssetDatabase.LoadAssetAtPath<GameObject>(filename);
+
+ _RefreshConfig(fbx, filename);
+ }
+
+ files = di.GetFiles("*.prefab", SearchOption.TopDirectoryOnly);
+ for (int i = 0; i < files.Length; ++i)
+ {
+ FileInfo fi = files[i];
+ string filename = fi.FullName;
+ filename = filename.Replace("\\", "/");
+ int index = filename.IndexOf("Assets/Equipment/");
+ filename = filename.Substring(index);
+ EditorUtility.DisplayProgressBar(string.Format("{0}-{1}/{2}", "Process Fbx", i, files.Length), filename, (float)i / files.Length);
+
+ GameObject fbx = AssetDatabase.LoadAssetAtPath<GameObject>(filename);
+
+ _RefreshExtraConfig(fbx, filename);
+ }
+ }
+
+
+ SaveEquipInfo();
+ AssetDatabase.Refresh();
+ EditorUtility.ClearProgressBar();
+ EditorUtility.DisplayDialog("Finish", "All objects processed finish", "OK");
+ }
+
+ [MenuItem(@"Assets/Tool/Equipment/PrintSpecialPart", false, 0)]
+ private static void PrintSpecialPart()
+ {
+ s_CombineConfig = CombineConfig.GetConfig();
+ LoadMeshPartInfo();
+ Debug.LogWarning("==================ReplaceMesh");
+ var itReplace = s_meshPartLis.replaceMeshPartsInfo.GetEnumerator();
+ while (itReplace.MoveNext())
+ {
+ Debug.LogWarning(itReplace.Current.Value);
+
+ }
+ Debug.LogWarning("==================ReplaceTex");
+ var itReplaceTex = s_meshPartLis.replaceTexPartsInfo.GetEnumerator();
+ while (itReplaceTex.MoveNext())
+ {
+ Debug.LogWarning(itReplaceTex.Current.Value);
+ }
+ }
+ private static string GetDefaultEquipPart(DefaultEquip.RowData de, EPartType part)
+ {
+ switch (part)
+ {
+ case EPartType.EFace:
+ return de.Face;
+ case EPartType.EHair:
+ return de.Hair;
+ case EPartType.EUpperBody:
+ return de.Body;
+ case EPartType.ELowerBody:
+ return de.Leg;
+ case EPartType.EGloves:
+ return de.Glove;
+ case EPartType.EBoots:
+ return de.Boots;
+ case EPartType.ESecondaryWeapon:
+ return de.SecondWeapon;
+ case EPartType.EHeadgear:
+ return de.Helmet;
+ case EPartType.EMainWeapon:
+ return de.Weapon;
+ }
+ return "";
+ }
+
+ private static int ConvertPart(int fp)
+ {
+ switch (fp)
+ {
+ case 0:
+ return (int)EPartType.EHeadgear;
+ case 1:
+ return (int)EPartType.EUpperBody;
+ case 2:
+ return (int)EPartType.ELowerBody;
+ case 3:
+ return (int)EPartType.EGloves;
+ case 4:
+ return (int)EPartType.EBoots;
+ case 5:
+ return (int)EPartType.EMainWeapon;
+ case 6:
+ return (int)EPartType.ESecondaryWeapon;
+ case 7:
+ return (int)EPartType.EWings;
+ case 8:
+ return (int)EPartType.ETail;
+ case 9:
+ return (int)EPartType.EDecal;
+ case 10:
+ return (int)EPartType.EFace;
+ case 11:
+ return (int)EPartType.EHair;
+ }
+ return -1;
+ }
+
+ private static string GetEquipPrefabModel(FashionList.RowData data, int profID)
+ {
+ switch (profID)
+ {
+ case 0:
+ return data.ModelPrefabWarrior;
+ case 1:
+ return data.ModelPrefabArcher;
+ case 2:
+ return data.ModelPrefabSorcer;
+ case 3:
+ return data.ModelPrefabCleric;
+ case 4:
+ return data.ModelPrefab5;
+ case 5:
+ return data.ModelPrefab6;
+ case 6:
+ return data.ModelPrefab7;
+ //case 8:
+ // return data.ModelPrefab8;
+ default:
+ return string.Empty;
+ }
+ }
+ private static void CheckMesh(string meshPath, string meshResPath, uint professionIndex,int part)
+ {
+ if (meshPath.EndsWith("_weapon"))
+ {
+ if (!File.Exists(meshPath + ".prefab"))
+ {
+ Debug.LogError("prefab not found:" + meshPath);
+ }
+ }
+ else
+ {
+ byte partType = 0;
+ string replaceMeshLocation = null;
+ string replaceTexLocation = null;
+ if (s_meshPartLis.GetMeshInfo(meshResPath, (int)professionIndex, part,"", out partType, ref replaceMeshLocation, ref replaceTexLocation))
+ {
+ if (replaceMeshLocation != null)
+ {
+ if (!File.Exists("Assets/Resources/" + replaceMeshLocation + ".asset"))
+ {
+ Debug.LogError("replace mesh not found:" + replaceMeshLocation);
+ }
+ }
+ else if (!File.Exists(meshPath + ".asset"))
+ {
+ Debug.LogError("mesh not found:" + meshPath);
+ }
+ if (replaceTexLocation != null)
+ {
+ if (!File.Exists("Assets/Resources/" + replaceTexLocation + ".tga"))
+ {
+ Debug.LogError("replace tex not found:" + replaceTexLocation);
+ }
+ }
+ }
+ else if (!string.IsNullOrEmpty(meshPath))
+ {
+ Debug.LogError("mesh not found in config:" + meshPath);
+ }
+ }
+
+ }
+ [MenuItem(@"Assets/Tool/Equipment/TestEquip", false, 0)]
+ private static void TestEquip()
+ {
+ s_CombineConfig = CombineConfig.GetConfig();
+ LoadMeshPartInfo();
+ XBinaryReader.Init();
+ XBinaryReader reader = XBinaryReader.Get();
+ DefaultEquip defaultEquip = new DefaultEquip();
+ FashionList fashionList = new FashionList();
+ TextAsset ta = Resources.Load<TextAsset>(@"Table/DefaultEquip");
+ if (ta != null)
+ {
+ reader.Init(ta);
+ defaultEquip.ReadFile(reader);
+ XBinaryReader.Return(reader);
+
+ for (int i = 0; i < defaultEquip.Table.Length; ++i)
+ {
+ DefaultEquip.RowData de = defaultEquip.Table[i];
+ string weaponPoint = de.WeaponPoint != null ? de.WeaponPoint[0] : "";
+
+
+ int professionIndex = -1;
+ for (int j = 0; j < s_CombineConfig.EquipPrefix.Length; ++j)
+ {
+ DefaultEquip.RowData startDe = defaultEquip.Table[j];
+ if (startDe.WeaponPoint != null && startDe.WeaponPoint[0] == weaponPoint)
+ {
+ professionIndex = j;
+ break;
+ }
+ }
+ if (professionIndex < 0)
+ {
+ Debug.LogError("professionIndex not found:" + i.ToString());
+ continue;
+ }
+ string proPrefix = s_CombineConfig.EquipPrefix[professionIndex];
+ for (int j = 0; j < s_CombineConfig.PartSuffix.Length; ++j)
+ {
+ string partSuffix = s_CombineConfig.PartSuffix[j];
+ string path = GetDefaultEquipPart(de, (EPartType)j);
+ string meshPath = "";
+ string meshResPath = "";
+ if (string.IsNullOrEmpty(path))
+ {
+ meshPath = string.Format("Assets/Resources/Equipments/Player/{0}{1}", proPrefix, partSuffix);
+ meshResPath = string.Format("Equipments/Player/{0}{1}", proPrefix, partSuffix);
+ }
+ else if (path.StartsWith("/"))
+ {
+ meshPath = string.Format("Assets/Resources/Equipments{0}/{1}{2}", path, proPrefix, partSuffix);
+ meshResPath = string.Format("Equipments{0}/{1}{2}", path, proPrefix, partSuffix);
+ }
+ else if (path == "E")
+ {
+ meshPath = "";
+ meshResPath = "";
+ }
+ else
+ {
+ meshPath = string.Format("Assets/Resources/Equipments/Player/{0}{1}", proPrefix, path);
+ meshResPath = string.Format("Equipments/Player/{0}{1}", proPrefix, path);
+ }
+ CheckMesh(meshPath, meshResPath, (uint)professionIndex,j);
+ }
+ }
+ }
+
+ ta = Resources.Load<TextAsset>(@"Table/FashionList");
+ if (ta != null)
+ {
+ reader.Init(ta);
+ fashionList.ReadFile(reader);
+
+ for (int i = 0; i < fashionList.Table.Length; ++i)
+ {
+ FashionList.RowData data = fashionList.Table[i];
+ int index = ConvertPart(data.EquipPos);
+
+ if (index >= 0 && index < s_CombineConfig.PartSuffix.Length)
+ {
+ for (int j = 0; j < s_CombineConfig.EquipPrefix.Length; ++j)
+ {
+ string proPrefix = s_CombineConfig.EquipPrefix[j];
+ string partSuffix = s_CombineConfig.PartSuffix[index];
+ string equipPath = GetEquipPrefabModel(data, j);
+ string meshPath = "";
+ string meshResPath = "";
+ if (equipPath == "E" || string.IsNullOrEmpty(data.SuitName) && string.IsNullOrEmpty(equipPath))
+ {
+ }
+ else
+ {
+ if (string.IsNullOrEmpty(data.SuitName))
+ {
+
+ meshPath = string.Format("Assets/Resources/Equipments/{0}/{1}{2}", equipPath, proPrefix, partSuffix);
+ meshResPath = string.Format("Equipments/{0}/{1}{2}", equipPath, proPrefix, partSuffix);
+ }
+ else
+ {
+ meshPath = string.Format("Assets/Resources/Equipments/{0}/{1}{2}", data.SuitName, proPrefix, partSuffix);
+ meshResPath = string.Format("Equipments/{0}/{1}{2}", data.SuitName, proPrefix, partSuffix);
+ }
+ }
+ CheckMesh(meshPath, meshResPath, (uint)j, index);
+ }
+
+ }
+ }
+ }
+ XBinaryReader.Return(reader);
+ }
+
+ [MenuItem(@"Assets/Tool/Equipment/MakeMesh", false, 0)]
+ private static void MakeMesh()
+ {
+ UnityEngine.Object[] objs = Selection.GetFiltered(typeof(Mesh), SelectionMode.Assets);
+ if(objs!=null&& objs.Length>0)
+ {
+ Mesh mesh = objs[0] as Mesh;
+ Mesh newMesh = UnityEngine.Object.Instantiate<Mesh>(mesh);
+ newMesh.name = "CombineMesh";
+ newMesh.Clear(true);
+ CreateOrReplaceAsset<Mesh>(newMesh, "Assets/Resources/Equipments/CombineMesh.asset");
+ }
+ }
+
+ private static bool _Save3Part(GameObject fbx, ModelImporter modelImporter, string path)
+ {
+ if (modelImporter == null)
+ return false;
+ string saveRootPath = "Assets/Resources/Prefabs/Equipment/";
+ GameObject go = GameObject.Instantiate(fbx) as GameObject;
+ List<Renderer> renderLst = ListPool<Renderer>.Get();
+ go.GetComponentsInChildren<Renderer>(true, renderLst);
+ foreach (Renderer r in renderLst)
+ {
+ ProcessRender(r);
+ }
+ ListPool<Renderer>.Release(renderLst);
+ Animator animator = go.GetComponent<Animator>();
+ animator.runtimeAnimatorController = Resources.Load("Controller/XMinorAnimator") as RuntimeAnimatorController;
+
+ go.layer = LayerMask.NameToLayer("Role");
+ CreateOrReplacePrefab(go, saveRootPath + fbx.name + ".prefab");
+
+ GameObject.DestroyImmediate(go);
+ modelImporter.isReadable = false;
+ return true;
+ }
+
+ [MenuItem(@"Assets/Tool/Equipment/Save3Part %4", false, 0)]
+ private static void Save3Part()
+ {
+ enumFbx.cb = _Save3Part;
+ EnumAsset<GameObject>(enumFbx, "Save3Part");
+ }
+
+
+ public static void AddPart(string meshPath, string replaceMesh,string replaceMeshDir, string texPath, bool isOnePart, bool hasAlpha, bool shareTex,string prefix)
+ {
+ uint hash = XCommon.singleton.XHash(meshPath);
+ if (string.IsNullOrEmpty(texPath) || hash == 0)
+ {
+ s_meshPartLis.meshPartsInfo.Remove(hash);
+ s_meshPartLis.replaceMeshPartsInfo.Remove(hash);
+ return;
+ }
+ byte type = 0;
+ if (isOnePart)
+ {
+ if (hasAlpha)
+ {
+ type = XMeshPartList.CutoutPart;
+ }
+ else
+ {
+ type = XMeshPartList.OnePart;
+ }
+ }
+ else
+ {
+ type = XMeshPartList.NormalPart;
+ }
+ string location = meshPath;
+ if (meshPath != replaceMesh)
+ {
+ location = replaceMesh;
+ type |= XMeshPartList.ReplacePart;
+ hash = XCommon.singleton.XHash(replaceMesh);
+ s_meshPartLis.replaceMeshPartsInfo[hash] = replaceMeshDir;
+ Debug.LogWarning(string.Format("ReplaceMesh:\r\nsrcmesh:{0}\r\nreplacemesh:{1}\r\nsavedmesh:{2}", meshPath, replaceMesh, replaceMeshDir));
+ }
+ if (shareTex)
+ {
+ type |= XMeshPartList.ShareTex;
+ int i = location.LastIndexOf("/");
+ if (i >= 0)
+ {
+ location = location.Substring(0, i);
+ if (location.Contains(prefix))
+ {
+ Debug.LogError(string.Format("path:{0} contain profession prefix:{1},please rename!", location, prefix));
+ }
+ }
+ }
+ else if (meshPath != texPath)
+ {
+ if (meshPath != replaceMesh && replaceMesh != texPath||
+ meshPath == replaceMesh)
+ {
+ type |= XMeshPartList.ReplaceTex;
+ string newTexPath = "";
+ if(texPath.Contains("/Player"))
+ {
+ int index = texPath.LastIndexOf("/");
+ newTexPath = texPath.Substring(index + 1);
+ }
+ else
+ {
+ int index = texPath.LastIndexOf("/");
+ newTexPath = texPath.Substring(index);
+ }
+ Debug.LogWarning(string.Format("ReplaceTex:\r\ntex:{0}\r\nmesh:{1}\r\nsavedmesh:{2}", texPath, replaceMesh, newTexPath));
+ s_meshPartLis.replaceTexPartsInfo[hash] = newTexPath;
+ }
+ }
+ s_meshPartLis.meshPartsInfo[hash] = type;
+ //if (s_meshPartLis.meshParts.ContainsKey(hash))
+ //{
+ // Debug.LogError("duplicate hash:" + meshPath);
+ //}
+ }
+
+ public static void SaveEquipInfo()
+ {
+ try
+ {
+ using (FileStream desStream = new FileStream(@"Assets/Resources/Equipments/equipmentInfo.bytes", FileMode.Create))
+ {
+ BinaryWriter writer = new BinaryWriter(desStream);
+ int professionCount = s_CombineConfig.EquipPrefix.Length;
+ writer.Write(professionCount);
+ for (int i = 0; i < professionCount; ++i)
+ {
+ writer.Write(s_CombineConfig.EquipPrefix[i]);
+ }
+
+ int partSuffixCount = s_CombineConfig.PartSuffix.Length;
+ writer.Write(partSuffixCount);
+ for (int i = 0; i < partSuffixCount; ++i)
+ {
+ writer.Write(s_CombineConfig.PartSuffix[i]);
+ }
+ //shared tex prefix
+ writer.Write(s_CombineConfig.EquipPrefix[0]);
+ List<string> stringTable = new List<string>();
+ Dictionary<string, ushort> stringHash = new Dictionary<string, ushort>();
+ var itReplace = s_meshPartLis.replaceMeshPartsInfo.GetEnumerator();
+ while (itReplace.MoveNext())
+ {
+ if(!stringHash.ContainsKey(itReplace.Current.Value))
+ {
+ stringHash.Add(itReplace.Current.Value, (ushort)stringTable.Count);
+ stringTable.Add(itReplace.Current.Value);
+ }
+ }
+ var itReplaceTex = s_meshPartLis.replaceTexPartsInfo.GetEnumerator();
+ while (itReplaceTex.MoveNext())
+ {
+ if (!stringHash.ContainsKey(itReplaceTex.Current.Value))
+ {
+ stringHash.Add(itReplaceTex.Current.Value, (ushort)stringTable.Count);
+ stringTable.Add(itReplaceTex.Current.Value);
+ }
+ }
+ writer.Write(stringTable.Count);
+ for (int i = 0; i < stringTable.Count; ++i)
+ {
+ writer.Write(stringTable[i]);
+ }
+
+ writer.Write(s_meshPartLis.meshPartsInfo.Count);
+ var it = s_meshPartLis.meshPartsInfo.GetEnumerator();
+ while (it.MoveNext())
+ {
+ writer.Write(it.Current.Key);
+ writer.Write(it.Current.Value);
+ }
+ writer.Write(s_meshPartLis.replaceMeshPartsInfo.Count);
+ itReplace = s_meshPartLis.replaceMeshPartsInfo.GetEnumerator();
+ while (itReplace.MoveNext())
+ {
+ writer.Write(itReplace.Current.Key);
+ ushort index = 0;
+ stringHash.TryGetValue(itReplace.Current.Value, out index);
+ writer.Write(index);
+
+ }
+ writer.Write(s_meshPartLis.replaceTexPartsInfo.Count);
+ itReplaceTex = s_meshPartLis.replaceTexPartsInfo.GetEnumerator();
+ while (itReplaceTex.MoveNext())
+ {
+ writer.Write(itReplaceTex.Current.Key);
+ ushort index = 0;
+ stringHash.TryGetValue(itReplaceTex.Current.Value, out index);
+ writer.Write(index);
+ }
+ desStream.Flush();
+ }
+ }
+ catch (System.Exception e)
+ {
+ Debug.LogError(e.Message);
+ }
+ }
+
+ //private static bool MakeEquipName(string name, int profession, out string dirName, out string newName)
+ //{
+ // string prefix = s_CombineConfig.EquipPrefix[profession];
+ // string replacePrefix = s_CombineConfig.EquipPrefixReplace[profession];
+ // name = name.ToLower();
+ // bool isWeapon = false;
+ // if (name.StartsWith("weapon/"))
+ // {
+ // name = name.Replace("weapon/", "");
+ // isWeapon = true;
+ // }
+ // if (name.StartsWith(replacePrefix))
+ // {
+ // newName = name.Replace(replacePrefix, prefix);
+ // dirName = "Player";
+ // if (isWeapon)
+ // {
+ // newName = "";
+ // }
+ // return true;
+ // }
+ // else if (name.StartsWith(prefix))
+ // {
+
+ // int suffix = name.LastIndexOf("_");
+ // if (suffix >= 0)
+ // {
+ // newName = prefix + name.Substring(suffix + 1);
+ // dirName = name.Substring(0, suffix);
+ // if (dirName.StartsWith(prefix))
+ // dirName = dirName.Substring(prefix.Length);
+ // if (isWeapon)
+ // {
+ // suffix = dirName.LastIndexOf("_");
+ // if (suffix >= 0)
+ // {
+ // dirName = dirName.Substring(0, suffix);
+ // }
+ // }
+ // }
+ // else
+ // {
+ // newName = name;
+ // dirName = "";
+ // }
+
+ // }
+ // else
+ // {
+ // newName = name;
+ // dirName = "";
+ // }
+ // return false;
+ //}
+ //private static bool MakeDefaultEquipName(string name, int profession, int part, out string newName)
+ //{
+ // //string prefix = s_CombineConfig.EquipPrefix[profession];
+ // //string replacePrefix = s_CombineConfig.EquipPrefixReplace[profession];
+ // //string partSuffix = s_CombineConfig.PartSuffix[part];
+ // //string secondSuffix = s_CombineConfig.SecondaryWeapon[profession].Substring(1);
+ // //string defaultPart = prefix + partSuffix;
+ // //name = name.ToLower();
+ // //bool isWeapon = false;
+ // //bool isSceondWeapon = part == 6;
+ // //newName = "";
+ // //if (name.StartsWith("weapon/"))
+ // //{
+ // // name = name.Replace("weapon/", "");
+ // // isWeapon = true;
+ // // defaultPart = prefix + "weapon";
+ // //}
+ // //if (name.StartsWith(replacePrefix))
+ // //{
+ // // newName = name.Replace(replacePrefix, prefix);
+ // // if (isSceondWeapon)
+ // // {
+ // // defaultPart = prefix + secondSuffix + "_weapon";
+ // // }
+ // // if (isWeapon)
+ // // {
+ // // int suffix = newName.LastIndexOf("_");
+ // // newName = prefix + newName.Substring(suffix + 1);
+ // // }
+ // // if (newName == defaultPart)
+ // // {
+ // // newName = "";
+ // // }
+ // // return true;
+ // //}
+ // //else if (name.StartsWith(prefix))
+ // //{
+
+ // // int suffix = name.LastIndexOf("_");
+ // // if (suffix >= 0)
+ // // {
+ // // newName = name.Substring(0, suffix);
+ // // if (newName.StartsWith(prefix))
+ // // newName = newName.Substring(prefix.Length);
+ // // if (isWeapon)
+ // // {
+ // // suffix = newName.LastIndexOf("_");
+ // // if (suffix >= 0)
+ // // {
+ // // newName = newName.Substring(0, suffix);
+ // // }
+ // // }
+ // // }
+ // // return true;
+ // //}
+ // //else
+ // //{
+ // // return false;
+ // //}
+
+ // string prefix = s_CombineConfig.EquipPrefix[profession];
+ // string replacePrefix = s_CombineConfig.EquipPrefixReplace[profession];
+ // name = name.ToLower();
+ // bool isWeapon = false;
+ // if (name.StartsWith("weapon/"))
+ // {
+ // name = name.Replace("weapon/", "");
+ // isWeapon = true;
+ // }
+
+ // int index = name.LastIndexOf("/");
+ // if (index >= 0)
+ // {
+ // name = name.Substring(index + 1);
+ // }
+ // if (name.Contains("_helmat"))
+ // name = name.Replace("_helmat", s_CombineConfig.HelmetString);
+ // newName = "";
+ // string defaultName = "";
+ // string defaultName2 = prefix + "head";
+ // string defaultName3 = prefix + s_CombineConfig.SecondaryWeapon[profession].Substring(1);
+ // if (!isWeapon)
+ // {
+ // int partIndex = GetUVOffset(profession, name, s_CombineConfig);
+ // if (partIndex < 0)
+ // {
+ // Debug.LogError("error part:" + name);
+ // return false;
+ // }
+ // string partSuffix = s_CombineConfig.PartSuffix[partIndex];
+ // defaultName = prefix + partSuffix;
+
+ // //if (partIndex == 6)
+ // //{
+ // // return true;
+ // //}
+ // }
+ // else
+ // {
+
+ // }
+
+
+ // if (name.StartsWith(replacePrefix))
+ // {
+ // if (isWeapon)
+ // {
+ // newName = "";
+ // }
+ // else
+ // {
+ // newName = name.Replace(replacePrefix, prefix);
+ // if (defaultName == newName || defaultName2 == newName || defaultName3 == newName)
+ // newName = "";
+ // }
+
+ // return true;
+ // }
+ // if (name.StartsWith(prefix))
+ // {
+ // newName = name.Replace(prefix, "/");
+ // index = newName.LastIndexOf("_");
+ // if (index >= 0)
+ // {
+ // newName = newName.Substring(0, index);
+ // }
+ // if (isWeapon)
+ // {
+ // index = newName.LastIndexOf("_");
+ // if (index >= 0)
+ // {
+ // newName = newName.Substring(0, index);
+ // }
+ // }
+ // return true;
+ // }
+ // newName = name;
+ // return true;
+ //}
+
+ //[MenuItem(@"Assets/Tool/Equipment/FashionList")]
+ //private static void FashionList()
+ //{
+ // s_CombineConfig = CombineConfig.GetConfig();
+ // int lineno = 1;
+ // using (FileStream fs = new FileStream(@"Assets/Table/FashionList.txt", FileMode.Open, System.IO.FileAccess.Read, FileShare.ReadWrite))
+ // {
+ // if (fs.Length > 0)
+ // {
+ // byte[] bytes = new byte[fs.Length];
+ // if (bytes != null)
+ // {
+ // fs.Read(bytes, 0, (int)fs.Length);
+ // Stream srcStream = new System.IO.MemoryStream(bytes);
+ // using (FileStream desStream = new FileStream(@"Assets/Table/FashionListNew.txt", FileMode.Create))
+ // {
+ // StreamReader reader = new StreamReader(srcStream);
+ // StreamWriter writer = new StreamWriter(desStream, new UnicodeEncoding());
+ // int suitNameIndex = -1;
+ // int[] professionIndex = new int[6] { -1, -1, -1, -1, -1, -1 };
+ // string[] professionStr = new string[] { "ModelPrefabWarrior", "ModelPrefabArcher", "ModelPrefabSorcer", "ModelPrefabCleric", "ModelPrefab5", "ModelPrefab6" };
+ // string[] newNames = new string[] { "", "", "", "", "", "" };
+ // string[] dirNames = new string[] { "", "", "", "", "", "" };
+
+ // while (true)
+ // {
+ // bool isParseOK = true;
+ // string line = reader.ReadLine();
+ // if (line == null)
+ // break;
+
+ // line = line.TrimEnd(eof);
+ // string[] cols = line.Split('\t');
+ // if (lineno == 1)
+ // {
+ // writer.WriteLine(line);
+ // for (int i = 0; i < cols.Length; ++i)
+ // {
+ // if (cols[i] == "SuitName")
+ // {
+ // suitNameIndex = i;
+ // }
+ // else
+ // {
+ // for(int j=0;j< professionStr.Length;++j)
+ // {
+ // if(cols[i] == professionStr[j])
+ // {
+ // professionIndex[j] = i;
+ // break;
+ // }
+ // }
+ // }
+ // }
+ // }
+ // else if (lineno == 2)
+ // {
+ // writer.WriteLine(line);
+ // }
+ // else
+ // {
+ // for (int i = 0; i < professionIndex.Length; ++i)
+ // {
+ // int index = professionIndex[i];
+ // string prefix = s_CombineConfig.EquipPrefix[i];
+ // string replacePrefix = s_CombineConfig.EquipPrefixReplace[i];
+ // string name = cols[index].ToLower();
+
+ // string newName = "";
+ // string dirName = "";
+ // bool isWeapon = false;
+ // if (name.StartsWith("weapon/"))
+ // {
+ // name = name.Replace("weapon/", "");
+ // isWeapon = true;
+ // }
+ // if (name.StartsWith(replacePrefix))
+ // {
+ // //player_xxx_xxx
+ // newName = name.Replace(replacePrefix, "");
+ // dirName = "Player";
+ // if (isWeapon)
+ // {
+ // newName = "";
+ // }
+ // }
+ // else if (name.StartsWith(prefix))
+ // {
+ // int suffix = name.LastIndexOf("_");
+ // if (suffix >= 0)
+ // {
+ // newName = name.Substring(suffix + 1);
+
+ // dirName = name.Substring(0, suffix);
+ // if (dirName.StartsWith(prefix))
+ // dirName = dirName.Substring(prefix.Length);
+ // if (isWeapon)
+ // {
+ // suffix = dirName.LastIndexOf("_");
+ // if (suffix >= 0)
+ // {
+ // dirName = dirName.Substring(0, suffix);
+ // }
+ // }
+ // }
+ // else
+ // {
+ // newName = name;
+ // dirName = "";
+ // }
+
+ // }
+ // else
+ // {
+ // if (string.IsNullOrEmpty(name))
+ // {
+ // name = "E";
+ // }
+ // newName = name;
+ // dirName = "";
+ // }
+ // newNames[i] = newName;
+ // dirNames[i] = dirName;
+ // }
+ // string dir = "";
+ // int dirIndex = 0;
+ // for (; dirIndex < dirNames.Length; ++dirIndex)
+ // {
+ // if (dirNames[dirIndex] != "")
+ // {
+ // dir = dirNames[dirIndex];
+ // dirIndex++;
+ // break;
+ // }
+
+
+ // }
+ // for (int i = dirIndex; i < dirNames.Length; ++i)
+ // {
+ // if (dirNames[i] != "")
+ // {
+ // if (dir != dirNames[i])
+ // {
+ // dir = "";
+ // break;
+ // }
+ // }
+
+ // }
+ // cols[suitNameIndex] = dir;
+ // for (int j = 0; j < professionIndex.Length; ++j)
+ // {
+ // if (dir == "Player")
+ // {
+ // cols[professionIndex[j]] = newNames[j];
+ // }
+ // else if (dir == "")
+ // {
+ // cols[professionIndex[j]] = dirNames[j];
+ // }
+ // else
+ // {
+ // cols[professionIndex[j]] = "";
+
+ // }
+
+ // }
+
+ // string newLine = "";
+ // for (int i = 0; i < cols.Length; ++i)
+ // {
+ // newLine += cols[i] + ((i != cols.Length - 1) ? "\t" : "");
+ // }
+ // writer.WriteLine(newLine);
+ // }
+ // line = null;
+ // if (!isParseOK) break;
+
+ // ++lineno;
+ // }
+ // writer.Flush();
+ // }
+ // srcStream.Close();
+ // }
+ // }
+ // }
+
+ //}
+ //[MenuItem(@"Assets/Tool/Equipment/DefaultEquip")]
+ //private static void DefaultEquip()
+ //{
+ // s_CombineConfig = CombineConfig.GetConfig();
+ // int lineno = 1;
+ // using (FileStream fs = new FileStream(@"Assets/Table/DefaultEquip.txt", FileMode.Open, System.IO.FileAccess.Read, FileShare.ReadWrite))
+ // {
+ // if (fs.Length > 0)
+ // {
+ // byte[] bytes = new byte[fs.Length];
+ // if (bytes != null)
+ // {
+ // fs.Read(bytes, 0, (int)fs.Length);
+ // Stream srcStream = new System.IO.MemoryStream(bytes);
+ // using (FileStream desStream = new FileStream(@"Assets/Table/DefaultEquipNew.txt", FileMode.Create))
+ // {
+ // StreamReader reader = new StreamReader(srcStream);
+ // StreamWriter writer = new StreamWriter(desStream, new UnicodeEncoding());
+ // int[] partIndexes = new int[9] { -1, -1, -1, -1, -1, -1, -1, -1, -1 };
+ // string[] partStr = new string[9] { "Face", "Hair", "Helmet", "Body", "Leg", "Glove", "Boots", "Weapon", "SecondWeapon" };
+ // string[] professionStr = new string[6] { "Point001_zhanshi", "BoxBone01_archer", "BoxBone01_sorceress|BoxBone02_sorceress", "BoxBone01_Cleric|BoxBone02_Cleric", "~BoxBone01_academic", "BoxBone01_assassin" };
+ // int WeaponPointIndex = -1;
+ // while (true)
+ // {
+ // bool isParseOK = true;
+ // string line = reader.ReadLine();
+ // if (line == null)
+ // break;
+
+ // line = line.TrimEnd(eof);
+ // string[] cols = line.Split('\t');
+ // if (lineno == 1)
+ // {
+ // writer.WriteLine(line);
+ // for (int i = 0; i < cols.Length; ++i)
+ // {
+ // string partName = cols[i];
+ // for (int j = 0; j < partStr.Length; ++j)
+ // {
+ // if(partName== partStr[j])
+ // {
+ // partIndexes[j] = i;
+ // break;
+ // }
+ // }
+ // if(partName== "WeaponPoint")
+ // {
+ // WeaponPointIndex = i;
+ // break;
+ // }
+ // }
+ // }
+ // else if (lineno == 2)
+ // {
+ // writer.WriteLine(line);
+ // }
+ // else
+ // {
+
+ // int profession = -1;
+ // for (int i = 0; i < professionStr.Length; ++i)
+ // {
+ // if (professionStr[i] == cols[WeaponPointIndex])
+ // {
+ // profession = i;
+ // break;
+ // }
+ // }
+ // if (profession >= 0 && profession < 6)
+ // {
+ // for (int j = 0; j < partIndexes.Length; ++j)
+ // {
+ // int partIndex = partIndexes[j];
+ // string partName = cols[partIndex].ToLower();
+ // if (string.IsNullOrEmpty(partName))
+ // {
+ // cols[partIndex] = "E";
+ // continue;
+ // }
+
+ // string newName = "";
+ // string prefix = s_CombineConfig.EquipPrefix[profession];
+ // string replacePrefix = s_CombineConfig.EquipPrefixReplace[profession];
+
+ // bool isWeapon = false;
+ // if (partName.StartsWith("weapon/"))
+ // {
+ // partName = partName.Replace("weapon/", "");
+ // isWeapon = true;
+ // }
+
+ // int index = partName.LastIndexOf("/");
+ // if (index >= 0)
+ // {
+ // partName = partName.Substring(index + 1);
+ // }
+ // if (partName.Contains("_helmat"))
+ // partName = partName.Replace("_helmat", s_CombineConfig.HelmetString);
+
+ // string defaultName = "";
+ // string defaultName2 = "head";
+ // string defaultName3 = s_CombineConfig.SecondaryWeapon[profession].Substring(1);
+ // if (!isWeapon)
+ // {
+ // int uvIndex = GetUVOffset(profession, partName, s_CombineConfig);
+ // if (uvIndex < 0)
+ // {
+ // Debug.LogError(string.Format("error part:{0} line :{1}", partName, lineno));
+ // continue;
+ // }
+ // string partSuffix = s_CombineConfig.PartSuffix[uvIndex];
+ // defaultName = partSuffix;
+ // }
+
+ // if (partName.StartsWith(replacePrefix))
+ // {
+ // if (isWeapon)
+ // {
+ // newName = "";
+ // }
+ // else
+ // {
+ // newName = partName.Replace(replacePrefix, "");
+ // if (defaultName == newName || defaultName2 == newName || defaultName3 == newName)
+ // newName = "";
+ // }
+ // }
+ // else if (partName.StartsWith(prefix))
+ // {
+ // newName = partName.Replace(prefix, "/");
+ // index = newName.LastIndexOf("_");
+ // if (index >= 0)
+ // {
+ // newName = newName.Substring(0, index);
+ // }
+ // if (isWeapon)
+ // {
+ // index = newName.LastIndexOf("_");
+ // if (index >= 0)
+ // {
+ // newName = newName.Substring(0, index);
+ // }
+ // }
+ // }
+ // else
+ // {
+ // newName = partName;
+ // }
+ // cols[partIndex] = newName;
+ // }
+ // }
+
+ // string newLine = "";
+ // for (int i = 0; i < cols.Length; ++i)
+ // {
+ // newLine += cols[i] + ((i != cols.Length - 1) ? "\t" : "");
+ // }
+ // writer.WriteLine(newLine);
+ // }
+ // line = null;
+ // if (!isParseOK) break;
+
+ // ++lineno;
+ // }
+ // writer.Flush();
+ // }
+ // srcStream.Close();
+ // }
+ // }
+ // }
+
+ //}
+
+ #endregion
+ #region fx
+ private static void _ConvertAnimator2Legacy(GameObject go, string path)
+ {
+ GameObject newGo = GameObject.Instantiate(go) as GameObject;
+ List<Animator> animators = new List<Animator>();
+ newGo.GetComponentsInChildren<Animator>(animators);
+ for (int i = 0; i < animators.Count; ++i)
+ {
+ Animator animator = animators[i];
+ if (animator.avatar != null)
+ {
+ Debug.LogWarning("avatar fx:" + path);
+ continue;
+ }
+
+ UnityEditor.Animations.AnimatorController ac = animator.runtimeAnimatorController as UnityEditor.Animations.AnimatorController;
+ if (ac != null)
+ {
+ UnityEditor.Animations.AnimatorControllerLayer[] layers = ac.layers;
+ if (layers == null || layers.Length != 1)
+ {
+ break;
+ }
+ else
+ {
+ foreach (UnityEditor.Animations.AnimatorControllerLayer acl in layers)
+ {
+ UnityEditor.Animations.AnimatorStateMachine asm = acl.stateMachine;
+
+ UnityEditor.Animations.ChildAnimatorState[] states = asm.states;
+ if (states.Length != 1)
+ {
+ UnityEditor.Animations.AnimatorState defaultState = asm.defaultState;
+ if (defaultState != null)
+ defaultState.name = "Anim";
+ break;
+ }
+ foreach (UnityEditor.Animations.ChildAnimatorState state in states)
+ {
+ AnimationClip clip = state.state.motion as AnimationClip;
+ if (clip != null)
+ {
+ bool loop = clip.isLooping;
+ clip.legacy = true;
+ if (loop)
+ clip.wrapMode = WrapMode.Loop;
+ GameObject animGo = animator.gameObject;
+ Animation animaton = animGo.GetComponent<Animation>();
+ if (animaton == null)
+ animaton = animGo.AddComponent<Animation>();
+ animaton.playAutomatically = true;
+ animaton.clip = clip;
+ animaton.cullingType = AnimationCullingType.BasedOnRenderers;
+ UnityEngine.Object.DestroyImmediate(animator);
+ }
+ else
+ {
+ break;
+ }
+
+ }
+
+ }
+ }
+
+ }
+ else
+ {
+ UnityEngine.Object.DestroyImmediate(animator);
+ }
+
+ }
+ PrefabUtility.ReplacePrefab(newGo, go, ReplacePrefabOptions.ReplaceNameBased);
+ GameObject.DestroyImmediate(newGo);
+ }
+ [MenuItem(@"Assets/Tool/Fx/ConvertAnimator2Legacy", false, 0)]
+ private static void ConvertAnimator2Legacy()
+ {
+ enumPrefab.cb = _ConvertAnimator2Legacy;
+ EnumAsset<GameObject>(enumPrefab, "ConvertAnimator2Legacy");
+ }
+
+ public static void GetAssetPath(string dir, List<string> assetPath)
+ {
+ DirectoryInfo di = new DirectoryInfo(dir);
+ FileInfo[] files = di.GetFiles("*.prefab", SearchOption.AllDirectories);
+ foreach (FileInfo fi in files)
+ {
+ string filePath = fi.FullName;
+ filePath = filePath.Replace("\\", "/");
+ int index = filePath.IndexOf("Assets/Resources/");
+ filePath = filePath.Substring(index);
+ assetPath.Add(filePath);
+ }
+ }
+ class AnimRefInfo
+ {
+ public GameObject go = null;
+ public string missingPath = null;
+ public int missingType = 0;//0 not found 1 deactive not found active
+ }
+
+ private static void FindAnimClip(GameObject instance, ref Transform clipTrans, ref AnimationClip clip)
+ {
+ Animator ator = instance.GetComponentInChildren<Animator>();
+ if (ator != null)
+ {
+ if (ator.avatar == null)
+ {
+ clipTrans = ator.transform;
+ UnityEditor.Animations.AnimatorController ac = ator.runtimeAnimatorController as UnityEditor.Animations.AnimatorController;
+ if (ac != null)
+ {
+ UnityEditor.Animations.AnimatorControllerLayer[] layers = ac.layers;
+ if (layers != null && layers.Length == 1)
+ {
+ UnityEditor.Animations.AnimatorControllerLayer acl = layers[0];
+ if (acl != null)
+ {
+ UnityEditor.Animations.AnimatorStateMachine asm = acl.stateMachine;
+ if (asm != null)
+ {
+ UnityEditor.Animations.AnimatorState defaultState = asm.defaultState;
+ if (defaultState != null)
+ {
+ clip = defaultState.motion as AnimationClip;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ else
+ {
+ Animation anim = instance.GetComponentInChildren<Animation>();
+ if (anim != null)
+ {
+ clipTrans = anim.transform;
+ clip = anim.clip;
+ }
+ }
+ }
+ private static bool CheckAnimRef(EditorCurveBinding[] curveBinding, Transform clipTrans, Transform currentTrans, ref AnimRefInfo ari)
+ {
+
+ if (curveBinding != null && clipTrans != null)
+ {
+ string path = currentTrans.name;
+ while (currentTrans.parent != null && clipTrans != currentTrans.parent)
+ {
+ currentTrans = currentTrans.parent;
+ path = string.Format("{0}/{1}", currentTrans.name, path);
+ }
+ for (int i = 0; i < curveBinding.Length; ++i)
+ {
+ var binding = curveBinding[i];
+ if (path == binding.path && binding.propertyName == "m_IsActive")
+ {
+ return true;
+ }
+
+ }
+ ari = new AnimRefInfo();
+ ari.missingPath = path;
+ return false;
+ }
+ return true;
+ }
+ private static void _FixAnimRef()
+ {
+
+ List<string> assetPath = ListPool<string>.Get();
+
+ Dictionary<string, List<string>> shareAnimFx = new Dictionary<string, List<string>>();
+ //Dictionary<string, List<AnimRefInfo>> missAimFx = new Dictionary<string, List<AnimRefInfo>>();
+ GetAssetPath("Assets/Resources/Effects", assetPath);
+ GetAssetPath("Assets/Resources/Prefabs/Bullets", assetPath);
+ GetAssetPath("Assets/Resources/Prefabs/Effects/Default", assetPath);
+ GetAssetPath("Assets/Resources/Prefabs/Effects/scene", assetPath);
+ for (int i = 0; i < assetPath.Count; ++i)
+ {
+ string path = assetPath[i];
+ EditorUtility.DisplayProgressBar(string.Format("{0}/{1}", i, assetPath.Count), path, (float)i / assetPath.Count);
+ GameObject prefab = AssetDatabase.LoadAssetAtPath(path, typeof(GameObject)) as GameObject;
+ if (prefab != null)
+ {
+ GameObject instance = GameObject.Instantiate<GameObject>(prefab);
+ Transform clipTrans = null;
+ AnimationClip clip = null;
+ FindAnimClip(instance, ref clipTrans, ref clip);
+ if (clip != null && clipTrans != null)
+ {
+ string animPath = AssetDatabase.GetAssetPath(clip);
+ List<string> fxList = null;
+ if (!shareAnimFx.TryGetValue(animPath, out fxList))
+ {
+ fxList = new List<string>();
+ shareAnimFx.Add(animPath, fxList);
+ }
+ fxList.Add(path);
+ }
+ GameObject.DestroyImmediate(instance);
+ }
+ }
+ for (int i = 0; i < assetPath.Count; ++i)
+ {
+ bool change = false;
+ errorLog = "";
+ string path = assetPath[i];
+ EditorUtility.DisplayProgressBar(string.Format("{0}/{1}", i, assetPath.Count), path, (float)i / assetPath.Count);
+ GameObject prefab = AssetDatabase.LoadAssetAtPath(path, typeof(GameObject)) as GameObject;
+ if (prefab != null)
+ {
+ GameObject instance = GameObject.Instantiate<GameObject>(prefab);
+ Transform clipTrans = null;
+ AnimationClip clip = null;
+ string animPath = "";
+ List<AnimRefInfo> missAnim = null;
+ List<string> fxList = null;
+ FindAnimClip(instance, ref clipTrans, ref clip);
+ EditorCurveBinding[] curveBinding = null;
+ if (clip != null && clipTrans != null)
+ {
+ animPath = AssetDatabase.GetAssetPath(clip);
+ shareAnimFx.TryGetValue(animPath, out fxList);
+
+ curveBinding = AnimationUtility.GetCurveBindings(clip);
+ for (int j = 0; j < curveBinding.Length; ++j)
+ {
+ var binding = curveBinding[j];
+ Transform t = clipTrans.Find(binding.path);
+ if (t == null)
+ {
+ if (missAnim == null)
+ {
+ missAnim = new List<AnimRefInfo>();
+ }
+ bool found = false;
+ for (int k = 0; k < missAnim.Count; ++k)
+ {
+ if(missAnim[k].missingPath== binding.path)
+ {
+ found = true;
+ break;
+ }
+ }
+ if(!found)
+ {
+ AnimRefInfo ari = new AnimRefInfo();
+ ari.missingPath = binding.path;
+ missAnim.Add(ari);
+ }
+ }
+ }
+ }
+
+ List<Renderer> renderLst = ListPool<Renderer>.Get();
+ instance.GetComponentsInChildren<Renderer>(true, renderLst);
+ for (int j = 0; j < renderLst.Count; ++j)
+ {
+ Renderer render = renderLst[j];
+ if (render != null)
+ {
+ if (!render.gameObject.activeSelf)
+ {
+ AnimRefInfo ari = null;
+ if (!CheckAnimRef(curveBinding, clipTrans, render.transform, ref ari))
+ {
+ if (missAnim == null)
+ {
+ missAnim = new List<AnimRefInfo>();
+ }
+ ari.go = render.gameObject;
+ ari.missingType = 1;
+ missAnim.Add(ari);
+ }
+ }
+ }
+ }
+ ListPool<Renderer>.Release(renderLst);
+
+ if (fxList != null && fxList.Count > 1 && missAnim != null)
+ {
+ errorLog += "共用animClip:\r\n";
+ for (int j = 0; j < fxList.Count; ++j)
+ {
+ errorLog += fxList[j] + "\r\n";
+ }
+ Debug.LogError(errorLog);
+ }
+ else if (missAnim != null && curveBinding != null && clip != null)
+ {
+ if (fxList != null&& fxList.Count>1)
+ {
+ errorLog += "共用animClip:\r\n";
+ for (int j = 0; j < fxList.Count; ++j)
+ {
+ errorLog += fxList[j] + "\r\n";
+ }
+ }
+ Debug.LogError("miss anim obj:" + errorLog + path);
+ if (needFix)
+ {
+ bool animChange = false;
+ for (int j = 0; j < missAnim.Count; ++j)
+ {
+ AnimRefInfo remove = missAnim[j];
+ if (remove != null)
+ {
+ for (int k = 0; k < curveBinding.Length; ++k)
+ {
+ var binding = curveBinding[k];
+ if (binding.path == remove.missingPath)
+ {
+ AnimationUtility.SetEditorCurve(clip, binding, null);
+ animChange = true;
+ }
+ }
+ if (remove.go != null)
+ {
+ GameObject.DestroyImmediate(remove.go);
+ change = true;
+ }
+ }
+ }
+ if (animChange)
+ {
+ CreateOrReplaceAsset<AnimationClip>(clip, animPath);
+ }
+ }
+
+ }
+ if (change && needFix)
+ PrefabUtility.ReplacePrefab(instance, prefab, ReplacePrefabOptions.ReplaceNameBased);
+ GameObject.DestroyImmediate(instance);
+ }
+ }
+
+ AssetDatabase.Refresh();
+ EditorUtility.ClearProgressBar();
+ EditorUtility.DisplayDialog("Finish", "All assets processed finish", "OK");
+ ListPool<string>.Release(assetPath);
+ }
+
+ [MenuItem(@"Assets/Tool/Fx/CheckAnim", false, 0)]
+ private static void CheckAnim()
+ {
+ needFix = false;
+ _FixAnimRef();
+ needFix = true;
+ }
+
+ [MenuItem(@"Assets/Tool/Fx/FixAnim", false, 0)]
+ private static void FixAnim()
+ {
+ needFix = true;
+ _FixAnimRef();
+ needFix = true;
+ }
+ #endregion
+ #region shader
+ class ShaderValue
+ {
+ public ShaderValue(string n, ShaderUtil.ShaderPropertyType t)
+ {
+ name = n;
+ type = t;
+ }
+ public string name = "";
+ public ShaderUtil.ShaderPropertyType type = ShaderUtil.ShaderPropertyType.Float;
+
+ public virtual void SetValue(Material mat)
+ {
+
+ }
+
+ public static void GetShaderValue(Material mat, List<ShaderValue> shaderValueLst)
+ {
+ Shader shader = mat.shader;
+ int count = ShaderUtil.GetPropertyCount(shader);
+ for (int i = 0; i < count; ++i)
+ {
+ ShaderValue sv = null;
+ string name = ShaderUtil.GetPropertyName(shader, i);
+ ShaderUtil.ShaderPropertyType type = ShaderUtil.GetPropertyType(shader, i);
+ switch (type)
+ {
+ case ShaderUtil.ShaderPropertyType.Color:
+ sv = new ShaderColorValue(name, type, mat);
+ break;
+ case ShaderUtil.ShaderPropertyType.Vector:
+ sv = new ShaderVectorValue(name, type, mat);
+ break;
+ case ShaderUtil.ShaderPropertyType.Float:
+ sv = new ShaderFloatValue(name, type, mat);
+ break;
+ case ShaderUtil.ShaderPropertyType.Range:
+ sv = new ShaderFloatValue(name, type, mat);
+ break;
+ case ShaderUtil.ShaderPropertyType.TexEnv:
+ sv = new ShaderTexValue(name, type, mat);
+ break;
+ }
+ shaderValueLst.Add(sv);
+ }
+ }
+ }
+
+ class ShaderIntValue : ShaderValue
+ {
+ public ShaderIntValue(string n, ShaderUtil.ShaderPropertyType t, Material mat)
+ : base(n, t)
+ {
+ value = mat.GetInt(n);
+ }
+ public int value = 0;
+ public override void SetValue(Material mat)
+ {
+ mat.SetInt(name, value);
+ }
+ }
+
+ class ShaderFloatValue : ShaderValue
+ {
+ public ShaderFloatValue(string n, ShaderUtil.ShaderPropertyType t, Material mat)
+ : base(n, t)
+ {
+ value = mat.GetFloat(n);
+ }
+ public float value = 0;
+ public override void SetValue(Material mat)
+ {
+ mat.SetFloat(name, value);
+ }
+ }
+
+ class ShaderVectorValue : ShaderValue
+ {
+ public ShaderVectorValue(string n, ShaderUtil.ShaderPropertyType t, Material mat)
+ : base(n, t)
+ {
+ value = mat.GetVector(n);
+ }
+ public Vector4 value = Vector4.zero;
+ public override void SetValue(Material mat)
+ {
+ mat.SetVector(name, value);
+ }
+ }
+ class ShaderColorValue : ShaderValue
+ {
+ public ShaderColorValue(string n, ShaderUtil.ShaderPropertyType t, Material mat)
+ : base(n, t)
+ {
+ value = mat.GetColor(n);
+ }
+ public Color value = Color.black;
+ public override void SetValue(Material mat)
+ {
+ mat.SetColor(name, value);
+ }
+ }
+ class ShaderTexValue : ShaderValue
+ {
+ public ShaderTexValue(string n, ShaderUtil.ShaderPropertyType t, Material mat)
+ : base(n, t)
+ {
+ value = mat.GetTexture(n);
+ offset = mat.GetTextureOffset(n);
+ scale = mat.GetTextureScale(n);
+ }
+ public Texture value = null;
+ public Vector2 offset = Vector2.zero;
+ public Vector2 scale = Vector2.one;
+
+ public override void SetValue(Material mat)
+ {
+ mat.SetTexture(name, value);
+ mat.SetTextureOffset(name, offset);
+ mat.SetTextureScale(name, scale);
+ }
+ }
+ [MenuItem(@"Assets/Tool/Shader/BuildBundle")]
+ private static void BuildBundle()
+ {
+ string targetDir = null;
+ if (EditorUserBuildSettings.activeBuildTarget == BuildTarget.Android)
+ {
+ targetDir = string.Format("Assets/StreamingAssets/update/Android/AssetBundles/");
+ }
+ else if (EditorUserBuildSettings.activeBuildTarget == BuildTarget.iOS)
+ {
+ targetDir = string.Format("Assets/StreamingAssets/update/iOS/AssetBundles/");
+ }
+ else if (EditorUserBuildSettings.activeBuildTarget == BuildTarget.StandaloneWindows)
+ {
+ targetDir = string.Format("Assets/StreamingAssets/update/AssetBundles/");
+ }
+ else
+ {
+ return;
+ }
+
+ string[] shaderPath = new string[] {
+ "Assets/Resources/Shader/Skin/Skin-Effect.shader",
+ "Assets/Resources/Shader/Skin/Skin-RimLightBlend8.shader",
+ "Assets/Resources/Shader/Skin/Skin-RimLightBlend.shader",
+ "Assets/Resources/Shader/Skin/Skin-RimLightBlendCutout.shader",
+ "Assets/Resources/Shader/Skin/Skin-RimLightBlendCutout4.shader",
+ "Assets/Resources/Shader/Common/FadeMaskRNoLight.shader",
+ "Assets/Resources/Shader/Common/TransparentGrayMaskRNoLight.shader",
+ "Assets/Resources/Shader/Shadow/CustomShadowR.shader",
+ "Assets/Resources/Shader/PostEffects/RadialBlur.shader",
+ "Assets/Resources/Shader/PostEffects/BlackWhite.shader",
+ "Assets/Resources/Shader/PostEffects/BlurEffectConeTaps.shader",
+ "Assets/Resources/Shader/NGUI/SeparateColorAlpha.shader",
+ "Assets/Resources/Shader/NGUI/Text.shader",
+ "Assets/Resources/Shader/NGUI/Additive.shader",
+ "Assets/Resources/Shader/NGUI/ColorTexture.shader",
+ "Assets/Resources/Shader/NGUI/RGBA.shader",
+ "Assets/Resources/Shader/NGUI/Mask.shader",
+ "Assets/Resources/Shader/NGUI/RenderTexture.shader",
+ "Assets/Resources/Shader/NGUI/WhiteAnim.shader",
+ "Assets/Resources/Shader/NGUI/TextureList2.shader",
+ "Assets/Resources/Shader/NGUI/TextureList4.shader",
+ "Assets/Resources/Shader/NGUI/Merge.shader",
+ "Assets/Resources/Shader/FxPro/BloomPro.shader",
+ "Assets/Resources/Shader/FxPro/DOFPro.shader",
+ "Assets/Resources/Shader/FxPro/FxPro.shader",
+ "Assets/Resources/Shader/FxPro/FxProTap.shader",
+ "Assets/Resources/Shader/FxPro/MobileDOFPro.shader"};
+
+ AssetBundleBuild abb;
+ abb.assetBundleName = "shaders.ab";
+ abb.assetBundleVariant = "";
+ abb.assetNames = shaderPath;
+ testAnimBundle[0] = abb;
+ BuildPipeline.BuildAssetBundles(targetDir, testAnimBundle, BuildAssetBundleOptions.DeterministicAssetBundle | BuildAssetBundleOptions.UncompressedAssetBundle, EditorUserBuildSettings.activeBuildTarget);
+
+
+ }
+
+ #endregion
+ #region Table
+ public static void PostImportAssets(string[] importedAssets, string[] deletedAssets, bool warning)
+ {
+ bool deal = false;
+ string tables = "";
+ if (importedAssets != null)
+ {
+ for (int i = 0; i < importedAssets.Length; ++i)
+ {
+ string path = importedAssets[i];
+ string tableName = GetTableName(path);
+ if (tableName != "")
+ {
+ tables += tableName + " ";
+ }
+ }
+ if (tables != "")
+ {
+ ExeTable2Bytes(tables);
+ deal = true;
+ }
+
+ }
+ for (int i = 0; i < deletedAssets.Length; ++i)
+ {
+ string tableName = GetTableName(deletedAssets[i]);
+
+ if (tableName != "")
+ {
+ string des = "Assets/Resources/Table/" + tableName + ".bytes";
+ if (File.Exists(des))
+ {
+ File.Delete(des);
+ deal = true;
+ }
+ }
+ }
+ if (deal)
+ {
+ AssetDatabase.Refresh();
+ }
+ }
+ private static string GetTableName(string tablePath)
+ {
+ if (tablePath.StartsWith("Assets/Table/") && tablePath.EndsWith(".txt"))
+ {
+ string tableName = tablePath.Replace("Assets/Table/", "");
+ tableName = tableName.Replace(".txt", "");
+ return tableName.Replace("\\", "/");
+ }
+ return "";
+ }
+ private static string GetTableName(UnityEngine.Object target)
+ {
+ return GetTableName(AssetDatabase.GetAssetPath(target));
+ }
+
+ private static void ExeTable2Bytes(string tables, string arg0 = "-q -tables ")
+ {
+#if UNITY_EDITOR_WIN
+ System.Diagnostics.Process exep = new System.Diagnostics.Process();
+ exep.StartInfo.FileName = @"..\XProject\Shell\Table2Bytes.exe";
+ exep.StartInfo.Arguments = arg0 + tables;
+ exep.StartInfo.CreateNoWindow = true;
+ exep.StartInfo.UseShellExecute = false;
+ exep.StartInfo.RedirectStandardOutput = true;
+ exep.StartInfo.StandardOutputEncoding = System.Text.Encoding.Default;
+ exep.Start();
+ string output = exep.StandardOutput.ReadToEnd();
+ exep.WaitForExit();
+ if (output != "")
+ {
+ int errorIndex = output.IndexOf("error:");
+ if(errorIndex>=0)
+ {
+ string errorStr = output.Substring(errorIndex);
+ Debug.LogError(errorStr);
+ Debug.Log(output.Substring(0, errorIndex));
+ }
+ else
+ {
+ Debug.Log(output);
+ }
+ }
+ AssetDatabase.Refresh();
+#endif
+ }
+
+ public static void Table2Bytes(UnityEngine.Object target)
+ {
+#if UNITY_EDITOR_WIN
+ string tableName = GetTableName(target);
+ if (tableName != "")
+ {
+ ExeTable2Bytes(tableName);
+ }
+ EditorUtility.DisplayDialog("Finish", "All tables processed finish", "OK");
+#endif
+ }
+ public static void Bytes2Txt(UnityEngine.Object target)
+ {
+#if UNITY_EDITOR_WIN
+ string tableName = GetTableName(target);
+ if (tableName != "")
+ {
+ ExeTable2Bytes(tableName);
+ }
+ EditorUtility.DisplayDialog("Finish", "All tables processed finish", "OK");
+#endif
+ }
+ public static void Table2Bytes(UnityEngine.Object[] targets)
+ {
+#if UNITY_EDITOR_WIN
+ if (targets != null)
+ {
+ string tables = "";
+ for (int i = 0; i < targets.Length; ++i)
+ {
+ string tableName = AssetDatabase.GetAssetPath(targets[i]);
+ if (tableName != "")
+ {
+ tables += tableName + " ";
+ }
+ }
+ if (tables != "")
+ {
+ ExeTable2Bytes(tables);
+ }
+ }
+ EditorUtility.DisplayDialog("Finish", "All tables processed finish", "OK");
+#endif
+ }
+ public static void AllTable2Bytes()
+ {
+ ExeTable2Bytes("");
+ EditorUtility.DisplayDialog("Finish", "All tables processed finish", "OK");
+ }
+ #endregion
+ #region res
+ [MenuItem(@"Assets/Tool/Res/FindAsset", false, 0)]
+ private static void FindAsset()
+ {
+ AssetFindEditor window = EditorWindow.GetWindow<AssetFindEditor>("查找资源", true);
+ window.position = new Rect(100, 100, 1200, 800);
+ }
+
+ [MenuItem(@"Assets/Tool/Res/LowPolygon", false, 0)]
+ private static void LowPolygon()
+ {
+ //Vector3[] oldVerts = mesh.vertices;
+ //Vector4[] oldTangents = mesh.tangents;
+ //Vector2[] oldUVs = mesh.uv;
+ //int[] triangles = mesh.triangles;
+ //Vector3[] newVerts = new Vector3[triangles.Length];
+ //Vector4[] newTangents = new Vector4[triangles.Length];
+ //Vector2[] newUVs = new Vector2[triangles.Length];
+ //for (int i = 0; i < triangles.Length; i++)
+ //{
+ // newVerts[i] = oldVerts[triangles[i]];
+ // newTangents[i] = oldTangents[triangles[i]];
+ // newUVs[i] = oldUVs[triangles[i]];
+ // triangles[i] = i;
+ //}
+ //mesh.vertices = newVerts;
+ //mesh.tangents = newTangents;
+ //mesh.triangles = triangles;
+ //mesh.uv = newUVs;
+ //mesh.RecalculateBounds();
+ //mesh.RecalculateNormals();
+ }
+ #endregion
+
+ #region utility
+ public static string GetFolder(string path)
+ {
+ path = path.Replace("\\", "/");
+ int index = path.LastIndexOf("/");
+ if(index>=0)
+ {
+ path = path.Substring(0, index);
+ }
+ return path;
+ }
+
+ public static string MakeAssetPath(string path,string newName,string ext)
+ {
+ path = GetFolder(path);
+ return string.Format("{0}/{1}.{2}", path, newName, ext);
+ }
+ public static string MakeAssetPathWithFolder(string path, string newName, string ext)
+ {
+ return string.Format("{0}/{1}.{2}", path, newName, ext);
+ }
+ #endregion
+ [MenuItem(@"Assets/Tool/Test/Test", false, 0)]
+ private static void Test()
+ {
+ string shaderTmpDir = @"..\XProject\ShaderTmp";
+ if (Directory.Exists(shaderTmpDir))
+ {
+ Directory.Delete(@"..\XProject\ShaderTmp", true);
+ }
+ Directory.CreateDirectory(shaderTmpDir);
+ string shaderDir = "XProject/Shader/Scene";
+ string replaceShaderDir = "Assets/Resources/Shader/Scene";
+ DirectoryInfo shaderReplaceDir = new DirectoryInfo(@"..\XProject\Shader\Scene");
+ FileInfo[] files = shaderReplaceDir.GetFiles("*.shader", SearchOption.AllDirectories);
+ for (int i = 0; i < files.Length; ++i)
+ {
+ FileInfo fi = files[i];
+ string path = fi.FullName.Replace("\\", "/");
+ int index = path.IndexOf(shaderDir);
+ string shaderPath = path.Substring(index + shaderDir.Length);
+ string replaceShaderPath = replaceShaderDir + shaderPath;
+ string tmpShaderPath = shaderTmpDir + shaderPath;
+ Debug.LogWarning(tmpShaderPath);
+ File.Copy(replaceShaderPath, tmpShaderPath);
+ }
+ }
+ }
+ public class PlayStateChange
+ {
+ private bool init = false;
+ private bool isPlaying = false;
+ public bool isStateChange = false;
+ public bool Update()
+ {
+ if(init)
+ {
+ isStateChange = isPlaying!= Application.isPlaying;
+ isPlaying = Application.isPlaying;
+ }
+ else
+ {
+ isPlaying = Application.isPlaying;
+ isStateChange = true;
+ init = true;
+ }
+ return isStateChange;
+ }
+ public void PostUpdate()
+ {
+ isStateChange = false;
+ }
+ }
+ public class ModelBone
+ {
+ public bool Check = false;
+ public string BoneName = "";
+ public string Path = "";
+ public ModelBone Parent = null;
+ public List<ModelBone> Child = new List<ModelBone>();
+ }
+
+ public class SelectBones : EditorWindow
+ {
+ protected GameObject model = null;
+ protected string prefabName = "";
+
+ //protected bool isReadable = false;
+ protected bool checkAll = false;
+ protected GameObject newGo = null;
+
+ protected List<string> exposedBones = new List<string>();
+ protected List<string> exExposedBones = new List<string>();
+ protected ModelBone root = new ModelBone();
+ protected ModelImporter modelImporter;
+ protected string path = "";
+ protected Vector2 scrollPos = Vector2.zero;
+ protected string creatorFolderName = "";
+ protected bool gameResource = true;
+ protected string prefabRootPath = "Assets/Resources/Prefabs/";
+ public virtual void Init()
+ {
+ UnityEngine.Object[] objs = Selection.GetFiltered(typeof(GameObject), SelectionMode.DeepAssets);
+ if (objs != null && objs.Length > 0)
+ {
+ model = objs[0] as GameObject;
+ path = "";
+ if (model != null)
+ {
+ path = AssetDatabase.GetAssetPath(model);
+ modelImporter = AssetImporter.GetAtPath(path) as ModelImporter;
+ //revert to default
+ modelImporter.optimizeGameObjects = false;
+ modelImporter.extraExposedTransformPaths = null;
+ AssetDatabase.ImportAsset(path, ImportAssetOptions.ForceUpdate);
+ if (prefabName == "")
+ {
+ prefabName = model.name.ToLower();
+ int index = prefabName.IndexOf("_bandpose");
+ if (index >= 0)
+ {
+ prefabName = prefabName.Substring(0, index);
+ }
+ }
+ FilterBone();
+ }
+ }
+ AssetDatabase.Refresh();
+ }
+ public void AddExExposeBone(string bone)
+ {
+ if (!exExposedBones.Contains(bone))
+ exExposedBones.Add(bone);
+ }
+ protected virtual void FilterBone()
+ {
+ //find skill bone
+ SearchSkill(model, path, exposedBones);
+ //find bone Hierarchy
+ root.BoneName = model.name;
+ FindModelBones(model.transform, "", root);
+ }
+
+
+ private void SearchSkill(GameObject go, string fbxfilename, List<string> bones)
+ {
+ string assetPath = "";
+ if (creatorFolderName != "")
+ {
+ assetPath = Application.dataPath + "/Resources/SkillPackage/" + creatorFolderName;
+ }
+ else
+ {
+ string foldername = System.IO.Path.GetDirectoryName(fbxfilename);
+ assetPath = Application.dataPath + "/Resources/SkillPackage/" + System.IO.Path.GetFileName(foldername);
+ }
+
+
+ if (!Directory.Exists(assetPath))
+ return;
+
+ DirectoryInfo di = new DirectoryInfo(assetPath);
+
+ FileInfo[] fis = di.GetFiles("*.txt");
+
+ foreach (FileInfo s in fis)
+ {
+ XSkillData skill = XDataIO<XSkillData>.singleton.DeserializeData(s.FullName);
+ foreach (XFxData fx in skill.Fx)
+ {
+ if (!string.IsNullOrEmpty(fx.Bone))
+ {
+ string boneName = fx.Bone;
+ if (go.transform.Find(boneName) != null && !bones.Contains(boneName))
+ {
+ bones.Add(boneName);
+ Debug.Log(string.Format("Skill:{0} Bone:{1}", s.Name, fx.Bone));
+ }
+
+ }
+ }
+ }
+
+ return;
+ }
+
+ private ModelBone FindModelBones(Transform t, string parentPath, ModelBone parent)
+ {
+ ModelBone modelBone = null;
+ if (t != model.transform)
+ {
+ modelBone = new ModelBone();
+ }
+ if (modelBone != null)
+ {
+ //SkinnedMeshRenderer skin = t.GetComponent<SkinnedMeshRenderer>();
+ //MeshRenderer mesh = t.GetComponent<MeshRenderer>();
+ modelBone.BoneName = t.name;
+ modelBone.Path = parentPath + t.name;
+ modelBone.Check = exposedBones.Contains(modelBone.Path) || exExposedBones.Contains(t.name);
+ modelBone.Parent = parent;
+ }
+ if (t != model.transform)
+ parentPath = parentPath + t.name + "/";
+ for (int i = 0; i < t.childCount; ++i)
+ {
+ ModelBone childModelBone = FindModelBones(t.GetChild(i), parentPath, modelBone);
+ if (modelBone != null)
+ modelBone.Child.Add(childModelBone);
+ else
+ parent.Child.Add(childModelBone);
+ }
+ return modelBone;
+ }
+
+ private void FindComponentSkinnedMesh(Transform t, List<SkinnedMeshRenderer> components)
+ {
+ SkinnedMeshRenderer comp = t.GetComponent<SkinnedMeshRenderer>();
+ if (comp != null)
+ {
+ components.Add(comp);
+ }
+ for (int i = 0; i < t.childCount; ++i)
+ {
+ FindComponentSkinnedMesh(t.GetChild(i), components);
+ }
+ }
+
+ private void FindComponentMesh(Transform t, List<MeshRenderer> components)
+ {
+ MeshRenderer comp = t.GetComponent<MeshRenderer>();
+ if (comp != null)
+ {
+ components.Add(comp);
+ }
+ for (int i = 0; i < t.childCount; ++i)
+ {
+ FindComponentMesh(t.GetChild(i), components);
+ }
+ }
+
+ private void DrawTree(ModelBone modelBone, int depth)
+ {
+ GUILayout.BeginHorizontal();
+ for (int i = 0; i < depth; ++i)
+ GUILayout.Label(" ", GUILayout.ExpandWidth(false));
+ modelBone.Check = EditorGUILayout.Toggle(modelBone.Check, GUILayout.Width(30));
+ GUILayout.Label(modelBone.BoneName, GUILayout.ExpandWidth(false));
+ GUILayout.EndHorizontal();
+ for (int i = 0; i < modelBone.Child.Count; ++i)
+ {
+ DrawTree(modelBone.Child[i], depth + 1);
+ }
+ }
+
+ private void ExposedBone(ModelBone modelBone)
+ {
+ if (modelBone.Check && !exposedBones.Contains(modelBone.Path))
+ {
+ exposedBones.Add(modelBone.Path);
+ }
+ for (int i = 0; i < modelBone.Child.Count; ++i)
+ {
+ ExposedBone(modelBone.Child[i]);
+ }
+ }
+
+ private void SetLayer(Transform t, int layer)
+ {
+ t.gameObject.layer = layer;
+ for (int i = 0; i < t.childCount; ++i)
+ {
+ SetLayer(t.GetChild(i), layer);
+ }
+ }
+
+ private bool CopyValue<T>(GameObject srcGO, GameObject destGO) where T : Component
+ {
+ T srcCC = srcGO.GetComponent<T>();
+ if (srcCC == null)
+ return false;
+
+ T destCC = destGO.GetComponent<T>();
+ if (destCC == null)
+ destCC = destGO.AddComponent<T>();
+
+ UnityEditorInternal.ComponentUtility.CopyComponent(srcCC);
+ UnityEditorInternal.ComponentUtility.PasteComponentValues(destCC);
+
+ return true;
+ }
+
+ private void CheckAll(ModelBone modelBone)
+ {
+ modelBone.Check = checkAll;
+ for (int i = 0; i < modelBone.Child.Count; ++i)
+ {
+ CheckAll(modelBone.Child[i]);
+ }
+ }
+ protected virtual void MakeGameObject()
+ {
+ ExposedBone(root);
+ if (checkAll)
+ {
+ modelImporter.optimizeGameObjects = false;
+ modelImporter.isReadable = false;
+ }
+ else
+ {
+ modelImporter.optimizeGameObjects = true;
+ modelImporter.isReadable = false;
+ modelImporter.extraExposedTransformPaths = exposedBones.ToArray();
+ }
+ AssetDatabase.ImportAsset(path, ImportAssetOptions.ForceUpdate);
+
+ List<SkinnedMeshRenderer> srcSkins = new List<SkinnedMeshRenderer>();
+ List<MeshRenderer> srcMeshs = new List<MeshRenderer>();
+
+
+ string prefabPath = prefabRootPath + prefabName + ".prefab";
+
+ GameObject srcPrefab = (GameObject)AssetDatabase.LoadAssetAtPath(prefabPath, typeof(GameObject));
+ if (srcPrefab != null)
+ {
+ FindComponentSkinnedMesh(srcPrefab.transform, srcSkins);
+ FindComponentMesh(srcPrefab.transform, srcMeshs);
+ }
+
+ newGo = UnityEngine.Object.Instantiate(model) as GameObject;
+ if (newGo != null)
+ {
+ newGo.name = prefabName;
+ List<SkinnedMeshRenderer> skins = new List<SkinnedMeshRenderer>();
+ FindComponentSkinnedMesh(newGo.transform, skins);
+ foreach (SkinnedMeshRenderer skin in skins)
+ {
+ AssetModify.ProcessSkinMesh(skin);
+ }
+ List<MeshRenderer> meshs = new List<MeshRenderer>();
+ FindComponentMesh(newGo.transform, meshs);
+ foreach (MeshRenderer mesh in meshs)
+ {
+ AssetModify.ProcessRender(mesh);
+ }
+ Animator srcAni = null;
+ if (srcPrefab != null)
+ {
+ CopyValue<CharacterController>(srcPrefab, newGo);
+ if (CopyValue<BoxCollider>(srcPrefab, newGo))
+ {
+ CopyValue<Rigidbody>(srcPrefab, newGo);
+ }
+ SetLayer(newGo.transform, srcPrefab.layer);
+ srcAni = srcPrefab.GetComponent<Animator>();
+ for (int i = 0; i < srcPrefab.transform.childCount; ++i)
+ {
+ Transform child = srcPrefab.transform.GetChild(i);
+ if (child.name.ToLower() == "hugemonstercolliders")
+ {
+ GameObject childGo = GameObject.Instantiate(child.gameObject) as GameObject;
+ childGo.name = "HugeMonsterColliders";
+ childGo.SetActive(false);
+ childGo.transform.parent = newGo.transform;
+ }
+ else if (child.name.StartsWith("Ty_"))
+ {
+ GameObject childGo = GameObject.Instantiate(child.gameObject) as GameObject;
+ childGo.name = child.name;
+ childGo.transform.parent = newGo.transform;
+ }
+ }
+ UnityEditor.Selection.activeObject = srcPrefab;
+ }
+ Animator desAni = newGo.GetComponent<Animator>();
+ if (desAni != null)
+ {
+ if (srcAni != null && srcAni.runtimeAnimatorController != null)
+ {
+ desAni.runtimeAnimatorController = Resources.Load("Controller/" + srcAni.runtimeAnimatorController.name) as RuntimeAnimatorController;
+ }
+ else
+ {
+ desAni.runtimeAnimatorController = Resources.Load("Controller/XAnimator") as RuntimeAnimatorController;
+ }
+ }
+ AssetModify.FixPrefab(prefabPath, newGo, true);
+ }
+ }
+
+ protected virtual void OnGUI()
+ {
+ scrollPos = GUILayout.BeginScrollView(scrollPos, GUILayout.ExpandWidth(true));
+ DrawTree(root, 0);
+ GUILayout.EndScrollView();
+ prefabName = EditorGUILayout.TextField("Prefab Name", prefabName);
+ //isReadable = EditorGUILayout.ToggleLeft("Is Readable", isReadable);
+ bool beforeCheck = checkAll;
+ checkAll = EditorGUILayout.ToggleLeft("Check All", checkAll);
+ if (beforeCheck != checkAll)
+ {
+ CheckAll(root);
+ }
+ gameResource = EditorGUILayout.ToggleLeft("Game Resource", gameResource);
+ if (GUILayout.Button("OK", GUILayout.ExpandWidth(false)))
+ {
+ MakeGameObject();
+
+ this.Close();
+ }
+ if (GUILayout.Button("Cancel", GUILayout.ExpandWidth(false)))
+ {
+ this.Close();
+ }
+ }
+ }
+
+ public class SelectEquipBones : SelectBones
+ {
+ private string spritePoint = "sprite";
+ private bool selectChar = false;
+ private string charPrefab = "";
+ private string selectCharPrefab = "";
+ private CombineConfig combineConfig = null;
+ public override void Init()
+ {
+ combineConfig = CombineConfig.GetConfig();
+ base.Init();
+ }
+ protected override void FilterBone()
+ {
+ if (model != null)
+ {
+ TextAsset ta = Resources.Load<TextAsset>(@"Table/DefaultEquip");
+ if (ta != null)
+ {
+ DefaultEquip de = new DefaultEquip();
+ XBinaryReader.Init();
+ XBinaryReader reader = XBinaryReader.Get();
+ reader.Init(ta);
+ //using (MemoryStream ms = new System.IO.MemoryStream(ta.bytes))
+ {
+ de.ReadFile(reader);
+ int id = 0;
+ for (int i = 0; i < combineConfig.BandposeName.Length; ++i)
+ {
+ if (model.name.ToLower() == combineConfig.BandposeName[i].ToLower())
+ {
+ id = i + 1;
+ prefabName = combineConfig.PrefabName[i];
+ charPrefab = prefabName;
+ selectCharPrefab = combineConfig.CreateCharPrefabName[i];
+ creatorFolderName = combineConfig.SkillFolderName[i];
+ }
+ }
+ if (id > 0)
+ {
+ DefaultEquip.RowData data = de.GetByProfID(id);
+ if (data != null)
+ {
+ AddExExposeBone(data.WingPoint);
+ AddExExposeBone(data.TailPoint);
+ if (data.WeaponPoint != null && data.WeaponPoint.Length > 0)
+ AddExExposeBone(data.WeaponPoint[0]);
+ if (data.WeaponPoint != null && data.WeaponPoint.Length > 1)
+ AddExExposeBone(data.WeaponPoint[1]);
+ AddExExposeBone(data.FishingPoint);
+ AddExExposeBone(data.FishingPoint);
+ }
+ }
+ }
+ XBinaryReader.Return(reader);
+ }
+ }
+ //isReadable = false;
+ base.FilterBone();
+ }
+
+ protected override void MakeGameObject()
+ {
+ if (!gameResource)
+ prefabRootPath = "Assets/Editor/EditorResources/Prefabs/";
+ base.MakeGameObject();
+ if (newGo != null)
+ {
+ GameObject spriteGo = new GameObject(spritePoint);
+ spriteGo.transform.parent = newGo.transform;
+ spriteGo.layer = newGo.layer;
+ if (gameResource)
+ {
+ int count = newGo.transform.childCount;
+ for (int i = count - 1; i >= 0; --i)
+ {
+ Transform child = newGo.transform.GetChild(i);
+ if (child.GetComponent<SkinnedMeshRenderer>() != null ||
+ child.GetComponent<MeshRenderer>() != null)
+ {
+ GameObject.DestroyImmediate(child.gameObject);
+ }
+ }
+
+ SkinnedMeshRenderer smr = newGo.GetComponent<SkinnedMeshRenderer>();
+ if (smr == null)
+ smr = newGo.AddComponent<SkinnedMeshRenderer>();
+ AssetModify.ProcessSkinMesh(smr);
+ smr.rootBone = newGo.transform;
+ smr.localBounds = new Bounds(new Vector3(0, 0.5f, 0), new Vector3(0.5f, 1.0f, 0.5f));
+ newGo.layer = newGo.layer;
+ }
+ AssetModify.FixPrefab(prefabRootPath + prefabName + ".prefab", newGo, true);
+ }
+ }
+ protected override void OnGUI()
+ {
+ bool select = EditorGUILayout.ToggleLeft("Is Select Char", selectChar);
+ if (select != selectChar)
+ {
+ selectChar = select;
+ prefabName = selectChar ? selectCharPrefab : charPrefab;
+
+ }
+ base.OnGUI();
+ }
+ }
+ public class TextureStatis : EditorWindow
+ {
+ //class TextureInfo
+ //{
+ // public Texture tex;
+ // public GameObject go;
+ //}
+ private Vector2 scrollPosition = Vector2.zero;
+ private List<Texture> textures = new List<Texture>();
+ private List<UISprite> sprite = new List<UISprite>();
+ private List<UITexture> texs = new List<UITexture>();
+ //private List<UITexture> texs = new List<UITexture>();
+ public void ScanGameObject()
+ {
+ textures.Clear();
+ GameObject go = Selection.activeGameObject;
+ if (go != null)
+ {
+ sprite.Clear();
+ go.GetComponentsInChildren<UISprite>(true, sprite);
+ foreach (UISprite s in sprite)
+ {
+ if (s != null && s.atlas != null && !textures.Contains(s.atlas.texture))
+ {
+ textures.Add(s.atlas.texture);
+ }
+ }
+ texs.Clear();
+ go.GetComponentsInChildren<UITexture>(true, texs);
+ foreach (UITexture t in texs)
+ {
+ if (t != null && t.mainTexture != null && !textures.Contains(t.mainTexture))
+ textures.Add(t.mainTexture);
+ }
+ }
+ }
+
+ private void OnGUI()
+ {
+ GUILayout.BeginHorizontal();
+
+ if (GUILayout.Button("Scan", GUILayout.MaxWidth(150)))
+ {
+ ScanGameObject();
+ }
+ GUILayout.EndHorizontal();
+ scrollPosition = GUILayout.BeginScrollView(scrollPosition, false, false);
+
+ for (int i = 0; i < textures.Count; ++i)
+ {
+ Texture tex = textures[i];
+ GUILayout.BeginHorizontal();
+ EditorGUILayout.ObjectField(tex.name, tex, typeof(Texture2D), true, GUILayout.MaxWidth(250));
+ GUILayout.EndHorizontal();
+
+ }
+ EditorGUILayout.EndScrollView();
+ }
+ }
+
+ public class TextureCommonCompress : EditorWindow
+ {
+ public enum ETextureSize
+ {
+ X32 = 32,
+ X64 = 64,
+ X128 = 128,
+ X256 = 256,
+ X512 = 512,
+ X1024 = 1024,
+
+ }
+ public enum ETextureCompress
+ {
+ ECompress,
+ E16,
+ E32,
+ EA8
+ }
+ protected ETextureSize compressSize = ETextureSize.X64;
+ protected TextureImporterFormat iosFormat = TextureImporterFormat.PVRTC_RGB4;
+ protected TextureImporterFormat androidFormat = TextureImporterFormat.ETC_RGB4;
+ protected ETextureCompress compressType = ETextureCompress.ECompress;
+ protected bool genMipmap = false;
+ protected TextureWrapMode wrapMode = TextureWrapMode.Repeat;
+ protected bool genAlpha = false;
+ protected bool genRAlpha = true;
+ protected ETextureSize alphaSize = ETextureSize.X64;
+
+ private bool _TextureCompress(Texture2D tex, TextureImporter textureImporter, string path)
+ {
+ textureImporter.textureType = TextureImporterType.Default;
+ textureImporter.anisoLevel = 0;
+ textureImporter.filterMode = FilterMode.Bilinear;
+ textureImporter.isReadable = false;
+ textureImporter.wrapMode = wrapMode;
+ textureImporter.mipmapEnabled = genMipmap;
+ switch (compressType)
+ {
+ case ETextureCompress.ECompress:
+ iosFormat = TextureImporterFormat.PVRTC_RGB4;
+ androidFormat = TextureImporterFormat.ETC_RGB4;
+ break;
+ case ETextureCompress.E16:
+ if (AssetModify.HasAlpha(tex, textureImporter))
+ {
+ iosFormat = TextureImporterFormat.RGBA32;
+ androidFormat = TextureImporterFormat.RGBA16;
+ }
+ else
+ {
+ iosFormat = TextureImporterFormat.RGB24;
+ androidFormat = TextureImporterFormat.RGB16;
+ }
+ break;
+ case ETextureCompress.E32:
+ if (AssetModify.HasAlpha(tex, textureImporter))
+ {
+ iosFormat = TextureImporterFormat.RGBA32;
+ androidFormat = TextureImporterFormat.RGBA32;
+ }
+ else
+ {
+ iosFormat = TextureImporterFormat.RGB24;
+ androidFormat = TextureImporterFormat.RGB24;
+ }
+ break;
+ case ETextureCompress.EA8:
+ iosFormat = TextureImporterFormat.Alpha8;
+ androidFormat = TextureImporterFormat.Alpha8;
+ break;
+ }
+ AssetModify.SetTexImportSetting(textureImporter, "Standalone", (int)compressSize, genAlpha ? TextureImporterFormat.DXT5 : TextureImporterFormat.DXT1);
+
+ if (genAlpha)
+ {
+ int extIndex = path.LastIndexOf(".");
+ if (extIndex >= 0)
+ {
+ string alphaTexPath = path.Substring(0, extIndex) + "_A.png";
+
+ if (genRAlpha)
+ {
+ AssetModify.SetTexImportSetting(textureImporter, BuildTarget.Android.ToString(), (int)compressSize, TextureImporterFormat.RGBA32);
+ AssetModify.SetTexImportSetting(textureImporter, "iPhone", (int)compressSize, TextureImporterFormat.RGBA32);
+ textureImporter.isReadable = true;
+ AssetDatabase.ImportAsset(path, ImportAssetOptions.ForceUpdate);
+ AssetModify.MakeAlphaRTex(alphaTexPath, (int)alphaSize, tex);
+ AssetModify.SetTexImportSetting(textureImporter, BuildTarget.Android.ToString(), (int)compressSize, androidFormat);
+ AssetModify.SetTexImportSetting(textureImporter, "iPhone", (int)compressSize, iosFormat);
+ textureImporter.isReadable = false;
+ AssetDatabase.ImportAsset(path, ImportAssetOptions.ForceUpdate);
+ }
+ else
+ {
+ File.Copy(path, alphaTexPath, true);
+ AssetDatabase.ImportAsset(alphaTexPath, ImportAssetOptions.ForceUpdate);
+ TextureImporter alphaTextureImporter = AssetImporter.GetAtPath(alphaTexPath) as TextureImporter;
+ if (alphaTextureImporter != null)
+ {
+ alphaTextureImporter.textureType = TextureImporterType.Default;
+ alphaTextureImporter.anisoLevel = 0;
+ alphaTextureImporter.mipmapEnabled = false;
+ alphaTextureImporter.isReadable = false;
+ alphaTextureImporter.npotScale = TextureImporterNPOTScale.ToNearest;
+ AssetModify.SetTexImportSetting(alphaTextureImporter, BuildTarget.Android.ToString(), (int)alphaSize, TextureImporterFormat.Alpha8);
+ AssetModify.SetTexImportSetting(alphaTextureImporter, "iPhone", (int)alphaSize, TextureImporterFormat.Alpha8);
+ AssetDatabase.ImportAsset(alphaTexPath, ImportAssetOptions.ForceUpdate);
+ }
+ }
+ }
+ }
+ return true;
+
+ }
+ private void Compress()
+ {
+ AssetModify.enumTex2D.cb = _TextureCompress;
+ AssetModify.EnumAsset<Texture2D>(AssetModify.enumTex2D, "TextureCompress");
+ }
+ private void OnGUI()
+ {
+ //GUILayout.BeginHorizontal();
+
+ if (GUILayout.Button("Compress", GUILayout.MaxWidth(150)))
+ {
+ Compress();
+ }
+
+ compressSize = (ETextureSize)EditorGUILayout.EnumPopup("缩放", compressSize);
+ compressType = (ETextureCompress)EditorGUILayout.EnumPopup("压缩格式", compressType);
+ wrapMode = (TextureWrapMode)EditorGUILayout.EnumPopup("采样模式", wrapMode);
+ genMipmap = EditorGUILayout.ToggleLeft("GenMipmap", genMipmap);
+ genAlpha = EditorGUILayout.ToggleLeft("GenAlpha", genAlpha);
+ if (genAlpha)
+ {
+ genRAlpha = EditorGUILayout.ToggleLeft("Gen R Channel Alpha", genRAlpha);
+ alphaSize = (ETextureSize)EditorGUILayout.EnumPopup("alpha缩放", alphaSize);
+ }
+ }
+ }
+ public enum ETexChanel
+ {
+ R,
+ G,
+ B,
+ A
+ }
+ public struct TexureImportInfo
+ {
+ public TextureImporterFormat format;
+ public int texSize;
+ public TextureWrapMode wrapMode;
+ public TextureImporter textureImporter;
+ public string path;
+ }
+ public class TextureCombine : EditorWindow
+ {
+ private Texture2D[] texs = new Texture2D[4];
+ private ETexChanel[] texChanels = new ETexChanel[4];
+ private TexureImportInfo[] importInfo = new TexureImportInfo[4];
+ private TextureImporterFormat desAndroidFormat = TextureImporterFormat.RGBA16;
+ private TextureImporterFormat desIOSFormat = TextureImporterFormat.RGBA16;
+ private int width = 256;
+ private int height = 256;
+ private string namepath = "";
+ private Vector2 scrollPosition = Vector2.zero;
+
+ private float GetChanel(Texture2D tex, ETexChanel chanel, int x, int y)
+ {
+ if (tex == null)
+ return 0.0f;
+ Color c = tex.GetPixel(x, y);
+ if (chanel == ETexChanel.R)
+ return c.r;
+ if (chanel == ETexChanel.G)
+ return c.g;
+ if (chanel == ETexChanel.B)
+ return c.b;
+ if (chanel == ETexChanel.A)
+ return c.a;
+ return 0.0f;
+ }
+
+ private void Combine()
+ {
+ if (namepath != "")
+ {
+ //Texture2D[] tmpTex = new Texture2D[4];
+ for (int i = 0, imax = texs.Length; i < imax; ++i)
+ {
+ Texture2D tex = texs[i];
+ if (tex != null)
+ {
+ string path = AssetDatabase.GetAssetPath(tex);
+ TextureImporter textureImporter = AssetImporter.GetAtPath(path) as TextureImporter;
+ if (textureImporter != null)
+ {
+ TexureImportInfo tii;
+
+ tii.wrapMode = textureImporter.wrapMode;
+ tii.textureImporter = textureImporter;
+ tii.path = path;
+ int texSize = 1024;
+ TextureImporterFormat format;
+ textureImporter.wrapMode = TextureWrapMode.Clamp;
+ textureImporter.GetPlatformTextureSettings(EditorUserBuildSettings.activeBuildTarget.ToString(), out texSize, out format);
+ AssetModify.SetTexImportSetting(textureImporter, "", texSize, TextureImporterFormat.Alpha8);
+
+ AssetDatabase.ImportAsset(path, ImportAssetOptions.ForceUpdate);
+ tii.format = format;
+ tii.texSize = texSize;
+ importInfo[i] = tii;
+ }
+ }
+ }
+ Material mat = new Material(Shader.Find("Custom/Editor/CombineTex"));
+ for (int i = 0, imax = texs.Length; i < imax; ++i)
+ {
+ mat.SetTexture("_Tex" + i.ToString(), texs[i]);
+ ETexChanel c = texChanels[i];
+ Vector4 chanelMask = Vector4.zero;
+ if (c == ETexChanel.R)
+ {
+ chanelMask = new Vector4(1, 0, 0, 0);
+ }
+ else if (c == ETexChanel.G)
+ {
+ chanelMask = new Vector4(0, 1, 0, 0);
+ }
+ else if (c == ETexChanel.B)
+ {
+ chanelMask = new Vector4(0, 0, 1, 0);
+ }
+ else if (c == ETexChanel.A)
+ {
+ chanelMask = new Vector4(0, 0, 0, 1);
+ }
+ mat.SetVector("_ChanelMask" + i.ToString(), chanelMask);
+ }
+ RenderTexture current = RenderTexture.active;
+ RenderTexture rt = new RenderTexture(width, height, 0, RenderTextureFormat.ARGB32);
+ Graphics.SetRenderTarget(rt);
+ // Set up the simple Matrix
+ GL.PushMatrix();
+ GL.LoadOrtho();
+ mat.SetPass(0);
+ GL.Begin(GL.QUADS);
+ GL.TexCoord2(0.0f, 0.0f); GL.Vertex3(0.0f, 0.0f, 0.1f);
+ GL.TexCoord2(1.0f, 0.0f); GL.Vertex3(1.0f, 0.0f, 0.1f);
+ GL.TexCoord2(1.0f, 1.0f); GL.Vertex3(1.0f, 1.0f, 0.1f);
+ GL.TexCoord2(0.0f, 1.0f); GL.Vertex3(0.0f, 1.0f, 0.1f);
+ GL.End();
+ GL.PopMatrix();
+
+ Texture2D des = new Texture2D(width, height);
+ des.ReadPixels(new Rect(0, 0, rt.width, rt.height), 0, 0);
+ Graphics.SetRenderTarget(current);
+ rt.Release();
+ GameObject.DestroyImmediate(mat);
+ byte[] bytes = des.EncodeToPNG();
+
+ File.WriteAllBytes(namepath, bytes);
+ AssetDatabase.ImportAsset(namepath, ImportAssetOptions.ForceUpdate);
+
+ TextureImporter desTexImporter = AssetImporter.GetAtPath(namepath) as TextureImporter;
+ if (desTexImporter != null)
+ {
+ int size = width > height ? width : height;
+ desTexImporter.textureType = TextureImporterType.Default;
+ desTexImporter.anisoLevel = 0;
+ desTexImporter.mipmapEnabled = false;
+ desTexImporter.isReadable = false;
+ desTexImporter.npotScale = TextureImporterNPOTScale.ToNearest;
+ AssetModify.SetTexImportSetting(desTexImporter, BuildTarget.Android.ToString(), size, desAndroidFormat);
+ AssetModify.SetTexImportSetting(desTexImporter, "iPhone", size, desIOSFormat);
+ AssetDatabase.ImportAsset(namepath, ImportAssetOptions.ForceUpdate);
+ }
+ for (int i = 0, imax = texs.Length; i < imax; ++i)
+ {
+ Texture2D tex = texs[i];
+ if (tex != null)
+ {
+ TexureImportInfo tii = importInfo[i];
+ AssetModify.SetTexImportSetting(tii.textureImporter, EditorUserBuildSettings.activeBuildTarget.ToString(), tii.texSize, tii.format);
+ tii.textureImporter.wrapMode = tii.wrapMode;
+ AssetDatabase.ImportAsset(tii.path, ImportAssetOptions.ForceUpdate);
+ }
+ }
+ EditorUtility.DisplayDialog("Finish", "Combine Finish", "OK");
+ }
+ else
+ {
+ EditorUtility.DisplayDialog("Error", "Empty file path", "OK");
+ }
+ }
+
+ private void OnGUI()
+ {
+ GUILayout.BeginHorizontal();
+
+ if (GUILayout.Button("Combine", GUILayout.MaxWidth(150)))
+ {
+ Combine();
+ }
+ GUILayout.EndHorizontal();
+ scrollPosition = GUILayout.BeginScrollView(scrollPosition, false, false);
+ for (int i = 0, imax = texs.Length; i < imax; ++i)
+ {
+ Texture2D tex = texs[i];
+ GUILayout.BeginHorizontal();
+ EditorGUILayout.LabelField(tex != null ? tex.name : "Empty");
+ GUILayout.EndHorizontal();
+
+ GUILayout.BeginHorizontal();
+ ETexChanel c = (ETexChanel)i;
+
+ texs[i] = EditorGUILayout.ObjectField("Chanel" + c, tex, typeof(Texture2D), true, GUILayout.MaxWidth(250)) as Texture2D;
+ if (texs[i] != null && namepath == "")
+ {
+ namepath = AssetDatabase.GetAssetPath(texs[i]);
+ int index = namepath.LastIndexOf(".");
+ if (index > 0)
+ namepath = namepath.Substring(0, index);
+ namepath += ".png";
+ }
+ texChanels[i] = (ETexChanel)EditorGUILayout.EnumPopup("通道", texChanels[i]);
+ GUILayout.EndHorizontal();
+ }
+ GUILayout.BeginHorizontal();
+ namepath = EditorGUILayout.TextField("Asset Path", namepath);
+ GUILayout.EndHorizontal();
+ GUILayout.BeginHorizontal();
+ width = EditorGUILayout.IntField("Width", width);
+ GUILayout.EndHorizontal();
+ GUILayout.BeginHorizontal();
+ height = EditorGUILayout.IntField("Height", height);
+ GUILayout.EndHorizontal();
+ EditorGUILayout.EndScrollView();
+
+ }
+
+ public static void ScaleTexture(Texture src, string despath, int width, int height, string shaderName, RenderTextureFormat renderFormat = RenderTextureFormat.ARGB32)
+ {
+ Material mat = new Material(Shader.Find(shaderName));
+ mat.mainTexture = src;
+ RenderTexture rt = new RenderTexture(width, height, 0, renderFormat);
+ RenderTexture current = RenderTexture.active;
+ Graphics.SetRenderTarget(rt);
+ // Set up the simple Matrix
+ GL.wireframe = true;
+ GL.PushMatrix();
+ GL.LoadOrtho();
+ mat.SetPass(0);
+ GL.Begin(GL.QUADS);
+ GL.TexCoord2(0.0f, 0.0f); GL.Vertex3(0.0f, 0.0f, 0.1f);
+ GL.TexCoord2(1.0f, 0.0f); GL.Vertex3(1.0f, 0.0f, 0.1f);
+ GL.TexCoord2(1.0f, 1.0f); GL.Vertex3(1.0f, 1.0f, 0.1f);
+ GL.TexCoord2(0.0f, 1.0f); GL.Vertex3(0.0f, 1.0f, 0.1f);
+ GL.End();
+ GL.PopMatrix();
+
+ Texture2D des = new Texture2D(width, height);
+ des.ReadPixels(new Rect(0, 0, rt.width, rt.height), 0, 0);
+ Graphics.SetRenderTarget(current);
+ rt.Release();
+ GL.wireframe = false;
+ GameObject.DestroyImmediate(mat);
+ if (File.Exists(despath))
+ {
+ File.Delete(despath);
+ AssetDatabase.Refresh();
+ }
+ byte[] bytes = des.EncodeToPNG();
+
+ File.WriteAllBytes(despath, bytes);
+ AssetDatabase.ImportAsset(despath, ImportAssetOptions.ForceUpdate);
+ }
+ public static void ScaleTexture(Texture src, string despath, Vector2 tile, Vector2 offset, string shaderName)
+ {
+ Shader shader = Shader.Find(shaderName);
+ Material mat = new Material(shader);
+ mat.SetTexture("_MainTex", src);
+ mat.SetTextureScale("_MainTex", tile);
+ mat.SetTextureOffset("_MainTex", offset);
+ RenderTexture rt = RenderTexture.GetTemporary(src.width, src.width, 0, RenderTextureFormat.ARGB32);
+ RenderTexture current = RenderTexture.active;
+ Graphics.SetRenderTarget(rt);
+ // Set up the simple Matrix
+ GL.PushMatrix();
+ GL.LoadOrtho();
+ mat.SetPass(0);
+ GL.Begin(GL.QUADS);
+ GL.TexCoord2(0.0f, 0.0f); GL.Vertex3(0.0f, 0.0f, 0.1f);
+ GL.TexCoord2(1.0f, 0.0f); GL.Vertex3(1.0f, 0.0f, 0.1f);
+ GL.TexCoord2(1.0f, 1.0f); GL.Vertex3(1.0f, 1.0f, 0.1f);
+ GL.TexCoord2(0.0f, 1.0f); GL.Vertex3(0.0f, 1.0f, 0.1f);
+ GL.End();
+ GL.PopMatrix();
+
+ Texture2D des = new Texture2D(src.width, src.height);
+ des.ReadPixels(new Rect(0, 0, rt.width, rt.height), 0, 0);
+ des.Apply();
+ Graphics.SetRenderTarget(current);
+ GameObject.DestroyImmediate(mat);
+ if (File.Exists(despath))
+ {
+ File.Delete(despath);
+ AssetDatabase.Refresh();
+ }
+ byte[] bytes = des.EncodeToPNG();
+ UnityEngine.Object.DestroyImmediate(des);
+ RenderTexture.ReleaseTemporary(rt);
+ File.WriteAllBytes(despath, bytes);
+ //AssetDatabase.ImportAsset(despath, ImportAssetOptions.ForceUpdate);
+ }
+ private static void Reimport(string texPath, Texture2D tex)
+ {
+ byte[] bytes = tex.EncodeToPNG();
+ File.WriteAllBytes(texPath, bytes);
+ AssetDatabase.ImportAsset(texPath, ImportAssetOptions.ForceUpdate);
+ AssetDatabase.Refresh();
+ tex = AssetDatabase.LoadAssetAtPath<Texture2D>(texPath);
+ TextureImporter texImporter = AssetImporter.GetAtPath(texPath) as TextureImporter;
+ AssetModify.DefaultCompress(tex, texImporter, texPath, !texPath.Contains("atlas/UI/"));
+ AssetDatabase.ImportAsset(texPath, ImportAssetOptions.ForceUpdate);
+ }
+ private static void Split(Texture2D src, TextureImporter textureImporter, int scale, int size, int width, int height, bool horizontal, string targetDir,bool createNew)
+ {
+ int splitCount = scale;
+ string[] splitTexPath = new string[splitCount];
+ Texture2D[] splitTex = new Texture2D[splitCount];
+ for (int i = 0; i < splitCount; ++i)
+ {
+ if (createNew)
+ {
+ splitTexPath[i] = string.Format("{0}/{1}_{2}.png", targetDir, src.name, i);
+ }
+ else
+ {
+ if (i == 0)
+ {
+ splitTexPath[i] = string.Format("{0}/{1}_{2}2Split.png", targetDir, src.name, horizontal ? "h" : "v");
+ }
+ else
+ {
+ splitTexPath[i] = string.Format("{0}/{1}_{2}2Split_2.png", targetDir, src.name, horizontal ? "h" : "v");
+ }
+ }
+
+
+
+ splitTex[i] = new Texture2D(size, size, TextureFormat.RGBA32, false);
+ }
+ AssetModify.MakeTexReadable(src, textureImporter, true);
+
+ if (horizontal)
+ {
+ for (int x = 0; x < width; ++x)
+ {
+ int index = x / size;
+ Texture2D tex = splitTex[index];
+ for (int y = 0; y < height; ++y)
+ {
+ Color c0 = src.GetPixel(x, y);
+ c0.a = 1;
+ tex.SetPixel(x, y, c0);
+ }
+ }
+ }
+ else
+ {
+ for (int y = 0; y < height; ++y)
+ {
+ int index = y / size;
+ Texture2D tex = splitTex[index];
+ for (int x = 0; x < width; ++x)
+ {
+ Color c0 = src.GetPixel(x, y);
+ c0.a = 1;
+ tex.SetPixel(x, y, c0);
+ }
+ }
+ }
+ AssetModify.MakeTexReadable(src, textureImporter, false);
+ for (int i = 0; i < splitCount; ++i)
+ {
+ Reimport(splitTexPath[i], splitTex[i]);
+ }
+ }
+
+ private static void Combine(Texture2D src, TextureImporter textureImporter, int size, int width, int height, bool horizontal, string targetDir, bool createNew)
+ {
+ string combineTexPath = null;
+ if(createNew)
+ combineTexPath = string.Format("{0}/{1}_0.png", targetDir, src.name);
+ else
+ combineTexPath = string.Format("{0}/{1}_{2}4Split.png", targetDir, src.name, horizontal ? "h" : "v");
+ Texture2D combineTex = new Texture2D(size, size, TextureFormat.RGBA32, false);
+ AssetModify.MakeTexReadable(src, textureImporter, true);
+
+ if (horizontal)
+ {
+ for (int x = 0; x < width; ++x)
+ {
+ for (int y = 0; y < height; ++y)
+ {
+ Color c0 = src.GetPixel(x, y);
+ c0.a = 1;
+ if (x >= size)
+ {
+ int newX = x - size;
+ int newY = y + size / 2;
+ combineTex.SetPixel(newX, newY, c0);
+ }
+ else
+ {
+ int newX = x;
+ int newY = y;
+ combineTex.SetPixel(newX, newY, c0);
+ }
+
+ }
+ }
+ }
+ else
+ {
+ for (int y = 0; y < height; ++y)
+ {
+ for (int x = 0; x < width; ++x)
+ {
+ Color c0 = src.GetPixel(x, y);
+ c0.a = 1;
+ if (y >= size)
+ {
+ int newX = x + size / 2;
+ int newY = y - size;
+ combineTex.SetPixel(newX, newY, c0);
+ }
+ else
+ {
+ int newX = x;
+ int newY = y;
+ combineTex.SetPixel(newX, newY, c0);
+ }
+ }
+ }
+ }
+ AssetModify.MakeTexReadable(src, textureImporter, false);
+ Reimport(combineTexPath, combineTex);
+ }
+ public static void SplitTexture(Texture2D src, TextureImporter textureImporter, bool compress)
+ {
+ string path = AssetDatabase.GetAssetPath(src);
+ string targetDir = path;
+ bool createNew = true;
+ if (path.StartsWith("Assets/atlas/UI"))
+ {
+ targetDir = path.Replace("Assets/", "Assets/Resources/");
+ createNew = false;
+ }
+ int index = targetDir.LastIndexOf("/");
+ if (index >= 0)
+ {
+ targetDir = targetDir.Substring(0, index);
+ }
+
+ int width = src.width;
+ int height = src.height;
+ int scaleW = width / height;
+ int scaleH = height / width;
+ if (scaleW == 2)
+ {
+ Split(src, textureImporter, scaleW, height, width, height, true, targetDir, createNew);
+ }
+ else if (scaleH == 2)
+ {
+ Split(src, textureImporter, scaleH, width, width, height, false, targetDir, createNew);
+ }
+ else if (scaleW == 4)
+ {
+ Combine(src, textureImporter, width / 2, width, height, true, targetDir, createNew);
+ }
+ else if (scaleH == 4)
+ {
+ Combine(src, textureImporter, height / 2, width, height, false, targetDir, createNew);
+ }
+ else
+ {
+ return;
+ }
+ }
+ }
+
+ //public class MakeEquip : EditorWindow
+ //{
+ // //public class ExtraSkinMeshTex
+ // //{
+ // // public XMeshTexData mtd;
+ // // public XMeshMultiTexData mmtd;
+ // // public string name = "";
+ // // public Texture2D tex;
+ // //}
+
+ // public UnityEngine.Object model = null;
+ // protected UnityEngine.Object currentModel = null;
+ // protected Vector2 scrollPos = Vector2.zero;
+ // private string srcString = "01";
+ // private string replaceString = "02";
+ // private string modelPath = "";
+ // //private XMeshPartList meshPartList = new XMeshPartList();
+ // protected List<EquipPathInfo> meshParts = new List<EquipPathInfo>();
+ // protected List<ExtraMeshTex> meshList = new List<ExtraMeshTex>();
+ // protected string equipPath = "Assets/Resources/Equipments/";
+ // protected string weaponPath = "Assets/Resources/Equipments/weapon/";
+
+ // public void Init()
+ // {
+ // AssetModify.s_meshPartLis.Load(true);
+ // model = Selection.activeObject;
+ // }
+ // protected virtual void OnGUI()
+ // {
+ // GUILayout.BeginHorizontal();
+ // EditorGUILayout.LabelField(model != null ? model.name : "Empty");
+ // GUILayout.EndHorizontal();
+
+ // GUILayout.BeginHorizontal();
+ // equipPath = EditorGUILayout.TextField("equip path", equipPath);
+ // GUILayout.EndHorizontal();
+
+ // GUILayout.BeginHorizontal();
+ // weaponPath = EditorGUILayout.TextField("weapon path", weaponPath);
+ // GUILayout.EndHorizontal();
+
+ // GUILayout.BeginHorizontal();
+ // model = EditorGUILayout.ObjectField("", model, typeof(UnityEngine.Object), true, GUILayout.MaxWidth(250));
+ // if (currentModel != model)
+ // {
+ // currentModel = model;
+ // //ReplaceEquip.PrepareReplace(currentModel, meshParts, meshList, AssetModify.s_meshPartLis, out modelPath);
+ // }
+ // GUILayout.EndHorizontal();
+
+ // scrollPos = GUILayout.BeginScrollView(scrollPos, GUILayout.ExpandWidth(true));
+ // for (int i = 0, imax = meshParts.Count; i < imax; ++i)
+ // {
+ // EquipPathInfo epi = meshParts[i];
+
+ // GUILayout.BeginHorizontal();
+ // EditorGUILayout.LabelField(epi.name);
+ // GUILayout.EndHorizontal();
+
+ // GUILayout.BeginHorizontal();
+ // GUILayout.BeginVertical();
+ // epi.newName = EditorGUILayout.TextField("", epi.newName, GUILayout.MaxWidth(300));
+ // GUILayout.EndVertical();
+
+ // GUILayout.BeginVertical();
+ // epi.newTexPath = EditorGUILayout.TextField(epi.newTexPath, GUILayout.MaxWidth(300));
+ // GUILayout.EndVertical();
+ // GUILayout.BeginVertical();
+ // if (GUILayout.Button("X", GUILayout.MaxWidth(20)))
+ // {
+ // epi.newName = "";
+ // epi.newTexPath = "";
+ // }
+ // GUILayout.EndVertical();
+ // GUILayout.EndHorizontal();
+ // }
+ // for (int i = 0, imax = meshList.Count; i < imax; ++i)
+ // {
+ // ExtraMeshTex emt = meshList[i];
+ // GUILayout.BeginHorizontal();
+ // EditorGUILayout.LabelField(emt.mesh != null ? emt.mesh.name : "");
+ // GUILayout.EndHorizontal();
+
+ // GUILayout.BeginHorizontal();
+ // GUILayout.BeginVertical();
+ // emt.newName = EditorGUILayout.TextField("", emt.newName, GUILayout.MaxWidth(300));
+ // GUILayout.EndVertical();
+
+ // GUILayout.BeginVertical();
+ // emt.newTexPath = EditorGUILayout.TextField("", emt.newTexPath, GUILayout.MaxWidth(300));
+ // GUILayout.EndVertical();
+ // GUILayout.BeginVertical();
+
+ // if (GUILayout.Button("X", GUILayout.MaxWidth(20)))
+ // {
+ // emt.newTexPath = "";
+ // emt.newName = "";
+ // }
+ // GUILayout.EndVertical();
+
+ // GUILayout.EndHorizontal();
+ // }
+
+
+ // GUILayout.EndScrollView();
+ // srcString = EditorGUILayout.TextField("Src String", srcString);
+ // replaceString = EditorGUILayout.TextField("Replace String", replaceString);
+ // //if (GUILayout.Button("Auto Gen", GUILayout.ExpandWidth(false)))
+ // //{
+ // // for (int i = 0, imax = meshParts.Count; i < imax; ++i)
+ // // {
+ // // EquipPathInfo epi = meshParts[i];
+ // // epi.newName = epi.name.Replace(srcString, replaceString);
+ // // epi.newTexPath = epi.texPath.Replace(srcString, replaceString);
+ // // }
+ // // for (int i = 0, imax = meshList.Count; i < imax; ++i)
+ // // {
+ // // ExtraMeshTex emt = meshList[i];
+ // // if (emt.mesh != null)
+ // // {
+ // // emt.name = emt.mesh.name.Replace(srcString, replaceString);
+ // // }
+ // // if (emt.srcMat != null)
+ // // {
+ // // Texture2D tex = emt.srcMat.mainTexture as Texture2D;
+ // // if (tex != null)
+ // // {
+ // // string texName = tex.name.Replace(srcString, replaceString);
+ // // emt.tex = AssetDatabase.LoadAssetAtPath(modelPath + texName + ".tga", typeof(Texture2D)) as Texture2D;
+ // // }
+ // // }
+ // // }
+ // //}
+ // if (GUILayout.Button("Export", GUILayout.ExpandWidth(false)))
+ // {
+ // if (model != null)
+ // {
+ // string[] replaceStrings = new string[] { replaceString };
+ // if (ReplaceEquip.MakeReplace(srcString, replaceStrings, meshParts, meshList, AssetModify.s_meshPartLis, modelPath))
+ // {
+ // AssetModify.SaveEquipInfo();
+ // AssetDatabase.Refresh();
+ // }
+ // }
+ // EditorUtility.DisplayDialog("Finish", "All obj processed finish", "OK");
+ // }
+ // if (GUILayout.Button("Cancel", GUILayout.ExpandWidth(false)))
+ // {
+ // this.Close();
+ // }
+ // }
+ //}
+
+ public class EquipPreview : EditorWindow
+ {
+ public class EquipData
+ {
+ public string name;
+ public string path;
+ }
+ public class ProfessionEquip
+ {
+ public EquipData[] equipDataList = new EquipData[(int)EPartType.EWeaponEnd];
+ }
+ public class EquipSuit
+ {
+ public ProfessionEquip[] professionList = null;
+ public string suitName = "";
+ }
+
+ public class PartData
+ {
+ public Mesh mesh;
+ public Texture2D tex;
+ public string path;
+ }
+ public class RoleData
+ {
+ public PartData[] partData = new PartData[(int)EPartType.ECombinePartEnd];
+ public GameObject[] mountPartData = new GameObject[4];
+ public Texture2D decalData = null;
+ public GameObject role = null;
+ }
+
+ private PlayStateChange playStateChange = new PlayStateChange();
+ private CombineConfig combineConfig = null;
+ private List<EquipSuit> equipSuitList = new List<EquipSuit>();
+ private List<EquipData>[] declList = null;
+ private DefaultEquip defaultEquip = new DefaultEquip();
+
+ private EquipData[] selectedEquipDataList = new EquipData[(int)EPartType.EWeaponEnd];
+ private EquipData selectedDecal = null;
+ private RoleData[] roleDataList = null;
+ private RoleData tmpRoleData = new RoleData();
+ private EquipData[] customEquipDataList = new EquipData[(int)EPartType.EWeaponEnd];
+ private string customDir = "";
+ private int m_professionIndex = 0;
+ private bool makeNew = false;
+ private string meshName = "";
+ private List<CombineInstance> ciList = new List<CombineInstance>();
+ private Vector2 fashionScrollPos = Vector2.zero;
+ private Vector2 decalScrollPos = Vector2.zero;
+ private Vector2 equipPathScrollPos = Vector2.zero;
+
+ [MenuItem(@"Assets/Tool/Equipment/Preview", false, 0)]
+ private static void PreviewEquip()
+ {
+ EquipPreview window = (EquipPreview)EditorWindow.GetWindow(typeof(EquipPreview), true, "套装预览");
+ window.minSize = new Vector2(800, 600);
+ window.Show();
+ }
+ private int ConvertPart(int pos)
+ {
+ switch (pos)
+ {
+ case 0:
+ return (int)EPartType.EHeadgear;
+ case 1:
+ return (int)EPartType.EUpperBody;
+ case 2:
+ return (int)EPartType.ELowerBody;
+ case 3:
+ return (int)EPartType.EGloves;
+ case 4:
+ return (int)EPartType.EBoots;
+ case 5:
+ return (int)EPartType.EMainWeapon;
+ case 6:
+ return (int)EPartType.ESecondaryWeapon;
+ case 7:
+ return (int)EPartType.EWings;
+ case 8:
+ return (int)EPartType.ETail;
+ case 9:
+ return (int)EPartType.EDecal;
+ case 10:
+ return (int)EPartType.EFace;
+ case 11:
+ return (int)EPartType.EHair;
+ }
+ return -1;
+ }
+
+
+ private string GetEquipName(int partIndex, string path)
+ {
+ if (partIndex >= 0 && partIndex < combineConfig.EquipPrefix.Length)
+ {
+ string proPrefix = combineConfig.EquipPrefix[m_professionIndex];
+ string partSuffix = combineConfig.PartSuffix[partIndex];
+
+ if (string.IsNullOrEmpty(path))
+ {
+ return string.Format("Equipments/Player/{0}{1}", proPrefix, partSuffix);
+ }
+ else if (path.StartsWith("/"))
+ {
+ return string.Format("Equipments/{0}/{1}{2}", path, proPrefix, partSuffix);
+ }
+ else if (path == "E")
+ {
+ return "";
+ }
+ else
+ {
+ return string.Format("Equipments/Player/{0}{1}", proPrefix, path);
+ }
+ }
+ else
+ {
+
+ return path;
+ }
+ }
+ private string GetDefaultPath(EPartType part, DefaultEquip.RowData data)
+ {
+ string partPath = "";
+ int partIndex = (int)part;
+ switch (part)
+ {
+ case EPartType.EFace:
+ partPath = GetEquipName(partIndex, data.Face);
+ break;
+ case EPartType.EHair:
+ partPath = GetEquipName(partIndex, data.Hair);
+ break;
+ case EPartType.EUpperBody:
+ partPath = GetEquipName(partIndex, data.Body);
+ break;
+ case EPartType.ELowerBody:
+ partPath = GetEquipName(partIndex, data.Leg);
+ break;
+ case EPartType.EGloves:
+ partPath = GetEquipName(partIndex, data.Glove);
+ break;
+ case EPartType.EBoots:
+ partPath = GetEquipName(partIndex, data.Boots);
+ break;
+ case EPartType.ESecondaryWeapon:
+ partPath = GetEquipName(partIndex, data.SecondWeapon);
+ break;
+ case EPartType.EMainWeapon:
+ partPath = GetEquipName(partIndex, data.Weapon);
+ break;
+ }
+ return partPath;
+ }
+
+ private void MakePartData(int index, DefaultEquip.RowData data, RoleData roleData, EquipData[] equipDataList)
+ {
+ EquipData ed = equipDataList[index];
+
+
+ string location = "";
+ string srcDir = "";
+ if (ed == null || string.IsNullOrEmpty(ed.path))
+ {
+ location = GetDefaultPath((EPartType)index, data);
+ srcDir = "Player";
+ }
+ else
+ {
+ location = ed.path;
+ int i = location.IndexOf("/");
+ srcDir = location.Substring(0, i);
+ }
+
+ if (index == (int)EPartType.EMainWeapon)
+ {
+ GameObject weapon = AssetDatabase.LoadAssetAtPath<GameObject>("Assets/Resources/Equipments/" + location + ".prefab");
+ if (weapon != null)
+ {
+ GameObject go = GameObject.Instantiate<GameObject>(weapon, null);
+ go.name = weapon.name;
+ roleData.mountPartData[0] = go;
+ }
+
+ }
+ else
+ {
+ byte partType = 0;
+ string meshLocation = null;
+ string texLocation = null;
+ string texpath = location;
+ if (AssetModify.s_meshPartLis.GetMeshInfo(location, m_professionIndex, index, srcDir, out partType, ref meshLocation, ref texLocation))
+ {
+ if(!string.IsNullOrEmpty(meshLocation))
+ {
+ location = meshLocation;
+ }
+ if (!string.IsNullOrEmpty(texLocation))
+ {
+ texpath = texLocation;
+ }
+ }
+ else
+ {
+ Debug.LogError("mesh not found:" + location);
+ location = GetDefaultPath((EPartType)index, data);
+ texpath = location;
+ }
+ string meshResPath = "Assets/Resources/" + location + ".asset";
+ string texResPath = "Assets/Resources/" + texpath + ".tga";
+ Mesh mesh = AssetDatabase.LoadAssetAtPath<Mesh>(meshResPath);
+ Texture2D tex = null;
+
+ if (File.Exists(texResPath))
+ {
+ tex = AssetDatabase.LoadAssetAtPath<Texture2D>(texResPath);
+ }
+ else
+ {
+ texResPath = texResPath.Replace("_a", "") + ".tga";
+ tex = AssetDatabase.LoadAssetAtPath<Texture2D>(texResPath);
+ }
+ PartData pd = roleData.partData[index];
+ if (pd == null)
+ {
+ pd = new PartData();
+ roleData.partData[index] = pd;
+ }
+ pd.mesh = mesh;
+ pd.tex = tex;
+ pd.path = meshResPath;
+ }
+
+ }
+ private void Preview(int x, int y, int z, EquipData[] equipDataList)
+ {
+ ciList.Clear();
+
+ RoleData roleData = makeNew ? tmpRoleData : roleDataList[m_professionIndex];
+
+ DefaultEquip.RowData data = defaultEquip.GetByProfID(m_professionIndex + 1);
+
+ for (int i = 0; i < equipDataList.Length; ++i)
+ {
+ MakePartData(i, data, roleData, equipDataList);
+ }
+
+ Material mat = null;
+ PartData bodyPart = roleData.partData[(int)EPartType.EUpperBody];
+ bool hasOnepart = false;
+ Texture2D alphaTex = null;
+ if (bodyPart != null && bodyPart.tex != null && bodyPart.tex.width == 1024)
+ {
+ hasOnepart = true;
+ alphaTex = AssetDatabase.LoadAssetAtPath<Texture2D>(bodyPart.path + "_A.png");
+ if(alphaTex!=null)
+ {
+ mat = new Material(Shader.Find("Custom/Skin/RimlightBlendCutout"));
+ }
+ else
+ {
+ mat = new Material(Shader.Find("Custom/Skin/RimlightBlend"));
+ }
+ }
+ else
+ {
+ mat = new Material(Shader.Find("Custom/Skin/RimlightBlend8"));
+ }
+ ciList.Clear();
+ for (int i = 0;i< roleData.partData.Length;++i)
+ {
+ PartData partData = roleData.partData[i];
+ if(partData.mesh!=null)
+ {
+ CombineInstance ci = new CombineInstance();
+ ci.mesh = partData.mesh;
+ ciList.Add(ci);
+ }
+ }
+ if (ciList.Count > 0)
+ {
+ GameObject roleGO = null;
+ SkinnedMeshRenderer roleSmr = null;
+ if (makeNew || roleData.role == null)
+ {
+ string skinPrfab = "Prefabs/" + combineConfig.PrefabName[m_professionIndex];
+ string anim = combineConfig.IdleAnimName[m_professionIndex];
+ GameObject prefab = Resources.Load<GameObject>(skinPrfab);
+ roleGO = GameObject.Instantiate<GameObject>(prefab);
+ roleGO.name = prefab.name;
+ CharacterController cc = roleGO.GetComponent<CharacterController>();
+ if (cc != null)
+ {
+ cc.enabled = false;
+ }
+ roleGO.transform.position = new Vector3(x, y, z);
+
+ Animator ator = roleGO.GetComponent<Animator>();
+ AnimatorOverrideController aoc = new AnimatorOverrideController();
+ aoc.runtimeAnimatorController = ator.runtimeAnimatorController;
+ ator.runtimeAnimatorController = aoc;
+ aoc["Idle"] = Resources.Load<AnimationClip>(anim);
+ roleData.role = roleGO;
+ }
+ else
+ {
+ roleGO = roleData.role;
+ }
+
+ roleSmr = roleGO.GetComponent<SkinnedMeshRenderer>();
+ if (roleSmr.sharedMesh == null)
+ roleSmr.sharedMesh = new Mesh();
+ roleGO.SetActive(false);
+ roleSmr.sharedMesh.CombineMeshes(ciList.ToArray(), true, false);
+ roleSmr.sharedMaterial = mat;
+ if (hasOnepart)
+ {
+ PartData face = roleData.partData[(int)EPartType.EFace];
+ PartData hair = roleData.partData[(int)EPartType.EHair];
+ PartData helmet = roleData.partData[(int)EPartType.EHeadgear];
+ mat.SetTexture("_Face", face.tex);
+ if (hair.tex == null)
+ {
+ mat.SetTexture("_Hair", helmet.tex);
+ }
+ else
+ {
+ mat.SetTexture("_Hair", hair.tex);
+ }
+ PartData body = roleData.partData[(int)EPartType.EUpperBody];
+ mat.SetTexture("_Body", body.tex);
+ if(alphaTex!=null)
+ {
+ mat.SetTexture("_Alpha", alphaTex);
+ }
+ }
+ else
+ {
+ for (int i = 0; i < roleData.partData.Length; ++i)
+ {
+ PartData partData = roleData.partData[i];
+ mat.SetTexture("_Tex" + i.ToString(), partData.tex);
+ }
+ }
+
+ roleGO.SetActive(true);
+
+ GameObject weaponGO = roleData.mountPartData[0];
+ if (weaponGO != null&&data.WeaponPoint != null && data.WeaponPoint.Length > 0)
+ {
+ string weapon = data.WeaponPoint[0];
+ Transform trans = roleGO.transform.Find(weapon);
+ if (trans != null)
+ {
+ weaponGO.transform.parent = trans;
+ weaponGO.transform.localPosition = Vector3.zero;
+ weaponGO.transform.localRotation = Quaternion.identity;
+ }
+ }
+ }
+ }
+
+ public void Init()
+ {
+ combineConfig = CombineConfig.GetConfig();
+ AssetModify.LoadMeshPartInfo();
+
+ XBinaryReader.Init();
+ XBinaryReader reader = XBinaryReader.Get();
+ TextAsset ta = Resources.Load<TextAsset>(@"Table/DefaultEquip");
+ if (ta != null)
+ {
+ reader.Init(ta);
+ defaultEquip.ReadFile(reader);
+ XBinaryReader.Return(reader);
+ }
+ int professionCount = combineConfig.EquipFolderName.Length;
+ roleDataList = new RoleData[professionCount];
+ declList = new List<EquipData>[professionCount];
+ for (int i = 0; i < professionCount; ++i)
+ {
+ declList[i] = new List<EquipData>();
+ roleDataList[i] = new RoleData();
+ }
+
+ DirectoryInfo di = new DirectoryInfo("Assets/Resources/Equipments");
+ DirectoryInfo[] subDirs = di.GetDirectories("*.*", SearchOption.TopDirectoryOnly);
+ for (int i = 0; i < subDirs.Length; ++i)
+ {
+ DirectoryInfo subDir = subDirs[i];
+ if (subDir.Name == "decal")
+ {
+ FileInfo[] files = subDir.GetFiles("*.tga", SearchOption.TopDirectoryOnly);
+ for (int j = 0; j < files.Length; ++j)
+ {
+ FileInfo file = files[j];
+ string name = file.Name.Replace(".tga", "");
+ int professionIndex = -1;
+ for (int k = 0; k < combineConfig.EquipPrefix.Length; ++k)
+ {
+ string prefix = combineConfig.EquipPrefix[k];
+ if (name.StartsWith(prefix))
+ {
+ professionIndex = k;
+ break;
+ }
+ }
+ if (professionIndex >= 0)
+ {
+ List<EquipData> decals = declList[professionIndex];
+ EquipData ed = new EquipData();
+ ed.name = name;
+ ed.path = "Equipments/decal/" + name;
+ decals.Add(ed);
+ }
+ }
+
+ }
+ else
+ {
+ EquipSuit es = new EquipSuit();
+ es.suitName = subDir.Name;
+ es.professionList = new ProfessionEquip[professionCount];
+ FileInfo[] files = subDir.GetFiles("*.asset", SearchOption.TopDirectoryOnly);
+ for (int j = 0; j < files.Length; ++j)
+ {
+ FileInfo file = files[j];
+ string name = file.Name.Replace(".asset", "");
+ string dirname = file.Directory.Name;
+ int professionIndex = -1;
+ for (int k = 0; k < combineConfig.EquipPrefix.Length; ++k)
+ {
+ string prefix = combineConfig.EquipPrefix[k];
+ if (name.StartsWith(prefix))
+ {
+ professionIndex = k;
+ break;
+ }
+ }
+ ProfessionEquip pe = null;
+ if (professionIndex >= 0)
+ {
+ pe = es.professionList[professionIndex];
+ if (pe == null)
+ {
+ pe = new ProfessionEquip();
+ es.professionList[professionIndex] = pe;
+ }
+ string tmp = name.Replace(combineConfig.EquipPrefix[professionIndex], "");
+ for (int k = 0; k < combineConfig.PartSuffix.Length; ++k)
+ {
+ string suffix = combineConfig.PartSuffix[k];
+ if (tmp.StartsWith(suffix))
+ {
+ EquipData ed = pe.equipDataList[k];
+ if (ed==null)
+ {
+ ed = new EquipData();
+ pe.equipDataList[k] = ed;
+ }
+ ed.name = name;
+ ed.path = "Equipments/" + dirname + "/" + name;
+ break;
+ }
+ }
+ }
+
+ }
+ equipSuitList.Add(es);
+ }
+ }
+ di = new DirectoryInfo("Assets/Resources/Prefabs/Equipment");
+ FileInfo[] prefabs = di.GetFiles("*.prefab", SearchOption.TopDirectoryOnly);
+ for (int i = 0; i < prefabs.Length; ++i)
+ {
+ FileInfo file = prefabs[i];
+ string name = file.Name.Replace(".prefab", "");
+ }
+ for (int i = 0; i < customEquipDataList.Length; ++i)
+ {
+ customEquipDataList[i] = new EquipData();
+ }
+ }
+
+ protected virtual void OnGUI()
+ {
+ if(playStateChange.Update())
+ {
+ Init();
+ playStateChange.PostUpdate();
+ }
+ GUILayout.BeginHorizontal();
+ if (combineConfig != null)
+ {
+ int selectIndex = m_professionIndex;
+ for (int i = 0; i < combineConfig.EquipFolderName.Length; ++i)
+ {
+ if (GUILayout.Button(combineConfig.EquipFolderName[i], GUILayout.MaxWidth(100)))
+ {
+ selectIndex = i;
+ break;
+ }
+ }
+ if (selectIndex != m_professionIndex)
+ {
+ selectedDecal = null;
+ for (int i = 0; i < selectedEquipDataList.Length; ++i)
+ {
+ selectedEquipDataList[i] = null;
+ }
+ m_professionIndex = selectIndex;
+ }
+ }
+
+ GUILayout.EndHorizontal();
+ GUILayout.BeginHorizontal();
+ if (GUILayout.Button("Preview", GUILayout.MaxWidth(100)))
+ {
+ Preview(m_professionIndex, 0, makeNew ? 0 : 1, selectedEquipDataList);
+ }
+ makeNew = GUILayout.Toggle(makeNew, "MakeNew", GUILayout.MinWidth(100), GUILayout.MaxWidth(100));
+ meshName = GUILayout.TextField(meshName, GUILayout.MaxWidth(200));
+ if (GUILayout.Button("Export", GUILayout.MaxWidth(100)))
+ {
+ RoleData roleData = roleDataList[m_professionIndex];
+ if (roleData.role != null)
+ {
+ GameObject newGo = GameObject.Instantiate<GameObject>(roleData.role);
+ SkinnedMeshRenderer smr = newGo.GetComponent<SkinnedMeshRenderer>();
+ if (smr != null && smr.sharedMesh != null)
+ {
+ Mesh mesh = UnityEngine.Object.Instantiate<Mesh>(smr.sharedMesh);
+ mesh.name = meshName;
+ Material mat = UnityEngine.Object.Instantiate<Material>(smr.sharedMaterial);
+ mat.name = meshName;
+ string folderName = combineConfig.SkillFolderName[m_professionIndex];
+ AssetModify.CreateOrReplaceAsset<Material>(mat, string.Format("Assets/Creatures/{0}/Materials/{1}.mat", folderName, meshName));
+ MeshUtility.SetMeshCompression(mesh, ModelImporterMeshCompression.High);
+ MeshUtility.Optimize(mesh);
+ mesh.UploadMeshData(true);
+ AssetModify.CreateOrReplaceAsset<Mesh>(mesh, string.Format("Assets/Creatures/{0}/{1}.asset", folderName, meshName));
+ smr.sharedMesh = mesh;
+ smr.sharedMaterial = mat;
+ }
+ }
+ }
+ GUILayout.EndHorizontal();
+ GUILayout.BeginHorizontal(GUILayout.MinHeight(400));
+ //时装
+ GUILayout.BeginVertical(GUI.skin.box, GUILayout.MaxWidth(800));
+ GUILayout.BeginHorizontal();
+ EditorGUILayout.LabelField("时装", GUILayout.MaxWidth(100));
+ GUILayout.EndHorizontal();
+ fashionScrollPos = GUILayout.BeginScrollView(fashionScrollPos, false, false);
+ for (int i = 0; i < equipSuitList.Count; ++i)
+ {
+ EquipSuit es = equipSuitList[i];
+ ProfessionEquip pe = es.professionList[m_professionIndex];
+ if (pe != null)
+ {
+ GUILayout.BeginHorizontal();
+
+ if(GUILayout.Button(es.suitName, GUILayout.MinWidth(150), GUILayout.MaxWidth(150)))
+ {
+ for (int j = 0; j < pe.equipDataList.Length; ++j)
+ {
+ selectedEquipDataList[j] = pe.equipDataList[j];
+ }
+
+ }
+ for (int j = 0; j < pe.equipDataList.Length; ++j)
+ {
+ EquipData ed = pe.equipDataList[j];
+ if (ed != null && !string.IsNullOrEmpty(ed.name))
+ {
+ bool selected = selectedEquipDataList[j] == ed;
+ bool afterSelected = GUILayout.Toggle(selected, ed.name, GUILayout.MinWidth(100), GUILayout.MaxWidth(100));
+ if (afterSelected != selected)
+ {
+ selectedEquipDataList[j] = afterSelected ? ed : null;
+ }
+ GUILayout.Space(5);
+ }
+ }
+ GUILayout.EndHorizontal();
+ }
+
+ }
+ EditorGUILayout.EndScrollView();
+ GUILayout.EndVertical();
+ //装备
+ GUILayout.BeginVertical(GUI.skin.box, GUILayout.MaxWidth(100));
+ GUILayout.BeginHorizontal();
+ EditorGUILayout.LabelField("纹身", GUILayout.MaxWidth(100));
+ GUILayout.EndHorizontal();
+ decalScrollPos = GUILayout.BeginScrollView(decalScrollPos, false, false);
+ List<EquipData> decals = declList[m_professionIndex];
+ for (int i = 0; i < decals.Count; ++i)
+ {
+ GUILayout.BeginHorizontal();
+ EquipData ed = decals[i];
+ bool selected = ed == selectedDecal;
+ bool afterSelected = GUILayout.Toggle(selected, ed.name, GUILayout.MinWidth(150), GUILayout.MaxWidth(150));
+ if (afterSelected != selected)
+ {
+ selectedDecal = afterSelected ? ed : null;
+ }
+ GUILayout.EndHorizontal();
+ }
+ //List<EquipPart> currentEquipPrefession = m_EquipList[m_professionIndex];
+ //for (int i = 0; i < currentEquipPrefession.Count; ++i)
+ //{
+ // EquipPart part = currentEquipPrefession[i];
+ // for (int j = 0; j < part.suitName.Count; ++j)
+ // {
+ // GUILayout.BeginHorizontal();
+ // EditorGUILayout.LabelField(part.suitName[j], GUILayout.MaxWidth(200));
+ // EditorGUILayout.LabelField(part.partPath[2], GUILayout.MaxWidth(150));
+ // if (j == 0)
+ // {
+ // if (GUILayout.Button("Preview", GUILayout.MaxWidth(100)))
+ // {
+ // Preview(m_professionIndex, part, -m_professionIndex, -2, -i);
+ // }
+ // }
+ // GUILayout.EndHorizontal();
+ // }
+ // GUILayout.Space(5);
+ //}
+ EditorGUILayout.EndScrollView();
+ GUILayout.EndVertical();
+
+ GUILayout.EndHorizontal();
+ GUILayout.Space(5);
+ GUILayout.BeginHorizontal();
+ GUILayout.BeginHorizontal();
+
+ customDir = EditorGUILayout.TextField("Dir", customDir, GUILayout.MaxWidth(250));
+ if(GUILayout.Button("Make", GUILayout.MaxWidth(50)))
+ {
+ string prefix = combineConfig.EquipPrefix[m_professionIndex];
+ for (int i = 0; i < customEquipDataList.Length; ++i)
+ {
+ EquipData ed = customEquipDataList[i];
+ ed.name = prefix + combineConfig.PartSuffix[i];
+ ed.path = string.Format("Equipments/{0}/{1}", customDir, ed.name);
+ }
+ Preview(0, 0, 0, customEquipDataList);
+ }
+ GUILayout.EndHorizontal();
+
+ //testFbx = EditorGUILayout.ObjectField(testFbx, typeof(GameObject), true) as GameObject;
+ //if (GUILayout.Button("Preview", GUILayout.MaxWidth(100)))
+ //{
+ // EquipPart ep = new EquipPart();
+ // ep.Init("Default");
+ // int prof = MakeTestEquip(ep);
+ // if (prof >= 0)
+ // Preview(prof, ep, 1, 0, 0);
+ //}
+ GUILayout.EndHorizontal();
+ //GUILayout.Space(5);
+ //GUILayout.BeginHorizontal();
+ //bool find = false;
+
+ //findEquip = EditorGUILayout.TextField(findEquip, GUILayout.MaxWidth(300));
+ //if (GUILayout.Button("Find", GUILayout.MaxWidth(100)))
+ //{
+ // find = true;
+ //}
+ //GUILayout.EndHorizontal();
+ //GUILayout.BeginHorizontal();
+ //equipPathScrollPos = GUILayout.BeginScrollView(equipPathScrollPos, false, false);
+ //for (int i = 0; i < meshPathList.Count; ++i)
+ //{
+ // EquipPathInfo epi = meshPathList[i];
+ // if (find)
+ // {
+ // string name = epi.name.ToLower();
+ // if (name.Contains(findEquip))
+ // {
+ // float currentFindHeight = i * 18;
+ // if (currentFindHeight > equipPathScrollPos.y)
+ // {
+ // find = false;
+ // equipPathScrollPos.y = currentFindHeight;
+ // }
+
+ // }
+ // }
+ // GUILayout.BeginHorizontal();
+ // EditorGUILayout.LabelField(epi.name, GUILayout.MaxWidth(300), GUILayout.MaxHeight(20));
+ // EditorGUILayout.LabelField(epi.texPath, GUILayout.MaxWidth(300));
+ // EditorGUILayout.LabelField((epi.type == XMeshPartList.NormalPart ? "normal" : (epi.type == XMeshPartList.CutoutPart ? "CutoutOnepart" : "Onepart")), GUILayout.MaxWidth(150));
+ // GUILayout.EndHorizontal();
+ // //EditorGUILayout.LabelField(string.Format("Name:{0} Tex:{1} Type:{2}", epi.name, epi.texPath, epi.type == 0 ? "normal" : (epi.type == 1 ? "CutoutOnepart" : "Onepart")), GUILayout.MaxWidth(800));
+ //}
+
+ //EditorGUILayout.EndScrollView();
+ //GUILayout.EndHorizontal();
+ }
+
+ void OnDestroy()
+ {
+ EditorUtility.UnloadUnusedAssetsImmediate();
+ }
+ }
+ //public class CvsTableEditor : EditorWindow
+ //{
+ // private UnityEngine.Object table = null;
+ // private string tableName = "";
+
+ // private List<string> scriptList = new List<string>();
+ // private string[] scriptArray;
+ // private int cvsIndex = -1;
+ // private string cvsName = "";
+ // private Assembly ass = null;
+ // public void Init(UnityEngine.Object obj)
+ // {
+ // if(obj==null)
+ // {
+ // table = null;
+ // tableName = "";
+ // cvsIndex = -1;
+ // return;
+ // }
+ // string path = AssetDatabase.GetAssetPath(obj);
+ // if (path.StartsWith("Assets/Table/") && path.EndsWith(".txt"))
+ // {
+ // table = obj;
+ // tableName = path.Replace("Assets/Table/", "");
+ // tableName = tableName.Replace(".txt", "");
+ // scriptList.Clear();
+ // ass = Assembly.Load("XUtliPoolLib");
+ // if (ass != null)
+ // {
+ // Type[] types = ass.GetExportedTypes();
+ // foreach (Type t in types)
+ // {
+ // if (t.IsSubclassOf(typeof(CVSReader)))
+ // {
+ // string firstWorld = t.Name.Substring(0, 1).ToUpper() + "/";
+ // scriptList.Add(firstWorld + t.Name);
+ // }
+ // }
+ // scriptList.Sort();
+ // scriptArray = scriptList.ToArray();
+ // }
+ // }
+ // }
+
+ // protected virtual void OnGUI()
+ // {
+ // if (table == null)
+ // return;
+ // GUILayout.BeginHorizontal();
+ // EditorGUILayout.LabelField("Table Init");
+ // if (GUILayout.Button("Generate", GUILayout.MaxWidth(150)))
+ // {
+ // if (ass != null && cvsName != "" && table != null)
+ // {
+ // Type readerType = ass.GetType("XUtliPoolLib." + cvsName, false);
+ // string des = "Assets/Resources/Table/" + tableName + ".bytes";
+ // //AssetModify._SaveBin(table as TextAsset, des, readerType);
+ // TableMap tableMap = XDataIO<TableMap>.singleton.DeserializeData("Assets/Editor/ResImporter/ImporterData/Table/Table.xml");
+ // if (tableMap != null)
+ // {
+ // bool find = false;
+ // for (int i = 0; i < tableMap.tableScriptMap.Count; ++i)
+ // {
+ // TableScriptMap tsm = tableMap.tableScriptMap[i];
+ // if (tsm.table == tableName)
+ // {
+ // tsm.script = cvsName;
+ // find = true;
+ // break;
+ // }
+ // }
+ // if (!find)
+ // {
+ // TableScriptMap newtsm = new TableScriptMap();
+ // newtsm.table = tableName;
+ // newtsm.script = cvsName;
+ // tableMap.tableScriptMap.Add(newtsm);
+ // }
+ // XDataIO<TableMap>.singleton.SerializeData("Assets/Editor/ResImporter/ImporterData/Table/Table.xml", tableMap);
+ // }
+ // }
+ // }
+ // GUILayout.EndHorizontal();
+ // GUILayout.BeginHorizontal();
+ // TextAsset tableObj = EditorGUILayout.ObjectField(table, typeof(TextAsset), true) as TextAsset;
+ // if(tableObj!=table)
+ // {
+ // Init(tableObj);
+ // }
+ // GUILayout.EndHorizontal();
+ // GUILayout.BeginHorizontal();
+ // int newSelect = EditorGUILayout.Popup(cvsIndex, scriptArray, GUILayout.MinWidth(110f));
+ // if (newSelect!= cvsIndex)
+ // {
+ // cvsName = scriptArray[newSelect].Substring(2);
+ // cvsIndex = newSelect;
+ // }
+ // GUILayout.EndHorizontal();
+
+ // }
+ //}
+
+ public class BytesTableViewEditor : EditorWindow
+ {
+ [Serializable]
+ public class PGCVSField
+ {
+ public string Name;
+ public string Type;
+ public string ClientType;
+ public string ColNameInExcel;
+ public int MakeIndex;
+ public bool ClientIndex = true;
+ public bool ServerOnly = false;
+ }
+
+ [Serializable]
+ public class PGCVSStruct
+ {
+ public string Name;
+ public string TableName;
+ public bool ServerOnly;
+
+ public List<PGCVSField> Fields = new List<PGCVSField>();
+ }
+ public class TableInfo
+ {
+ public List<PGCVSStruct> tables = new List<PGCVSStruct>();
+ }
+ private TableInfo tableInfo = new TableInfo();
+ //private UnityEngine.TextAsset table = null;
+ private string tableName = "";
+ private string scriptName = "";
+ private Type tableType = null;
+ private Type tableRowType = null;
+ private FieldInfo[] tableRowTypeField = null;
+ private CVSReader reader = null;
+ private FieldInfo tableListInfo = null;
+
+ private List<string> tableData = new List<string>();
+ private Vector2 scrollPos;
+ private GUILayoutOption scrollOp0 = null;
+ private int pageCount = 50;
+ private int totalPage = 0;
+ private int currentPage = 0;
+ private int gotoPage = 0;
+ private string searchKey = "";
+ private List<int> findLine = new List<int>();
+
+ public void Init(UnityEngine.Object obj)
+ {
+ if (obj == null)
+ {
+ tableName = "";
+ return;
+ }
+ string path = AssetDatabase.GetAssetPath(obj);
+ if (path.StartsWith("Assets/Resources/Table/") && path.EndsWith(".bytes"))
+ {
+ UnityEngine.TextAsset table = obj as TextAsset;
+ tableName = path.Replace("Assets/Resources/Table/", "");
+ tableName = tableName.Replace(".bytes", "");
+
+ Assembly ass = Assembly.Load("XUtliPoolLib");
+ if (ass != null)
+ {
+ XmlSerializer serializer = new XmlSerializer(tableInfo.tables.GetType());
+ try
+ {
+ string dataFilePath = @"..\XProject\Shell\cvs.xml";
+ FileStream fs = new FileStream(dataFilePath, FileMode.Open);
+ tableInfo.tables = (List<PGCVSStruct>)serializer.Deserialize(fs);
+ fs.Close();
+ }
+ catch (Exception e)
+ {
+ Debug.LogError(e.Message);
+ return;
+ }
+ if (tableInfo != null)
+ {
+ for (int i = 0; i < tableInfo.tables.Count; ++i)
+ {
+ PGCVSStruct tableStruct = tableInfo.tables[i];
+ if(string.IsNullOrEmpty(tableStruct.TableName))
+ {
+ //Debug.LogError("error table name:" + tableStruct.Name);
+ }
+ else
+ {
+ string[] tableNames = tableStruct.TableName.Split('|');
+ for (int j = 0; j < tableNames.Length; ++j)
+ {
+ if (tableNames[j] == tableName)
+ {
+ scriptName = tableStruct.Name;
+ tableType = ass.GetType("XUtliPoolLib." + scriptName, false);
+ if (tableType != null)
+ {
+ tableRowType = tableType.GetNestedType("RowData");
+ if (tableRowType != null)
+ {
+ tableRowTypeField = tableRowType.GetFields();
+ tableListInfo = tableType.GetField("Table");
+ reader = Activator.CreateInstance(tableType) as CVSReader;
+ if (reader != null)
+ {
+ CVSReader.Init();
+ XBinaryReader.Init();
+ XBinaryReader read = XBinaryReader.Get();
+ read.Init(table);
+ //Stream stream = new System.IO.MemoryStream(table.bytes);
+ reader.ReadFile(read);
+ XBinaryReader.Return(read);
+ System.Collections.IList tableList = null;
+ System.Collections.IDictionary dicList = null;
+ System.Object tableObj = tableListInfo.GetValue(reader);
+ tableList = tableObj as System.Collections.IList;
+ dicList = tableObj as System.Collections.IDictionary;
+ tableData.Clear();
+ if ((tableList != null || dicList != null) && tableRowTypeField != null)
+ {
+ System.Text.StringBuilder sb = new System.Text.StringBuilder();
+
+ string formatStr = "{{{0}:{1}}},";
+ string formatStrEnd = "{{{0}:{1}}}";
+ string format = "";
+ int count = tableList != null ? tableList.Count : dicList.Count;
+ var it = dicList != null ? dicList.GetEnumerator() : null;
+ for (int x = 0; x < count; ++x)
+ {
+ System.Object data = null;
+ if (tableList != null)
+ data = tableList[x];
+ else
+ {
+ it.MoveNext();
+ data = it.Value;
+ }
+
+
+ for (int y = 0; y < tableRowTypeField.Length; ++y)
+ {
+ FieldInfo fi = tableRowTypeField[y];
+ System.Object value = null;
+ if (data is string)
+ {
+ value = data;
+ }
+ else
+ {
+ value = fi.GetValue(data);
+ }
+ string str = "";
+ if (value is Array)
+ {
+ Array arr = value as Array;
+ System.Collections.IList lst = value as System.Collections.IList;
+ if (arr != null && lst != null)
+ {
+ for (int a = 0; a < arr.Length; ++a)
+ {
+ str += lst[a].ToString();
+ if (a != arr.Length - 1)
+ {
+ str += "|";
+ }
+ }
+ }
+ }
+ else
+ {
+ if (value != null)
+ {
+ str = value.ToString();
+ }
+ }
+ if (y != tableRowTypeField.Length - 1)
+ {
+ format = formatStrEnd;
+ }
+ else
+ {
+ format = formatStr;
+ }
+ sb.Append(string.Format(format, y, str));
+ }
+ tableData.Add(sb.ToString());
+ sb.Length = 0;
+ }
+ RefreshPage(tableData.Count);
+ }
+ }
+ }
+ }
+ return;
+ }
+ }
+ }
+
+
+ }
+ }
+ }
+ }
+ }
+ private void RefreshPage(int count)
+ {
+ currentPage = 0;
+ totalPage = count / pageCount;
+ if (tableData.Count % pageCount > 0)
+ {
+ totalPage++;
+ }
+ }
+
+ protected virtual void OnGUI()
+ {
+ if (scrollOp0 == null)
+ {
+ scrollOp0 = GUILayout.ExpandWidth(true);
+ }
+ GUILayout.BeginHorizontal();
+ EditorGUILayout.LabelField("Table");
+ GUILayout.EndHorizontal();
+
+ GUILayout.BeginHorizontal();
+
+ if (GUILayout.Button("Pre Page", GUILayout.Width(80)))
+ {
+ currentPage--;
+ if (currentPage < 0)
+ {
+ currentPage = 0;
+ }
+ }
+ if (GUILayout.Button("Next Page", GUILayout.Width(80)))
+ {
+ currentPage++;
+ if (currentPage >= totalPage)
+ {
+ currentPage = totalPage;
+ }
+ }
+ int page = EditorGUILayout.IntField(gotoPage, GUILayout.Width(80));
+ if (page != currentPage && page > 0 && page <= totalPage)
+ {
+ gotoPage = page;
+ }
+ if (GUILayout.Button("GoTo", GUILayout.Width(80)))
+ {
+ currentPage = gotoPage - 1;
+ }
+ GUILayout.Label(string.Format("Page:{0}/{1} Line:{2}", currentPage + 1, totalPage, tableData.Count));
+ if (GUILayout.Button("Export", GUILayout.Width(80)))
+ {
+ try
+ {
+ using (FileStream fs = new FileStream(string.Format("Assets/Resources/Table/{0}.txt", tableName), FileMode.Create))
+ {
+ StreamWriter sw = new StreamWriter(fs);
+
+ for (int i = 0; i < tableData.Count; ++i)
+ {
+ string col = tableData[i];
+ sw.WriteLine(col);
+ }
+ }
+ }
+ catch(Exception e)
+ {
+ Debug.LogError(e.Message);
+ }
+
+ }
+
+ string key = GUILayout.TextField(searchKey, GUILayout.Width(300));
+ if (searchKey != key)
+ {
+ searchKey = key;
+ if (searchKey == "")
+ {
+ RefreshPage(tableData.Count);
+ }
+ }
+ if (GUILayout.Button("Search", GUILayout.Width(80)) && searchKey != "")
+ {
+ findLine.Clear();
+ for (int i = 0; i < tableData.Count; ++i)
+ {
+ string col = tableData[i];
+ int index = col.IndexOf(searchKey);
+ if (index >= 0)
+ {
+ findLine.Add(i);
+ }
+ }
+ if (findLine.Count > 0)
+ {
+ RefreshPage(findLine.Count);
+ }
+ }
+
+ GUILayout.EndHorizontal();
+
+ if (tableRowTypeField != null)
+ {
+ GUILayout.BeginHorizontal();
+
+ scrollPos = GUILayout.BeginScrollView(scrollPos);
+ GUILayout.BeginHorizontal();
+ for (int i = 0; i < tableRowTypeField.Length; ++i)
+ {
+ FieldInfo fi = tableRowTypeField[i];
+ GUILayout.Button(string.Format("{0}:{1}", i, fi.Name));
+ }
+ GUILayout.EndHorizontal();
+ int endCount = (currentPage + 1) * pageCount;
+ if (findLine.Count > 0)
+ {
+ for (int i = currentPage * pageCount; i < findLine.Count && i < endCount; ++i)
+ {
+ int index = findLine[i];
+ string col = tableData[index];
+ GUILayout.BeginHorizontal();
+ GUILayout.TextField(col);
+ GUILayout.EndHorizontal();
+ }
+ }
+ else
+ {
+ for (int i = currentPage * pageCount; i < tableData.Count && i < endCount; ++i)
+ {
+ string col = tableData[i];
+ GUILayout.BeginHorizontal();
+ GUILayout.TextField(col);
+ GUILayout.EndHorizontal();
+ }
+ }
+
+ GUILayout.EndScrollView();
+ GUILayout.EndHorizontal();
+ }
+
+ }
+ }
+
+ //public class MaterialFindEditor : EditorWindow
+ //{
+ // //public enum EResType
+ // //{
+ // // Fx = 0,
+ // // UI,
+ // // Equipments,
+ // // Prefab,
+ // // Scene
+ // //}
+ // //class MatPrefab : INameCompare
+ // //{
+ // // public Material mat = null;
+ // // public List<GameObject> prefabs = new List<GameObject>();
+ // // public string Name
+ // // {
+ // // get
+ // // {
+ // // return mat != null ? mat.name : "";
+ // // }
+ // // }
+ // //}
+ // //private Dictionary<Shader,List<MatPrefab>> m_Shaders = new Dictionary<Shader, List<MatPrefab>>();
+ // //private List<MatPrefab> m_MaterialPrefabs = null;
+ // //private MatPrefab m_MatPrefab = null;
+ // //private Vector2 shaderScrollPos = Vector2.zero;
+ // //private Vector2 materialScrollPos = Vector2.zero;
+ // //private Vector2 prefabScrollPos = Vector2.zero;
+ // //private Shader m_SelectShader = null;
+
+ // //private EResType resType = EResType.Fx;
+ // //private NameSort<MatPrefab> matSort = new NameSort<MatPrefab>();
+ // //private Shader replaceShader = null;
+ // //private string[] resPaths = new string[] {
+ // // "Assets/Resources/Effects",
+ // // "Assets/Resources/atlas/UI",
+ // // "Assets/Resources/Equipments",
+ // // "Assets/Prefabs",
+ // // "Assets/XScene"};
+ // //private void FindMat(string prefabPath,GameObject prefab, Material mat)
+ // //{
+ // // if (mat == null)
+ // // {
+ // // Debug.LogError("null mat:" + prefabPath);
+ // // }
+ // // else
+ // // {
+ // // Shader shader = mat.shader;
+ // // List<MatPrefab> matPrefabs = null;
+ // // if (!m_Shaders.TryGetValue(shader, out matPrefabs))
+ // // {
+ // // matPrefabs = new List<MatPrefab>();
+ // // m_Shaders.Add(shader, matPrefabs);
+ // // }
+ // // foreach(MatPrefab mp in matPrefabs)
+ // // {
+ // // if(mp.mat==mat)
+ // // {
+ // // if(!mp.prefabs.Contains(prefab))
+ // // {
+ // // mp.prefabs.Add(prefab);
+ // // }
+ // // return;
+ // // }
+ // // }
+ // // MatPrefab newMp = new MatPrefab();
+ // // newMp.mat = mat;
+ // // newMp.prefabs.Add(prefab);
+ // // matPrefabs.Add(newMp);
+ // // }
+ // //}
+ // //private void FindMat(string path)
+ // //{
+ // // m_Shaders.Clear();
+ // // m_MaterialPrefabs = null;
+ // // m_MatPrefab = null;
+ // // DirectoryInfo di = new DirectoryInfo(path);
+ // // List<Renderer> renders = new List<Renderer>();
+
+ // // FileInfo[] files = di.GetFiles("*.prefab", SearchOption.AllDirectories);
+
+ // // for (int i = 0; i < files.Length; ++i)
+ // // {
+ // // FileInfo fi = files[i];
+ // // string prefabPath = fi.FullName.Replace("\\", "/");
+ // // int index = prefabPath.IndexOf(path);
+ // // prefabPath = prefabPath.Substring(index);
+ // // EditorUtility.DisplayProgressBar(string.Format("{0}-{1}/{2}", prefabPath, i, files.Length), path, (float)i / files.Length);
+
+ // // GameObject prefab = AssetDatabase.LoadAssetAtPath(prefabPath, typeof(GameObject)) as GameObject;
+ // // GameObject instance = GameObject.Instantiate(prefab) as GameObject;
+ // // instance.GetComponentsInChildren<Renderer>(true, renders);
+ // // //if (!isEquip)
+ // // {
+
+ // // for (int j = 0; j < renders.Count; ++j)
+ // // {
+ // // Renderer render = renders[j];
+ // // if(render is ParticleSystemRenderer)
+ // // {
+ // // ParticleSystemRenderer psr = render as ParticleSystemRenderer;
+ // // FindMat(prefabPath, prefab, psr.sharedMaterial);
+
+
+ // // }
+ // // else
+ // // {
+ // // Material[] mats = render.sharedMaterials;
+ // // foreach (Material mat in mats)
+ // // {
+ // // FindMat(prefabPath, prefab, mat);
+ // // }
+ // // }
+
+ // // }
+ // // }
+
+ // // GameObject.DestroyImmediate(instance);
+ // // }
+ // // EditorUtility.ClearProgressBar();
+ // //}
+
+
+ // //private void ReplaceShader(Shader des,List<MatPrefab> patPrefab)
+ // //{
+ // // foreach(MatPrefab mp in patPrefab)
+ // // {
+ // // if (mp.mat != null)
+ // // mp.mat.shader = des;
+ // // }
+ // //}
+ // //protected virtual void OnGUI()
+ // //{
+ // // GUILayout.BeginHorizontal();
+ // // resType = (EResType)EditorGUILayout.EnumPopup("资源目录", resType, GUILayout.MaxWidth(250));
+ // // GUILayout.EndHorizontal();
+ // // GUILayout.BeginHorizontal();
+ // // EditorGUILayout.ObjectField("SelectedShader", m_SelectShader, typeof(Shader), true, GUILayout.MaxWidth(450));
+ // // if (GUILayout.Button("Scan", GUILayout.MaxWidth(150)))
+ // // {
+ // // string resPath = resPaths[(int)resType];
+ // // FindMat(resPath);
+ // // }
+ // // GUILayout.EndHorizontal();
+ // // GUILayout.BeginHorizontal();
+
+ // // GUILayout.BeginVertical();
+ // // shaderScrollPos = GUILayout.BeginScrollView(shaderScrollPos, false, false,GUILayout.MaxHeight(400));
+ // // GUILayout.BeginHorizontal();
+ // // replaceShader = EditorGUILayout.ObjectField("TargetShader", replaceShader, typeof(Shader), true, GUILayout.MaxWidth(450)) as Shader;
+ // // GUILayout.EndHorizontal();
+ // // var it = m_Shaders.GetEnumerator();
+ // // while(it.MoveNext())
+ // // {
+ // // GUILayout.BeginHorizontal();
+ // // Shader shader = it.Current.Key;
+ // // EditorGUILayout.ObjectField(it.Current.Value.Count.ToString(), shader, typeof(Shader), true, GUILayout.MaxWidth(450));
+ // // if (GUILayout.Button("Select", GUILayout.MaxWidth(50)))
+ // // {
+ // // m_SelectShader = shader;
+ // // m_MaterialPrefabs = it.Current.Value;
+ // // m_MaterialPrefabs.Sort(matSort);
+ // // m_MatPrefab = null;
+ // // }
+ // // if (GUILayout.Button("Replace", GUILayout.MaxWidth(70)))
+ // // {
+ // // ReplaceShader(replaceShader, it.Current.Value);
+ // // }
+ // // GUILayout.EndHorizontal();
+ // // }
+ // // EditorGUILayout.EndScrollView();
+
+ // // GUILayout.EndVertical();
+
+ // // GUILayout.BeginVertical();
+ // // materialScrollPos = GUILayout.BeginScrollView(materialScrollPos, false, false, GUILayout.MaxHeight(400));
+ // // if(m_MaterialPrefabs != null)
+ // // {
+ // // for (int i = 0; i < m_MaterialPrefabs.Count; ++i)
+ // // {
+ // // GUILayout.BeginHorizontal();
+ // // MatPrefab mp = m_MaterialPrefabs[i];
+ // // EditorGUILayout.ObjectField(mp.prefabs.Count.ToString(), mp.mat, typeof(Material), true, GUILayout.MaxWidth(400));
+ // // if (GUILayout.Button("Prefab", GUILayout.MaxWidth(70)))
+ // // {
+ // // m_MatPrefab = mp;
+ // // }
+ // // GUILayout.EndHorizontal();
+ // // }
+ // // }
+
+ // // EditorGUILayout.EndScrollView();
+ // // GUILayout.EndVertical();
+ // // GUILayout.EndHorizontal();
+ // // GUILayout.BeginHorizontal();
+ // // GUILayout.BeginVertical();
+ // // prefabScrollPos = GUILayout.BeginScrollView(prefabScrollPos, false, false);
+ // // if (m_MatPrefab != null)
+ // // {
+ // // for (int i = 0; i < m_MatPrefab.prefabs.Count; ++i)
+ // // {
+ // // GameObject go = m_MatPrefab.prefabs[i];
+ // // GUILayout.BeginHorizontal();
+ // // EditorGUILayout.ObjectField("", go, typeof(GameObject), true, GUILayout.Width(300));
+ // // GUILayout.EndHorizontal();
+ // // }
+ // // }
+
+ // // EditorGUILayout.EndScrollView();
+ // // GUILayout.EndVertical();
+
+ // // GUILayout.EndHorizontal();
+ // //}
+
+ // //public string[] GetMaterialTexturePaths(Material _mat)
+ // //{
+ // // List<string> results = new List<string>();
+ // // UnityEngine.Object[] roots = new UnityEngine.Object[] { _mat };
+ // // UnityEngine.Object[] dependObjs = EditorUtility.CollectDependencies(roots);
+ // // foreach (UnityEngine.Object dependObj in dependObjs)
+ // // {
+ // // if (dependObj.GetType() == typeof(Texture2D))
+ // // {
+ // // string texpath = AssetDatabase.GetAssetPath(dependObj.GetInstanceID());
+ // // results.Add(texpath);
+ // // }
+ // // }
+ // // return results.ToArray();
+ // //}
+ //}
+
+
+
+
+ public class AssetFindEditor : EditorWindow
+ {
+ public enum EResType
+ {
+ Shader = 0,
+ Texture,
+ Mesh,
+ }
+ public enum EResFolder
+ {
+ Fx = 0,
+ UI,
+ Equip,
+ Prefab,
+ Scene,
+ SceneIOS,
+ }
+ interface INameCompare
+ {
+ string Name { get; }
+ }
+ class NameSort<T> : IComparer<T> where T : INameCompare
+ {
+ public int Compare(T x, T y)
+ {
+ return x.Name.CompareTo(y.Name);
+ }
+ }
+ interface ISizeCompare
+ {
+ int Size { get; }
+ }
+ delegate void OnResGUI();
+ delegate void ScanFun(string path);
+
+ private EResType m_ResType = EResType.Shader;
+ private EResFolder m_ResFolder = EResFolder.Fx;
+ private NameSort<MatPrefab> m_MatPrefabSort = new NameSort<MatPrefab>();
+ private OnResGUI[] onResGui = new OnResGUI[12];
+ private ScanFun[] onScan = new ScanFun[3];
+ private OnResGUI[] onHead = new OnResGUI[3];
+ private string[] m_ResPaths = new string[]
+ {
+ "Assets/Resources/Effects",
+ "Assets/Resources/atlas/UI|Assets/Resources/StaticUI|Assets/Resources/UI",
+ "Assets/Resources/Equipments",
+ "Assets/Resources/Prefabs",
+ "Assets/XScene|Assets/Resources/Skyboxes",
+ "Assets/XSceneIOS"
+ };
+ List<MeshFilter> mfList = new List<MeshFilter>();
+ List<SkinnedMeshRenderer> smrList = new List<SkinnedMeshRenderer>();
+ List<Renderer> renderList = new List<Renderer>();
+ List<UITexture> uiTextureList = new List<UITexture>();
+ private GUILayoutOption horizontalMaxWidth = null;
+ private GUILayoutOption horizontalMinWidth = null;
+ private GUILayoutOption horizontalMaxHeigth = null;
+ private GUILayoutOption horizontalMinHeigth = null;
+ private GUILayoutOption verticalMaxWidth = null;
+ private GUILayoutOption verticalMinWidth = null;
+ private GUILayoutOption verticalMaxHeigth = null;
+ private GUILayoutOption verticalMinHeigth = null;
+ private float m_Width = 800;
+ private float m_Height = 600;
+ class MatPrefab : INameCompare
+ {
+ public Material mat = null;
+ public List<GameObject> prefabs = new List<GameObject>();
+ public string Name
+ {
+ get
+ {
+ return mat != null ? mat.name : "";
+ }
+ }
+ }
+ private Dictionary<Material, MatPrefab> m_MatPrefabList = new Dictionary<Material, MatPrefab>();
+
+ private Vector2 m_MatScrollPos = Vector2.zero;
+ private Vector2 m_PrefabScrollPos = Vector2.zero;
+ private List<MatPrefab> m_SelectMatPrefabs = null;
+ private List<Material> m_FindMaterial = new List<Material>();
+ private MatPrefab m_SelectMatPrefab = null;
+ private void OnEnable()
+ {
+ Init();
+ }
+ #region Shader
+
+ private Dictionary<Shader, List<MatPrefab>> m_Shaders = new Dictionary<Shader, List<MatPrefab>>();
+ private Shader m_ShaderSelectShader = null;
+ private Shader m_ShaderReplaceShader = null;
+
+ private Vector2 m_ShaderScrollPos = Vector2.zero;
+ #endregion
+ #region Texture
+ public enum ETexSortType
+ {
+ Format,
+ Size
+ }
+ public enum ETexPlatform
+ {
+ Android,
+ iPhone
+ }
+ private class TexInfo : INameCompare
+ {
+ public Texture tex;
+ public string path = "";
+ public long sizeAndroid = 0;
+ public long sizeiPhone = 0;
+ public string androidFormatStr = "";
+ public string iPhoneFormatStr = "";
+ public bool mipmap = false;
+ public List<MatPrefab> matPrefab = new List<MatPrefab>();
+ public string Name
+ {
+ get
+ {
+ return tex != null ? tex.name : "";
+ }
+ }
+ }
+ private class TexListInfo : ISizeCompare
+ {
+ public int sizeKey = 0;
+ public string formatStr = "";
+ public string formatStr2 = "";
+ public List<TexInfo> texList = new List<TexInfo>();
+ public long size = 0;
+ public bool sorted = false;
+ public int Size
+ {
+ get
+ {
+ return sizeKey;
+ }
+ }
+ }
+ private ETexPlatform m_TexPlatform = ETexPlatform.Android;
+ private ETexSortType m_TexSortType = ETexSortType.Format;
+
+ private List<TexListInfo> m_TexFormatAndroidList = new List<TexListInfo>();
+ private List<TexListInfo> m_TexFormatiPhoneList = new List<TexListInfo>();
+ private List<TexListInfo> m_TexSizeAndroidList = new List<TexListInfo>();
+ private List<TexListInfo> m_TexSizeiPhoneList = new List<TexListInfo>();
+
+ private Dictionary<string, TexInfo> m_TexTexInfoMap = new Dictionary<string, TexInfo>();
+ private long m_TexTotalAndroidSize = 0;
+ private long m_TexTotaliPhoneSize = 0;
+ private int m_TexTotalCount = 0;
+ private string m_texMapName = "";
+ private TexListInfo m_TexSelectTexListInfo = null;
+ private TexInfo m_TexSelectTexInfo = null;
+ private Vector2 m_TexTypeScrollPos = Vector2.zero;
+ private Vector2 m_TexTexScrollPos = Vector2.zero;
+
+ private List<Texture> m_TexFindCache = new List<Texture>();
+ private NameSort<TexInfo> m_TexSort = new NameSort<TexInfo>();
+ private SizeSort<TexListInfo> m_TexListSort = new SizeSort<TexListInfo>();
+ #endregion
+ #region Mesh
+ public enum EMeshInfoCategory
+ {
+ Vertex = 0,
+ UV2,
+ Optimize,
+ Readable,
+ OptimizeGameObject,
+ Fbx,
+ Normal,
+ Tangents,
+ }
+
+
+ private class MeshInfo : ISizeCompare
+ {
+ public List<GameObject> PrefabList = new List<GameObject>();
+ public Mesh mesh = null;
+ public int vertexCount = 0;
+ public int triangleCount = 0;
+ public bool hasUV2 = false;
+ public bool optimize = false;
+ public bool readable = false;
+ public bool disaplyReadable = false;
+ public bool normal = true;
+ public bool tangents = false;
+ public bool optimizeGameObject = false;
+ public bool fbx = false;
+ public string meshPath = "";
+ public bool hasSkin = false;
+ public int Size
+ {
+ get
+ {
+ return vertexCount;
+ }
+ }
+
+ public void Export(bool readable)
+ {
+ if (meshPath == "")
+ meshPath = AssetDatabase.GetAssetPath(mesh);
+ if (fbx)
+ {
+ ModelImporter modelImporter = AssetImporter.GetAtPath(meshPath) as ModelImporter;
+ AssetModify.ExportMeshAvatar(modelImporter, meshPath, null);
+ }
+ else
+ {
+
+ string data = File.ReadAllText(meshPath);
+ if (readable)
+ {
+ data = data.Replace("m_IsReadable: 0", "m_IsReadable: 1");
+ }
+ else
+ {
+ data = data.Replace("m_IsReadable: 1", "m_IsReadable: 0");
+ }
+
+ File.WriteAllText(meshPath, data);
+ }
+ }
+ }
+
+ class SizeSort<T> : IComparer<T> where T : ISizeCompare
+ {
+ public int Compare(T x, T y)
+ {
+ return x.Size.CompareTo(y.Size);
+ }
+ }
+ private class SizeMeshInfo
+ {
+ public SizeMeshInfo(string name)
+ {
+ this.name = name;
+ }
+ public string name = "";
+ public List<MeshInfo> MeshList = new List<MeshInfo>();
+ public bool sorted = false;
+ public void Clear()
+ {
+ MeshList.Clear();
+ sorted = false;
+ }
+ }
+ private EMeshInfoCategory m_MeshInfoCategory = EMeshInfoCategory.Vertex;
+ private List<SizeMeshInfo> m_MeshSizeList = new List<SizeMeshInfo>();
+ private SizeMeshInfo m_MeshSelectedSizeMeshInfo = null;
+ private MeshInfo m_MeshSelectedMeshInfo = null;
+ private int m_MeshTotalCount = 0;
+
+ private Vector2 m_MeshSizeScrollPos = Vector2.zero;
+ private Vector2 m_MeshMeshScrollPos = Vector2.zero;
+ private Vector2 m_MeshPrefabScrollPos = Vector2.zero;
+ private SizeSort<MeshInfo> m_SizeSort = new SizeSort<MeshInfo>();
+ private GUIStyle redStyle = null;
+ #endregion
+ public void Init()
+ {
+ onResGui[0] = OnShaderInfoList;
+ onResGui[1] = OnShaderMatList;
+ onResGui[2] = OnPrefabList;
+ onResGui[3] = null;
+
+ onResGui[4] = OnTexInfoList;
+ onResGui[5] = OnTexTexList;
+ onResGui[6] = OnTexMatList;
+ onResGui[7] = OnPrefabList;
+
+ onResGui[8] = OnMeshSizeList;
+ onResGui[9] = OnMeshInfoList;
+ onResGui[10] = OnMeshPrefabList;
+ onResGui[11] = null;
+
+ onScan[0] = ScanShader;
+ onScan[1] = ScanTexture;
+ onScan[2] = ScanMesh;
+
+ onHead[0] = OnShaderHead;
+ onHead[1] = OnTexHead;
+ onHead[2] = OnMeshHead;
+
+ m_MeshSizeList.Clear();
+ m_MeshSizeList.Add(new SizeMeshInfo("0-200"));
+ m_MeshSizeList.Add(new SizeMeshInfo("201-500"));
+ m_MeshSizeList.Add(new SizeMeshInfo("501-1000"));
+ m_MeshSizeList.Add(new SizeMeshInfo("1001-1500"));
+ m_MeshSizeList.Add(new SizeMeshInfo("1500-"));
+
+ }
+ #region ShaderFun
+ void OnShaderHead()
+ {
+ m_ShaderSelectShader = EditorGUILayout.ObjectField("SelectedShader", m_ShaderSelectShader, typeof(Shader), true, GUILayout.MaxWidth(400)) as Shader;
+ if (GUILayout.Button("FindShader", GUILayout.MaxWidth(100)))
+ {
+ FindShader(m_ShaderSelectShader);
+ }
+ m_ShaderReplaceShader = EditorGUILayout.ObjectField("TargetShader", m_ShaderReplaceShader, typeof(Shader), true, GUILayout.MaxWidth(400)) as Shader;
+ if (GUILayout.Button("Replace", GUILayout.MaxWidth(70)))
+ {
+ ReplaceShader(m_ShaderReplaceShader, m_SelectMatPrefabs);
+ }
+
+ }
+ void OnShaderInfoList()
+ {
+ m_ShaderScrollPos = GUILayout.BeginScrollView(m_ShaderScrollPos, false, false, GUILayout.MaxHeight(400));
+ if (m_FindMaterial.Count != 0)
+ {
+ for (int i = 0; i < m_FindMaterial.Count; ++i)
+ {
+ Material mat = m_FindMaterial[i];
+ GUILayout.BeginHorizontal();
+ EditorGUILayout.ObjectField("", mat, typeof(Material), true, GUILayout.MaxWidth(450));
+ GUILayout.EndHorizontal();
+ }
+ }
+ else
+ {
+ var it = m_Shaders.GetEnumerator();
+ while (it.MoveNext())
+ {
+ GUILayout.BeginHorizontal();
+ Shader shader = it.Current.Key;
+ EditorGUILayout.ObjectField(it.Current.Value.Count.ToString(), shader, typeof(Shader), true, GUILayout.MaxWidth(450));
+ if (GUILayout.Button("Select", GUILayout.MaxWidth(50)))
+ {
+ m_SelectMatPrefabs = it.Current.Value;
+ m_SelectMatPrefab = null;
+ m_ShaderSelectShader = shader;
+ }
+ GUILayout.EndHorizontal();
+ }
+ }
+
+
+ EditorGUILayout.EndScrollView();
+ }
+ void OnShaderMatList()
+ {
+ OnMatList(m_ShaderSelectShader != null ? m_ShaderSelectShader.name : "");
+ }
+
+ void ScanShader(string path)
+ {
+ if (m_ResFolder == EResFolder.Scene || m_ResFolder == EResFolder.UI)
+ {
+ DirectoryInfo di = new DirectoryInfo(path);
+ FileInfo[] files = di.GetFiles("*.mat", SearchOption.AllDirectories);
+ for (int i = 0; i < files.Length; ++i)
+ {
+ FileInfo fi = files[i];
+ string matPath = fi.FullName.Replace("\\", "/");
+ int index = matPath.IndexOf(path);
+ matPath = matPath.Substring(index);
+
+ EditorUtility.DisplayProgressBar(string.Format("ScanSceneMat-{0}/{1}", i, files.Length), matPath, (float)i / files.Length);
+ Material mat = AssetDatabase.LoadAssetAtPath(matPath, typeof(Material)) as Material;
+ MatPrefab mp = null;
+ RecordMatPrefab("", null, mat, out mp);
+ RecordShderMatPrefab("", mat, mp);
+ }
+ EditorUtility.ClearProgressBar();
+ }
+ }
+
+ private void ReplaceShader(Shader des, List<MatPrefab> patPrefab)
+ {
+ foreach (MatPrefab mp in patPrefab)
+ {
+ if (mp.mat != null)
+ mp.mat.shader = des;
+ }
+ }
+
+ private void FindShader(Shader shader)
+ {
+ m_FindMaterial.Clear();
+ DirectoryInfo di = new DirectoryInfo("Assets/");
+ FileInfo[] files = di.GetFiles("*.mat", SearchOption.AllDirectories);
+ for (int i = 0; i < files.Length; ++i)
+ {
+ string path = files[i].FullName;
+ path = path.Replace("\\", "/");
+ int index = path.IndexOf("Assets/");
+ path = path.Substring(index);
+ Material mat = AssetDatabase.LoadAssetAtPath<Material>(path);
+ if (mat != null&& shader==mat.shader)
+ {
+ m_FindMaterial.Add(mat);
+ }
+ }
+ }
+ #endregion
+ #region TextureFun
+ void OnTexHead()
+ {
+ m_TexPlatform = (ETexPlatform)EditorGUILayout.EnumPopup("平台", m_TexPlatform, GUILayout.MaxWidth(250));
+ m_TexSortType = (ETexSortType)EditorGUILayout.EnumPopup("统计类型", m_TexSortType, GUILayout.MaxWidth(250));
+ if (m_TexPlatform == ETexPlatform.Android)
+ {
+ EditorGUILayout.LabelField(string.Format("Total Count:{0} TotalSize:{1}KB-{2}MB ", m_TexTotalCount, m_TexTotalAndroidSize / 1024, m_TexTotalAndroidSize / 1024 / 1024));
+ }
+ else
+ {
+ EditorGUILayout.LabelField(string.Format("Total Count:{0} TotalSize:{1}KB-{2}MB ", m_TexTotalCount, m_TexTotaliPhoneSize / 1024, m_TexTotaliPhoneSize / 1024 / 1024));
+ }
+ }
+ void OnTexInfoList()
+ {
+ m_TexTypeScrollPos = GUILayout.BeginScrollView(m_TexTypeScrollPos, false, false);
+
+ List<TexListInfo> texList = m_TexPlatform == ETexPlatform.Android ? m_TexFormatAndroidList : m_TexFormatiPhoneList;
+ if (m_TexSortType == ETexSortType.Size)
+ {
+ texList = m_TexPlatform == ETexPlatform.Android ? m_TexSizeAndroidList : m_TexSizeiPhoneList;
+ }
+ for (int i = 0; i < texList.Count; ++i)
+ {
+ GUILayout.BeginHorizontal();
+ TexListInfo texListInfo = texList[i];
+ string name = texListInfo.formatStr;
+ string name2 = texListInfo.formatStr2;
+ if (string.IsNullOrEmpty(name2))
+ {
+ EditorGUILayout.LabelField(string.Format("{0} Count:{1} Size:{2}KB-{3}MB ", name, texListInfo.texList.Count, texListInfo.size / 1024, texListInfo.size / 1024 / 1024), GUILayout.MaxWidth(400));
+ }
+ else
+ {
+ EditorGUILayout.LabelField(string.Format("{0}({4}) Count:{1} Size:{2}KB-{3}MB ", name, texListInfo.texList.Count, texListInfo.size / 1024, texListInfo.size / 1024 / 1024, name2), GUILayout.MaxWidth(400));
+ }
+
+ if (GUILayout.Button("Select", GUILayout.MaxWidth(50)))
+ {
+ m_TexSelectTexListInfo = texListInfo;
+ m_texMapName = name;
+ if (!m_TexSelectTexListInfo.sorted)
+ {
+ m_TexSelectTexListInfo.texList.Sort(m_TexSort);
+ m_TexSelectTexListInfo.sorted = true;
+ }
+ m_TexSelectTexInfo = null;
+ m_SelectMatPrefabs = null;
+ m_SelectMatPrefab = null;
+ }
+
+ GUILayout.EndHorizontal();
+ }
+ EditorGUILayout.EndScrollView();
+ }
+
+ void OnTexTexList()
+ {
+ if (m_TexSelectTexListInfo != null)
+ {
+ GUILayout.BeginHorizontal();
+ EditorGUILayout.LabelField(string.Format("Name:{0} Count:{1}", m_texMapName, m_TexSelectTexListInfo.texList.Count));
+ if (GUILayout.Button("CompressAll", GUILayout.MaxWidth(150)))
+ {
+ CompressTex(m_TexSelectTexListInfo);
+ }
+ if (GUILayout.Button("DisableMipmapAll", GUILayout.MaxWidth(150)))
+ {
+ DisableMipmap(m_TexSelectTexListInfo);
+ }
+ GUILayout.EndHorizontal();
+ m_TexTexScrollPos = GUILayout.BeginScrollView(m_TexTexScrollPos, false, false);
+ for (int i = 0; i < m_TexSelectTexListInfo.texList.Count; ++i)
+ {
+ TexInfo texInfo = m_TexSelectTexListInfo.texList[i];
+ GUILayout.BeginHorizontal();
+ EditorGUILayout.ObjectField(m_TexPlatform == ETexPlatform.Android ? texInfo.androidFormatStr : texInfo.iPhoneFormatStr, texInfo.tex, typeof(Texture), true);
+ if (GUILayout.Button("Compress", GUILayout.MaxWidth(70)))
+ {
+ Texture2D tex = texInfo.tex as Texture2D;
+ if (tex != null)
+ AssetModify.DefaultCompressTex(tex, texInfo.path, m_ResFolder == EResFolder.Equip, m_ResFolder == EResFolder.Equip);
+ }
+ if (texInfo.mipmap)
+ {
+ if (GUILayout.Button("DisableMipmap", GUILayout.MaxWidth(100)))
+ {
+ Texture2D tex = texInfo.tex as Texture2D;
+ if (tex != null)
+ {
+ AssetModify.EnableMipmap(tex, texInfo.path, false);
+ }
+ }
+ }
+ else
+ {
+ if (GUILayout.Button("OpenMipmap", GUILayout.MaxWidth(100)))
+ {
+ Texture2D tex = texInfo.tex as Texture2D;
+ if (tex != null)
+ {
+ AssetModify.EnableMipmap(tex, texInfo.path, true);
+ }
+ }
+ }
+
+ if (GUILayout.Button(string.Format("Mat:{0}", texInfo.matPrefab.Count), GUILayout.MaxWidth(50)))
+ {
+ m_TexSelectTexInfo = texInfo;
+ m_SelectMatPrefab = null;
+ }
+ GUILayout.EndHorizontal();
+ }
+ EditorGUILayout.EndScrollView();
+ }
+
+
+ }
+
+ void OnTexMatList()
+ {
+ if (m_TexSelectTexInfo != null)
+ {
+ m_SelectMatPrefabs = m_TexSelectTexInfo.matPrefab;
+ OnMatList(m_TexSelectTexInfo.Name);
+ }
+
+ }
+
+ private void ScanTexture(string path, string ext)
+ {
+ DirectoryInfo di = new DirectoryInfo(path);
+ FileInfo[] files = di.GetFiles(ext, SearchOption.AllDirectories);
+ for (int i = 0; i < files.Length; ++i)
+ {
+ FileInfo fi = files[i];
+ string texPath = fi.FullName.Replace("\\", "/");
+ int index = texPath.IndexOf(path);
+ texPath = texPath.Substring(index);
+
+ EditorUtility.DisplayProgressBar(string.Format("Scan{0}-{1}/{2}", ext, i, files.Length), path, (float)i / files.Length);
+ InnerScanTex(texPath);
+ }
+ EditorUtility.ClearProgressBar();
+ }
+
+ void ScanTexture(string path)
+ {
+ if (m_ResFolder == EResFolder.Equip || m_ResFolder == EResFolder.UI)
+ {
+ ScanTexture(path, "*.png");
+ ScanTexture(path, "*.tga");
+ }
+ }
+ private void ProcessTexListInfo(string formatStr, string formatStr2, List<TexListInfo> lst, TexInfo ti, long size, int sizeKey)
+ {
+ TexListInfo find = null;
+ for (int i = 0; i < lst.Count; ++i)
+ {
+ TexListInfo tli = lst[i];
+ if (tli.formatStr == formatStr)
+ {
+ if (string.IsNullOrEmpty(formatStr2) || formatStr2 == tli.formatStr2)
+ {
+ find = tli;
+ break;
+ }
+ }
+
+ }
+ if (find == null)
+ {
+ find = new TexListInfo();
+ find.formatStr = formatStr;
+ find.formatStr2 = formatStr2;
+ find.sizeKey = sizeKey;
+ lst.Add(find);
+ }
+ if (!find.texList.Contains(ti))
+ {
+ find.texList.Add(ti);
+ find.size += size;
+ }
+ }
+ private void RecordTexInfo(Texture tex, string path, TexInfo ti)
+ {
+ AssetImporter assetImport = AssetImporter.GetAtPath(path);
+ TextureImporter texImport = assetImport as TextureImporter;
+ if (texImport != null && tex != null)
+ {
+ ti.mipmap = texImport.mipmapEnabled;
+ TextureImporterPlatformSettings tipsAndroid = texImport.GetPlatformTextureSettings("Android");
+ TextureImporterPlatformSettings tipsiPhone = texImport.GetPlatformTextureSettings("iPhone");
+ long sizePer32Android = GetSize(tipsAndroid.format);
+ long sizePer32iPhone = GetSize(tipsiPhone.format);
+ ti.sizeAndroid = tex.width * tex.height * sizePer32Android / 4;
+ if (texImport.mipmapEnabled)
+ {
+ ti.sizeAndroid = (long)(ti.sizeAndroid * 1.33f);
+ }
+ string androidFormatStr = tipsAndroid.format.ToString();
+ string androidSizeStr = string.Format("{0}x{1}", tex.width, tex.height);
+
+
+
+ int iPhoneWidth = tex.width;
+ int iPhoneHeigh = tex.height;
+ string iPhoneSizeStr2 = "";
+
+ if (tipsiPhone.format == TextureImporterFormat.PVRTC_RGB4 ||
+ tipsiPhone.format == TextureImporterFormat.PVRTC_RGB2 ||
+ tipsiPhone.format == TextureImporterFormat.PVRTC_RGBA2 ||
+ tipsiPhone.format == TextureImporterFormat.PVRTC_RGBA4)
+ {
+
+ iPhoneWidth = tex.width > tex.height ? tex.width : tex.height;
+ iPhoneHeigh = iPhoneWidth;
+ TextureImporterFormat newFormat;
+ long uncompressed = GetUnCompressedSize(tipsiPhone.format, out newFormat);
+ long size = iPhoneWidth * iPhoneHeigh * sizePer32iPhone / 4;
+ long uncompressedsize = tex.width * tex.height * uncompressed / 4;
+ if (size < uncompressedsize)
+ {
+ if (tex.width != tex.height)
+ {
+ if (tipsiPhone.maxTextureSize <= tex.width && tipsiPhone.maxTextureSize <= tex.height)
+ {
+ iPhoneWidth = tipsiPhone.maxTextureSize;
+ iPhoneHeigh = tipsiPhone.maxTextureSize;
+ size = iPhoneWidth * iPhoneHeigh * sizePer32iPhone / 4;
+ }
+ else
+ {
+ iPhoneSizeStr2 = androidSizeStr;
+ }
+ }
+ }
+ else
+ {
+ iPhoneWidth = tex.width;
+ iPhoneHeigh = tex.height;
+ tipsiPhone.format = newFormat;
+ }
+
+ }
+ string iPhoneFormatStr = tipsiPhone.format.ToString();
+ string iPhoneSizeStr = string.Format("{0}x{1}", iPhoneWidth, iPhoneHeigh);
+ ti.sizeiPhone = iPhoneWidth * iPhoneHeigh * sizePer32iPhone / 4;
+ if (texImport.mipmapEnabled)
+ {
+ ti.sizeiPhone = (long)(ti.sizeiPhone * 1.33f);
+ }
+ ti.androidFormatStr = androidFormatStr;
+ ti.iPhoneFormatStr = iPhoneFormatStr;
+ ProcessTexListInfo(androidFormatStr, "", m_TexFormatAndroidList, ti, ti.sizeAndroid, 0);
+ ProcessTexListInfo(iPhoneFormatStr, "", m_TexFormatiPhoneList, ti, ti.sizeiPhone, 0);
+
+ ProcessTexListInfo(androidSizeStr, "", m_TexSizeAndroidList, ti, ti.sizeAndroid, tex.width * tex.height);
+ ProcessTexListInfo(iPhoneSizeStr, iPhoneSizeStr2, m_TexSizeiPhoneList, ti, ti.sizeiPhone, iPhoneWidth * iPhoneHeigh);
+
+ m_TexTotalAndroidSize += ti.sizeAndroid;
+ m_TexTotaliPhoneSize += ti.sizeiPhone;
+ m_TexTotalCount++;
+ }
+
+
+ }
+ private long GetUnCompressedSize(TextureImporterFormat format, out TextureImporterFormat newFormat)
+ {
+ long sizePer32 = 1;
+ newFormat = format;
+ switch (format)
+ {
+ case TextureImporterFormat.PVRTC_RGB4:
+ newFormat = TextureImporterFormat.RGB24;
+ sizePer32 = 12;
+ break;
+ case TextureImporterFormat.PVRTC_RGBA4:
+ newFormat = TextureImporterFormat.RGBA32;
+ sizePer32 = 16;
+ break;
+ case TextureImporterFormat.PVRTC_RGB2:
+ newFormat = TextureImporterFormat.RGB16;
+ sizePer32 = 6;
+ break;
+ case TextureImporterFormat.PVRTC_RGBA2:
+ newFormat = TextureImporterFormat.RGBA16;
+ sizePer32 = 8;
+ break;
+ }
+ return sizePer32;
+ }
+
+ private long GetSize(TextureImporterFormat format)
+ {
+ long sizePer32 = 1;
+ switch (format)
+ {
+ case TextureImporterFormat.ETC_RGB4:
+ case TextureImporterFormat.PVRTC_RGB4:
+ case TextureImporterFormat.PVRTC_RGBA4:
+ sizePer32 = 2;
+ break;
+ case TextureImporterFormat.PVRTC_RGB2:
+ case TextureImporterFormat.PVRTC_RGBA2:
+ sizePer32 = 1;
+ break;
+ case TextureImporterFormat.RGB16:
+ sizePer32 = 6;
+ break;
+ case TextureImporterFormat.RGBA16:
+ sizePer32 = 8;
+ break;
+ case TextureImporterFormat.RGB24:
+ sizePer32 = 12;
+ break;
+ case TextureImporterFormat.RGBA32:
+ sizePer32 = 16;
+ break;
+ case TextureImporterFormat.Alpha8:
+ sizePer32 = 4;
+ break;
+ }
+ return sizePer32;
+ }
+
+ private bool ProcessTex(string path, out TexInfo ti)
+ {
+ if (!m_TexTexInfoMap.TryGetValue(path, out ti))
+ {
+ ti = new TexInfo();
+ ti.path = path;
+ m_TexTexInfoMap.Add(path, ti);
+ return true;
+ }
+ return false;
+ }
+
+ private void InnerScanTex(string path)
+ {
+ TexInfo ti = null;
+ if (ProcessTex(path, out ti))
+ {
+ Texture tex = AssetDatabase.LoadAssetAtPath(path, typeof(Texture)) as Texture;
+ ti.tex = tex;
+ RecordTexInfo(tex, path, ti);
+ }
+ else
+ {
+ Debug.LogError(string.Format("null tex:{0}", path));
+ }
+ }
+
+ private TexInfo InnerScanTex(Texture tex, string prefabPath, string matName)
+ {
+ if (tex != null)
+ {
+ TexInfo ti = null;
+ string path = AssetDatabase.GetAssetPath(tex);
+ if (ProcessTex(path, out ti))
+ {
+ ti.tex = tex;
+ RecordTexInfo(tex, path, ti);
+ }
+ return ti;
+ }
+ else
+ {
+ Debug.LogError(string.Format("null tex,mat:{0} prefab:{1}", matName, prefabPath));
+ return null;
+ }
+ }
+ private void CompressTex(TexListInfo texListInfo)
+ {
+ for (int i = 0; i < texListInfo.texList.Count; ++i)
+ {
+ EditorUtility.DisplayProgressBar(string.Format("{0}-{1}/{2}", "compress tex", i, texListInfo.texList.Count), "", (float)i / texListInfo.texList.Count);
+ TexInfo ti = texListInfo.texList[i];
+ Texture2D tex = ti.tex as Texture2D;
+ if (tex != null)
+ {
+ AssetModify.DefaultCompressTex(tex, ti.path, m_ResFolder == EResFolder.Equip, m_ResFolder == EResFolder.Equip);
+ }
+ }
+ EditorUtility.ClearProgressBar();
+ AssetDatabase.Refresh();
+ }
+
+ private void DisableMipmap(TexListInfo texListInfo)
+ {
+ for (int i = 0; i < texListInfo.texList.Count; ++i)
+ {
+ EditorUtility.DisplayProgressBar(string.Format("{0}-{1}/{2}", "compress tex", i, texListInfo.texList.Count), "", (float)i / texListInfo.texList.Count);
+ TexInfo ti = texListInfo.texList[i];
+ Texture2D tex = ti.tex as Texture2D;
+ if (tex != null)
+ {
+ AssetModify.EnableMipmap(tex, ti.path, false);
+ }
+ }
+ EditorUtility.ClearProgressBar();
+ AssetDatabase.Refresh();
+ }
+
+ void ScanUI(GameObject prefab, GameObject instance, string prefabPath)
+ {
+ instance.GetComponentsInChildren<UITexture>(true, uiTextureList);
+ if (uiTextureList.Count > 0)
+ {
+ for (int i = 0; i < uiTextureList.Count; ++i)
+ {
+ UITexture uiTex = uiTextureList[i];
+ if (!string.IsNullOrEmpty(uiTex.texPath))
+ {
+ string path = "Assets/Resources/" + uiTex.texPath + ".png";
+ Texture tex = null;
+ if (!File.Exists(path))
+ Debug.LogError(string.Format("Tex not found:{0} prefab:{1} go:{2}", uiTex.texPath, prefabPath, uiTex.name));
+ else
+ {
+ tex = AssetDatabase.LoadAssetAtPath<Texture>(path);
+
+ }
+
+ if (tex != null)
+ {
+ int index = uiTex.texPath.LastIndexOf("/");
+ string alphapath = uiTex.texPath;
+ if (index >= 0 && index < uiTex.texPath.Length - 1)
+ {
+ alphapath = uiTex.texPath.Substring(index + 1);
+ }
+ else
+ {
+ Debug.LogError(string.Format("prefab:{0} texpath:{1} gameobject:{2}", prefabPath, uiTex.texPath, uiTex.name));
+ }
+ alphapath = "Assets/Resources/atlas/UI/Alpha/" + alphapath + "_A.png";
+ Texture alphaTex = AssetDatabase.LoadAssetAtPath<Texture>(alphapath);
+ Material uiTexMat = new Material(Shader.Find("Custom/UI/SeparateColorAlpha"));
+ uiTexMat.name = prefab.name;
+ MatPrefab mp = null;
+ RecordMatPrefab(prefabPath, prefab, uiTexMat, out mp);
+ RecordShderMatPrefab(prefabPath, uiTexMat, mp);
+ TexInfo ti = null;
+
+ if (ProcessTex(path, out ti))
+ {
+ ti.tex = tex;
+ RecordTexInfo(tex, path, ti);
+ }
+ if (ti != null)
+ {
+ if (!ti.matPrefab.Contains(mp))
+ {
+ ti.matPrefab.Add(mp);
+ }
+ }
+ if (alphaTex != null)
+ {
+ if (ProcessTex(alphapath, out ti))
+ {
+ ti.tex = alphaTex;
+ RecordTexInfo(alphaTex, alphapath, ti);
+ }
+ if (ti != null)
+ {
+ if (!ti.matPrefab.Contains(mp))
+ {
+ ti.matPrefab.Add(mp);
+ }
+ }
+ }
+
+ }
+
+
+ }
+ }
+ }
+
+ uiTextureList.Clear();
+ }
+ #endregion
+ #region MeshFun
+ void OnMeshHead()
+ {
+ EditorGUILayout.LabelField(string.Format("Total Count:{0}", m_MeshTotalCount));
+ if (m_MeshSelectedSizeMeshInfo != null)
+ {
+ EditorGUILayout.LabelField(string.Format("Mesh Size Type :{0}", m_MeshSelectedSizeMeshInfo.name));
+ int buttonState = 0;
+ if (GUILayout.Button("Readable", GUILayout.MaxWidth(100)))
+ {
+ buttonState = 1;
+ }
+ if (GUILayout.Button("NotReadable", GUILayout.MaxWidth(100)))
+ {
+ buttonState = 2;
+ }
+ if (buttonState != 0)
+ {
+ for (int i = 0; i < m_MeshSelectedSizeMeshInfo.MeshList.Count; ++i)
+ {
+ m_MeshSelectedSizeMeshInfo.MeshList[i].Export(buttonState == 1);
+ }
+ }
+ }
+ m_MeshInfoCategory = (EMeshInfoCategory)EditorGUILayout.EnumPopup("MeshInfo", m_MeshInfoCategory, GUILayout.MaxWidth(250));
+
+ }
+ void OnMeshSizeList()
+ {
+ m_MeshSizeScrollPos = GUILayout.BeginScrollView(m_MeshSizeScrollPos, false, false);
+ for (int i = 0; i < m_MeshSizeList.Count; ++i)
+ {
+ SizeMeshInfo smi = m_MeshSizeList[i];
+ GUILayout.BeginHorizontal();
+ EditorGUILayout.LabelField(string.Format("{0} Count:{1}", smi.name, smi.MeshList.Count));
+ if (GUILayout.Button("Select", GUILayout.MaxWidth(50)))
+ {
+ m_MeshSelectedSizeMeshInfo = smi;
+ if (!m_MeshSelectedSizeMeshInfo.sorted)
+ {
+ m_MeshSelectedSizeMeshInfo.MeshList.Sort(m_SizeSort);
+ m_MeshSelectedSizeMeshInfo.sorted = true;
+ }
+ m_MeshSelectedMeshInfo = null;
+ }
+ GUILayout.EndHorizontal();
+ }
+ EditorGUILayout.EndScrollView();
+ }
+ void OnMeshInfoList()
+ {
+ m_MeshMeshScrollPos = GUILayout.BeginScrollView(m_MeshMeshScrollPos, false, false);
+ if (m_MeshSelectedSizeMeshInfo != null)
+ {
+ bool nextRead = false;
+ for (int i = 0; i < m_MeshSelectedSizeMeshInfo.MeshList.Count; ++i)
+ {
+ bool readWarning = false;
+ if (nextRead)
+ {
+ readWarning = true;
+ nextRead = false;
+ }
+ MeshInfo mi = m_MeshSelectedSizeMeshInfo.MeshList[i];
+ if (i + 1 < m_MeshSelectedSizeMeshInfo.MeshList.Count)
+ {
+ MeshInfo nextMi = m_MeshSelectedSizeMeshInfo.MeshList[i + 1];
+ int vc = Math.Abs(mi.vertexCount - nextMi.vertexCount);
+ int index = Math.Abs(mi.triangleCount - nextMi.triangleCount);
+ if (vc < 1 && index < 1)
+ {
+ readWarning = true;
+ nextRead = true;
+ }
+ }
+ if (mi.mesh != null)
+ {
+ if (m_MeshInfoCategory != EMeshInfoCategory.Vertex)
+ {
+ readWarning = false;
+ }
+ GUILayout.BeginHorizontal();
+ if (redStyle == null)
+ {
+ redStyle = new GUIStyle();
+ redStyle.normal.textColor = Color.red;
+ }
+ string str = "";
+ switch (m_MeshInfoCategory)
+ {
+ case EMeshInfoCategory.Vertex:
+ str = string.Format("v:{0} t:{1}", mi.vertexCount, mi.triangleCount);
+ break;
+ case EMeshInfoCategory.Fbx:
+ str = mi.fbx ? "Fbx" : "";
+ break;
+ case EMeshInfoCategory.UV2:
+ str = mi.hasUV2 ? "UV2" : "";
+ break;
+ case EMeshInfoCategory.Optimize:
+ str = mi.optimize ? "Optimize" : "";
+ break;
+ case EMeshInfoCategory.Readable:
+ if(mi.disaplyReadable)
+ {
+ str = mi.readable ? "Readable" : "";
+ }
+ else
+ {
+ str = mi.readable ? "" : "NotReadable";
+ }
+ if(mi.hasSkin)
+ {
+ if(m_ResFolder== EResFolder.Equip)
+ {
+ if(mi.mesh.name.EndsWith("_weapon"))
+ {
+ if (mi.readable)
+ {
+ str = mi.readable ? "Readable" : "";
+ readWarning = true;
+ }
+ }
+ else
+ {
+ if (mi.readable)
+ {
+ str = "";
+ readWarning = false;
+ }
+ else
+ {
+ str = "NotReadable";
+ readWarning = true;
+ }
+ }
+
+ }
+ else
+ {
+ if (mi.readable)
+ {
+ str = mi.readable ? "Readable" : "";
+ readWarning = true;
+ }
+ }
+
+ }
+ else if (mi.disaplyReadable && mi.readable || !mi.disaplyReadable && !mi.readable)
+ {
+ readWarning = true;
+ }
+
+
+ break;
+ case EMeshInfoCategory.OptimizeGameObject:
+ str = mi.optimizeGameObject ? "OptimizeGameObject" : "";
+ break;
+ case EMeshInfoCategory.Normal:
+ str = mi.normal ? "Normal" : "";
+ break;
+ case EMeshInfoCategory.Tangents:
+ str = mi.tangents ? "Tangents" : "";
+ break;
+ }
+ if (readWarning)
+ {
+ EditorGUILayout.LabelField(str, redStyle, GUILayout.MaxWidth(150));
+ }
+ else
+ {
+ EditorGUILayout.LabelField(str, GUILayout.MaxWidth(150));
+ }
+
+ EditorGUILayout.ObjectField("", mi.mesh, typeof(Mesh), true, GUILayout.MaxWidth(450));
+ if (GUILayout.Button("Prefab", GUILayout.MaxWidth(50)))
+ {
+ m_MeshSelectedMeshInfo = mi;
+ }
+ if (GUILayout.Button("NoRead", GUILayout.MaxWidth(80)))
+ {
+ mi.Export(false);
+ }
+ if (GUILayout.Button("Read", GUILayout.MaxWidth(50)))
+ {
+ mi.Export(true);
+ }
+ GUILayout.EndHorizontal();
+ }
+
+ }
+ }
+ EditorGUILayout.EndScrollView();
+ }
+ void OnMeshPrefabList()
+ {
+ m_MeshPrefabScrollPos = GUILayout.BeginScrollView(m_MeshPrefabScrollPos, false, false);
+ if (m_MeshSelectedMeshInfo != null)
+ {
+ for (int i = 0; i < m_MeshSelectedMeshInfo.PrefabList.Count; ++i)
+ {
+ GUILayout.BeginHorizontal();
+ UnityEngine.Object obj = m_MeshSelectedMeshInfo.PrefabList[i];
+ if (obj != null)
+ {
+ EditorGUILayout.ObjectField("", obj, typeof(UnityEngine.Object), true);
+ }
+ GUILayout.EndHorizontal();
+ }
+ }
+ EditorGUILayout.EndScrollView();
+ }
+ private void InnerScanMesh(Mesh mesh, GameObject obj,string meshPath)
+ {
+ int vertexCount = mesh.vertexCount;
+ int index = 0;
+ bool displayReadable = m_ResFolder != EResFolder.Scene;
+ if (vertexCount >= 0 && vertexCount < 200)
+ {
+ index = 0;
+ }
+ else if (vertexCount >= 200 && vertexCount < 500)
+ {
+ index = 1;
+
+ }
+ else if (vertexCount >= 500 && vertexCount < 1000)
+ {
+ index = 2;
+ }
+ else if (vertexCount >= 1000 && vertexCount < 1500)
+ {
+ index = 3;
+ }
+ else
+ {
+ index = 4;
+ if (m_ResFolder == EResFolder.Scene)
+ displayReadable = true;
+ }
+
+ MeshInfo findMi = null;
+ SizeMeshInfo smi = m_MeshSizeList[index];
+ for (int i = 0; i < smi.MeshList.Count; ++i)
+ {
+ MeshInfo mi = smi.MeshList[i];
+ if (mi.mesh == mesh)
+ {
+ findMi = mi;
+ break;
+ }
+ }
+ if (findMi == null)
+ {
+ string path = AssetDatabase.GetAssetPath(mesh);
+ ModelImporter modelImporter = AssetImporter.GetAtPath(path) as ModelImporter;
+
+ findMi = new MeshInfo();
+ findMi.mesh = mesh;
+ smi.MeshList.Add(findMi);
+ findMi.vertexCount = vertexCount;
+ findMi.triangleCount = (int)mesh.GetIndexCount(0) / 3;
+ Vector2[] uv2 = mesh.uv2;
+ findMi.hasUV2 = uv2 != null && uv2.Length > 0;
+ findMi.readable = mesh.isReadable;
+ findMi.disaplyReadable = displayReadable;
+ findMi.hasSkin = mesh.bindposes.Length > 0;
+ Vector3[] normal = mesh.normals;
+ findMi.normal = normal != null && normal.Length > 0;
+ Vector4[] tangents = mesh.tangents;
+ findMi.tangents = tangents != null && tangents.Length > 0;
+ findMi.optimize = modelImporter != null ? modelImporter.optimizeMesh : true;
+ findMi.optimizeGameObject = modelImporter != null ? modelImporter.optimizeGameObjects : true;
+ findMi.fbx = modelImporter != null;
+ m_MeshTotalCount++;
+ }
+ if (obj != null)
+ {
+ int find = findMi.PrefabList.IndexOf(obj);
+ if (find < 0)
+ {
+ findMi.PrefabList.Add(obj);
+ }
+ }
+ }
+ void ScanMesh(GameObject prefab, GameObject instance)
+ {
+ instance.GetComponentsInChildren<MeshFilter>(true, mfList);
+ for (int j = 0; j < mfList.Count; ++j)
+ {
+ Mesh mesh = mfList[j].sharedMesh;
+ if (mesh != null)
+ InnerScanMesh(mesh, prefab,"");
+ }
+ mfList.Clear();
+ instance.GetComponentsInChildren<SkinnedMeshRenderer>(true, smrList);
+ for (int j = 0; j < smrList.Count; ++j)
+ {
+ Mesh mesh = smrList[j].sharedMesh;
+ if (mesh != null)
+ InnerScanMesh(mesh, prefab, "");
+ }
+ smrList.Clear();
+ }
+ void ScanMesh(string path)
+ {
+ DirectoryInfo di = new DirectoryInfo(path);
+ FileInfo[] files = di.GetFiles("*.asset", SearchOption.AllDirectories);
+ for (int i = 0; i < files.Length; ++i)
+ {
+ FileInfo fi = files[i];
+ string meshPath = fi.FullName.Replace("\\", "/");
+ int index = meshPath.IndexOf(path);
+ meshPath = meshPath.Substring(index);
+
+ EditorUtility.DisplayProgressBar(string.Format("Scan Mesh Asset-{0}/{1}", i, files.Length), path, (float)i / files.Length);
+ Mesh mesh = AssetDatabase.LoadAssetAtPath<Mesh>(meshPath);
+ if (mesh != null)
+ InnerScanMesh(mesh, null, meshPath);
+ }
+ EditorUtility.ClearProgressBar();
+ }
+ #endregion
+ #region common
+ private void RecordShderMatPrefab(string prefabPath, Material mat, MatPrefab mp)
+ {
+ Shader shader = mat.shader;
+ if (shader != null)
+ {
+ List<MatPrefab> mpList = null;
+ if (!m_Shaders.TryGetValue(shader, out mpList))
+ {
+ mpList = new List<MatPrefab>();
+ m_Shaders[shader] = mpList;
+ }
+ if (mp != null && mpList.IndexOf(mp) < 0)
+ {
+ mpList.Add(mp);
+ }
+ }
+ else
+ {
+ Debug.LogError("null shader:" + prefabPath);
+ }
+ }
+
+ private bool RecordMatPrefab(string prefabPath, GameObject prefab, Material mat, out MatPrefab mp)
+ {
+ bool matNotProcessed = false;
+ if (!m_MatPrefabList.TryGetValue(mat, out mp))
+ {
+ mp = new MatPrefab();
+ mp.mat = mat;
+ m_MatPrefabList.Add(mat, mp);
+ matNotProcessed = true;
+ }
+ if (prefab != null && !mp.prefabs.Contains(prefab))
+ mp.prefabs.Add(prefab);
+ return matNotProcessed;
+ }
+
+ private void InnerScanMat(string prefabPath, GameObject prefab, Material mat)
+ {
+ if (mat == null)
+ {
+ Debug.LogError("null mat:" + prefabPath);
+ }
+ else
+ {
+ MatPrefab mp = null;
+ RecordMatPrefab(prefabPath, prefab, mat, out mp);
+ RecordShderMatPrefab(prefabPath, mat, mp);
+ AssetModify.GetMatTex(mat, m_TexFindCache);
+ for (int i = 0; i < m_TexFindCache.Count; ++i)
+ {
+ Texture t = m_TexFindCache[i];
+ TexInfo ti = InnerScanTex(t, prefabPath, mat.name);
+ if (ti != null)
+ {
+ if (!ti.matPrefab.Contains(mp))
+ {
+ ti.matPrefab.Add(mp);
+ }
+ }
+ }
+ m_TexFindCache.Clear();
+ }
+ }
+
+ void ScanRender(GameObject prefab, GameObject instance, string prefabPath)
+ {
+ instance.GetComponentsInChildren<Renderer>(true, renderList);
+ for (int i = 0; i < renderList.Count; ++i)
+ {
+ Renderer render = renderList[i];
+ if (render is ParticleSystemRenderer)
+ {
+ ParticleSystemRenderer psr = render as ParticleSystemRenderer;
+ InnerScanMat(prefabPath, prefab, psr.sharedMaterial);
+ }
+ else
+ {
+ Material[] mats = render.sharedMaterials;
+ if (mats == null || mats.Length == 0)
+ {
+ Debug.LogError("no mat:" + prefabPath);
+ }
+ else
+ {
+ foreach (Material mat in mats)
+ {
+ InnerScanMat(prefabPath, prefab, mat);
+ }
+ }
+ }
+ }
+ renderList.Clear();
+ }
+ void Scan(int resType, string paths)
+ {
+ m_MatPrefabList.Clear();
+ m_MatScrollPos = Vector2.zero;
+ m_PrefabScrollPos = Vector2.zero;
+
+ m_SelectMatPrefabs = null;
+ m_SelectMatPrefab = null;
+ //shader
+ m_Shaders.Clear();
+ m_ShaderSelectShader = null;
+ m_ShaderReplaceShader = null;
+ m_FindMaterial.Clear();
+ //tex
+ m_TexFormatAndroidList.Clear();
+ m_TexFormatiPhoneList.Clear();
+ m_TexSizeAndroidList.Clear();
+ m_TexSizeiPhoneList.Clear();
+ m_TexTexInfoMap.Clear();
+ m_TexTotalAndroidSize = 0;
+ m_TexTotaliPhoneSize = 0;
+ m_TexTotalCount = 0;
+ m_texMapName = "";
+ m_TexSelectTexListInfo = null;
+ m_TexSelectTexInfo = null;
+ //mesh
+ for (int i = 0; i < m_MeshSizeList.Count; ++i)
+ {
+ m_MeshSizeList[i].Clear();
+ }
+ m_MeshSelectedSizeMeshInfo = null;
+ m_MeshSelectedMeshInfo = null;
+ m_MeshTotalCount = 0;
+
+ EditorUtility.UnloadUnusedAssetsImmediate();
+
+ string[] pathLst = paths.Split('|');
+ foreach (string path in pathLst)
+ {
+ DirectoryInfo di = new DirectoryInfo(path);
+ FileInfo[] files = files = di.GetFiles("*.prefab", SearchOption.AllDirectories);
+ for (int i = 0; i < files.Length; ++i)
+ {
+ FileInfo fi = files[i];
+ string prefabPath = fi.FullName.Replace("\\", "/");
+ int index = prefabPath.IndexOf(path);
+ prefabPath = prefabPath.Substring(index);
+ EditorUtility.DisplayProgressBar(string.Format("ScanPrefab-{0}/{1}", i, files.Length), path, (float)i / files.Length);
+
+ GameObject prefab = AssetDatabase.LoadAssetAtPath(prefabPath, typeof(GameObject)) as GameObject;
+ if (prefab != null)
+ {
+ GameObject instance = GameObject.Instantiate<GameObject>(prefab);
+ //mesh
+ ScanMesh(prefab, instance);
+ //render
+ ScanRender(prefab, instance, prefabPath);
+ //ui
+ ScanUI(prefab, instance, prefabPath);
+ GameObject.DestroyImmediate(instance);
+ }
+ }
+ EditorUtility.ClearProgressBar();
+ for (int i = 0; i < onScan.Length; ++i)
+ {
+ if (onScan[i] != null)
+ {
+ onScan[i](path);
+ }
+ }
+
+ }
+ m_TexFormatAndroidList.Sort(m_TexListSort);
+ m_TexFormatiPhoneList.Sort(m_TexListSort);
+ m_TexSizeAndroidList.Sort(m_TexListSort);
+ m_TexSizeiPhoneList.Sort(m_TexListSort);
+ }
+ #endregion
+ #region ui
+ void OnMatList(string name)
+ {
+ GUILayout.BeginHorizontal();
+ EditorGUILayout.LabelField(string.Format("Name:{0} Count:{1}", name, m_SelectMatPrefabs != null ? m_SelectMatPrefabs.Count : 0));
+ GUILayout.EndHorizontal();
+ if (m_SelectMatPrefabs != null)
+ {
+ m_MatScrollPos = GUILayout.BeginScrollView(m_MatScrollPos, false, false);
+ for (int i = 0; i < m_SelectMatPrefabs.Count; ++i)
+ {
+ MatPrefab mp = m_SelectMatPrefabs[i];
+ GUILayout.BeginHorizontal();
+
+ EditorGUILayout.ObjectField(mp.Name, mp.mat, typeof(Material), true, GUILayout.MaxWidth(450));
+ if (GUILayout.Button("Prefab", GUILayout.MaxWidth(70)))
+ {
+ m_SelectMatPrefab = mp;
+ }
+ GUILayout.EndHorizontal();
+ }
+ EditorGUILayout.EndScrollView();
+ }
+
+
+ }
+
+ void OnPrefabList()
+ {
+
+ if (m_SelectMatPrefab != null)
+ {
+ EditorGUILayout.LabelField(string.Format("Name:{0} Count:{1}", m_SelectMatPrefab.Name, m_SelectMatPrefab.prefabs.Count));
+ m_PrefabScrollPos = GUILayout.BeginScrollView(m_PrefabScrollPos, false, false);
+ for (int i = 0; i < m_SelectMatPrefab.prefabs.Count; ++i)
+ {
+ GameObject prefab = m_SelectMatPrefab.prefabs[i];
+ GUILayout.BeginHorizontal();
+ EditorGUILayout.ObjectField(prefab != null ? prefab.name : "", prefab, typeof(GameObject), true, GUILayout.MaxWidth(450));
+ GUILayout.EndHorizontal();
+ }
+ EditorGUILayout.EndScrollView();
+ }
+
+ }
+ void OnGUIBlock(OnResGUI onGuiLeft, OnResGUI onGuiRight)
+ {
+ //box left
+ GUILayout.BeginVertical(GUI.skin.box, verticalMaxWidth, verticalMinWidth, verticalMaxHeigth, verticalMinHeigth);
+ if (onGuiLeft != null)
+ {
+ onGuiLeft();
+ }
+ GUILayout.EndVertical();
+
+ //box right
+ GUILayout.BeginVertical(GUI.skin.box, verticalMaxWidth, verticalMinWidth, verticalMaxHeigth, verticalMinHeigth);
+ if (onGuiRight != null)
+ {
+ onGuiRight();
+ }
+ GUILayout.EndVertical();
+ }
+
+ void SizeChange()
+ {
+ bool change = false;
+ if (m_Width != this.position.width)
+ {
+ m_Width = this.position.width;
+ change = true;
+ }
+ if (m_Height != this.position.height)
+ {
+ m_Height = this.position.height;
+ change = true;
+ }
+ if (horizontalMaxWidth == null || change)
+ {
+ horizontalMaxWidth = GUILayout.MaxWidth(m_Width - 8);
+ }
+ if (horizontalMinWidth == null || change)
+ {
+ horizontalMinWidth = GUILayout.MinWidth(m_Width - 8);
+ }
+
+ if (horizontalMaxHeigth == null || change)
+ {
+ horizontalMaxHeigth = GUILayout.MaxHeight(m_Height / 2 - 30);
+ }
+ if (horizontalMinHeigth == null || change)
+ {
+ horizontalMinHeigth = GUILayout.MinHeight(m_Height / 2 - 30);
+ }
+
+ if (verticalMaxWidth == null || change)
+ {
+ verticalMaxWidth = GUILayout.MaxWidth(m_Width / 2 - 8);
+ }
+ if (verticalMinWidth == null || change)
+ {
+ verticalMinWidth = GUILayout.MinWidth(m_Width / 2 - 8);
+ }
+
+ if (verticalMaxHeigth == null || change)
+ {
+ verticalMaxHeigth = GUILayout.MaxHeight(m_Height / 2 - 30);
+ }
+ if (verticalMinHeigth == null || change)
+ {
+ verticalMinHeigth = GUILayout.MinHeight(m_Height / 2 - 30);
+ }
+ }
+
+ void OnGUI()
+ {
+ SizeChange();
+ GUILayout.BeginHorizontal();
+ m_ResType = (EResType)EditorGUILayout.EnumPopup("资源统计类型", m_ResType, GUILayout.MaxWidth(250));
+ m_ResFolder = (EResFolder)EditorGUILayout.EnumPopup("资源统计目录", m_ResFolder, GUILayout.MaxWidth(250));
+ int resType = (int)m_ResType;
+ if (GUILayout.Button("Scan", GUILayout.MaxWidth(150)))
+ {
+ string resFolder = m_ResPaths[(int)m_ResFolder];
+ Scan(resType, resFolder);
+ }
+ GUILayout.EndHorizontal();
+
+ //head line
+ GUILayout.BeginHorizontal();
+ if (onHead[resType] != null)
+ {
+ onHead[resType]();
+ }
+ GUILayout.EndHorizontal();
+
+ //box up
+ GUILayout.BeginHorizontal(GUI.skin.box, horizontalMaxWidth, horizontalMinWidth, horizontalMaxHeigth, horizontalMinHeigth);
+ OnGUIBlock(onResGui[resType * 4], onResGui[resType * 4 + 1]);
+ GUILayout.EndHorizontal();
+
+ //box down
+ GUILayout.BeginHorizontal(GUI.skin.box, horizontalMaxWidth, horizontalMinWidth, horizontalMaxHeigth, horizontalMinHeigth);
+ OnGUIBlock(onResGui[resType * 4 + 2], onResGui[resType * 4 + 3]);
+ GUILayout.EndHorizontal();
+ }
+ #endregion
+ }
+
+ public class TerrainEditor : EditorWindow
+ {
+ private Terrain terrain;
+ private Terrain[] terrains;
+ //[MenuItem(@"Assets/TerrainEditor", false, 0)]
+ //private static void EditTerrain()
+ //{
+ // TerrainEditor window = EditorWindow.GetWindow<TerrainEditor>("TerrainEditor", true);
+ // window.position = new Rect(100, 100, 1200, 800);
+ //}
+ private void ExportTerrainBlendTex(TerrainData td, List<Texture2D> texs)
+ {
+ float[,,] map = td.GetAlphamaps(0, 0, td.alphamapWidth, td.alphamapHeight);
+ int layerCount = map.GetLength(2);
+ if (layerCount == 0)
+ return;
+
+ for (int i = 0; i < layerCount; i += 4)
+ {
+ texs.Add(new Texture2D(td.alphamapWidth, td.alphamapHeight, TextureFormat.ARGB32, false));
+ }
+ int maxLayCount = texs.Count * 4;
+ float[] colorValue = new float[maxLayCount];
+ for (int y = 0; y < td.alphamapHeight; y++)
+ {
+ for (int x = 0; x < td.alphamapWidth; x++)
+ {
+ for (int i = 0; i < colorValue.Length; ++i)
+ {
+
+ if (i < layerCount)
+ {
+ colorValue[i] = map[y, x, i];
+ }
+ else
+ {
+ colorValue[i] = 0.0f;
+ }
+ }
+ int index = 0;
+ for (int i = 0; i < layerCount; i += 4)
+ {
+ Color c = new Color(colorValue[i], colorValue[i + 1], colorValue[i + 2], colorValue[i + 3]);
+ texs[index++].SetPixel(x, y, c);
+ }
+
+ }
+ }
+ for (int i = 0; i < texs.Count; ++i)
+ {
+ if (texs[i] != null)
+ texs[i].Apply();
+ }
+ }
+ private void ExportMesh()
+ {
+ if(terrain!=null)
+ {
+ TerrainData td = terrain.terrainData;
+
+
+ float width = td.size.x;
+ float length = td.size.z;
+
+ float heithMapWidthScale = td.heightmapWidth/width;
+ float heightMapLengthScale = td.heightmapHeight/length;
+
+ int widthVertexCount = td.alphamapWidth;
+ int lengthVertexCount = td.alphamapHeight;
+ float widthPerBlock = width / (float)(td.alphamapWidth - 1);
+ float lengthPerBlock = length / (float)(td.alphamapHeight - 1);
+ float uvPerBlock = 1.0f / (float)(td.alphamapWidth - 1);
+ List<Vector3> vertex = new List<Vector3>();
+ List<int> index = new List<int>();
+ List<Vector2> uv = new List<Vector2>();
+ //float minWidth = 30.0f;
+ //float minLength = 23.0f;
+ //float maxWidth = 138.3f;
+ //float maxLength = 130.3f;
+ for (int z = 0; z < lengthVertexCount - 1; ++z)
+ {
+ for (int x = 0; x < widthVertexCount - 1; ++x)
+ {
+ float currentX = x * widthPerBlock;
+ float currentY = z * lengthPerBlock;
+ //if (currentX >= minWidth && currentX <= maxWidth && currentY >= minLength && currentY <= maxLength)
+ {
+ int vertexIndex = vertex.Count;
+
+ index.Add(vertexIndex); index.Add(vertexIndex + 2); index.Add(vertexIndex + 1);
+ index.Add(vertexIndex); index.Add(vertexIndex + 3); index.Add(vertexIndex + 2);
+ Vector3 p0 = new Vector3(x * widthPerBlock, 0, z * lengthPerBlock);
+ p0.y = td.GetHeight((int)(p0.x * heithMapWidthScale), (int)(p0.z * heightMapLengthScale));
+ Vector3 p1 = new Vector3((x + 1) * widthPerBlock, 0, z * lengthPerBlock);
+ p1.y = td.GetHeight((int)(p1.x * heithMapWidthScale), (int)(p1.z * heightMapLengthScale));
+ Vector3 p2 = new Vector3((x + 1) * widthPerBlock, 0, (z + 1) * lengthPerBlock);
+ p2.y = td.GetHeight((int)(p2.x * heithMapWidthScale), (int)(p2.z * heightMapLengthScale));
+ Vector3 p3 = new Vector3(x * widthPerBlock, 0, (z + 1) * lengthPerBlock);
+ p3.y = td.GetHeight((int)(p3.x * heithMapWidthScale), (int)(p3.z * heightMapLengthScale));
+ vertex.Add(p0);
+ vertex.Add(p1);
+ vertex.Add(p2);
+ vertex.Add(p3);
+ Vector2 uv0 = new Vector2(x * uvPerBlock, z * uvPerBlock);
+ Vector2 uv1 = new Vector2((x + 1) * uvPerBlock, z * uvPerBlock);
+ Vector2 uv2 = new Vector2((x + 1) * uvPerBlock, (z + 1) * uvPerBlock);
+ Vector2 uv3 = new Vector2(x * uvPerBlock, (z + 1) * uvPerBlock);
+ uv.Add(uv0);
+ uv.Add(uv1);
+ uv.Add(uv2);
+ uv.Add(uv3);
+ }
+ }
+ }
+ UnityEngine.SceneManagement.Scene s = EditorSceneManager.GetActiveScene();
+ Mesh terrainMesh = new Mesh();
+ terrainMesh.name = s.name+ "_terrain";
+ terrainMesh.vertices = vertex.ToArray();
+ terrainMesh.triangles = index.ToArray();
+ terrainMesh.uv = uv.ToArray();
+ terrainMesh.uv2 = null;
+ MeshUtility.SetMeshCompression(terrainMesh, ModelImporterMeshCompression.Medium);
+ MeshUtility.Optimize(terrainMesh);
+ terrainMesh.UploadMeshData(true);
+ string sceneDir = "";
+
+ int j = s.path.LastIndexOf("/");
+ if(j >= 0)
+ {
+ sceneDir = s.path.Substring(0, j);
+ }
+ string terrainMehsPath = string.Format("{0}/{1}_terrain.asset", sceneDir, s.name);
+ AssetModify.CreateOrReplaceAsset<Mesh>(terrainMesh, terrainMehsPath);
+ List<Texture2D> texs = new List<Texture2D>();
+ ExportTerrainBlendTex(td, texs);
+ for (int i = 0; i < texs.Count; ++i)
+ {
+ if (texs[i] != null)
+ {
+ byte[] bytes = texs[i].EncodeToPNG();
+ string filePath = string.Format("{0}/{1}_{2}.png", sceneDir, s.name, i);
+ File.WriteAllBytes(filePath, bytes);
+ }
+ }
+ AssetDatabase.SaveAssets();
+ AssetDatabase.Refresh();
+
+ }
+
+ }
+ //private void DisplayTerrainInfo()
+ //{
+ // if (terrains != null)
+ // {
+ // for(int i=0;i< terrains.Length;++i)
+ // {
+ // TerrainData td = terrains[i].terrainData;
+
+ // }
+ // }
+
+ //}
+ protected virtual void OnGUI()
+ {
+ if(terrain==null)
+ {
+ terrain = Terrain.activeTerrain;
+ }
+ if (terrains == null)
+ {
+ terrains = Terrain.activeTerrains;
+ }
+ GUILayout.BeginHorizontal();
+ if (GUILayout.Button("ExportMesh", GUILayout.MaxWidth(100)))
+ {
+ ExportMesh();
+ }
+ GUILayout.EndHorizontal();
+ }
+ }
+}
+#endif
\ No newline at end of file diff --git a/Client/Assets/Scripts/XEditor/AssetModify.cs.meta b/Client/Assets/Scripts/XEditor/AssetModify.cs.meta new file mode 100644 index 00000000..3a37c779 --- /dev/null +++ b/Client/Assets/Scripts/XEditor/AssetModify.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2
+guid: 6c2b33b65d8dc4a4ba004f5623cd0553
+timeCreated: 1503462207
+licenseType: Pro
+MonoImporter:
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Client/Assets/Scripts/XEditor/CombineConfig.cs b/Client/Assets/Scripts/XEditor/CombineConfig.cs new file mode 100644 index 00000000..0ac62c1a --- /dev/null +++ b/Client/Assets/Scripts/XEditor/CombineConfig.cs @@ -0,0 +1,65 @@ +#if UNITY_EDITOR
+using UnityEngine;
+using System.Collections;
+using UnityEditor;
+public class CombineConfig : MonoBehaviour
+{
+ public string BodyString;//_body
+ public string LegString;//_leg
+ public string GloveString;//_glove
+ public string BootString;//_boots
+ public string HeadString;//_head
+ public string FaceString;//_face
+ public string HairString;//_hair
+ public string HelmetString;//_helmet
+
+ public int professionCount;
+
+ public string[] EquipFolderName;//Warrior,Sorcer,Archer,Cleric,Academic,Assassin
+ public string[] SecondaryWeapon;// _gauntlet,_book,_quiver,_shield,_gauntlet,_scimitar
+ public string[] BandposeName;//player_warrior_bandpose,player_archer_bandpose,player_sorceress_bandpose,player_cleric_bandpose,player_academic_bandpose,player_assassin_bandpose
+ public string[] PrefabName;//ZJ_zhanshi_SkinnedMesh,Player_archer_SkinnedMesh,Player_sorceress_SkinnedMesh,Player_cleric_SkinnedMesh,Player_academic_SkinnedMesh,Player_assassin_SkinnedMesh
+ public string[] CreateCharPrefabName;
+ public string[] SkillFolderName;//Player_warrior,Player_archer,Player_sorceress,Player_cleric,Player_academic,Player_assassin
+ public string[] IdleAnimName;
+ public string[] FashionListColumn;
+ public string[] EquipPrefix;
+ public string[] EquipPrefixReplace;
+ public string[] PartSuffix;
+
+ [MenuItem(@"Assets/Tool/Equipment/InitCombineConfig")]
+ public static void Init()
+ {
+ GameObject go = new GameObject("CombineConfig");
+ CombineConfig cc = go.AddComponent<CombineConfig>();
+ cc.BodyString = "_body";
+ cc.LegString = "_leg";
+ cc.GloveString = "_glove";
+ cc.BootString = "_boots";
+ cc.HeadString = "_head";
+ cc.FaceString = "_face";
+ cc.HairString = "_hair";
+ cc.HelmetString = "_helmet";
+ cc.professionCount = 6;
+ cc.EquipFolderName = new string[] { "/warrior", "/archer", "/sorcer", "/cleric", "/academic", "/assassin" };
+ cc.SecondaryWeapon = new string[] { "_gauntlet", "_quiver", "_book", "_shield", "_gauntlet", "_crook" };
+ cc.BandposeName = new string[] { "player_warrior_bandpose", "player_archer_bandpose", "player_sorceress_bandpose", "player_cleric_bandpose", "player_academic_bandpose", "player_assassin_bandpose" };
+ cc.PrefabName = new string[] { "ZJ_zhanshi_SkinnedMesh", "Player_archer_SkinnedMesh", "Player_sorceress_SkinnedMesh", "Player_cleric_SkinnedMesh", "Player_academic_SkinnedMesh", "Player_assassin_SkinnedMesh" };
+ cc.CreateCharPrefabName = new string[] { "Player_warrior_SkinnedMesh_createchar", "Player_archer_SkinnedMesh_createchar", "Player_sorceress_SkinnedMesh_createchar", "Player_cleric_SkinnedMesh_createchar", "Player_academic_SkinnedMesh_createchar", "Player_assassin_SkinnedMesh" };
+ cc.SkillFolderName = new string[] { "Player_warrior", "Player_archer", "Player_sorceress", "Player_cleric", "Player_academic", "Player_assassin" };
+ cc.IdleAnimName = new string[] { "Animation/Player_warrior/Player_warrior_idle_normal", "Animation/Player_archer/Player_archer_idle_normal", "Animation/Player_sorceress/Player_sorceress_stand_normal", "Animation/Player_cleric/Player_cleric_idle_normal", "Animation/Player_academic/Player_academic_idle_normal", "Animation/Player_assassin/Player_assassin_idle_normal" };
+ cc.FashionListColumn = new string[] { "ModelPrefabWarrior", "ModelPrefabArcher", "ModelPrefabSorcer", "ModelPrefabCleric", "ModelPrefab5", "ModelPrefab6" };
+ cc.EquipPrefix = new string[] { "wa_", "ar_", "so_", "cl_", "ac_", "as_" };
+ cc.EquipPrefixReplace = new string[] { "player_warrior_", "player_archer_", "player_sorceress_", "cl_normal02_", "player_academic_", "player_assassin_" };
+ cc.PartSuffix = new string[] { "face", "hair", "body", "leg", "glove", "boots", "second", "helmet","weapon" };
+ XEditor.AssetModify.CreateOrReplacePrefab(go, "Assets/Editor/EditorRes/CombineConfig.prefab");
+ GameObject.DestroyImmediate(go);
+ }
+
+ public static CombineConfig GetConfig()
+ {
+ GameObject go = AssetDatabase.LoadAssetAtPath("Assets/Editor/EditorRes/CombineConfig.prefab", typeof(GameObject)) as GameObject;
+ return go.GetComponent<CombineConfig>();
+ }
+}
+#endif
\ No newline at end of file diff --git a/Client/Assets/Scripts/XEditor/CombineConfig.cs.meta b/Client/Assets/Scripts/XEditor/CombineConfig.cs.meta new file mode 100644 index 00000000..90521865 --- /dev/null +++ b/Client/Assets/Scripts/XEditor/CombineConfig.cs.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2
+guid: a673f6d8226da2642a1699854b04bef1
+MonoImporter:
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
diff --git a/Client/Assets/Scripts/XEditor/LoadGameAtHere.cs b/Client/Assets/Scripts/XEditor/LoadGameAtHere.cs new file mode 100644 index 00000000..670c3cbe --- /dev/null +++ b/Client/Assets/Scripts/XEditor/LoadGameAtHere.cs @@ -0,0 +1,15 @@ +#if UNITY_EDITOR
+using UnityEngine;
+using System.Collections;
+using XUtliPoolLib;
+
+public class LoadGameAtHere : MonoBehaviour
+{
+ // Use this for initialization
+ void Start ()
+ {
+ if(null == XInterfaceMgr.singleton.GetInterface<IEntrance>(0))
+ UnityEngine.SceneManagement.SceneManager.LoadScene(0);
+ }
+}
+#endif
\ No newline at end of file diff --git a/Client/Assets/Scripts/XEditor/LoadGameAtHere.cs.meta b/Client/Assets/Scripts/XEditor/LoadGameAtHere.cs.meta new file mode 100644 index 00000000..2836f13d --- /dev/null +++ b/Client/Assets/Scripts/XEditor/LoadGameAtHere.cs.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2
+guid: c081edc5f06dece49a05acf7c1bbc619
+MonoImporter:
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
diff --git a/Client/Assets/Scripts/XEditor/MainFbx.cs b/Client/Assets/Scripts/XEditor/MainFbx.cs new file mode 100644 index 00000000..a4e81b1b --- /dev/null +++ b/Client/Assets/Scripts/XEditor/MainFbx.cs @@ -0,0 +1,65 @@ +#if UNITY_EDITOR
+using UnityEngine;
+using UnityEditor;
+using System.IO;
+
+public class MainFbx : MonoBehaviour
+{
+ public GameObject fbx;
+
+ public static void _MakeMainFbx(GameObject fbx)
+ {
+ string fbxPath = AssetDatabase.GetAssetPath(fbx).ToLower();
+ if(fbxPath.EndsWith("_bandpose.fbx"))
+ {
+ int index = fbxPath.LastIndexOf("/");
+ if (index >= 0)
+ {
+ string dir = fbxPath.Substring(0, index);
+ index = dir.LastIndexOf("/");
+ if (index >= 0)
+ {
+ string dirname = dir.Substring(index + 1);
+ GameObject mainFbx = new GameObject(dirname);
+ MainFbx mf = mainFbx.AddComponent<MainFbx>();
+ mf.fbx = fbx;
+ string prefabPath = dir + "/" + dirname + ".prefab";
+ XEditor.AssetModify.CreateOrReplacePrefab(mainFbx, prefabPath);
+ GameObject.DestroyImmediate(mainFbx);
+ }
+ }
+ }
+
+ }
+
+ [MenuItem(@"Assets/Tool/Fbx/MakeMainFbx")]
+ public static void MakeMainFbx()
+ {
+ GameObject[] fbxs = Selection.gameObjects;
+ if (fbxs.Length == 1)
+ {
+ _MakeMainFbx(fbxs[0]);
+ }
+ }
+
+ [MenuItem(@"Assets/Tool/Fbx/RefreshMainFbx")]
+ private static void RefreshMainFbx()
+ {
+ DirectoryInfo di = new DirectoryInfo("Assets/Creatures");
+ DirectoryInfo[] subDirs = di.GetDirectories("*.*", SearchOption.TopDirectoryOnly);
+ foreach (DirectoryInfo subDir in subDirs)
+ {
+ FileInfo[] files = subDir.GetFiles("*_bandpose.fbx", SearchOption.TopDirectoryOnly);
+ if (files.Length == 1)
+ {
+ string path = files[0].FullName.Replace("\\", "/");
+ int index = path.IndexOf("Assets/Creatures");
+ path = path.Substring(index);
+ GameObject fbx = AssetDatabase.LoadAssetAtPath<GameObject>(path);
+ _MakeMainFbx(fbx);
+ }
+ }
+ AssetDatabase.Refresh();
+ }
+}
+#endif
\ No newline at end of file diff --git a/Client/Assets/Scripts/XEditor/MainFbx.cs.meta b/Client/Assets/Scripts/XEditor/MainFbx.cs.meta new file mode 100644 index 00000000..5c119fa7 --- /dev/null +++ b/Client/Assets/Scripts/XEditor/MainFbx.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2
+guid: c34515b87c7bebb45a4bc09f369cfebe
+timeCreated: 1503296011
+licenseType: Pro
+MonoImporter:
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Client/Assets/Scripts/XEditor/Render2Texture.cs b/Client/Assets/Scripts/XEditor/Render2Texture.cs new file mode 100644 index 00000000..f4afd1bc --- /dev/null +++ b/Client/Assets/Scripts/XEditor/Render2Texture.cs @@ -0,0 +1,84 @@ +#if UNITY_EDITOR
+using System.IO;
+using UnityEngine;
+using UnityEditor;
+
+[RequireComponent(typeof(Camera))]
+public class Render2Texture : MonoBehaviour
+{
+
+ public Camera cameraCache;
+ public MeshRenderer mr;
+
+ public Texture2D Render(Texture src, Texture tex1, int width, int height, Vector2 tile, Vector2 offset, string shaderName)
+ {
+ if (cameraCache != null && mr != null)
+ {
+ Shader shader = Shader.Find(shaderName);
+ Material mat = new Material(shader);
+ mat.SetTexture("_MainTex", src);
+ if (mat.HasProperty("_Tex1"))
+ mat.SetTexture("_Tex1", tex1);
+ mat.SetTextureScale("_MainTex", tile);
+ mat.SetTextureOffset("_MainTex", offset);
+ width = width <= 0 ? src.width : width;
+ height = height <= 0 ? src.height : height;
+ RenderTexture current = RenderTexture.active;
+ RenderTexture rt = RenderTexture.GetTemporary(width, height, 0, RenderTextureFormat.ARGB32);
+ cameraCache.targetTexture = rt;
+ mr.sharedMaterial = mat;
+ cameraCache.Render();
+ Texture2D des = new Texture2D(src.width, src.height);
+ Graphics.SetRenderTarget(rt);
+ des.ReadPixels(new Rect(0, 0, rt.width, rt.height), 0, 0);
+ des.Apply();
+ GameObject.DestroyImmediate(mat);
+ Graphics.SetRenderTarget(current);
+ RenderTexture.ReleaseTemporary(rt);
+
+ return des;
+ }
+ return null;
+ }
+
+ public static Texture2D ScaleTexture(Texture src, string despath, int width, int height, Vector2 tile, Vector2 offset, string shaderName)
+ {
+ Texture2D tex = null;
+ GameObject prefab = AssetDatabase.LoadAssetAtPath<GameObject>("Assets/Editor/EditorRes/Render2Tex.prefab");
+ if(prefab!=null)
+ {
+ GameObject render2Tex = GameObject.Instantiate<GameObject>(prefab);
+ Render2Texture r2t = render2Tex.GetComponent<Render2Texture>();
+ if (r2t != null)
+ {
+ tex = r2t.Render(src, null, width, height, tile, offset, shaderName);
+ if (tex != null && !string.IsNullOrEmpty(despath))
+ {
+ byte[] bytes = tex.EncodeToPNG();
+ File.WriteAllBytes(despath, bytes);
+ AssetDatabase.Refresh();
+ }
+ }
+ GameObject.DestroyImmediate(render2Tex);
+ }
+ return tex;
+ }
+
+ public static Texture2D CompactTexture(Texture tex0, Texture tex1, int width, int height, Vector2 tile, Vector2 offset, string shaderName)
+ {
+ Texture2D tex = null;
+ GameObject prefab = AssetDatabase.LoadAssetAtPath<GameObject>("Assets/Editor/EditorRes/Render2Tex.prefab");
+ if (prefab != null)
+ {
+ GameObject render2Tex = GameObject.Instantiate<GameObject>(prefab);
+ Render2Texture r2t = render2Tex.GetComponent<Render2Texture>();
+ if (r2t != null)
+ {
+ tex = r2t.Render(tex0, tex1, width, height, tile, offset, shaderName);
+ }
+ GameObject.DestroyImmediate(render2Tex);
+ }
+ return tex;
+ }
+}
+#endif
\ No newline at end of file diff --git a/Client/Assets/Scripts/XEditor/Render2Texture.cs.meta b/Client/Assets/Scripts/XEditor/Render2Texture.cs.meta new file mode 100644 index 00000000..d9bd950a --- /dev/null +++ b/Client/Assets/Scripts/XEditor/Render2Texture.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2
+guid: 664ec7a85598d0b4ca1061e4c724542a
+timeCreated: 1505118927
+licenseType: Pro
+MonoImporter:
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Client/Assets/Scripts/XEditor/ReplaceEquip.cs b/Client/Assets/Scripts/XEditor/ReplaceEquip.cs new file mode 100644 index 00000000..2161ccbb --- /dev/null +++ b/Client/Assets/Scripts/XEditor/ReplaceEquip.cs @@ -0,0 +1,399 @@ +#if UNITY_EDITOR
+using System;
+using System.Collections.Generic;
+using UnityEngine;
+using UnityEditor;
+using XUtliPoolLib;
+using XEditor;
+using System.IO;
+
+public class ReplaceEquip : MonoBehaviour
+{
+ [Serializable]
+ public class ReplacePair
+ {
+ public string srcMeshName;
+ public string replaceEquipName;
+ public Texture2D replaceTex;
+ public bool isShareTex;
+ }
+ public GameObject fbx;
+ public string srcName;
+ public string replaceName;
+ public string srcDir;
+ public string targetDir;
+ [SerializeField]
+ public ReplacePair[] ReplaceMeshList;
+ static List<SkinnedMeshRenderer> smrList = new List<SkinnedMeshRenderer>();
+ static List<MeshFilter> mfList = new List<MeshFilter>();
+ static List<ReplacePair> rpList = new List<ReplacePair>();
+ public void Refresh()
+ {
+ if (fbx == null)
+ return;
+ string fbxPath = AssetDatabase.GetAssetPath(fbx).ToLower();
+
+ int profession = AssetModify.GetProfession(fbxPath);
+ if (profession < 0)
+ {
+ Debug.LogError("profession not found:"+ fbxPath);
+ return;
+ }
+ string srcDirName = AssetModify.MakeEquipDir(fbx.name, profession);
+ if (string.IsNullOrEmpty(srcDirName))
+ {
+ Debug.LogError("equip dir not generate");
+ return;
+ }
+ srcDir = "Equipments/" + srcDirName;
+ string targetDirName = srcDirName.Replace(srcName, replaceName);
+ targetDir = "Equipments/" + targetDirName;
+
+ GameObject fbxIns = GameObject.Instantiate<GameObject>(fbx);
+ rpList.Clear();
+ smrList.Clear();
+ fbxIns.GetComponentsInChildren<SkinnedMeshRenderer>(smrList);
+
+ foreach (SkinnedMeshRenderer smr in smrList)
+ {
+ ReplacePair rp = new ReplacePair();
+ rp.srcMeshName = smr.name;
+ if(smr.name.ToLower().EndsWith("_weapon"))
+ {
+ rp.replaceEquipName = AssetModify.MakeWeaponName(profession);
+ }
+ else
+ {
+ rp.replaceEquipName = AssetModify.MakeEquipName(smr.sharedMesh.name, profession, targetDirName);
+ }
+ if (smr.sharedMaterial != null)
+ {
+ Texture2D tex = smr.sharedMaterial.mainTexture as Texture2D;
+ string texPath = AssetDatabase.GetAssetPath(tex).ToLower();
+ string targetTexPath = texPath.Replace(srcName, replaceName);
+ rp.replaceTex = AssetDatabase.LoadAssetAtPath<Texture2D>(targetTexPath);
+ }
+ rpList.Add(rp);
+ }
+ smrList.Clear();
+ mfList.Clear();
+ fbxIns.GetComponentsInChildren<MeshFilter>(mfList);
+ foreach (MeshFilter mf in mfList)
+ {
+ ReplacePair rp = new ReplacePair();
+ rp.srcMeshName = mf.name;
+ rp.replaceEquipName = AssetModify.MakeWeaponName(profession);
+ MeshRenderer mr = mf.GetComponent<MeshRenderer>();
+ if (mr != null && mr.sharedMaterial != null)
+ {
+ Texture2D tex = mr.sharedMaterial.mainTexture as Texture2D;
+ string texPath = AssetDatabase.GetAssetPath(tex).ToLower();
+ string targetTexPath = texPath.Replace(srcName, replaceName);
+ rp.replaceTex = AssetDatabase.LoadAssetAtPath<Texture2D>(targetTexPath);
+ }
+ rpList.Add(rp);
+ }
+ mfList.Clear();
+ GameObject.DestroyImmediate(fbxIns);
+ ReplaceMeshList = rpList.ToArray();
+ rpList.Clear();
+ }
+
+ [MenuItem(@"Assets/Tool/Equipment/InitReplaceEquip")]
+ public static void Init()
+ {
+ GameObject[] objs = Selection.gameObjects;
+ AssetModify.InitCombineConfig();
+ foreach (GameObject obj in objs)
+ {
+ string path = AssetDatabase.GetAssetPath(obj).ToLower();
+ ReplaceEquip re = null;
+ GameObject replaceEquip = null;
+ bool save = false;
+ if (path.EndsWith(".prefab"))
+ {
+ re = obj.GetComponent<ReplaceEquip>();
+ }
+ else if (path.EndsWith(".fbx"))
+ {
+ replaceEquip = new GameObject(obj.name);
+ re = replaceEquip.AddComponent<ReplaceEquip>();
+ re.srcName = "01";
+ re.replaceName = "02";
+ re.fbx = obj;
+ save = true;
+ }
+ if (re == null)
+ {
+ if (replaceEquip != null)
+ {
+ GameObject.DestroyImmediate(replaceEquip);
+ }
+ continue;
+ }
+ re.Refresh();
+ if (save)
+ {
+ int index = path.LastIndexOf(".");
+ if (index > 0)
+ {
+ path = path.Substring(0, index) + ".prefab";
+ XEditor.AssetModify.CreateOrReplacePrefab(replaceEquip, path);
+ }
+ }
+
+ if (replaceEquip != null)
+ {
+ GameObject.DestroyImmediate(replaceEquip);
+ }
+ }
+ }
+ public void Process(bool make = true)
+ {
+ if (ReplaceMeshList != null)
+ {
+ string saveRootPath = "Assets/Resources/" + targetDir + "/";
+ if (make && !Directory.Exists(saveRootPath))
+ {
+ Directory.CreateDirectory(saveRootPath);
+ }
+ AssetModify.usedTex.Clear();
+ foreach (ReplacePair rp in ReplaceMeshList)
+ {
+ Texture2D tex = rp.replaceTex;
+ if (tex != null)
+ {
+ if (rp.replaceEquipName.EndsWith("_weapon"))
+ {
+ if(make)
+ {
+ string srcWeaponPrefab = string.Format("Assets/Resources/{0}/{1}.prefab", srcDir, rp.replaceEquipName);
+ string targetWeaponPrefab = string.Format("Assets/Resources/{0}/{1}.prefab", targetDir, rp.replaceEquipName);
+ GameObject srcWeapon = AssetDatabase.LoadAssetAtPath<GameObject>(srcWeaponPrefab);
+ if (srcWeapon != null)
+ {
+
+ Renderer render = srcWeapon.GetComponent<Renderer>();
+ if (render != null)
+ {
+ GameObject targetWeapon = GameObject.Instantiate<GameObject>(srcWeapon);
+ Renderer targetRender = targetWeapon.GetComponent<Renderer>();
+ targetWeapon.name = rp.replaceEquipName;
+ Material desMat = new Material(render.sharedMaterial);
+ desMat.name = rp.replaceTex.name;
+ desMat.mainTexture = rp.replaceTex;
+ AssetModify.DefaultCompressTex(rp.replaceTex, AssetDatabase.GetAssetPath(rp.replaceTex), true, true);
+ string srcMatPath = AssetDatabase.GetAssetPath(render.sharedMaterial);
+ int index = srcMatPath.LastIndexOf("/");
+ string targetMatPath = string.Format("{0}/{1}.mat", srcMatPath.Substring(0, index), desMat.name);
+ Material newMat = AssetModify.CreateOrReplaceAsset<Material>(desMat, targetMatPath);
+ targetRender.sharedMaterial = newMat;
+ AssetModify.CreateOrReplacePrefab(targetWeapon, targetWeaponPrefab);
+ GameObject.DestroyImmediate(targetWeapon);
+ }
+ }
+ else
+ {
+ Debug.LogError("null prefab:" + srcWeaponPrefab);
+ }
+ }
+ }
+ else
+ {
+ string srcMeshPath = srcDir + "/" + rp.replaceEquipName;
+ string replaceMeshPath = targetDir + "/" + rp.replaceEquipName;
+ AssetModify.PartTexInfo partTexInfo = null;
+ if (!AssetModify.usedTex.TryGetValue(tex.GetHashCode(), out partTexInfo))
+ {
+ string srcTexPath = AssetDatabase.GetAssetPath(tex);
+ partTexInfo = new AssetModify.PartTexInfo();
+ if (rp.isShareTex)
+ {
+ partTexInfo.texPath = "Equipments/" + targetDir + "/" + rp.replaceEquipName;
+ partTexInfo.isAlpha = File.Exists(partTexInfo.texPath + "_A.png");
+ }
+ else
+ {
+ bool isAlpha = false;
+ if(make)
+ {
+ string targetTexPath = saveRootPath + rp.replaceEquipName + ".tga";
+ AssetDatabase.CopyAsset(srcTexPath, targetTexPath);
+ Texture2D mainTex = AssetDatabase.LoadAssetAtPath<Texture2D>(targetTexPath);
+ Texture2D alphaTex = null;
+ if (File.Exists("Assets/Resources/Equipments/" + targetDir + "/" + rp.replaceEquipName + "_A.png"))
+ {
+ alphaTex = AssetModify.ConvertTexRtex(mainTex);
+ }
+ AssetModify.DefaultCompressTex(mainTex, targetTexPath, true, true);
+ isAlpha = alphaTex != null;
+ }
+ else
+ {
+ isAlpha = File.Exists(replaceMeshPath + "_A.png");
+ }
+
+ partTexInfo.texPath = replaceMeshPath;
+ partTexInfo.isAlpha = isAlpha;
+ AssetModify.usedTex.Add(tex.GetHashCode(), partTexInfo);
+ }
+ }
+ string prefix = "";
+ int index = rp.replaceEquipName.IndexOf("_");
+ if (index >= 0)
+ {
+ prefix = rp.replaceEquipName.Substring(0, index);
+ }
+ AssetModify.AddPart(srcMeshPath, replaceMeshPath, srcDir.Replace("Equipments/",""), partTexInfo.texPath, tex.width == 1024, partTexInfo.isAlpha, rp.isShareTex, prefix);
+ }
+ }
+ else
+ {
+ Debug.LogError("null tex:" + rp.srcMeshName);
+ }
+ }
+ }
+ }
+ [MenuItem(@"Assets/Tool/Equipment/MakeReplaceEquip")]
+ public static void MakeReplaceEquip()
+ {
+ AssetModify.InitCombineConfig();
+ AssetModify.LoadMeshPartInfo();
+ GameObject[] objs = Selection.gameObjects;
+
+ for (int i = 0; i < objs.Length; ++i)
+ {
+ GameObject obj = objs[i];
+ EditorUtility.DisplayProgressBar(string.Format("{0}-{1}/{2}", "Process GameObject", i, objs.Length), obj.name, (float)i / objs.Length);
+ string path = AssetDatabase.GetAssetPath(obj).ToLower();
+ ReplaceEquip re = null;
+ if (path.EndsWith(".prefab"))
+ {
+ re = obj.GetComponent<ReplaceEquip>();
+ }
+ if (re == null)
+ {
+ continue;
+ }
+ re.Process();
+ }
+ AssetModify.SaveEquipInfo();
+ AssetDatabase.Refresh();
+ EditorUtility.ClearProgressBar();
+ EditorUtility.DisplayDialog("Finish", "All objects processed finish", "OK");
+ }
+ //public void RefreshConfig()
+ //{
+ // if (ReplaceMeshList != null)
+ // {
+ // string saveRootPath = "Assets/Resources/" + targetDir + "/";
+ // AssetModify.usedTex.Clear();
+ // foreach (ReplacePair rp in ReplaceMeshList)
+ // {
+ // Texture2D tex = rp.replaceTex;
+ // if (tex != null)
+ // {
+ // if (!rp.replaceEquipName.EndsWith("_weapon"))
+ // {
+ // string srcMeshPath = srcDir + "/" + rp.srcMeshName;
+ // string replaceMeshPath = targetDir + "/" + rp.replaceEquipName;
+ // AssetModify.PartTexInfo partTexInfo = null;
+ // if (!AssetModify.usedTex.TryGetValue(tex.GetHashCode(), out partTexInfo))
+ // {
+ // string srcTexPath = AssetDatabase.GetAssetPath(tex);
+ // partTexInfo = new AssetModify.PartTexInfo();
+ // if (rp.isShareTex)
+ // {
+ // partTexInfo.texPath = "Equipments/" + srcDir + "/" + rp.replaceEquipName;
+ // partTexInfo.isAlpha = File.Exists(partTexInfo.texPath + "_A.png");
+ // }
+ // else
+ // {
+ // partTexInfo.texPath = replaceMeshPath;
+ // partTexInfo.isAlpha = File.Exists(partTexInfo.texPath + "_A.png");
+ // AssetModify.usedTex.Add(tex.GetHashCode(), partTexInfo);
+ // }
+ // }
+ // string prefix = "";
+ // int index = rp.srcMeshName.IndexOf("_");
+ // if(index>=0)
+ // {
+ // prefix = rp.srcMeshName.Substring(0, index);
+ // }
+ // AssetModify.AddPart(srcMeshPath, replaceMeshPath, rp.replaceEquipName, partTexInfo.texPath, tex.width == 1024, partTexInfo.isAlpha, rp.isShareTex, prefix);
+ // }
+ // }
+ // else
+ // {
+ // Debug.LogError("null tex:" + fbx.name);
+ // }
+ // }
+ // }
+ //}
+}
+
+[CanEditMultipleObjects, CustomEditor(typeof(ReplaceEquip))]
+public class ReplaceEquipEditor : Editor
+{
+ public override void OnInspectorGUI()
+ {
+ base.OnInspectorGUI();
+ if (GUILayout.Button("Refresh", GUILayout.MaxWidth(100)))
+ {
+ AssetModify.InitCombineConfig();
+ for (int i = 0; i < targets.Length; ++i)
+ {
+ ReplaceEquip re = targets[i] as ReplaceEquip;
+ if (re != null)
+ {
+ re.Refresh();
+ GameObject go = GameObject.Instantiate<GameObject>(re.gameObject);
+ PrefabUtility.ReplacePrefab(go, re.gameObject, ReplacePrefabOptions.ReplaceNameBased);
+ GameObject.DestroyImmediate(go);
+ }
+
+ }
+
+ }
+ if (GUILayout.Button("Make", GUILayout.MaxWidth(100)))
+ {
+ if(targets.Length>0)
+ {
+ AssetModify.InitCombineConfig();
+ AssetModify.LoadMeshPartInfo();
+ for (int i = 0; i < targets.Length; ++i)
+ {
+ ReplaceEquip re = targets[i] as ReplaceEquip;
+ EditorUtility.DisplayProgressBar(string.Format("{0}-{1}/{2}", "Process GameObject", i, targets.Length), "", (float)i / targets.Length);
+ if (re != null)
+ {
+ re.Process();
+ }
+ }
+ AssetModify.SaveEquipInfo();
+ AssetDatabase.Refresh();
+ EditorUtility.ClearProgressBar();
+ EditorUtility.DisplayDialog("Finish", "All objects processed finish", "OK");
+ }
+
+ }
+
+ }
+}
+public class EquipPathInfo : IComparable<EquipPathInfo>
+{
+ public string name = "";
+ public string texPath = "";
+ public byte type = 0;
+ public string newName = "";
+ public string newTexPath = "";
+ public Texture2D replaceTex = null;
+ public int CompareTo(EquipPathInfo other)
+ {
+ if (other == null)
+ return 1;
+ return name.CompareTo(other.name);
+ }
+}
+
+#endif
\ No newline at end of file diff --git a/Client/Assets/Scripts/XEditor/ReplaceEquip.cs.meta b/Client/Assets/Scripts/XEditor/ReplaceEquip.cs.meta new file mode 100644 index 00000000..9ff93202 --- /dev/null +++ b/Client/Assets/Scripts/XEditor/ReplaceEquip.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2
+guid: 3ebf6dcc14175374cb1d045f70f03716
+timeCreated: 1499084064
+licenseType: Pro
+MonoImporter:
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Client/Assets/Scripts/XEditor/SceneConfig.cs b/Client/Assets/Scripts/XEditor/SceneConfig.cs new file mode 100644 index 00000000..aa3c2075 --- /dev/null +++ b/Client/Assets/Scripts/XEditor/SceneConfig.cs @@ -0,0 +1,62 @@ +#if UNITY_EDITOR
+using UnityEngine;
+using System.Collections.Generic;
+using UnityEditor;
+public class SceneConfig : MonoBehaviour
+{
+ [System.Serializable]
+ public class TerrainMeshInfo
+ {
+ public bool enable = true;
+ public int lod = 1;
+ public List<LodArea> lodArea;
+ public List<Vector4> excludeArea;
+ public Vector4 area;
+ public TerrainMeshInfo(float widthPerBlockLod0, float lengthPerBlockLod0, int index,int terrainBlock)
+ {
+ int i = index % terrainBlock;
+ int j = index / terrainBlock;
+
+ float widthPerBlock = widthPerBlockLod0;
+ float lengthPerBlock = lengthPerBlockLod0;
+ int startX = i * 32;
+ int startZ = j * 32;
+ int endX = startX + 32;
+ int endZ = startZ + 32;
+
+ area.x = startX * widthPerBlockLod0;
+ area.y = startZ * lengthPerBlockLod0;
+
+ area.z = endX * widthPerBlockLod0;
+ area.w = endZ * lengthPerBlockLod0;
+
+ }
+ public void AddLodArea()
+ {
+ if (lodArea == null)
+ lodArea = new List<LodArea>();
+ lodArea.Add(new LodArea(area));
+ }
+ public void RemoveLodArea(int i)
+ {
+ if (lodArea != null)
+ {
+ lodArea.RemoveAt(i);
+ }
+ }
+ }
+ [System.Serializable]
+ public class LodArea
+ {
+ public Vector4 area;
+ public int lod = 1;
+ public LodArea(Vector4 a)
+ {
+ area = a;
+ }
+ }
+ public int terrainBlock;
+ public TerrainMeshInfo[] terrainMeshInfo;
+ public Vector4 terrainLightmapScaleOffset;
+}
+#endif
\ No newline at end of file diff --git a/Client/Assets/Scripts/XEditor/SceneConfig.cs.meta b/Client/Assets/Scripts/XEditor/SceneConfig.cs.meta new file mode 100644 index 00000000..61fec7ce --- /dev/null +++ b/Client/Assets/Scripts/XEditor/SceneConfig.cs.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2
+guid: c429025866e19bc498b7d4265f55bac3
+MonoImporter:
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
diff --git a/Client/Assets/Scripts/XEditor/XBehaviorTree.cs b/Client/Assets/Scripts/XEditor/XBehaviorTree.cs new file mode 100644 index 00000000..30b79ad8 --- /dev/null +++ b/Client/Assets/Scripts/XEditor/XBehaviorTree.cs @@ -0,0 +1,225 @@ +#if UNITY_EDITOR
+using XUtliPoolLib;
+using UnityEngine;
+using BehaviorDesigner.Runtime;
+using System.Collections.Generic;
+using System.IO;
+using System.Runtime.Serialization.Formatters.Binary;
+using BehaviorDesigner.Runtime.Tasks;
+using UnityEditor;
+
+public class XBehaviorTree : MonoBehaviour, IXBehaviorTree
+{
+ public static Dictionary<string, BehaviorSource> BehaviorCache = new Dictionary<string, BehaviorSource>();
+
+ public bool Deprecated
+ {
+ get;
+ set;
+ }
+
+ void Awake()
+ {
+ _behavior_tree = gameObject.AddComponent<BehaviorTree>();
+ }
+ public static BehaviorSource DeepClone(BehaviorSource source) //深clone
+ {
+ MemoryStream stream = new MemoryStream();
+ BinaryFormatter formatter = new BinaryFormatter();
+ formatter.Serialize(stream, source);
+ stream.Position = 0;
+ return formatter.Deserialize(stream) as BehaviorSource;
+ }
+
+ public void SetManual(bool enable)
+ {
+ if (enable)
+ BehaviorManager.instance.UpdateInterval = UpdateIntervalType.Manual;
+ }
+ public void TickBehaviorTree()
+ {
+ if (_behavior_tree != null)
+ BehaviorManager.instance.Tick(_behavior_tree);
+ }
+
+ public bool SetBehaviorTree(string name)
+ {
+ if (string.IsNullOrEmpty(name))
+ return false;
+
+ string location = "Assets/Behavior Designer/Behavior Data/" + name + ".asset";
+ ExternalBehaviorTree ebt = UnityEditor.AssetDatabase.LoadAssetAtPath(location, typeof(ExternalBehaviorTree)) as ExternalBehaviorTree;
+ _behavior_tree.ExternalBehavior = ebt;
+ _behavior_tree.RestartWhenComplete = true;
+
+ return true;
+ }
+
+ public void EnableBehaviorTree(bool enable)
+ {
+ if (_behavior_tree == null)
+ return;
+
+ if (enable)
+ _behavior_tree.EnableBehavior();
+ else
+ _behavior_tree.DisableBehavior();
+
+ }
+
+ public void OnStartSkill(uint skillid)
+ {
+ //List<XAIIsCastingSkill> castingSkills = _behavior_tree.FindTasks<XAIIsCastingSkill>();
+
+ //for (int i = 0; i < castingSkills.Count; i++)
+ // castingSkills[i].IsCastingSkill = true;
+
+ //List<XAITryCastSkill> trySkills = _behavior_tree.FindTasks<XAITryCastSkill>();
+ //for (int i = 0; i < trySkills.Count; i++)
+ // trySkills[i].CastSkillId = skillid;
+ }
+
+ public void OnEndSkill(uint skillid)
+ {
+ //List<XAIIsCastingSkill> castingSkills = _behavior_tree.FindTasks<XAIIsCastingSkill>();
+
+ //for (int i = 0; i < castingSkills.Count; i++)
+ // castingSkills[i].IsCastingSkill = false;
+ }
+
+ public void OnSkillHurt()
+ {
+ //List<XAIIsCastingSkill> isCasting = _behavior_tree.FindTasks<XAIIsCastingSkill>();
+
+ //for (int i = 0; i < isCasting.Count; i++)
+ // isCasting[i].IsHurt = true;
+ }
+
+ public float OnGetHeartRate()
+ {
+ if (_behavior_tree == null)
+ return 0;
+
+ SharedFloat innerRate = (SharedFloat)_behavior_tree.GetVariable("heartrate");
+ return innerRate.Value;
+ }
+
+ public void SetTarget(Transform target)
+ {
+ SharedTransform innertarget = (SharedTransform)_behavior_tree.GetVariable("target");
+
+ if (innertarget != null)
+ {
+ innertarget.SetValue(target);
+ }
+ }
+
+ public void SetNavPoint(Transform navpoint)
+ {
+ SharedTransform innernav = (SharedTransform)_behavior_tree.GetVariable("navtarget");
+
+ if (innernav != null)
+ {
+ innernav.SetValue(navpoint);
+ }
+ }
+
+ public void SetVariable(string name, object value)
+ {
+ if (_behavior_tree == null)
+ return;
+
+ SharedVariable sharedvar = _behavior_tree.GetVariable(name);
+
+ if (sharedvar != null)
+ {
+ sharedvar.SetValue(value);
+ }
+ }
+
+ public void SetIntByName(string name, int value)
+ {
+ if (_behavior_tree == null)
+ return;
+
+ SharedVariable sharedvar = _behavior_tree.GetVariable(name);
+
+ if (sharedvar != null)
+ {
+ sharedvar.SetValue(value);
+ }
+ }
+ public void SetFloatByName(string name, float value)
+ {
+ if (_behavior_tree == null)
+ return;
+
+ SharedVariable sharedvar = _behavior_tree.GetVariable(name);
+
+ if (sharedvar != null)
+ {
+ sharedvar.SetValue(value);
+ }
+ }
+ public void SetBoolByName(string name, bool value)
+ {
+ if (_behavior_tree == null)
+ return;
+
+ SharedVariable sharedvar = _behavior_tree.GetVariable(name);
+
+ if (sharedvar != null)
+ {
+ sharedvar.SetValue(value);
+ }
+ }
+ public void SetVector3ByName(string name, Vector3 value)
+ {
+ if (_behavior_tree == null)
+ return;
+
+ SharedVariable sharedvar = _behavior_tree.GetVariable(name);
+
+ if (sharedvar != null)
+ {
+ sharedvar.SetValue(value);
+ }
+ }
+ public void SetTransformByName(string name, Transform value)
+ {
+ if (_behavior_tree == null)
+ return;
+
+ SharedVariable sharedvar = _behavior_tree.GetVariable(name);
+
+ if (sharedvar != null)
+ {
+ sharedvar.SetValue(value);
+ }
+ }
+ public void SetXGameObjectByName(string name, XGameObject value)
+ {
+ if(_behavior_tree == null)
+ return;
+
+ SharedVariable sharedvar = _behavior_tree.GetVariable(name);
+
+ if (sharedvar != null)
+ {
+ sharedvar.SetValue(value == null ? null : value.Find(""));
+ }
+ }
+
+ public static AudioClip GetAudioClip(string path)
+ {
+#if UNITY_EDITOR
+ AudioClip clip = UnityEditor.AssetDatabase.LoadAssetAtPath(path, typeof(AudioClip)) as AudioClip;
+ return clip;
+#else
+ return null;
+#endif
+ }
+
+ private BehaviorTree _behavior_tree = null;
+}
+#endif
\ No newline at end of file diff --git a/Client/Assets/Scripts/XEditor/XBehaviorTree.cs.meta b/Client/Assets/Scripts/XEditor/XBehaviorTree.cs.meta new file mode 100644 index 00000000..abf85227 --- /dev/null +++ b/Client/Assets/Scripts/XEditor/XBehaviorTree.cs.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2
+guid: 977f57dd6f0609645986383a875f4e02
+MonoImporter:
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
diff --git a/Client/Assets/Scripts/XEditor/XCharacterMaterial.cs b/Client/Assets/Scripts/XEditor/XCharacterMaterial.cs new file mode 100644 index 00000000..4e43dda2 --- /dev/null +++ b/Client/Assets/Scripts/XEditor/XCharacterMaterial.cs @@ -0,0 +1,45 @@ +#if UNITY_EDITOR
+using UnityEditor;
+using UnityEngine;
+using XEditor;
+using XUtliPoolLib;
+using System.Collections.Generic;
+
+public enum EEquipType
+{
+ Archer,
+ Cleric,
+ Sorcer,
+ Warrior,
+ Academic,
+ Spirit,
+ Tail,
+ Wing,
+ Char,
+ SelectChar,
+ Creator
+}
+public class XCharacterMaterial : MonoBehaviour
+{
+ //private string characterType = "Archer";
+ public Material mat = null;
+ private SkinnedMeshRenderer skin = null;
+ public void OnAttached()
+ {
+ skin = gameObject.GetComponentInChildren<SkinnedMeshRenderer>();
+
+ }
+
+ void Update()
+ {
+ if(mat!=null&&mat!= skin.sharedMaterial)
+ {
+
+ mat.CopyPropertiesFromMaterial(skin.sharedMaterial);
+ skin.sharedMaterial = mat;
+
+ }
+ }
+
+}
+#endif
\ No newline at end of file diff --git a/Client/Assets/Scripts/XEditor/XCharacterMaterial.cs.meta b/Client/Assets/Scripts/XEditor/XCharacterMaterial.cs.meta new file mode 100644 index 00000000..6c00d8df --- /dev/null +++ b/Client/Assets/Scripts/XEditor/XCharacterMaterial.cs.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2
+guid: bc13215ef9a18b34680dcc091c054a55
+MonoImporter:
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
diff --git a/Client/Assets/Scripts/XEditor/XCutSceneEditor.meta b/Client/Assets/Scripts/XEditor/XCutSceneEditor.meta new file mode 100644 index 00000000..e06310d0 --- /dev/null +++ b/Client/Assets/Scripts/XEditor/XCutSceneEditor.meta @@ -0,0 +1,5 @@ +fileFormatVersion: 2
+guid: 700c1cc4ea0385749999c386755f001c
+folderAsset: yes
+DefaultImporter:
+ userData:
diff --git a/Client/Assets/Scripts/XEditor/XCutSceneEditor/XActor.cs b/Client/Assets/Scripts/XEditor/XCutSceneEditor/XActor.cs new file mode 100644 index 00000000..10da6925 --- /dev/null +++ b/Client/Assets/Scripts/XEditor/XCutSceneEditor/XActor.cs @@ -0,0 +1,169 @@ +#if UNITY_EDITOR
+using UnityEngine;
+using XEditor;
+using XUtliPoolLib;
+using UnityEditor;
+
+namespace XEditor
+{
+ internal class XActor
+ {
+ private GameObject _actor = null;
+ private Transform _shadow = null;
+ private Transform _bip = null;
+ private Animator _ator = null;
+
+ private static Terrain _terrain = null;
+
+ private AudioSource _audio_motion = null;
+ private AudioSource _audio_action = null;
+ private AudioSource _audio_skill = null;
+
+ static XActor()
+ {
+ _terrain = Terrain.activeTerrain;
+ /*if (_terrain == null)
+ {
+ SceneTable.RowData sceneConf = XSceneMgr.singleton.GetSceneData(_scene_id);
+ if (sceneConf.BlockFilePath.Length > 0)
+ {
+ _grid = new XGrid();
+ if (!_grid.LoadFile(@"Assets\Resources\" + sceneConf.BlockFilePath))
+ {
+ Debug.Log(@"Load Grid file: Assets\Resources\" + sceneConf.BlockFilePath + " failed!");
+ _grid = null;
+ }
+ }
+ }*/
+ }
+
+ public GameObject Actor { get { return _actor; } }
+ public Transform Bip { get { return _bip; } }
+
+ public XActor(float x, float y, float z, string clip)
+ {
+ _actor = AssetDatabase.LoadAssetAtPath("Assets/Editor/EditorResources/Prefabs/ZJ_zhanshi.prefab", typeof(GameObject)) as GameObject;
+ _actor = UnityEngine.Object.Instantiate(_actor) as GameObject;
+ DisablePhysic();
+ _actor.transform.position = new Vector3(x, y, z);
+ _ator = _actor.GetComponent<Animator>();
+
+ AnimatorOverrideController overrideController = new AnimatorOverrideController();
+
+ overrideController.runtimeAnimatorController = _ator.runtimeAnimatorController;
+ _ator.runtimeAnimatorController = overrideController;
+
+ overrideController["Idle"] = XResourceLoaderMgr.singleton.GetSharedResource<AnimationClip>(clip, ".anim");
+
+ _shadow = _actor.transform.Find("Shadow");
+ if (_shadow != null) _shadow.GetComponent<Renderer>().enabled = true;
+
+ _ator.cullingMode = AnimatorCullingMode.AlwaysAnimate;
+ }
+
+ public XActor(string prefab, float x, float y, float z, string clip)
+ {
+ _actor = XResourceLoaderMgr.singleton.CreateFromPrefab(prefab, new Vector3(x, y, z), Quaternion.identity) as GameObject;
+ _ator = _actor.GetComponent<Animator>();
+ DisablePhysic();
+ if (_ator != null)
+ {
+ AnimatorOverrideController overrideController = new AnimatorOverrideController();
+
+ overrideController.runtimeAnimatorController = _ator.runtimeAnimatorController;
+ _ator.runtimeAnimatorController = overrideController;
+
+ overrideController["Idle"] = XResourceLoaderMgr.singleton.GetSharedResource<AnimationClip>(clip, ".anim");
+
+ _shadow = _actor.transform.Find("Shadow");
+ if (_shadow != null) _shadow.GetComponent<Renderer>().enabled = true;
+
+ _ator.cullingMode = AnimatorCullingMode.AlwaysAnimate;
+ }
+ }
+
+ public XActor(uint id, float x, float y, float z, string clip)
+ {
+ _actor = UnityEngine.Object.Instantiate(XStatisticsLibrary.GetDummy(id), new Vector3(x, y, z), Quaternion.identity) as GameObject;
+ _ator = _actor.GetComponent<Animator>();
+ DisablePhysic();
+ AnimatorOverrideController overrideController = new AnimatorOverrideController();
+
+ overrideController.runtimeAnimatorController = _ator.runtimeAnimatorController;
+ _ator.runtimeAnimatorController = overrideController;
+
+ overrideController["Idle"] = XResourceLoaderMgr.singleton.GetSharedResource<AnimationClip>(clip, ".anim");
+
+ _shadow = _actor.transform.Find("Shadow");
+ if (_shadow != null) _shadow.GetComponent<Renderer>().enabled = true;
+
+ _ator.cullingMode = AnimatorCullingMode.AlwaysAnimate;
+ }
+ private void DisablePhysic()
+ {
+ if (_actor != null)
+ {
+ CharacterController cc = _actor.GetComponent<CharacterController>();
+ if (cc != null) cc.enabled = false;
+ }
+ }
+ public void Update(float fDelta)
+ {
+ StickShadow();
+ }
+
+ public AudioSource GetAudioSourceByChannel(AudioChannel channel)
+ {
+ switch (channel)
+ {
+ case AudioChannel.Action:
+ {
+ if (_audio_action == null)
+ _audio_action = _actor.AddComponent<AudioSource>();
+
+ return _audio_action;
+ }
+ case AudioChannel.Motion:
+ {
+ if (_audio_motion == null)
+ _audio_motion = _actor.AddComponent<AudioSource>();
+
+ return _audio_motion;
+ }
+ case AudioChannel.Skill:
+ {
+ if (_audio_skill == null)
+ _audio_skill = _actor.AddComponent<AudioSource>();
+
+ return _audio_skill;
+ }
+ }
+
+ return _audio_action;
+ }
+
+ protected void StickShadow()
+ {
+ if (_bip == null) return;
+
+ Vector3 shadow_pos;
+
+ shadow_pos.x = _bip.position.x;
+ shadow_pos.z = _bip.position.z;
+ shadow_pos.y = XActor.TerrainY(_bip.transform.position) + 0.02f;
+
+ _shadow.position = shadow_pos;
+ }
+
+ public static float TerrainY(Vector3 pos)
+ {
+ if (_terrain != null)
+ {
+ return _terrain.SampleHeight(pos);
+ }
+
+ return 0;
+ }
+ }
+}
+#endif
\ No newline at end of file diff --git a/Client/Assets/Scripts/XEditor/XCutSceneEditor/XActor.cs.meta b/Client/Assets/Scripts/XEditor/XCutSceneEditor/XActor.cs.meta new file mode 100644 index 00000000..6a6a396d --- /dev/null +++ b/Client/Assets/Scripts/XEditor/XCutSceneEditor/XActor.cs.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2
+guid: bd3b38fa8b5218048b476a668d580aaa
+MonoImporter:
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
diff --git a/Client/Assets/Scripts/XEditor/XCutSceneEditor/XCutSceneCamera.cs b/Client/Assets/Scripts/XEditor/XCutSceneEditor/XCutSceneCamera.cs new file mode 100644 index 00000000..dd33f871 --- /dev/null +++ b/Client/Assets/Scripts/XEditor/XCutSceneEditor/XCutSceneCamera.cs @@ -0,0 +1,175 @@ +#if UNITY_EDITOR
+using System;
+using UnityEngine;
+using XUtliPoolLib;
+
+namespace XEditor
+{
+ internal class XCutSceneCamera
+ {
+ private GameObject _cameraObject = null;
+
+ private GameObject _dummyObject = null;
+ private Transform _dummyCamera = null;
+ private Transform _cameraTransform = null;
+
+ private Animator _ator = null;
+ public AnimatorOverrideController _overrideController = new AnimatorOverrideController();
+
+ private UnityEngine.Camera _camera = null;
+
+ private bool _root_pos_inited = false;
+
+ private Vector3 _root_pos = Vector3.zero;
+
+ private Quaternion _idle_root_rotation = Quaternion.identity;
+ private Vector3 _dummyCamera_pos = Vector3.zero;
+
+ private CameraMotionSpace _effect_axis = CameraMotionSpace.World;
+ private XCameraMotionData _motion = new XCameraMotionData();
+
+ public XActor Target = null;
+
+ private string _trigger = null;
+
+ public UnityEngine.Camera UnityCamera
+ {
+ get { return _camera; }
+ }
+
+ public Transform CameraTrans
+ {
+ get { return _cameraTransform; }
+ }
+
+ public Animator CameraAnimator
+ {
+ get { return _ator; }
+ }
+
+ public Vector3 Position
+ {
+ get { return _cameraTransform.position; }
+ }
+
+ public Quaternion Rotaton
+ {
+ get { return _cameraTransform.rotation; }
+ }
+
+ public bool Initialize()
+ {
+ _cameraObject = GameObject.Find(@"Main Camera");
+
+ if (null != _cameraObject)
+ {
+ _camera = _cameraObject.GetComponent<UnityEngine.Camera>();
+ _cameraTransform = _cameraObject.transform;
+
+ XResourceLoaderMgr.SafeDestroy(ref _dummyObject);
+ _dummyObject = XResourceLoaderMgr.singleton.CreateFromPrefab("Prefabs/DummyCamera") as GameObject;
+ _dummyObject.name = "Dummy Camera";
+
+ _dummyCamera = _dummyObject.transform.GetChild(0);
+ _ator = _dummyObject.GetComponent<Animator>();
+
+ _overrideController.runtimeAnimatorController = _ator.runtimeAnimatorController;
+ _ator.runtimeAnimatorController = _overrideController;
+
+ _root_pos_inited = false;
+ }
+
+ return true;
+ }
+
+ public void OverrideAnimClip(string motion, string clipname)
+ {
+ //get override clip
+ AnimationClip animClip = XResourceLoaderMgr.singleton.GetSharedResource<AnimationClip>(clipname, ".anim");
+ OverrideAnimClip(motion, animClip);
+ }
+
+ public void OverrideAnimClip(string motion, AnimationClip clip)
+ {
+ //override
+ if (clip != null && _overrideController[motion] != clip) _overrideController[motion] = clip;
+ }
+
+ public void PostUpdate(float fDeltaT)
+ {
+ if (!_root_pos_inited)
+ {
+ _root_pos = _dummyCamera.position;
+ _root_pos_inited = true;
+
+ _idle_root_rotation = _motion.Follow_Position ? Quaternion.Euler(0, 180, 0) : Quaternion.identity;
+ }
+
+ InnerUpdateEx();
+ TriggerEffect();
+ }
+
+ private void InnerPosition()
+ {
+ _dummyCamera_pos = _idle_root_rotation * (_dummyCamera.position - _dummyObject.transform.position) + _dummyObject.transform.position;
+ }
+
+ private void InnerUpdateEx()
+ {
+ InnerPosition();
+
+ Vector3 v_self_p = Target == null ? Vector3.zero : Target.Actor.transform.position;
+
+ Vector3 forward = Vector3.Cross(_dummyCamera.forward, _dummyCamera.up);
+ Quaternion q = Quaternion.LookRotation(forward, _dummyCamera.up);
+
+ Vector3 delta = (_dummyCamera_pos - _root_pos);
+ Vector3 target_pos = _root_pos + (_motion.Follow_Position ? v_self_p : Vector3.zero);
+
+ _cameraTransform.rotation = _idle_root_rotation * q;
+
+ switch (_effect_axis)
+ {
+ case CameraMotionSpace.World:
+ {
+ target_pos += delta;
+ } break;
+ }
+
+ _cameraTransform.position = target_pos;
+ }
+
+ public void Effect(XCameraMotionData motion)
+ {
+ //must be called from UPDATE pass
+ AnimationClip clip = XResourceLoaderMgr.singleton.GetSharedResource<AnimationClip>(motion.Motion, ".anim");
+
+ if (clip != null)
+ {
+ _trigger = "ToEffect";
+ if (_overrideController["CameraEffect"] != clip) _overrideController["CameraEffect"] = clip;
+
+ _motion.Follow_Position = motion.Follow_Position;
+ _motion.Coordinate = motion.Coordinate;
+ _motion.AutoSync_At_Begin = motion.AutoSync_At_Begin;
+ _motion.LookAt_Target = motion.LookAt_Target;
+
+ _motion.Motion = motion.Motion;
+ }
+ }
+
+ private void TriggerEffect()
+ {
+ if (_trigger != null && !_ator.IsInTransition(0))
+ {
+ _effect_axis = _motion.Coordinate;
+
+ _ator.SetTrigger(_trigger);
+ _root_pos_inited = false;
+
+ _trigger = null;
+ }
+ }
+ }
+}
+#endif
\ No newline at end of file diff --git a/Client/Assets/Scripts/XEditor/XCutSceneEditor/XCutSceneCamera.cs.meta b/Client/Assets/Scripts/XEditor/XCutSceneEditor/XCutSceneCamera.cs.meta new file mode 100644 index 00000000..6a416832 --- /dev/null +++ b/Client/Assets/Scripts/XEditor/XCutSceneEditor/XCutSceneCamera.cs.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2
+guid: dee1aadae6624184e959a5e3a447de60
+MonoImporter:
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
diff --git a/Client/Assets/Scripts/XEditor/XCutSceneEditor/XCutSceneUI.cs b/Client/Assets/Scripts/XEditor/XCutSceneEditor/XCutSceneUI.cs new file mode 100644 index 00000000..ad881dae --- /dev/null +++ b/Client/Assets/Scripts/XEditor/XCutSceneEditor/XCutSceneUI.cs @@ -0,0 +1,77 @@ +#if UNITY_EDITOR
+using UnityEngine;
+using XUtliPoolLib;
+using XEditor;
+
+public class XCutSceneUI : XSingleton<XCutSceneUI>
+{
+ public UISprite m_BG;
+ public UILabel m_Text;
+ public UILabel m_Skip;
+ public UIPlayTween m_IntroTween;
+ public UILabel m_Name;
+
+ public GameObject _objUI;
+
+ public override bool Init()
+ {
+ UIPanel p = NGUITools.CreateUI(false);
+
+ _objUI = XResourceLoaderMgr.singleton.CreateFromPrefab("UI/Common/CutSceneUI") as GameObject;
+
+ if (null != _objUI)
+ {
+ _objUI.transform.parent = p.transform;
+ _objUI.transform.localPosition = new Vector3(0.0f, 0.0f, 0);
+ _objUI.transform.localScale = new Vector3(1, 1, 1);
+ }
+
+ UIRoot rt = p.gameObject.GetComponent<UIRoot>();
+ rt.scalingStyle = UIRoot.Scaling.FixedSize;
+ rt.manualHeight = 1148;
+
+ m_Text = _objUI.transform.Find("_canvas/DownBG/Text").GetComponent<UILabel>();
+
+ m_Name = _objUI.transform.Find("_canvas/Intro/Name").GetComponent<UILabel>();
+ m_IntroTween = _objUI.transform.Find("_canvas/Intro").GetComponent<UIPlayTween>();
+
+ m_Text.text = "";
+
+ _objUI.SetActive(false);
+ m_IntroTween.gameObject.SetActive(false);
+ return true;
+ }
+
+ public void SetText(string text)
+ {
+ m_Text.text = text;
+ }
+
+ public void SetVisible(bool visible)
+ {
+ _objUI.SetActive(visible);
+ }
+
+ public void SetIntroText(bool enabled, string name, string text, float x, float y)
+ {
+ if (!_objUI.activeInHierarchy) return;
+
+ if (enabled)
+ {
+ m_Name.text = name;
+
+ m_IntroTween.gameObject.transform.localPosition = new Vector2(x, y);
+ m_IntroTween.tweenGroup = 0;
+ m_IntroTween.ResetByGroup(true, 0);
+ m_IntroTween.Play(true);
+
+ }
+ else
+ {
+ m_IntroTween.tweenGroup = 1;
+ m_IntroTween.ResetByGroup(true, 1);
+ m_IntroTween.Play(true);
+ }
+ }
+}
+#endif
\ No newline at end of file diff --git a/Client/Assets/Scripts/XEditor/XCutSceneEditor/XCutSceneUI.cs.meta b/Client/Assets/Scripts/XEditor/XCutSceneEditor/XCutSceneUI.cs.meta new file mode 100644 index 00000000..be172409 --- /dev/null +++ b/Client/Assets/Scripts/XEditor/XCutSceneEditor/XCutSceneUI.cs.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2
+guid: 608b30d1d55920f469da985b4a5289d0
+MonoImporter:
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
diff --git a/Client/Assets/Scripts/XEditor/XCutSceneEditor/XScriptStandalone.cs b/Client/Assets/Scripts/XEditor/XCutSceneEditor/XScriptStandalone.cs new file mode 100644 index 00000000..bdaac549 --- /dev/null +++ b/Client/Assets/Scripts/XEditor/XCutSceneEditor/XScriptStandalone.cs @@ -0,0 +1,191 @@ +#if UNITY_EDITOR
+using UnityEngine;
+using XEditor;
+using XUtliPoolLib;
+using System.Collections.Generic;
+using System.Collections;
+
+public class XScriptStandalone : MonoBehaviour
+{
+ private XCutSceneCamera _cut_scene_camera = null;
+ private List<XActor> _actors = new List<XActor>();
+
+ private uint _token = 0;
+
+ [SerializeField]
+ public XCutSceneData _cut_scene_data = null;
+
+ public GameObject _ui_root;
+
+ // Use this for initialization
+ void Start ()
+ {
+ _cut_scene_camera = new XCutSceneCamera();
+ _cut_scene_camera.Initialize();
+
+ XCameraMotionData m = new XCameraMotionData();
+ m.AutoSync_At_Begin = false;
+ m.Coordinate = CameraMotionSpace.World;
+ m.Follow_Position = _cut_scene_data.GeneralShow;
+ m.LookAt_Target = false;
+ m.At = 0;
+ m.Motion = _cut_scene_data.CameraClip;
+
+ _cut_scene_camera.Effect(m);
+ _cut_scene_camera.UnityCamera.fieldOfView = _cut_scene_data.FieldOfView;
+
+ XCutSceneUI.singleton.Init();
+ XCutSceneUI.singleton.SetText("");
+
+ if (!_cut_scene_data.GeneralShow)
+ {
+ foreach (XActorDataClip clip in _cut_scene_data.Actors)
+ {
+ XResourceLoaderMgr.singleton.GetSharedResource<AnimationClip>(clip.Clip, ".anim");
+ XTimerMgr.singleton.SetTimer(clip.TimeLineAt / 30.0f - 0.016f, BeOnStage, clip);
+ }
+
+ foreach (XPlayerDataClip clip in _cut_scene_data.Player)
+ {
+ XResourceLoaderMgr.singleton.GetSharedResource<AnimationClip>(clip.Clip1, ".anim");
+ XTimerMgr.singleton.SetTimer(clip.TimeLineAt / 30.0f - 0.016f, BePlayerOnStage, clip);
+ }
+
+ foreach (XFxDataClip clip in _cut_scene_data.Fxs)
+ {
+ XTimerMgr.singleton.SetTimer(clip.TimeLineAt / 30.0f, Fx, clip);
+ }
+ }
+
+ foreach (XAudioDataClip clip in _cut_scene_data.Audios)
+ {
+ XTimerMgr.singleton.SetTimer(clip.TimeLineAt / 30.0f, Audio, clip);
+ }
+
+ if (_cut_scene_data.AutoEnd) XTimerMgr.singleton.SetTimer((_cut_scene_data.TotalFrame - 30) / 30.0f, EndShow, null);
+
+ if (_cut_scene_data.Mourningborder)
+ {
+ XCutSceneUI.singleton.SetVisible(true);
+
+ foreach (XSubTitleDataClip clip in _cut_scene_data.SubTitle)
+ {
+ XTimerMgr.singleton.SetTimer(clip.TimeLineAt / 30.0f, SubTitle, clip);
+ }
+
+ foreach (XSlashDataClip clip in _cut_scene_data.Slash)
+ {
+ XTimerMgr.singleton.SetTimer(clip.TimeLineAt / 30.0f, Slash, clip);
+ }
+ }
+ }
+
+ // Update is called once per frame
+ void Update ()
+ {
+ XTimerMgr.singleton.Update(Time.deltaTime);
+
+ foreach (XActor actor in _actors)
+ actor.Update(Time.deltaTime);
+ }
+
+ void BePlayerOnStage(object o)
+ {
+ XPlayerDataClip clip = o as XPlayerDataClip;
+ _actors.Add(new XActor(clip.AppearX, clip.AppearY, clip.AppearZ, clip.Clip1));
+ }
+
+ void BeOnStage(object o)
+ {
+ XActor target = null;
+
+ XActorDataClip clip = o as XActorDataClip;
+ if(clip.bUsingID)
+ target = new XActor((uint)clip.StatisticsID, clip.AppearX, clip.AppearY, clip.AppearZ, clip.Clip);
+ else
+ target = new XActor(clip.Prefab, clip.AppearX, clip.AppearY, clip.AppearZ, clip.Clip);
+
+ _actors.Add(target);
+ }
+
+ void Fx(object o)
+ {
+ XFxDataClip clip = o as XFxDataClip;
+
+ Transform transform = (clip.BindIdx < 0) ? null : _actors[clip.BindIdx].Actor.transform;
+ if (clip.Bone != null && clip.Bone.Length > 0)
+ transform = transform.Find(clip.Bone);
+ else
+ transform = null;
+
+ XFx fx = XFxMgr.singleton.CreateFx(clip.Fx);
+
+ fx.DelayDestroy = clip.Destroy_Delay;
+ if (transform != null)
+ fx.Play(transform,Vector3.zero, clip.Scale * Vector3.one, 1, clip.Follow);
+ else
+ fx.Play(new Vector3(clip.AppearX, clip.AppearY, clip.AppearZ), XCommon.singleton.FloatToQuaternion(clip.Face),Vector3.one);
+ }
+
+ void Audio(object o)
+ {
+ XAudioDataClip clip = o as XAudioDataClip;
+
+ if (clip.BindIdx < 0) return;
+
+ //AudioClip audio = XResourceLoaderMgr.singleton.GetSharedResource<AudioClip>(clip.Clip);
+ //AudioSource source = _actors[clip.BindIdx].GetAudioSourceByChannel(clip.Channel);
+
+ XFmod fmod = _actors[clip.BindIdx].Actor.GetComponent<XFmod>();
+ if(fmod == null)
+ fmod = _actors[clip.BindIdx].Actor.AddComponent<XFmod>();
+
+ fmod.StartEvent("event:/" + clip.Clip, clip.Channel);
+ //source.Stop();
+
+ //source.clip = audio;
+ //source.volume = clip.Volume;
+ //source.loop = clip.Loop;
+ //source.Play();
+ }
+
+ void SubTitle(object o)
+ {
+ XSubTitleDataClip clip = o as XSubTitleDataClip;
+
+ XCutSceneUI.singleton.SetText(clip.Context);
+ XTimerMgr.singleton.KillTimer(_token);
+
+ _token = XTimerMgr.singleton.SetTimer(clip.Duration / 30.0f, EndSubTitle, null);
+ }
+
+ void Slash(object o)
+ {
+ XSlashDataClip clip = o as XSlashDataClip;
+
+ XCutSceneUI.singleton.SetIntroText(true, clip.Name, clip.Discription, clip.AnchorX, clip.AnchorY);
+
+ XTimerMgr.singleton.SetTimer(clip.Duration, EndSlash, null);
+ }
+
+ void EndShow(object o)
+ {
+ XTimerMgr.singleton.KillTimer(_token);
+ }
+
+ void EndSlash(object o)
+ {
+ XCutSceneUI.singleton.SetIntroText(false, "", "", 0, 0);
+ }
+
+ void EndSubTitle(object o)
+ {
+ XCutSceneUI.singleton.SetText("");
+ }
+
+ void LateUpdate()
+ {
+ _cut_scene_camera.PostUpdate(Time.deltaTime);
+ }
+}
+#endif
\ No newline at end of file diff --git a/Client/Assets/Scripts/XEditor/XCutSceneEditor/XScriptStandalone.cs.meta b/Client/Assets/Scripts/XEditor/XCutSceneEditor/XScriptStandalone.cs.meta new file mode 100644 index 00000000..e64b53bd --- /dev/null +++ b/Client/Assets/Scripts/XEditor/XCutSceneEditor/XScriptStandalone.cs.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2
+guid: ed8a14250c743d94ab894b0e2200a094
+MonoImporter:
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
diff --git a/Client/Assets/Scripts/XEditor/XResourceHelp.cs b/Client/Assets/Scripts/XEditor/XResourceHelp.cs new file mode 100644 index 00000000..3abf9897 --- /dev/null +++ b/Client/Assets/Scripts/XEditor/XResourceHelp.cs @@ -0,0 +1,32 @@ +#if UNITY_EDITOR
+using UnityEngine;
+using System.Collections;
+using XUtliPoolLib;
+using UnityEditor;
+
+public class XResourceHelp : MonoBehaviour, IResourceHelp
+{
+ public bool Deprecated
+ {
+ get;
+ set;
+ }
+
+ public void CheckResource(UnityEngine.Object o, string path)
+ {
+#if UNITY_EDITOR
+ string p = AssetDatabase.GetAssetPath(o);
+
+ string s = "Assets/Resources/";
+
+ if (s.Length < p.Length)
+ {
+ string t = p.Substring(s.Length);
+ if(t.IndexOf(path) != 0)
+ XDebug.singleton.AddErrorLog("找海公:" + path);
+ }
+#endif
+ }
+
+}
+#endif
\ No newline at end of file diff --git a/Client/Assets/Scripts/XEditor/XResourceHelp.cs.meta b/Client/Assets/Scripts/XEditor/XResourceHelp.cs.meta new file mode 100644 index 00000000..0779a8e8 --- /dev/null +++ b/Client/Assets/Scripts/XEditor/XResourceHelp.cs.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2
+guid: 7836d9f3c3d931047a73ef922ec67ab5
+MonoImporter:
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
diff --git a/Client/Assets/Scripts/XEditor/XSkillEditor.meta b/Client/Assets/Scripts/XEditor/XSkillEditor.meta new file mode 100644 index 00000000..7bedec17 --- /dev/null +++ b/Client/Assets/Scripts/XEditor/XSkillEditor.meta @@ -0,0 +1,5 @@ +fileFormatVersion: 2
+guid: 152c8f4625f550c4e844968423894915
+folderAsset: yes
+DefaultImporter:
+ userData:
diff --git a/Client/Assets/Scripts/XEditor/XSkillEditor/Effect.meta b/Client/Assets/Scripts/XEditor/XSkillEditor/Effect.meta new file mode 100644 index 00000000..7692e7f6 --- /dev/null +++ b/Client/Assets/Scripts/XEditor/XSkillEditor/Effect.meta @@ -0,0 +1,5 @@ +fileFormatVersion: 2
+guid: a50e3f493c054284ba34989bde5e2806
+folderAsset: yes
+DefaultImporter:
+ userData:
diff --git a/Client/Assets/Scripts/XEditor/XSkillEditor/Effect/ImageEffectBase.cs b/Client/Assets/Scripts/XEditor/XSkillEditor/Effect/ImageEffectBase.cs new file mode 100644 index 00000000..bf9e66e2 --- /dev/null +++ b/Client/Assets/Scripts/XEditor/XSkillEditor/Effect/ImageEffectBase.cs @@ -0,0 +1,56 @@ +#if UNITY_EDITOR
+using UnityEngine;
+
+[RequireComponent (typeof(Camera))]
+[AddComponentMenu("")]
+public class ImageEffectBase : MonoBehaviour {
+ /// Provides a shader property that is set in the inspector
+ /// and a material instantiated from the shader
+ public Shader m_shader;
+ private Material m_Material;
+ protected string m_shaderName = "Mobile/Diffuse";
+ protected virtual void Start ()
+ {
+ // Disable if we don't support image effects
+ if (!SystemInfo.supportsImageEffects) {
+ enabled = false;
+ return;
+ }
+
+ // Disable the image effect if the shader can't
+ // run on the users graphics card
+ if (!shader || !shader.isSupported)
+ enabled = false;
+ }
+ public virtual Shader shader
+ {
+ get
+ {
+ if (m_shader == null)
+ {
+ m_shader = Shader.Find(m_shaderName);
+ }
+ return m_shader;
+ }
+ set
+ {
+ m_shader = value;
+ }
+ }
+ protected Material material {
+ get {
+ if (m_Material == null) {
+ m_Material = new Material (shader);
+ m_Material.hideFlags = HideFlags.HideAndDontSave;
+ }
+ return m_Material;
+ }
+ }
+
+ protected virtual void OnDisable() {
+ if( m_Material ) {
+ DestroyImmediate( m_Material );
+ }
+ }
+}
+#endif
\ No newline at end of file diff --git a/Client/Assets/Scripts/XEditor/XSkillEditor/Effect/ImageEffectBase.cs.meta b/Client/Assets/Scripts/XEditor/XSkillEditor/Effect/ImageEffectBase.cs.meta new file mode 100644 index 00000000..42c7ce0d --- /dev/null +++ b/Client/Assets/Scripts/XEditor/XSkillEditor/Effect/ImageEffectBase.cs.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2
+guid: c965db0de94104d4996defd5df4f006e
+MonoImporter:
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
diff --git a/Client/Assets/Scripts/XEditor/XSkillEditor/Effect/RadialBlur.cs b/Client/Assets/Scripts/XEditor/XSkillEditor/Effect/RadialBlur.cs new file mode 100644 index 00000000..553496bf --- /dev/null +++ b/Client/Assets/Scripts/XEditor/XSkillEditor/Effect/RadialBlur.cs @@ -0,0 +1,49 @@ +#if UNITY_EDITOR
+using UnityEngine;
+
+[ExecuteInEditMode]
+[RequireComponent(typeof(Camera))]
+
+public class RadialBlur : ImageEffectBase
+{
+ public float blurStrength = 6.0f;
+ public float blurWidth = 0.7f;
+
+ void Awake()
+ {
+ enabled = false;
+ m_shaderName = "Hidden/radialBlur";
+ //if (!SystemInfo.supportsRenderTextures)
+ //{
+ // enabled = false;
+ // return;
+ //}
+ }
+ void OnEnable()
+ {
+ }
+ void OnRenderImage(RenderTexture source, RenderTexture dest)
+ {
+ // Create the accumulation texture
+ //if (accumTexture == null || accumTexture.width != source.width || accumTexture.height != source.height)
+ //{
+ // DestroyImmediate(accumTexture);
+ // accumTexture = new RenderTexture(source.width, source.height, 0);
+ // accumTexture.hideFlags = HideFlags.HideAndDontSave;
+ // Graphics.Blit(source, accumTexture);
+ //}
+
+ material.SetTexture("_MainTex", source);
+ material.SetFloat("_BlurStrength", blurStrength);
+ material.SetFloat("_BlurWidth", blurWidth);
+ material.SetFloat("_iHeight", 1);
+ material.SetFloat("_iWidth", 1);
+ //accumTexture.MarkRestoreExpected();
+
+ // Graphics.Blit(source, accumTexture, material);
+ // Graphics.Blit(accumTexture, dest);
+
+ Graphics.Blit(source, dest, material);
+ }
+}
+#endif
\ No newline at end of file diff --git a/Client/Assets/Scripts/XEditor/XSkillEditor/Effect/RadialBlur.cs.meta b/Client/Assets/Scripts/XEditor/XSkillEditor/Effect/RadialBlur.cs.meta new file mode 100644 index 00000000..456d3d2c --- /dev/null +++ b/Client/Assets/Scripts/XEditor/XSkillEditor/Effect/RadialBlur.cs.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2
+guid: bd9d2efe45f76fb4d87e90244d34accb
+MonoImporter:
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
diff --git a/Client/Assets/Scripts/XEditor/XSkillEditor/XBullet.cs b/Client/Assets/Scripts/XEditor/XSkillEditor/XBullet.cs new file mode 100644 index 00000000..f5b0a127 --- /dev/null +++ b/Client/Assets/Scripts/XEditor/XSkillEditor/XBullet.cs @@ -0,0 +1,443 @@ +#if UNITY_EDITOR
+using System;
+using System.Collections.Generic;
+using UnityEngine;
+using XUtliPoolLib;
+
+namespace XEditor
+{
+ internal class XBullet
+ {
+ private struct XBulletTarget
+ {
+ public uint TimerToken;
+ public bool Hurtable;
+ public int HurtCount;
+ }
+
+ private bool _active = true;
+ private bool _pingponged = false;
+ private bool _collided = false;
+
+ private uint _tail_results_token = 0;
+ private int _tail_results = 0;
+
+ private float _elapsed = 0;
+
+ private GameObject _bullet = null;
+ private XBulletData _data = null;
+ private RaycastHit _hitInfo;
+ private Vector3 _origin = Vector3.zero;
+ private XFmod _emitter = null;
+
+ private Dictionary<XSkillHit, XBulletTarget> _hurt_target = new Dictionary<XSkillHit, XBulletTarget>();
+
+ public XBullet(XBulletData data)
+ {
+ _data = data;
+
+ _elapsed = 0.0f;
+
+ GameObject o = Resources.Load(_data.Prefab) as GameObject;
+ _bullet = GameObject.Instantiate(o, _data.BulletRay.origin, _data.Velocity > 0 ? Quaternion.LookRotation(_data.BulletRay.direction) : Quaternion.LookRotation(_data.Firer.transform.forward)) as GameObject;
+
+ _data.Firer.ShownTransform = _bullet.transform;
+
+ if (!string.IsNullOrEmpty(_data.Skill.Result[_data.Sequnce].LongAttackData.Audio))
+ {
+ if (_emitter == null)
+ _emitter = _bullet.AddComponent<XFmod>();
+
+ _emitter.StartEvent("event:/" + _data.Skill.Result[_data.Sequnce].LongAttackData.Audio, _data.Skill.Result[_data.Sequnce].LongAttackData.Audio_Channel);
+ }
+ }
+
+ public bool IsExpired()
+ {
+ if (_tail_results != 0)
+ {
+ if (_tail_results >= _data.Skill.Result[_data.Sequnce].LongAttackData.TriggerAtEnd_Count)
+ return true;
+ else
+ return false;
+ }
+
+ if (_data.Skill.Result[_data.Sequnce].LongAttackData.IsPingPong && !_pingponged)
+ {
+ if (XCommon.singleton.IsGreater(_elapsed, _data.Life)) _pingponged = true;
+ }
+
+ bool expired = (!_active || (!_pingponged && XCommon.singleton.IsGreater(_elapsed, _data.Life)));
+
+ if (_data.Skill.Result[_data.Sequnce].LongAttackData.TriggerAtEnd_Count <= 0)
+ return expired;
+ else
+ {
+ if (expired)
+ {
+ _active = false;
+ OnTailResult(null);
+
+ return false;
+ }
+ else
+ return expired;
+ }
+ }
+
+ public bool IsHurtEntity(XSkillHit id)
+ {
+ XBulletTarget target;
+ if (id != null && _hurt_target.TryGetValue(id, out target))
+ {
+ return !target.Hurtable;
+ }
+ else
+ return false;
+ }
+
+ private void OnTailResult(object o)
+ {
+ if (o == null)
+ {
+ _tail_results = 0;
+ FakeDestroyBulletObject();
+ }
+
+ if (_tail_results < _data.Skill.Result[_data.Sequnce].LongAttackData.TriggerAtEnd_Count)
+ {
+ _tail_results++;
+
+ TailResult(_tail_results == 1);
+
+ XTimerMgr.singleton.KillTimer(_tail_results_token);
+ _tail_results_token = XTimerMgr.singleton.SetTimer(_data.Skill.Result[_data.Sequnce].LongAttackData.TriggerAtEnd_Cycle, OnTailResult, this);
+ }
+ }
+
+ private void TailResult(bool present)
+ {
+ if (_data.Skill.Result[_data.Sequnce].LongAttackData.TriggerAtEnd)
+ {
+ if (_data.Warning) _bullet.transform.position = _data.WarningPos;
+ Result(null);
+ }
+
+ if (!present) return;
+
+ if (_data.Skill.Result[_data.Sequnce].LongAttackData.End_Fx != null && _data.Skill.Result[_data.Sequnce].LongAttackData.End_Fx.Length > 0)
+ {
+ GameObject o = Resources.Load(_data.Skill.Result[_data.Sequnce].LongAttackData.End_Fx) as GameObject;
+ GameObject fx = GameObject.Instantiate(o) as GameObject;
+
+ Vector3 pos = _bullet.transform.position;
+ if (_data.Skill.Result[_data.Sequnce].LongAttackData.EndFx_Ground) pos.y = 0;
+ fx.transform.position = pos;
+ fx.transform.rotation = _bullet.transform.rotation;
+
+ GameObject.Destroy(fx, _data.Skill.Result[_data.Sequnce].LongAttackData.EndFx_LifeTime);
+ }
+
+ if (!string.IsNullOrEmpty(_data.Skill.Result[_data.Sequnce].LongAttackData.End_Audio))
+ {
+ if (_data.Firer.Emitter == null)
+ _data.Firer.Emitter = _bullet.AddComponent<XFmod>();
+
+ _data.Firer.Emitter.Update3DAttributes(_bullet.transform.position, _data.Skill.Result[_data.Sequnce].LongAttackData.End_Audio_Channel);
+ _data.Firer.Emitter.StartEvent("event:/" + _data.Skill.Result[_data.Sequnce].LongAttackData.End_Audio, _data.Skill.Result[_data.Sequnce].LongAttackData.Audio_Channel);
+ }
+
+ if (_data.Firer.ShownTransform == _bullet.transform)
+ _data.Firer.ShownTransform = _data.Firer.transform;
+ }
+
+ private void FakeDestroyBulletObject()
+ {
+ if (null != _bullet)
+ {
+ Vector3 pos = _bullet.transform.position;
+ Quaternion quat = _bullet.transform.rotation;
+
+ GameObject.Destroy(_bullet);
+
+ _bullet = new GameObject("fakeBullet");
+ _bullet.transform.position = pos;
+ _bullet.transform.rotation = quat;
+ _bullet.SetActive(true);
+ }
+ }
+
+ public void Destroy()
+ {
+ XTimerMgr.singleton.KillTimer(_tail_results_token);
+
+ if (_data.Skill.Result[_data.Sequnce].LongAttackData.Type == XResultBulletType.Ring)
+ {
+ _data.Firer.ir = 0;
+ _data.Firer.or = 0;
+ }
+
+ if (_data.Skill.Result[_data.Sequnce].LongAttackData.TriggerAtEnd_Count == 0) TailResult(true);
+
+ if (null != _bullet)
+ {
+ GameObject.Destroy(_bullet);
+ }
+
+ foreach (XBulletTarget bt in _hurt_target.Values)
+ {
+ XTimerMgr.singleton.KillTimer(bt.TimerToken);
+ }
+
+ _bullet = null;
+ _data = null;
+ }
+
+ public bool Collided
+ {
+ get { return _collided; }
+ }
+
+ private void OnRefined(object o)
+ {
+ XBulletTarget bt;
+ XSkillHit id = (XSkillHit)o;
+
+ if (_hurt_target.TryGetValue(id, out bt))
+ {
+ if (bt.HurtCount < _data.Skill.Result[_data.Sequnce].LongAttackData.Refine_Count)
+ {
+ bt.Hurtable = true;
+ _hurt_target[id] = bt;
+ }
+ }
+ }
+
+ public void Result(XSkillHit hit)
+ {
+ if (IsHurtEntity(hit)) return;
+
+ //trigger skill result
+ _data.Firer.innerResult(_data.Sequnce, _bullet.transform.forward, _bullet.transform.position, _data.Skill, hit);
+
+ if (hit != null)
+ {
+ XBulletTarget bt;
+ if (!_hurt_target.TryGetValue(hit, out bt))
+ {
+ bt = new XBulletTarget();
+ _hurt_target.Add(hit, bt);
+ }
+
+ XTimerMgr.singleton.KillTimer(bt.TimerToken);
+
+ bt.Hurtable = false;
+ bt.HurtCount++;
+ bt.TimerToken = _data.Skill.Result[_data.Sequnce].LongAttackData.Refine_Cycle > 0 ?
+ XTimerMgr.singleton.SetTimer(_data.Skill.Result[_data.Sequnce].LongAttackData.Refine_Cycle, OnRefined, hit) :
+ 0;
+
+ _hurt_target[hit] = bt;
+ }
+
+ if (_data.Skill.Result[_data.Sequnce].LongAttackData.TriggerOnce)
+ {
+ if (_data.Skill.Result[_data.Sequnce].LongAttackData.IsPingPong)
+ _pingponged = true;
+ else
+ _active = false;
+ }
+ }
+
+ public void Update(float fDeltaT)
+ {
+ if (!_active) return;
+
+ _elapsed += fDeltaT;
+
+ float dis = 0; Vector3 dir = Vector3.forward;
+
+ switch (_data.Skill.Result[_data.Sequnce].LongAttackData.Type)
+ {
+ case XResultBulletType.Ring:
+ {
+ _bullet.transform.position = _data.Firer.transform.position;
+ }break;
+ case XResultBulletType.Sphere:
+ case XResultBulletType.Plane:
+ {
+ dis = (_elapsed > _data.Runningtime && _elapsed < _data.Life) ? 0 : _data.Velocity * fDeltaT;
+ dir = _bullet.transform.forward;
+ }break;
+ case XResultBulletType.Satellite:
+ {
+ if (_elapsed - fDeltaT == 0)
+ {
+ _bullet.transform.position = _data.Firer.transform.position + _data.BulletRay.direction * _data.Skill.Result[_data.Sequnce].LongAttackData.RingRadius;
+
+ dis = 0;
+ dir = XCommon.singleton.HorizontalRotateVetor3(_data.Firer.transform.forward, _data.Skill.Result[_data.Sequnce].LongAttackData.Palstance < 0 ? -90 : 90);
+ }
+ else
+ {
+ Vector3 curr = XCommon.singleton.HorizontalRotateVetor3(_data.BulletRay.direction, _data.Skill.Result[_data.Sequnce].LongAttackData.Palstance * (_elapsed - fDeltaT)) * _data.Skill.Result[_data.Sequnce].LongAttackData.RingRadius;
+ Vector3 next = XCommon.singleton.HorizontalRotateVetor3(_data.BulletRay.direction, _data.Skill.Result[_data.Sequnce].LongAttackData.Palstance * _elapsed) * _data.Skill.Result[_data.Sequnce].LongAttackData.RingRadius;
+
+ _bullet.transform.rotation = XCommon.singleton.VectorToQuaternion(XCommon.singleton.Horizontal(next - curr));
+
+ next += _data.Firer.transform.position;
+
+ Vector3 d = next - _bullet.transform.position; d.y = 0;
+ dis = d.magnitude;
+ dir = d.normalized;
+ }
+
+ }break;
+ }
+
+ if (_data.Skill.Result[_data.Sequnce].LongAttackData.IsPingPong && _pingponged)
+ {
+ Vector3 v = _data.Firer.transform.position - _bullet.transform.position; v.y = 0;
+
+ if (dis >= Vector3.Magnitude(v))
+ {
+ dis = Vector3.Magnitude(v);
+ _active = false;
+ }
+
+ dir = XCommon.singleton.Horizontal(v);
+ }
+ else
+ {
+ if (_data.Target != null && _data.Skill.Result[_data.Sequnce].LongAttackData.Follow)
+ {
+ dir = XCommon.singleton.Horizontal(_data.Target.transform.position - _bullet.transform.position);
+ }
+ }
+
+ if (_data.Skill.Result[_data.Sequnce].LongAttackData.Type != XResultBulletType.Satellite) _bullet.transform.rotation = XCommon.singleton.VectorToQuaternion(dir);
+ Vector3 move = dir * dis;
+ _origin.Set(_bullet.transform.position.x, _bullet.transform.position.y, _bullet.transform.position.z);
+
+ if (_active)
+ {
+ _bullet.transform.position += move;
+
+ if (_data.Skill.Result[_data.Sequnce].LongAttackData.Manipulation)
+ {
+ XSkillHit[] hits = GameObject.FindObjectsOfType<XSkillHit>();
+
+ Vector3 center = _bullet.transform.position;
+
+ foreach (XSkillHit hit in hits)
+ {
+ Vector3 gap = center - hit.transform.position; gap.y = 0;
+
+ if (gap.magnitude < _data.Skill.Result[_data.Sequnce].LongAttackData.ManipulationRadius)
+ {
+ float len = _data.Skill.Result[_data.Sequnce].LongAttackData.ManipulationForce * fDeltaT;
+ hit.transform.Translate(gap.normalized * Mathf.Min(dis, len), Space.World);
+ }
+ }
+ }
+ }
+
+ if (_data.Skill.Result[_data.Sequnce].LongAttackData.WithCollision)
+ {
+ switch (_data.Skill.Result[_data.Sequnce].LongAttackData.Type)
+ {
+ case XResultBulletType.Ring:
+ {
+ float t = XCommon.singleton.IsGreater(_elapsed, _data.Life) ? 0 : (_data.Skill.Result[_data.Sequnce].LongAttackData.RingFull ? (XCommon.singleton.IsGreater(_elapsed, _data.Life * 0.5f) ? (_data.Life - _elapsed) : _elapsed) : _elapsed);
+ float ir = t * _data.Skill.Result[_data.Sequnce].LongAttackData.RingVelocity;
+ float or = ir + _data.Skill.Result[_data.Sequnce].LongAttackData.RingRadius;
+
+ _data.Firer.ir = ir;
+ _data.Firer.or = or;
+
+ RingCollideUnit(ir, or, _data.Firer.transform.position, this);
+ }break;
+ case XResultBulletType.Sphere:
+ case XResultBulletType.Satellite:
+ {
+ Vector3 project = new Vector3(move.x, 0, move.z);
+ float hlen = project.magnitude * 0.5f;
+
+ dir.y = 0;
+
+ float rotation = (dir.sqrMagnitude == 0) ? 0 : Vector3.Angle(Vector3.right, dir);
+ if (rotation > 0 && XCommon.singleton.Clockwise(Vector3.right, dir)) rotation = -rotation;
+
+ BulletCollideUnit(
+ new Vector3(_origin.x + dir.x * hlen, 0, _origin.z + dir.z * hlen),
+ hlen,
+ rotation,
+ _data.Radius,
+ this);
+ } break;
+ case XResultBulletType.Plane:
+ {
+ PlaneBulletCollideUnit(_origin, move, _data.Radius, this);
+ } break;
+ }
+ }
+ }
+
+ private static void RingCollideUnit(float ir, float or, Vector3 center, XBullet bullet)
+ {
+ XSkillHit[] ents = GameObject.FindObjectsOfType<XSkillHit>();
+
+ for (int i = 0; i < ents.Length; i++)
+ {
+ bool collided = false;
+
+ Vector3 v = ents[i].transform.position - center; v.y = 0;
+ float dis = v.sqrMagnitude;
+ collided = dis > (ir * ir) && dis < (or * or);
+
+ if (collided) bullet.Result(ents[i]);
+ if (bullet.IsExpired()) break;
+ }
+ }
+
+ private static void BulletCollideUnit(Vector3 rectcenter, float hlen, float rotation, float r, XBullet bullet)
+ {
+ XSkillHit[] ents = GameObject.FindObjectsOfType<XSkillHit>();
+
+ for (int i = 0; i < ents.Length; i++)
+ {
+ bool collided = false;
+
+ Vector3 cycle = ents[i].RadiusCenter; cycle -= rectcenter; cycle.y = 0;
+ cycle = XCommon.singleton.HorizontalRotateVetor3(cycle, rotation, false);
+
+ collided = XCommon.singleton.IsRectCycleCross(hlen, r, cycle, ents[i].Radius) || Vector3.SqrMagnitude(cycle) < r * r;
+
+ if (collided) bullet.Result(ents[i]);
+ if (bullet.IsExpired()) break;
+ }
+ }
+
+ private static void PlaneBulletCollideUnit(Vector3 origin, Vector3 move, float r, XBullet bullet)
+ {
+ Vector3 side = XCommon.singleton.HorizontalRotateVetor3(move, 90);
+ Vector3 left = origin + side * r;
+ Vector3 right = origin - side * r;
+
+ XSkillHit[] ents = GameObject.FindObjectsOfType<XSkillHit>();
+
+ for (int i = 0; i < ents.Length; i++)
+ {
+ bool collided = false;
+
+ Vector3 pos = ents[i].RadiusCenter;
+
+ collided = XCommon.singleton.IsLineSegmentCross(pos, pos - move, left, right);
+
+ if (collided) bullet.Result(ents[i]);
+ if (bullet.IsExpired()) break;
+ }
+ }
+ }
+}
+#endif
\ No newline at end of file diff --git a/Client/Assets/Scripts/XEditor/XSkillEditor/XBullet.cs.meta b/Client/Assets/Scripts/XEditor/XSkillEditor/XBullet.cs.meta new file mode 100644 index 00000000..fac02c7b --- /dev/null +++ b/Client/Assets/Scripts/XEditor/XSkillEditor/XBullet.cs.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2
+guid: f9cb93fd63d4fd34795eb5647f44fbbe
+MonoImporter:
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
diff --git a/Client/Assets/Scripts/XEditor/XSkillEditor/XBulletData.cs b/Client/Assets/Scripts/XEditor/XSkillEditor/XBulletData.cs new file mode 100644 index 00000000..d39f48e9 --- /dev/null +++ b/Client/Assets/Scripts/XEditor/XSkillEditor/XBulletData.cs @@ -0,0 +1,85 @@ +#if UNITY_EDITOR
+using System;
+using UnityEngine;
+using XUtliPoolLib;
+
+namespace XEditor
+{
+ internal class XBulletData
+ {
+ private XSkillData _data = null;
+ private XSkillHoster _hoster = null;
+
+ private Vector3 _warning_pos = Vector3.zero;
+
+ private int _sequnce = 0;
+ private float _velocity = 0;
+ private bool _warning = false;
+
+ private GameObject _target = null;
+
+ public XBulletData(XSkillHoster firer, XSkillData data, GameObject target, int idx, float diviation, int wid)
+ {
+ _sequnce = idx;
+
+ _data = data;
+ _hoster = firer;
+
+ _warning_pos = Vector3.zero;
+
+ if (data.Result[idx].Attack_All)
+ {
+ _warning_pos = target.transform.position;
+ }
+ else if (data.Result[idx].Warning)
+ {
+ _warning_pos = firer.WarningPosAt[data.Result[idx].Warning_Idx][wid];
+ }
+
+ _warning = _warning_pos.sqrMagnitude > 0;
+
+ float height = XAnimationLibrary.AssociatedAnimations((uint)_hoster.ConfigData.Player).BoundHeight;
+
+ Vector3 begin = _hoster.gameObject.transform.position; begin.y += height * 0.5f;
+ Vector3 dir = _warning ? (_warning_pos - _hoster.gameObject.transform.position) : firer.transform.forward;
+
+ begin += firer.transform.rotation * new Vector3(
+ data.Result[idx].LongAttackData.At_X,
+ data.Result[idx].LongAttackData.At_Y,
+ data.Result[idx].LongAttackData.At_Z
+ );
+
+ dir.y = 0;
+
+ Vector3 flyTo = XCommon.singleton.HorizontalRotateVetor3(dir.normalized, diviation);
+
+ float h = (_data.Result[_sequnce].LongAttackData.AimTargetCenter && firer.Target != null) ? (begin.y - height * 0.5f) : 0;
+ _velocity = Warning ? (WarningPos - begin).magnitude / Runningtime : _data.Result[_sequnce].LongAttackData.Velocity;
+ flyTo = (h == 0 || _velocity == 0) ? flyTo : (h * Vector3.down + _velocity * Runningtime * flyTo).normalized;
+
+ BulletRay = new Ray(begin, flyTo);
+
+ _target = _data.Result[_sequnce].LongAttackData.Follow ? firer.Target : null;
+ }
+
+ public Ray BulletRay;
+
+ public GameObject Target { get { return _target; } }
+
+ public Vector3 WarningPos { get { return _warning_pos; } }
+ public bool Warning { get { return _warning; } }
+
+ public XSkillData Skill { get { return _data; } }
+
+ public XSkillHoster Firer { get { return _hoster; } }
+ public string Prefab { get { return _data.Result[_sequnce].LongAttackData.Prefab; } }
+
+ public int Sequnce { get { return _sequnce; } }
+
+ public float Velocity { get { return _velocity; } }
+ public float Life { get { return _data.Result[_sequnce].LongAttackData.Runningtime + _data.Result[_sequnce].LongAttackData.Stickytime; } }
+ public float Runningtime { get { return _data.Result[_sequnce].LongAttackData.Runningtime; } }
+ public float Radius { get { return _data.Result[_sequnce].LongAttackData.Radius; } }
+ }
+}
+#endif
\ No newline at end of file diff --git a/Client/Assets/Scripts/XEditor/XSkillEditor/XBulletData.cs.meta b/Client/Assets/Scripts/XEditor/XSkillEditor/XBulletData.cs.meta new file mode 100644 index 00000000..2288bfcb --- /dev/null +++ b/Client/Assets/Scripts/XEditor/XSkillEditor/XBulletData.cs.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2
+guid: 24dbb885a8c4cf34395c5f2d1b6cc28e
+MonoImporter:
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
diff --git a/Client/Assets/Scripts/XEditor/XSkillEditor/XBulletMgr.cs b/Client/Assets/Scripts/XEditor/XSkillEditor/XBulletMgr.cs new file mode 100644 index 00000000..3053179d --- /dev/null +++ b/Client/Assets/Scripts/XEditor/XSkillEditor/XBulletMgr.cs @@ -0,0 +1,34 @@ +#if UNITY_EDITOR
+using System;
+using System.Collections.Generic;
+using XUtliPoolLib;
+
+namespace XEditor
+{
+ internal class XBulletMgr : XSingleton<XBulletMgr>
+ {
+ private List<XBullet> _bullets = new List<XBullet>();
+
+ public void ShootBullet(XBullet bullet)
+ {
+ _bullets.Add(bullet);
+ }
+
+ public void Update(float fDeltaT)
+ {
+ int len = _bullets.Count;
+
+ for (int i = len - 1; i >= 0; i--)
+ {
+ if(_bullets[i].IsExpired())
+ {
+ _bullets[i].Destroy();
+ _bullets.RemoveAt(i);
+ }
+ else
+ _bullets[i].Update(fDeltaT);
+ }
+ }
+ }
+}
+#endif
\ No newline at end of file diff --git a/Client/Assets/Scripts/XEditor/XSkillEditor/XBulletMgr.cs.meta b/Client/Assets/Scripts/XEditor/XSkillEditor/XBulletMgr.cs.meta new file mode 100644 index 00000000..f6baad93 --- /dev/null +++ b/Client/Assets/Scripts/XEditor/XSkillEditor/XBulletMgr.cs.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2
+guid: 3f5a1fb204f5d3a4cb1a4d00f336b938
+MonoImporter:
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
diff --git a/Client/Assets/Scripts/XEditor/XSkillEditor/XCameraShake.cs b/Client/Assets/Scripts/XEditor/XSkillEditor/XCameraShake.cs new file mode 100644 index 00000000..f05296c5 --- /dev/null +++ b/Client/Assets/Scripts/XEditor/XSkillEditor/XCameraShake.cs @@ -0,0 +1,157 @@ +#if UNITY_EDITOR
+using System;
+using UnityEngine;
+using XUtliPoolLib;
+
+namespace XEditor
+{
+ public class XCameraShake
+ {
+ private GameObject _gameObject = null;
+ private Camera _camera = null;
+
+ private float _timeEscaped = 0;
+ private float _timeInterval = 0;
+ private bool _shake = false;
+
+ private Vector3 x = Vector3.zero;
+ private Vector3 y = Vector3.zero;
+ private Vector3 z = Vector3.zero;
+
+ private float _time = 0;
+ private float _fovAmp = 0;
+ private float _amplitude_x = 0;
+ private float _amplitude_y = 0;
+ private float _amplitude_z = 0;
+ private float _frequency = 0;
+ private CameraMotionSpace _coordinate = CameraMotionSpace.World;
+ private bool _shakeX = true;
+ private bool _shakeY = true;
+ private bool _shakeZ = true;
+
+ private bool _random = false;
+ private float _fov = 0;
+
+ private int _rfactor = 1;
+
+ public XCameraShake(GameObject go, Camera camera)
+ {
+ _camera = camera;
+ _gameObject = go;
+ }
+
+ public bool OnShake(
+ float time,
+ float fovAmp,
+ float amplitude_x,
+ float amplitude_y,
+ float amplitude_z,
+ float frequency,
+ CameraMotionSpace coordinate,
+ bool shakeX,
+ bool shakeY,
+ bool shakeZ,
+ bool random)
+ {
+ _time = time;
+
+ _fovAmp = fovAmp;
+ _amplitude_x = amplitude_x;
+ _amplitude_y = amplitude_y;
+ _amplitude_z = amplitude_z;
+ _frequency = frequency;
+ _coordinate = coordinate;
+ _shakeX = shakeX;
+ _shakeY = shakeY;
+ _shakeZ = shakeZ;
+
+ _random = random;
+
+ _fov = _camera.fieldOfView;
+
+ if (null != _camera)
+ {
+ _timeEscaped = 0;
+ _timeInterval = 0;
+
+ _shake = true;
+
+ switch (_coordinate)
+ {
+ case CameraMotionSpace.Camera:
+ {
+ x = _camera.transform.right;
+ y = _camera.transform.up;
+ z = _camera.transform.forward;
+ } break;
+ case CameraMotionSpace.Self:
+ {
+ x = _gameObject.transform.right;
+ y = _gameObject.transform.up;
+ z = _gameObject.transform.forward;
+ } break;
+ case CameraMotionSpace.World:
+ {
+ x = Vector3.right;
+ y = Vector3.up;
+ z = Vector3.forward;
+ } break;
+ }
+ }
+
+ _rfactor = 1;
+ return true;
+ }
+
+ public void Update(float fDeltaT)
+ {
+ if (null != _camera && _shake)
+ {
+ _timeEscaped += fDeltaT;
+ _timeInterval += fDeltaT;
+
+ if (XCommon.singleton.IsGreater(_timeEscaped, _time))
+ {
+ StopShake();
+ }
+ else
+ {
+ if (XCommon.singleton.IsGreater(_timeInterval, 1 / _frequency))
+ {
+ _rfactor = -_rfactor;
+
+ _camera.transform.position += Shake();
+
+ float fov = UnityEngine.Random.Range(-_fovAmp, _fovAmp);
+ _camera.fieldOfView = _fov + (_random ? fov : _fovAmp * _rfactor);
+
+ _timeInterval = 0;
+ }
+ }
+ }
+ }
+
+ private void StopShake()
+ {
+ _timeEscaped = 0;
+ _shake = false;
+
+ _camera.fieldOfView = _fov;
+ }
+
+ private Vector3 Shake()
+ {
+ float offsetX = _random ? UnityEngine.Random.Range(-_amplitude_x, _amplitude_x) : _amplitude_x * _rfactor;
+ float offsetY = _random ? UnityEngine.Random.Range(-_amplitude_y, _amplitude_y) : _amplitude_y * _rfactor;
+ float offsetZ = _random ? UnityEngine.Random.Range(-_amplitude_z, _amplitude_z) : _amplitude_z * _rfactor;
+
+ Vector3 v = Vector3.zero;
+ if (_shakeX) v += (x * offsetX);
+ if (_shakeY) v += (y * offsetY);
+ if (_shakeZ) v += (z * offsetZ);
+
+ return v;
+ }
+ }
+}
+#endif
\ No newline at end of file diff --git a/Client/Assets/Scripts/XEditor/XSkillEditor/XCameraShake.cs.meta b/Client/Assets/Scripts/XEditor/XSkillEditor/XCameraShake.cs.meta new file mode 100644 index 00000000..7497705c --- /dev/null +++ b/Client/Assets/Scripts/XEditor/XSkillEditor/XCameraShake.cs.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2
+guid: 44c2c35851099364fb63d66fe106386a
+MonoImporter:
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
diff --git a/Client/Assets/Scripts/XEditor/XSkillEditor/XDataBuilder.cs b/Client/Assets/Scripts/XEditor/XSkillEditor/XDataBuilder.cs new file mode 100644 index 00000000..8f51ed33 --- /dev/null +++ b/Client/Assets/Scripts/XEditor/XSkillEditor/XDataBuilder.cs @@ -0,0 +1,347 @@ +#if UNITY_EDITOR
+using System;
+using UnityEditor;
+using UnityEditorInternal;
+using UnityEngine;
+using XUtliPoolLib;
+
+using System.IO;
+using System.Runtime.Serialization;
+using System.Runtime.Serialization.Formatters.Binary;
+using System.Collections.Generic;
+
+namespace XEditor
+{
+ public class XDataBuilder : XSingleton<XDataBuilder>
+ {
+ public static GameObject hoster = null;
+ public static DateTime Time;
+ public static string prefixPath = "";
+
+ public void Load(string pathwithname)
+ {
+ try
+ {
+ XSkillHoster.Quit = false;
+ XConfigData conf = XDataIO<XConfigData>.singleton.DeserializeData(XEditorPath.GetCfgFromSkp(pathwithname));
+ GameObject prefab = XAnimationLibrary.GetDummy((uint)conf.Player);
+
+ if (prefab == null)
+ {
+ Debug.Log("<color=red>Prefab not found by id: " + conf.Player + "</color>");
+ }
+
+ ColdBuild(prefab, conf);
+
+ prefixPath = pathwithname.Substring(0, pathwithname.IndexOf("/SkillPackage"));
+ Time = File.GetLastWriteTime(pathwithname);
+ }
+ catch (Exception e)
+ {
+ Debug.Log("<color=red>Error occurred during loading config file: " + pathwithname + " with error " + e.Message + "</color>");
+ }
+ }
+
+ public void HotBuild(XSkillHoster hoster, XConfigData conf)
+ {
+ hoster.SkillDataExtra.JaEx.Clear();
+ if (conf.Ja != null)
+ {
+ foreach (XJADataExtra ja in conf.Ja)
+ {
+ XJADataExtraEx jaex = new XJADataExtraEx();
+
+ if (ja.Next_Skill_PathWithName != null && ja.Next_Skill_PathWithName.Length > 0)
+ {
+ XSkillData skill = XDataIO<XSkillData>.singleton.DeserializeData("Assets/Resources/" + ja.Next_Skill_PathWithName);
+ jaex.Next = skill;
+ }
+
+ if (ja.JA_Skill_PathWithName != null && ja.JA_Skill_PathWithName.Length > 0)
+ {
+ XSkillData skill = XDataIO<XSkillData>.singleton.DeserializeData("Assets/Resources/" + ja.JA_Skill_PathWithName);
+ jaex.Ja = skill;
+ }
+
+ hoster.SkillDataExtra.JaEx.Add(jaex);
+ }
+ }
+
+ if(hoster.SkillData.TypeToken == 3)
+ {
+ hoster.SkillDataExtra.CombinedEx.Clear();
+ hoster.SkillDataExtra.SkillClip_Frame = 0;
+
+ if (conf.Combined != null)
+ {
+ foreach (XCombinedDataExtra combine in conf.Combined)
+ {
+ XCombinedDataExtraEx combineex = new XCombinedDataExtraEx();
+
+ if (combine.Skill_PathWithName != null && combine.Skill_PathWithName.Length > 0)
+ {
+ XSkillData skill = XDataIO<XSkillData>.singleton.DeserializeData("Assets/Resources/" + combine.Skill_PathWithName);
+ combineex.Skill = skill;
+ combineex.Clip = Resources.Load(skill.ClipName, typeof(AnimationClip)) as AnimationClip;
+
+ hoster.SkillDataExtra.CombinedEx.Add(combineex);
+ hoster.SkillDataExtra.SkillClip_Frame += (combineex.Clip.length / (1.0f / 30.0f));
+ }
+ }
+ }
+ }
+ }
+
+ public void HotBuildEx(XSkillHoster hoster, XConfigData conf)
+ {
+ XSkillDataExtra edata = hoster.SkillDataExtra;
+ XSkillData data = hoster.SkillData;
+
+ edata.ResultEx.Clear();
+ edata.ChargeEx.Clear();
+ edata.Fx.Clear();
+ edata.Audio.Clear();
+ edata.HitEx.Clear();
+ edata.ManipulationEx.Clear();
+
+ if (data.Result != null)
+ {
+ foreach (XResultData result in data.Result)
+ {
+ XResultDataExtraEx rdee = new XResultDataExtraEx();
+ if (result.LongAttackEffect)
+ {
+ rdee.BulletPrefab = Resources.Load(result.LongAttackData.Prefab) as GameObject;
+ rdee.BulletEndFx = Resources.Load(result.LongAttackData.End_Fx) as GameObject;
+ rdee.BulletHitGroundFx = Resources.Load(result.LongAttackData.HitGround_Fx) as GameObject;
+ }
+ edata.ResultEx.Add(rdee);
+ }
+ }
+
+ if (data.Charge != null)
+ {
+ foreach (XChargeData charge in data.Charge)
+ {
+ XChargeDataExtraEx cdee = new XChargeDataExtraEx();
+ cdee.Charge_Curve_Prefab_Forward = Resources.Load(charge.Curve_Forward) as GameObject;
+ cdee.Charge_Curve_Forward = cdee.Charge_Curve_Prefab_Forward == null ? null : cdee.Charge_Curve_Prefab_Forward.GetComponent<XCurve>().Curve;
+
+ cdee.Charge_Curve_Prefab_Side = Resources.Load(charge.Curve_Side) as GameObject;
+ cdee.Charge_Curve_Side = cdee.Charge_Curve_Prefab_Side == null ? null : cdee.Charge_Curve_Prefab_Side.GetComponent<XCurve>().Curve;
+
+ if (charge.Using_Up)
+ {
+ cdee.Charge_Curve_Prefab_Up = Resources.Load(charge.Curve_Up) as GameObject;
+ cdee.Charge_Curve_Up = cdee.Charge_Curve_Prefab_Up == null ? null : cdee.Charge_Curve_Prefab_Up.GetComponent<XCurve>().Curve;
+ }
+
+ edata.ChargeEx.Add(cdee);
+ }
+ }
+
+ if (data.Manipulation != null)
+ {
+ foreach (XManipulationData manipulation in data.Manipulation)
+ {
+ XManipulationDataExtra me = new XManipulationDataExtra();
+
+ edata.ManipulationEx.Add(me);
+ }
+ }
+
+ if (data.Hit != null)
+ {
+ foreach (XHitData hit in data.Hit)
+ {
+ XHitDataExtraEx hee = new XHitDataExtraEx();
+ hee.Fx = Resources.Load(hit.Fx) as GameObject;
+
+ edata.HitEx.Add(hee);
+ }
+ }
+
+ if (data.Fx != null)
+ {
+ foreach (XFxData fx in data.Fx)
+ {
+ XFxDataExtra fxe = new XFxDataExtra();
+ fxe.Fx = Resources.Load(fx.Fx) as GameObject;
+ if (fx.Bone != null && fx.Bone.Length > 0)
+ {
+ Transform attachPoint = hoster.gameObject.transform.Find(fx.Bone);
+ if (attachPoint != null)
+ {
+ fxe.BindTo = attachPoint.gameObject;
+ }
+ else
+ {
+ int index = fx.Bone.LastIndexOf("/");
+ if (index >= 0)
+ {
+ string bone = fx.Bone.Substring(index + 1);
+ attachPoint = hoster.gameObject.transform.Find(bone);
+ if (attachPoint != null)
+ {
+ fxe.BindTo = attachPoint.gameObject;
+ }
+ }
+
+ }
+ }
+
+ fxe.Ratio = fx.At / data.Time;
+
+ edata.Fx.Add(fxe);
+ }
+ }
+
+ if (data.Warning != null)
+ {
+ foreach (XWarningData warning in data.Warning)
+ {
+ XWarningDataExtra we = new XWarningDataExtra();
+ we.Fx = Resources.Load(warning.Fx) as GameObject;
+ we.Ratio = warning.At / data.Time;
+
+ edata.Warning.Add(we);
+ }
+ }
+
+ if (data.Mob != null)
+ {
+ foreach (XMobUnitData mob in data.Mob)
+ {
+ XMobUnitDataExtra me = new XMobUnitDataExtra();
+ me.Ratio = mob.At / data.Time;
+
+ edata.Mob.Add(me);
+ }
+ }
+
+ if (data.Audio != null)
+ {
+ foreach (XAudioData au in data.Audio)
+ {
+ XAudioDataExtra aue = new XAudioDataExtra();
+ aue.audio = Resources.Load(au.Clip) as AudioClip;
+ aue.Ratio = au.At / data.Time;
+
+ edata.Audio.Add(aue);
+ }
+ }
+
+ if (data.CameraMotion != null)
+ {
+ edata.MotionEx = new XCameraMotionDataExtra();
+ edata.MotionEx.Motion3D = Resources.Load(data.CameraMotion.Motion3D, typeof(AnimationClip)) as AnimationClip;
+ edata.MotionEx.Motion2_5D = Resources.Load(data.CameraMotion.Motion2_5D, typeof(AnimationClip)) as AnimationClip;
+ edata.MotionEx.Ratio = data.CameraMotion.At / data.Time;
+ }
+
+ if (data.CameraPostEffect != null)
+ {
+ edata.PostEffectEx = new XCameraPostEffectDataExtraEx();
+ edata.PostEffectEx.Effect = AssetDatabase.LoadAssetAtPath(conf.PostEffect.EffectLocation, typeof(UnityEngine.Object));
+ //edata.PostEffectEx.Shader = Resources.Load(data.CameraPostEffect.Shader, typeof(UnityEngine.Shader)) as UnityEngine.Shader;
+ edata.PostEffectEx.At_Ratio = data.CameraPostEffect.At / data.Time;
+ edata.PostEffectEx.End_Ratio = data.CameraPostEffect.At / data.Time;
+ }
+ }
+
+ public void ColdBuild(GameObject prefab, XConfigData conf)
+ {
+ if (hoster != null) GameObject.DestroyImmediate(hoster);
+
+ hoster = UnityEngine.Object.Instantiate(prefab, Vector3.zero, Quaternion.identity) as GameObject;
+ hoster.transform.localScale = Vector3.one * XAnimationLibrary.AssociatedAnimations((uint)conf.Player).Scale;
+
+ hoster.AddComponent<XSkillHoster>();
+
+ CharacterController cc = hoster.GetComponent<CharacterController>();
+ if (cc != null) cc.enabled = false;
+
+ UnityEngine.AI.NavMeshAgent agent = hoster.GetComponent<UnityEngine.AI.NavMeshAgent>();
+ if (agent != null) agent.enabled = false;
+
+ XSkillHoster component = hoster.GetComponent<XSkillHoster>();
+
+ string directory = conf.Directory[conf.Directory.Length - 1] == '/' ? conf.Directory.Substring(0, conf.Directory.Length - 1) : conf.Directory;
+ string path = XEditorPath.GetPath("SkillPackage" + "/" + directory);
+
+ component.ConfigData = conf;
+ component.SkillData = XDataIO<XSkillData>.singleton.DeserializeData(path + conf.SkillName + ".txt");
+
+ component.SkillDataExtra.ScriptPath = path;
+ component.SkillDataExtra.ScriptFile = conf.SkillName;
+
+ component.SkillDataExtra.SkillClip = RestoreClip(conf.SkillClip, conf.SkillClipName);
+
+ if (component.SkillData.TypeToken != 3)
+ {
+ if (component.SkillData.Time == 0)
+ component.SkillData.Time = component.SkillDataExtra.SkillClip.length;
+ }
+
+ HotBuild(component, conf);
+ HotBuildEx(component, conf);
+
+ EditorGUIUtility.PingObject(hoster);
+ Selection.activeObject = hoster;
+ }
+
+ public void Update(XSkillHoster hoster)
+ {
+ string pathwithname = hoster.SkillDataExtra.ScriptPath + hoster.ConfigData.SkillName + ".txt";
+
+ DateTime time = File.GetLastWriteTime(pathwithname);
+
+ if (Time == default(DateTime)) Time = time;
+
+ if (time != Time)
+ {
+ Time = time;
+
+ if(EditorUtility.DisplayDialog("WARNING!",
+ "Skill has been Modified outside, Press 'OK' to reload file or 'Ignore' to maintain your change. (Make sure the '.config' file for skill script has been well synchronized)",
+ "Ok", "Ignore"))
+ {
+ hoster.ConfigData = XDataIO<XConfigData>.singleton.DeserializeData(XEditorPath.GetCfgFromSkp(pathwithname));
+ hoster.SkillData = XDataIO<XSkillData>.singleton.DeserializeData(pathwithname);
+
+ XDataBuilder.singleton.HotBuild(hoster, hoster.ConfigData);
+ XDataBuilder.singleton.HotBuildEx(hoster, hoster.ConfigData);
+ }
+ }
+ }
+
+ private AnimationClip RestoreClip(string path, string name)
+ {
+ if (path == null || name == null || path == "" || name == "") return null;
+
+ int last = path.LastIndexOf('.');
+ string subfix = path.Substring(last, path.Length - last).ToLower();
+
+ if (subfix == ".fbx")
+ {
+ UnityEngine.Object[] objs = AssetDatabase.LoadAllAssetsAtPath(path);
+ foreach (UnityEngine.Object obj in objs)
+ {
+ AnimationClip clip = obj as AnimationClip;
+ if (clip != null && clip.name == name)
+ return clip;
+ }
+ }
+ else if (subfix == ".anim")
+ {
+ return AssetDatabase.LoadAssetAtPath(path, typeof(AnimationClip)) as AnimationClip;
+
+ }
+ else
+ return null;
+
+ return null;
+ }
+ }
+}
+#endif
\ No newline at end of file diff --git a/Client/Assets/Scripts/XEditor/XSkillEditor/XDataBuilder.cs.meta b/Client/Assets/Scripts/XEditor/XSkillEditor/XDataBuilder.cs.meta new file mode 100644 index 00000000..7400f70e --- /dev/null +++ b/Client/Assets/Scripts/XEditor/XSkillEditor/XDataBuilder.cs.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2
+guid: 4f8b987db0de1b845b2cab2335d6b233
+MonoImporter:
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
diff --git a/Client/Assets/Scripts/XEditor/XSkillEditor/XDataIO.cs b/Client/Assets/Scripts/XEditor/XSkillEditor/XDataIO.cs new file mode 100644 index 00000000..adb34806 --- /dev/null +++ b/Client/Assets/Scripts/XEditor/XSkillEditor/XDataIO.cs @@ -0,0 +1,95 @@ +#if UNITY_EDITOR
+using System;
+using UnityEngine;
+using XUtliPoolLib;
+
+using System.IO;
+using System.Text;
+using System.Xml.Serialization;
+using UnityEditor;
+using System.Runtime.Serialization.Formatters.Binary;
+
+namespace XEditor
+{
+ public class XDataIO<T> : XSingleton<XDataIO<T>>
+ {
+ XmlSerializer _formatter = new XmlSerializer(typeof(T));
+
+ public void SerializeData(string pathwithname, T data)
+ {
+ using (FileStream writer = new FileStream(pathwithname, FileMode.Create))
+ {
+ //using Encoding
+ StreamWriter sw = new StreamWriter(writer, Encoding.UTF8);
+ XmlSerializerNamespaces xsn = new XmlSerializerNamespaces();
+ //empty name spaces
+ xsn.Add(string.Empty, string.Empty);
+
+ _formatter.Serialize(sw, data, xsn);
+
+ AssetDatabase.Refresh();
+ }
+ }
+
+ public void SerializeData(string pathwithname, T data, Type[] types)
+ {
+ using (FileStream writer = new FileStream(pathwithname, FileMode.Create))
+ {
+ //using Encoding
+ StreamWriter sw = new StreamWriter(writer, Encoding.UTF8);
+ XmlSerializerNamespaces xsn = new XmlSerializerNamespaces();
+ //empty name spaces
+ xsn.Add(string.Empty, string.Empty);
+
+ XmlSerializer formatter = new XmlSerializer(typeof(T), types);
+ formatter.Serialize(sw, data, xsn);
+
+ AssetDatabase.Refresh();
+ }
+ }
+
+ public T DeserializeData(string pathwithname)
+ {
+ try
+ {
+ using (FileStream reader = new FileStream(pathwithname, FileMode.Open))
+ {
+ //IFormatter formatter = new BinaryFormatter();
+ System.Xml.Serialization.XmlSerializer formatter = new System.Xml.Serialization.XmlSerializer(typeof(T));
+ return (T)formatter.Deserialize(reader);
+ }
+ }
+ catch (Exception e)
+ {
+ Debug.LogError(e.Message);
+ return default(T);
+ }
+ }
+
+ public T DeserializeData(Stream stream)
+ {
+ try
+ {
+ //IFormatter formatter = new BinaryFormatter();
+ System.Xml.Serialization.XmlSerializer formatter = new System.Xml.Serialization.XmlSerializer(typeof(T));
+ return (T)formatter.Deserialize(stream);
+ }
+ catch (Exception e)
+ {
+ Debug.LogError(e.Message);
+ return default(T);
+ }
+ }
+
+ public T DeserializeData(string pathwithname, Type[] types)
+ {
+ using (FileStream reader = new FileStream(pathwithname, FileMode.Open))
+ {
+ //IFormatter formatter = new BinaryFormatter();
+ System.Xml.Serialization.XmlSerializer formatter = new System.Xml.Serialization.XmlSerializer(typeof(T), types);
+ return (T)formatter.Deserialize(reader);
+ }
+ }
+ }
+}
+#endif
\ No newline at end of file diff --git a/Client/Assets/Scripts/XEditor/XSkillEditor/XDataIO.cs.meta b/Client/Assets/Scripts/XEditor/XSkillEditor/XDataIO.cs.meta new file mode 100644 index 00000000..1dae6847 --- /dev/null +++ b/Client/Assets/Scripts/XEditor/XSkillEditor/XDataIO.cs.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2
+guid: d3b1fdc81b2846d4fa6534bde4ec0b9b
+MonoImporter:
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
diff --git a/Client/Assets/Scripts/XEditor/XSkillEditor/XEditorData.cs b/Client/Assets/Scripts/XEditor/XSkillEditor/XEditorData.cs new file mode 100644 index 00000000..760e1335 --- /dev/null +++ b/Client/Assets/Scripts/XEditor/XSkillEditor/XEditorData.cs @@ -0,0 +1,695 @@ +#if UNITY_EDITOR
+using System;
+using System.Collections.Generic;
+using System.Text;
+using UnityEngine;
+
+using XUtliPoolLib;
+
+using System.IO;
+using UnityEditor;
+
+namespace XEditor
+{
+ public class XParse
+ {
+ private static bool inited = false;
+ public static float Parse(string str)
+ {
+ if(!inited)
+ {
+ System.Threading.Thread.CurrentThread.CurrentCulture = System.Globalization.CultureInfo.InvariantCulture;
+ inited = true;
+ }
+ float value = 0.0f;
+ float.TryParse(str, out value);
+ return value;
+ }
+ }
+ public class XGloabelConfLibrary
+ {
+ private static GlobalTable _table = new GlobalTable();
+
+ public static float Hit_PresentStraight;
+ public static float Hit_HardStraight;
+ public static float Hit_Offset;
+ public static float Hit_Height;
+
+ static string GetValue(string key)
+ {
+ string ret = "";
+ uint k = XCommon.singleton.XHash(key);
+ if (_table.Table.TryGetValue(k, out ret))
+ {
+ return ret;
+ }
+
+ return ret;
+ }
+ static XGloabelConfLibrary()
+ {
+ XTableReader.ReadFile(@"Table/GlobalConfig", _table);
+
+ Hit_PresentStraight = XParse.Parse(GetValue("PresentStraight"));
+ Hit_HardStraight = XParse.Parse(GetValue("HardStraight"));
+ Hit_Offset = XParse.Parse(GetValue("Offset"));
+ Hit_Height = XParse.Parse(GetValue("Height"));
+ }
+ }
+
+ public class XQTEStatusLibrary
+ {
+ private static XQTEStatusTable _table = new XQTEStatusTable();
+ public static List<string> NameList = null;
+ public static List<string> KeyList = null;
+
+ static XQTEStatusLibrary()
+ {
+ XTableReader.ReadFile(@"Table/QteStatusList", _table);
+
+ NameList = new List<string>();
+ KeyList = new List<string>();
+
+ for (int i = 0; i < _table.Table.Length; ++i)
+ {
+ XQTEStatusTable.RowData row = _table.Table[i];
+ NameList.Add(row.Value + " " + row.Name);
+ }
+
+ for (int i = 0; i < (int)KKSG.XSkillSlot.Attack_Max; i++)
+ KeyList.Add(((KKSG.XSkillSlot)i).ToString());
+ }
+
+ public static int GetStatusValue(int idx)
+ {
+ if (idx < 0 || idx >= NameList.Count) return 0;
+
+ string[] strs = NameList.ToArray();
+
+ for (int i = 0; i < _table.Table.Length; ++i)
+ {
+ XQTEStatusTable.RowData row = _table.Table[i];
+ if ((row.Value + " " + row.Name) == strs[idx])
+ return (int)row.Value;
+ }
+
+ return 0;
+ }
+
+ public static int GetStatusIdx(int qte)
+ {
+ string[] strs = NameList.ToArray();
+
+ string str = null;
+ for (int i = 0; i < _table.Table.Length; ++i)
+ {
+ XQTEStatusTable.RowData row = _table.Table[i];
+ if (row.Value == qte)
+ {
+ str = (row.Value + " " + row.Name);
+ break;
+ }
+ }
+
+ if (str != null)
+ {
+ for (int i = 0; i < strs.Length; i++)
+ {
+ if (strs[i] == str) return i;
+ }
+ }
+
+ return 0;
+ }
+ }
+
+ public class XSkillListLibrary
+ {
+ private static SkillList _skilllist = new SkillList();
+
+ static XSkillListLibrary()
+ {
+ XTableReader.ReadFile(@"Table/SkillList", _skilllist);
+ }
+
+ public static SkillList.RowData[] AllList()
+ {
+ return _skilllist.Table;
+ }
+ }
+
+ public class XAnimationLibrary
+ {
+ private static XEntityPresentation _presentations = new XEntityPresentation();
+
+ static XAnimationLibrary()
+ {
+ XTableReader.ReadFile(@"Table/XEntityPresentation", _presentations);
+ }
+
+ public static XEntityPresentation.RowData AssociatedAnimations(uint presentid)
+ {
+ return _presentations.GetByPresentID(presentid);
+ }
+
+ public static GameObject GetDummy(uint presentid)
+ {
+ XEntityPresentation.RowData raw_data = AssociatedAnimations(presentid);
+ if (raw_data == null) return null;
+
+ string prefab = raw_data.Prefab;
+
+ int n = prefab.LastIndexOf("_SkinnedMesh");
+ int m = prefab.LastIndexOf("Loading");
+
+ return n < 0 || m > 0?
+ AssetDatabase.LoadAssetAtPath("Assets/Resources/Prefabs/" + prefab + ".prefab", typeof(GameObject)) as GameObject :
+ AssetDatabase.LoadAssetAtPath("Assets/Editor/EditorResources/Prefabs/" + prefab.Substring(0, n) + ".prefab", typeof(GameObject)) as GameObject;
+ }
+ }
+
+ public class XStatisticsLibrary
+ {
+ private static XEntityStatistics _statistics = new XEntityStatistics();
+
+ static XStatisticsLibrary()
+ {
+ XTableReader.ReadFile(@"Table/XEntityStatistics", _statistics);
+ }
+
+ public static XEntityStatistics.RowData AssociatedData(uint id)
+ {
+ return _statistics.GetByID(id);
+ }
+
+ public static GameObject GetDummy(uint id)
+ {
+ XEntityStatistics.RowData data = AssociatedData(id);
+ if (data == null) return null;
+ return XAnimationLibrary.GetDummy(data.PresentID);
+ }
+ }
+
+ public class XSceneLibrary
+ {
+ private static SceneTable _table = new SceneTable();
+
+ static XSceneLibrary()
+ {
+ XTableReader.ReadFile(@"Table/SceneList", _table);
+ }
+
+ public static SceneTable.RowData AssociatedData(uint id)
+ {
+ return _table.GetBySceneID((int)id);
+ }
+
+ public static string GetDynamicString(string levelConfig)
+ {
+ for (int i = 0; i < _table.Table.Length; i++)
+ {
+ if (_table.Table[i].configFile == levelConfig)
+ return _table.Table[i].DynamicScene;
+ }
+
+ return "";
+ }
+ }
+
+ //public class XEquipBoneLibrary
+ //{
+ // private static EquipBones _statistics = new EquipBones();
+
+ // static XEquipBoneLibrary()
+ // {
+ // //XResourceLoaderMgr.singleton.ReadFile(@"Table/EquipBones", _statistics);
+ // }
+
+ // public static void Read()
+ // {
+ // XResourceLoaderMgr.singleton.ReadFile(@"Table/EquipBones", _statistics);
+ // }
+
+ // public static EquipBones.RowData AssociatedData(string EquipName)
+ // {
+ // return _statistics.GetByEquipName(EquipName);
+ // }
+
+ // public static void ChangeData(string EquipName, EquipBones.RowData data)
+ // {
+ // for (int i = 0; i < _statistics.Table.Count; i++)
+ // {
+ // if (_statistics.Table[i].EquipName == EquipName)
+ // {
+ // _statistics.Table[i] = data;
+ // return;
+ // }
+ // }
+
+ // _statistics.Table.Add(data);
+ // }
+
+ // public static void WriteToFile()
+ // {
+ // string path = "./Assets/Resources/Table/EquipBones.txt";
+
+ // using (FileStream writer = new FileStream(path, FileMode.Truncate))
+ // {
+ // StreamWriter sw = new StreamWriter(writer, Encoding.Unicode);
+
+ // _statistics.Comment = new List<string>();
+ // _statistics.Comment.Add("comment_EquipName");
+ // _statistics.Comment.Add("comment_bones");
+
+ // _statistics.WriteFile(sw);
+
+ // sw.Flush();
+ // sw.Close();
+ // }
+ // }
+ //}
+
+ [Serializable]
+ public class XConfigData
+ {
+ [SerializeField]
+ public string SkillName;
+ [SerializeField]
+ public float Speed = 2.0f;
+ [SerializeField]
+ public float RotateSpeed = 12.0f;
+
+ [SerializeField]
+ public string SkillClip;
+ [SerializeField]
+ public string SkillClipName;
+
+ [SerializeField]
+ public string Directory = null;
+ [SerializeField]
+ public int Player = 0;
+ [SerializeField]
+ public int Dummy = 0;
+
+ [SerializeField]
+ public List<XResultDataExtra> Result = new List<XResultDataExtra>();
+ [SerializeField]
+ public List<XChargeDataExtra> Charge = new List<XChargeDataExtra>();
+ [SerializeField]
+ public List<XJADataExtra> Ja = new List<XJADataExtra>();
+ [SerializeField]
+ public List<XCombinedDataExtra> Combined = new List<XCombinedDataExtra>();
+ [SerializeField]
+ public List<XCameraEffectDataExtra> CameraEffect = new List<XCameraEffectDataExtra>();
+ [SerializeField]
+ public XLogicalDataExtra Logical = new XLogicalDataExtra();
+ [SerializeField]
+ public XUltraDataExtra Ultra = new XUltraDataExtra();
+ [SerializeField]
+ public XCameraPostEffectDataExtra PostEffect = new XCameraPostEffectDataExtra();
+
+ public void Add<T>(T data) where T : XBaseDataExtra
+ {
+ Type t = typeof(T);
+
+ if (t == typeof(XResultDataExtra)) Result.Add(data as XResultDataExtra);
+ else if (t == typeof(XChargeDataExtra)) Charge.Add(data as XChargeDataExtra);
+ else if (t == typeof(XJADataExtra)) Ja.Add(data as XJADataExtra);
+ else if (t == typeof(XCombinedDataExtra)) Combined.Add(data as XCombinedDataExtra);
+ else if (t == typeof(XCameraEffectDataExtra)) CameraEffect.Add(data as XCameraEffectDataExtra);
+ }
+ }
+
+ [Serializable]
+ public class XEditorData
+ {
+ //for serialized
+ [SerializeField]
+ public bool XResult_foldout;
+ [SerializeField]
+ public bool XCharge_foldout;
+ [SerializeField]
+ public bool XHit_foldout;
+ [SerializeField]
+ public bool XJA_foldout;
+ [SerializeField]
+ public bool XScript_foldout;
+ [SerializeField]
+ public bool XMob_foldout;
+ [SerializeField]
+ public bool XCastChain_foldout;
+ [SerializeField]
+ public bool XManipulation_foldout;
+ [SerializeField]
+ public bool XLogical_foldout;
+ [SerializeField]
+ public bool XCombined_foldout;
+ [SerializeField]
+ public bool XUltra_foldout;
+ [SerializeField]
+ public bool XFx_foldout;
+ [SerializeField]
+ public bool XAudio_foldout;
+ [SerializeField]
+ public bool XCameraEffect_foldout;
+ [SerializeField]
+ public bool XCameraMotion_foldout;
+ [SerializeField]
+ public bool XCameraPostEffect_foldout;
+ [SerializeField]
+ public bool XEffect_foldout;
+ [SerializeField]
+ public bool XHitDummy_foldout;
+ [SerializeField]
+ public bool XQTEStatus_foldout;
+ [SerializeField]
+ public bool XWarning_foldout;
+ [SerializeField]
+ public bool XComboSkills_foldout;
+
+ [SerializeField]
+ public bool XAutoSelected;
+ [SerializeField]
+ public bool XFrameByFrame;
+ [SerializeField]
+ public bool XAutoJA = false;
+
+ public void ToggleFold<T>(bool b) where T : XBaseData
+ {
+ Type t = typeof(T);
+
+ if (t == typeof(XResultData)) XResult_foldout = b;
+ else if (t == typeof(XChargeData)) XCharge_foldout = b;
+ else if (t == typeof(XJAData)) XJA_foldout = b;
+ else if (t == typeof(XHitData)) XHit_foldout = b;
+ else if (t == typeof(XScriptData)) XScript_foldout = b;
+ else if (t == typeof(XLogicalData)) XLogical_foldout = b;
+ else if (t == typeof(XFxData)) XFx_foldout = b;
+ else if (t == typeof(XAudioData)) XAudio_foldout = b;
+ else if (t == typeof(XCameraEffectData)) XCameraEffect_foldout = b;
+ else if (t == typeof(XWarningData)) XWarning_foldout = b;
+ }
+ }
+
+ [Serializable]
+ public class XSkillDataExtra
+ {
+ [SerializeField]
+ public AnimationClip SkillClip;
+ [SerializeField]
+ public float SkillClip_Frame;
+ [SerializeField]
+ public string ScriptPath;
+ [SerializeField]
+ public string ScriptFile;
+ [SerializeField]
+ public GameObject Dummy;
+
+ [SerializeField]
+ public List<XResultDataExtraEx> ResultEx = new List<XResultDataExtraEx>();
+ [SerializeField]
+ public List<XChargeDataExtraEx> ChargeEx = new List<XChargeDataExtraEx>();
+ [SerializeField]
+ public List<XFxDataExtra> Fx = new List<XFxDataExtra>();
+ [SerializeField]
+ public List<XManipulationDataExtra> ManipulationEx = new List<XManipulationDataExtra>();
+ [SerializeField]
+ public List<XWarningDataExtra> Warning = new List<XWarningDataExtra>();
+ [SerializeField]
+ public List<XAudioDataExtra> Audio = new List<XAudioDataExtra>();
+ [SerializeField]
+ public List<XMobUnitDataExtra> Mob = new List<XMobUnitDataExtra>();
+ [SerializeField]
+ public XCameraMotionDataExtra MotionEx = new XCameraMotionDataExtra();
+ [SerializeField]
+ public XChainCastExtra Chain = new XChainCastExtra();
+ [SerializeField]
+ public XCameraPostEffectDataExtraEx PostEffectEx = new XCameraPostEffectDataExtraEx();
+ [SerializeField]
+ public List<XJADataExtraEx> JaEx = new List<XJADataExtraEx>();
+ [SerializeField]
+ public List<XHitDataExtraEx> HitEx = new List<XHitDataExtraEx>();
+ [SerializeField]
+ public List<XCombinedDataExtraEx> CombinedEx = new List<XCombinedDataExtraEx>();
+
+ public void Add<T>(T data) where T : XBaseDataExtra
+ {
+ Type t = typeof(T);
+
+ if (t == typeof(XFxDataExtra)) Fx.Add(data as XFxDataExtra);
+ else if (t == typeof(XWarningDataExtra)) Warning.Add(data as XWarningDataExtra);
+ else if (t == typeof(XMobUnitDataExtra)) Mob.Add(data as XMobUnitDataExtra);
+ else if (t == typeof(XAudioDataExtra)) Audio.Add(data as XAudioDataExtra);
+ else if (t == typeof(XJADataExtraEx)) JaEx.Add(data as XJADataExtraEx);
+ else if (t == typeof(XManipulationDataExtra)) ManipulationEx.Add(data as XManipulationDataExtra);
+ else if (t == typeof(XHitDataExtraEx)) HitEx.Add(data as XHitDataExtraEx);
+ else if (t == typeof(XResultDataExtraEx)) ResultEx.Add(data as XResultDataExtraEx);
+ else if (t == typeof(XChargeDataExtraEx)) ChargeEx.Add(data as XChargeDataExtraEx);
+ else if (t == typeof(XCombinedDataExtraEx)) CombinedEx.Add(data as XCombinedDataExtraEx);
+ }
+ }
+
+ [Serializable]
+ public class XBaseDataExtra { }
+
+ [Serializable]
+ public class XResultDataExtra : XBaseDataExtra
+ {
+ [SerializeField]
+ public float Result_Ratio = 0;
+ }
+
+ [Serializable]
+ public class XChargeDataExtra : XBaseDataExtra
+ {
+ [SerializeField]
+ public float Charge_Ratio = 0;
+ [SerializeField]
+ public float Charge_End_Ratio = 0;
+ }
+
+ [Serializable]
+ public class XChargeDataExtraEx : XBaseDataExtra
+ {
+ [SerializeField]
+ public GameObject Charge_Curve_Prefab_Forward = null;
+ [SerializeField]
+ public AnimationCurve Charge_Curve_Forward = null;
+ [SerializeField]
+ public GameObject Charge_Curve_Prefab_Side = null;
+ [SerializeField]
+ public AnimationCurve Charge_Curve_Side = null;
+ [SerializeField]
+ public GameObject Charge_Curve_Prefab_Up = null;
+ [SerializeField]
+ public AnimationCurve Charge_Curve_Up = null;
+ }
+
+ [Serializable]
+ public class XUltraDataExtra : XBaseDataExtra
+ {
+ [SerializeField]
+ public string ultra_end_Skill_PathWithName = null;
+ }
+
+ [Serializable]
+ public class XResultDataExtraEx : XBaseDataExtra
+ {
+ [SerializeField]
+ public GameObject BulletPrefab = null;
+ [SerializeField]
+ public GameObject BulletEndFx = null;
+ [SerializeField]
+ public GameObject BulletHitGroundFx = null;
+ }
+
+ [Serializable]
+ public class XJADataExtraEx : XBaseDataExtra
+ {
+ [SerializeField]
+ public XSkillData Next = null;
+ [SerializeField]
+ public XSkillData Ja = null;
+ }
+
+ [Serializable]
+ public class XCombinedDataExtraEx : XBaseDataExtra
+ {
+ [SerializeField]
+ public XSkillData Skill = null;
+ [SerializeField]
+ public AnimationClip Clip = null;
+ }
+
+ [Serializable]
+ public class XCameraEffectDataExtra : XBaseDataExtra
+ {
+ [SerializeField]
+ public float Ratio = 0;
+ }
+
+ [Serializable]
+ public class XJADataExtra : XBaseDataExtra
+ {
+ [SerializeField]
+ public float JA_Begin_Ratio = 0;
+ [SerializeField]
+ public float JA_End_Ratio = 0;
+ [SerializeField]
+ public float JA_Point_Ratio = 0;
+ [SerializeField]
+ public string JA_Skill_PathWithName = null;
+ [SerializeField]
+ public string Next_Skill_PathWithName = null;
+ }
+
+ [Serializable]
+ public class XCombinedDataExtra : XBaseDataExtra
+ {
+ [SerializeField]
+ public float From_Ratio = 0;
+ [SerializeField]
+ public float To_Ratio = 0;
+ [SerializeField]
+ public string Skill_PathWithName = null;
+ }
+
+ [Serializable]
+ public class XCameraMotionDataExtra : XBaseDataExtra
+ {
+ [SerializeField]
+ public AnimationClip Motion3D = null;
+ [SerializeField]
+ public AnimationClip Motion2_5D = null;
+ [SerializeField]
+ public float Ratio = 0;
+ }
+
+ [Serializable]
+ public class XCameraPostEffectDataExtra : XBaseDataExtra
+ {
+ [SerializeField]
+ public string EffectLocation = null;
+ }
+
+ [Serializable]
+ public class XMobUnitDataExtra : XBaseDataExtra
+ {
+ [SerializeField]
+ public float Ratio = 0;
+ }
+
+ [Serializable]
+ public class XChainCastExtra : XBaseDataExtra
+ {
+ [SerializeField]
+ public float Ratio = 0;
+ }
+
+ [Serializable]
+ public class XCameraPostEffectDataExtraEx : XBaseDataExtra
+ {
+ [SerializeField]
+ public UnityEngine.Object Effect = null;
+ [SerializeField]
+ public UnityEngine.Shader Shader = null;
+ [SerializeField]
+ public float At_Ratio = 0;
+ [SerializeField]
+ public float End_Ratio = 0;
+ [SerializeField]
+ public float Solid_At_Ratio = 0;
+ [SerializeField]
+ public float Solid_End_Ratio = 0;
+ }
+
+ [Serializable]
+ public class XQTEDataExtra
+ {
+ [SerializeField]
+ public float QTE_At_Ratio = 0;
+ [SerializeField]
+ public float QTE_End_Ratio = 0;
+ }
+
+ [Serializable]
+ public class XLogicalDataExtra : XBaseDataExtra
+ {
+ [SerializeField]
+ public float Not_Move_At_Ratio = 0;
+ [SerializeField]
+ public float Not_Move_End_Ratio = 0;
+ [SerializeField]
+ public float Not_Dash_At_Ratio = 0;
+ [SerializeField]
+ public float Not_Dash_End_Ratio = 0;
+ [SerializeField]
+ public float Rotate_At_Ratio = 0;
+ [SerializeField]
+ public float Rotate_End_Ratio = 0;
+ [SerializeField]
+ public List<XQTEDataExtra> QTEDataEx = new List<XQTEDataExtra>();
+ [SerializeField]
+ public float Cancel_At_Ratio = 0;
+ [SerializeField]
+ public float Preserved_Ratio = 0;
+ [SerializeField]
+ public float Preserved_End_Ratio = 0;
+ [SerializeField]
+ public float ExString_Ratio = 0;
+ [SerializeField]
+ public float Not_Selected_At_Ratio = 0;
+ [SerializeField]
+ public float Not_Selected_End_Ratio = 0;
+ }
+
+ [Serializable]
+ public class XFxDataExtra : XBaseDataExtra
+ {
+ [SerializeField]
+ public GameObject Fx = null;
+ [SerializeField]
+ public GameObject BindTo = null;
+ [SerializeField]
+ public float Ratio = 0;
+ [SerializeField]
+ public float End_Ratio = -1;
+ }
+
+ [Serializable]
+ public class XManipulationDataExtra : XBaseDataExtra
+ {
+ [SerializeField]
+ public float At_Ratio = 0;
+ [SerializeField]
+ public float End_Ratio = 0;
+ [SerializeField]
+ public bool Present = true;
+ }
+
+ [Serializable]
+ public class XWarningDataExtra : XBaseDataExtra
+ {
+ [SerializeField]
+ public GameObject Fx = null;
+ [SerializeField]
+ public float Ratio = 0;
+ }
+
+ [Serializable]
+ public class XAudioDataExtra : XBaseDataExtra
+ {
+ [SerializeField]
+ public AudioClip audio = null;
+ [SerializeField]
+ public float Ratio = 0;
+ }
+
+ [Serializable]
+ public class XHitDataExtraEx : XBaseDataExtra
+ {
+ [SerializeField]
+ public GameObject Fx = null;
+ }
+}
+#endif
\ No newline at end of file diff --git a/Client/Assets/Scripts/XEditor/XSkillEditor/XEditorData.cs.meta b/Client/Assets/Scripts/XEditor/XSkillEditor/XEditorData.cs.meta new file mode 100644 index 00000000..1aeef38e --- /dev/null +++ b/Client/Assets/Scripts/XEditor/XSkillEditor/XEditorData.cs.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2
+guid: 6f74b6399b1b40b4f8d3ae179db757a9
+MonoImporter:
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
diff --git a/Client/Assets/Scripts/XEditor/XSkillEditor/XEditorPath.cs b/Client/Assets/Scripts/XEditor/XSkillEditor/XEditorPath.cs new file mode 100644 index 00000000..6e85d8d6 --- /dev/null +++ b/Client/Assets/Scripts/XEditor/XSkillEditor/XEditorPath.cs @@ -0,0 +1,85 @@ +#if UNITY_EDITOR
+using System;
+using UnityEditor;
+
+namespace XEditor
+{
+ public class XEditorPath
+ {
+ public static readonly string Sce = "Assets/XScene/";
+ public static readonly string Cts = "Assets/Resources/CutScene/";
+ public static readonly string Skp = "Assets/Resources/SkillPackage/";
+ public static readonly string Crv = "Assets/Editor/EditorResources/Curve/";
+ public static readonly string Cfg = "Assets/Editor/EditorResources/SkillPackage/";
+ public static readonly string Scb = "Assets/Resources/Table/SceneBlock/";
+ public static readonly string Lev = "Assets/Resources/Table/Level/";
+
+ private static readonly string _root = "Assets/Resources";
+ private static readonly string _editor_root = "Assets/Editor";
+ private static readonly string _editor_res_root = "Assets/Editor/EditorResources";
+
+ public static string GetCfgFromSkp(string skp, string suffix = ".config")
+ {
+ skp = skp.Replace("/Resources/", "/Editor/EditorResources/");
+ int m = skp.LastIndexOf('.');
+
+ return skp.Substring(0, m) + suffix;
+ }
+
+ private static void RootPath()
+ {
+ if (!System.IO.Directory.Exists(_root))
+ {
+ AssetDatabase.CreateFolder("Assets", "Resources");
+ }
+ }
+
+ private static void EditorRootPath()
+ {
+ if (!System.IO.Directory.Exists(_editor_root))
+ {
+ AssetDatabase.CreateFolder("Assets", "Editor");
+ }
+
+ if (!System.IO.Directory.Exists(_editor_res_root))
+ {
+ AssetDatabase.CreateFolder("Assets/Editor", "EditorResources");
+ }
+ }
+
+ public static string BuildPath(string dictionary, string root)
+ {
+ string[] splits = dictionary.Split('/');
+ string _base = root;
+
+ foreach (string s in splits)
+ {
+ string path = _base + "/" + s + "/";
+
+ if (!System.IO.Directory.Exists(path))
+ {
+ AssetDatabase.CreateFolder(_base, s);
+ }
+
+ _base = path.Substring(0, path.Length - 1);
+ }
+
+ return _base + "/";
+ }
+
+ public static string GetEditorBasedPath(string dictionary)
+ {
+ EditorRootPath();
+
+ return BuildPath(dictionary, _editor_res_root);
+ }
+
+ public static string GetPath(string dictionary)
+ {
+ RootPath();
+
+ return BuildPath(dictionary, _root);
+ }
+ }
+}
+#endif
\ No newline at end of file diff --git a/Client/Assets/Scripts/XEditor/XSkillEditor/XEditorPath.cs.meta b/Client/Assets/Scripts/XEditor/XSkillEditor/XEditorPath.cs.meta new file mode 100644 index 00000000..9286e417 --- /dev/null +++ b/Client/Assets/Scripts/XEditor/XSkillEditor/XEditorPath.cs.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2
+guid: 3c12cb2816c50a54ba933da363e766ed
+MonoImporter:
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
diff --git a/Client/Assets/Scripts/XEditor/XSkillEditor/XGesture.cs b/Client/Assets/Scripts/XEditor/XSkillEditor/XGesture.cs new file mode 100644 index 00000000..5c7b1eb1 --- /dev/null +++ b/Client/Assets/Scripts/XEditor/XSkillEditor/XGesture.cs @@ -0,0 +1,205 @@ +#if UNITY_EDITOR
+using System;
+using System.Collections.Generic;
+using XUtliPoolLib;
+using UnityEngine;
+
+namespace XEditor
+{
+ internal class XGesture : XSingleton<XGesture>
+ {
+ public enum SwypeDirectionType
+ {
+ Left, Right
+ }
+
+ private bool _one = false;
+ private bool _double = false;
+ private bool _bswype = false;
+
+ private float _last_swype_at = 0;
+
+ private float _start_at = 0;
+ //private float _swype_start_at = 0;
+
+ private Vector2 _start = Vector2.zero;
+ private Vector2 _swype_start = Vector2.zero;
+
+ private Vector2 _end = Vector2.zero;
+ private XTouchItem _touch;
+
+ private Vector3 _swypedir = Vector3.zero;
+ private Vector3 _touchpos = Vector3.zero;
+
+ private float _last_touch_at = 0;
+
+ private SwypeDirectionType _swype_type;
+
+ public bool Gestured
+ {
+ get { return _bswype || _one || _double; }
+ }
+
+ public bool OneTouch
+ {
+ get { return _one; }
+ }
+
+ public bool DoubleTouch
+ {
+ get { return _double; }
+ }
+
+ public bool Swype
+ {
+ get { return _bswype; }
+ }
+
+ public float LastSwypeAt
+ {
+ get { return _last_swype_at; }
+ }
+
+ public Vector3 SwypeDirection
+ {
+ get { return -_swypedir; }
+ }
+
+ public SwypeDirectionType SwypeType
+ {
+ get { return _swype_type; }
+ }
+
+ public Vector3 TouchPosition
+ {
+ get { return _touchpos; }
+ }
+
+ public void Update()
+ {
+ XTouch.singleton.Update();
+ _touch = XTouch.singleton.GetTouch();
+
+ if (_touch != null)
+ {
+ if (_touch.Phase == TouchPhase.Began)
+ {
+ _start = _touch.Position;
+ _swype_start = _start;
+
+ _start_at = Time.time;
+ //_swype_start_at = _start_at;
+ }
+
+ _bswype = SwypeUpdate();
+ _one = OneUpdate();
+ _double = DoubleUpdate();
+ }
+ else
+ {
+ Clear();
+ }
+ }
+
+ private void Clear()
+ {
+ _one = false;
+ _double = false;
+ _bswype = false;
+ }
+
+ private bool OneUpdate()
+ {
+ TouchPhase phase = _touch.Phase;
+
+ if ((phase == TouchPhase.Ended ||
+ phase == TouchPhase.Canceled))
+ {
+ Vector2 delta = _touch.Position - _start;
+
+ float dist = Mathf.Sqrt(Mathf.Pow(delta.x, 2) + Mathf.Pow(delta.y, 2));
+ float duration = Time.time - _start_at;
+
+ if (dist < 5 && duration < 0.2f / Time.timeScale)
+ {
+ _last_touch_at = Time.time;
+ _touchpos = _touch.Position;
+
+ return true;
+ }
+ else
+ return false;
+ }
+
+ return false;
+ }
+
+ private bool DoubleUpdate()
+ {
+ if (_touch.Phase == TouchPhase.Began)
+ {
+ float deltaT = Time.time - _last_touch_at;
+ if (XCommon.singleton.IsLess(deltaT, 0.5f / Time.timeScale))
+ {
+ Vector2 delta;
+ delta.x = _start.x - TouchPosition.x;
+ delta.y = _start.y - TouchPosition.y;
+
+ float dist = Mathf.Sqrt(Mathf.Pow(delta.x, 2) + Mathf.Pow(delta.y, 2));
+
+ if (dist < 50.0f)
+ {
+ _touchpos = _touch.Position;
+ _one = false;
+
+ return true;
+ }
+ else
+ return false;
+ }
+ }
+
+ return false;
+ }
+
+ private bool SwypeUpdate()
+ {
+ TouchPhase phase = _touch.Phase;
+
+ if (phase == TouchPhase.Moved)
+ {
+ _end = _touch.Position;
+ Vector2 delta = _end - _swype_start;
+
+ float endAt = Time.time;
+
+ float dist = Mathf.Sqrt(Mathf.Pow(delta.x, 2) + Mathf.Pow(delta.y, 2));
+ //float angle = Mathf.Atan(delta.y / delta.x) * (180.0f / Mathf.PI);
+ //float duration = endAt - _swype_start_at;
+ //float speed = dist / duration;
+
+ if (dist > 50.0f)
+ {
+ _swype_type = XCommon.singleton.IsGreater(_swype_start.x, Screen.width * 0.5f) ? XGesture.SwypeDirectionType.Right : XGesture.SwypeDirectionType.Left;
+
+ _swype_start = _end;
+ //_swype_start_at = Time.time;
+
+ _swypedir.x = delta.x;
+ _swypedir.y = 0;
+ _swypedir.z = delta.y;
+
+ _swypedir.Normalize();
+ _touchpos = _end;
+
+ _last_swype_at = endAt; // _swype_start_at;
+
+ return true;
+ }
+ }
+
+ return false;
+ }
+ }
+}
+#endif
\ No newline at end of file diff --git a/Client/Assets/Scripts/XEditor/XSkillEditor/XGesture.cs.meta b/Client/Assets/Scripts/XEditor/XSkillEditor/XGesture.cs.meta new file mode 100644 index 00000000..aa3272ca --- /dev/null +++ b/Client/Assets/Scripts/XEditor/XSkillEditor/XGesture.cs.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2
+guid: 1c3f08e53b58ec74e85dc716d4b04732
+MonoImporter:
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
diff --git a/Client/Assets/Scripts/XEditor/XSkillEditor/XSerialized.cs b/Client/Assets/Scripts/XEditor/XSkillEditor/XSerialized.cs new file mode 100644 index 00000000..6d71a0bc --- /dev/null +++ b/Client/Assets/Scripts/XEditor/XSkillEditor/XSerialized.cs @@ -0,0 +1,70 @@ +#if UNITY_EDITOR
+using System;
+using System.Collections.Generic;
+using UnityEngine;
+
+using System.IO;
+using System.Runtime.Serialization;
+using System.Runtime.Serialization.Formatters.Binary;
+
+namespace XEditor
+{
+ public class XSerialized<T> where T : class
+ {
+ //deep copy of T
+ private static string SerializeToString(T value)
+ {
+ using (MemoryStream objectStream = new MemoryStream())
+ {
+ IFormatter formatter = new BinaryFormatter();
+ formatter.Serialize(objectStream, value);
+ objectStream.Flush();
+ return Convert.ToBase64String(objectStream.ToArray());
+ }
+ }
+
+ private static T DeserializeFromString(string data)
+ {
+ byte[] bytes = Convert.FromBase64String(data);
+ using (MemoryStream stream = new MemoryStream(bytes))
+ {
+ return (T)(new BinaryFormatter()).Deserialize(stream);
+ }
+ }
+
+ [SerializeField]
+ private string _serializedData;
+
+ protected T _class;
+
+ public XSerialized() { }
+
+ public XSerialized(T _class)
+ {
+ Set(_class);
+ }
+
+ public void Set(T _class)
+ {
+ this._class = _class;
+ Serialize();
+ }
+
+ public T Get()
+ {
+ if (_class == null) _class = Deserialize();
+ return _class;
+ }
+
+ public virtual void Serialize()
+ {
+ _serializedData = SerializeToString(_class);
+ }
+
+ protected virtual T Deserialize()
+ {
+ return DeserializeFromString(_serializedData);
+ }
+ }
+}
+#endif
\ No newline at end of file diff --git a/Client/Assets/Scripts/XEditor/XSkillEditor/XSerialized.cs.meta b/Client/Assets/Scripts/XEditor/XSkillEditor/XSerialized.cs.meta new file mode 100644 index 00000000..f4c68d74 --- /dev/null +++ b/Client/Assets/Scripts/XEditor/XSkillEditor/XSerialized.cs.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2
+guid: 91e1ee7b64f910b4f814f69fdd807984
+MonoImporter:
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
diff --git a/Client/Assets/Scripts/XEditor/XSkillEditor/XSkillCamera.cs b/Client/Assets/Scripts/XEditor/XSkillEditor/XSkillCamera.cs new file mode 100644 index 00000000..f7a2af18 --- /dev/null +++ b/Client/Assets/Scripts/XEditor/XSkillEditor/XSkillCamera.cs @@ -0,0 +1,389 @@ +#if UNITY_EDITOR
+using System;
+using System.Collections.Generic;
+using UnityEngine;
+using XUtliPoolLib;
+
+namespace XEditor
+{
+ public class XSkillCamera
+ {
+ public XSkillCamera(GameObject hoster)
+ {
+ _hoster = hoster;
+ }
+
+ private GameObject _hoster = null;
+ private enum XCameraExStatus
+ {
+ Idle,
+ Dash,
+ Effect,
+ UltraShow,
+ UltraEnd
+ }
+
+ private bool _status_changed = false;
+
+ private XCameraExStatus _status = XCameraExStatus.Idle;
+
+ private GameObject _cameraObject = null;
+
+ private GameObject _dummyObject = null;
+ private Transform _dummyCamera = null;
+ private Transform _cameraTransform = null;
+
+ private Animator _ator = null;
+ public AnimatorOverrideController _overrideController = new AnimatorOverrideController();
+
+ private string _trigger = null;
+
+ private UnityEngine.Camera _camera = null;
+
+ private float _elapsed = 0;
+
+ private bool _damp = false;
+ private float _damp_delta = 0;
+ private Vector3 _damp_dir = Vector3.zero;
+
+ private bool _follow_position = true;
+ private bool _relative_to_idle = false;
+ private bool _look_at = false;
+ private bool _sync_begin = false;
+ private CameraMotionSpace _effect_axis = CameraMotionSpace.World;
+
+ private bool _root_pos_inited = false;
+ private bool _idle_root_pos_inited = false;
+
+ private Vector3 _root_pos = Vector3.zero;
+ private Vector3 _idle_root_pos = Vector3.zero;
+
+ private Vector3 _v_self_p = Vector3.zero;
+ private Quaternion _q_self_r = Quaternion.identity;
+
+ private Quaternion _idle_root_rotation = Quaternion.identity;
+ private float _idle_root_rotation_y = 0;
+
+ private Vector3 _last_dummyCamera_pos = Vector3.zero;
+ private Vector3 _dummyCamera_pos = Vector3.zero;
+
+ private readonly float _damp_factor = 1.0f;
+
+ private XCameraMotionData _motion = new XCameraMotionData();
+
+ //kill all timer when leave scene.
+ private uint _token = 0;
+
+ public UnityEngine.Camera UnityCamera
+ {
+ get { return _camera; }
+ }
+
+ public Transform CameraTrans
+ {
+ get { return _cameraTransform; }
+ }
+
+ public Animator CameraAnimator
+ {
+ get { return _ator; }
+ }
+
+ public Vector3 Position
+ {
+ get { return _cameraTransform.position; }
+ }
+
+ public Quaternion Rotaton
+ {
+ get { return _cameraTransform.rotation; }
+ }
+
+ public bool Initialize()
+ {
+ _cameraObject = GameObject.Find(@"Main Camera");
+
+ if (null != _cameraObject)
+ {
+ _camera = _cameraObject.GetComponent<UnityEngine.Camera>();
+ _cameraTransform = _cameraObject.transform;
+
+ XResourceLoaderMgr.SafeDestroy(ref _dummyObject);
+
+ _dummyObject = XResourceLoaderMgr.singleton.CreateFromPrefab("Prefabs/DummyCamera") as GameObject;
+ _dummyObject.name = "Dummy Camera";
+
+ _dummyCamera = _dummyObject.transform.GetChild(0);
+ _ator = _dummyObject.GetComponent<Animator>();
+
+ _overrideController.runtimeAnimatorController = _ator.runtimeAnimatorController;
+ _ator.runtimeAnimatorController = _overrideController;
+
+ _root_pos_inited = false;
+ _idle_root_pos_inited = false;
+
+ _status = XCameraExStatus.Idle;
+ _status_changed = false;
+
+ _idle_root_rotation_y = 0;
+
+ //_overrideController["Idle"] = Resources.Load("Animation/Main_Camera/Main_Camera_Idle");
+ }
+
+ return true;
+ }
+
+ public void Damp()
+ {
+ _damp = true;
+ _elapsed = 0;
+ }
+
+ public void YRotate(float addation)
+ {
+ if (addation != 0)
+ {
+ _idle_root_rotation_y += addation;
+
+ _idle_root_rotation = Quaternion.Euler(0, _idle_root_rotation_y, 0);
+ _root_pos = _idle_root_rotation * _dummyCamera.position;
+ }
+ }
+
+ public void OverrideAnimClip(string motion, string clipname)
+ {
+ //get override clip
+ AnimationClip animClip = XResourceLoaderMgr.singleton.GetSharedResource<AnimationClip>(clipname, ".anim");
+ OverrideAnimClip(motion, animClip);
+ }
+
+ public void OverrideAnimClip(string motion, AnimationClip clip)
+ {
+ //override
+ if (clip != null && _overrideController[motion] != clip) _overrideController[motion] = clip;
+ }
+
+ public void Effect(XCameraMotionData motion)
+ {
+ Effect(motion, "ToEffect");
+ }
+
+ public void UltraShow()
+ {
+ _trigger = "ToUltraShow";
+
+ _motion.Follow_Position = false;
+ _motion.Coordinate = CameraMotionSpace.Self;
+ _motion.AutoSync_At_Begin = true;
+ _motion.LookAt_Target = false;
+ }
+
+ public void UltraEnd()
+ {
+ _trigger = "ToUltraEnd";
+
+ _motion.Follow_Position = false;
+ _motion.Coordinate = CameraMotionSpace.World;
+ _motion.AutoSync_At_Begin = true;
+ _motion.LookAt_Target = false;
+ }
+
+ public void PostUpdate(float fDeltaT)
+ {
+ if (!_root_pos_inited)
+ {
+ _idle_root_rotation = Quaternion.Euler(0, _idle_root_rotation_y, 0);
+
+ _root_pos = _idle_root_rotation * _dummyCamera.position;
+ _root_pos_inited = true;
+
+ if (!_idle_root_pos_inited)
+ {
+ _idle_root_pos = _idle_root_rotation * _dummyCamera.position;
+ _idle_root_pos_inited = true;
+ }
+ }
+
+ InnerUpdateEx();
+ TriggerEffect();
+ }
+
+ private void AutoSync()
+ {
+ _q_self_r = _hoster.transform.rotation;
+ _v_self_p = _hoster.transform.position;
+ }
+
+ private void InnerPosition()
+ {
+ _dummyCamera_pos = _idle_root_rotation * _dummyCamera.position;
+
+ if (_damp)
+ {
+ _damp_dir = (_dummyCamera_pos - _last_dummyCamera_pos);
+ if (_elapsed == 0) _damp_delta = _damp_dir.magnitude;
+ _damp_dir.Normalize();
+
+ if (_elapsed > _damp_factor)
+ {
+ _elapsed = _damp_factor;
+ _damp = false;
+ }
+
+ _dummyCamera_pos = _dummyCamera_pos - _damp_dir * (_damp_delta * ((_damp_factor - _elapsed) / _damp_factor));
+ }
+
+ _last_dummyCamera_pos = _dummyCamera_pos;
+ }
+
+ private void InnerUpdateEx()
+ {
+ InnerPosition();
+
+ Quaternion q_self_r = _hoster.transform.rotation;
+ Vector3 v_self_p = _hoster.transform.position;
+
+ Vector3 r = _dummyCamera.rotation.eulerAngles; r.y -= 90;
+ float f = r.x; r.x = r.z; r.z = f;
+
+ if (_status_changed || _status == XCameraExStatus.Idle) _status_changed = false;
+
+ Vector3 delta = (_dummyCamera_pos - _root_pos);
+ Vector3 target_pos;
+
+ {
+ target_pos = (_sync_begin ? _q_self_r : Quaternion.identity) * (_relative_to_idle ? _idle_root_pos : _root_pos);
+ delta = (_sync_begin ? _q_self_r : Quaternion.identity) * delta;
+
+ if (!_look_at) _cameraTransform.rotation = _idle_root_rotation * (_sync_begin ? _q_self_r : Quaternion.identity) * Quaternion.Euler(r);
+ }
+
+ target_pos += (_follow_position ? v_self_p : (_sync_begin ? _v_self_p : Vector3.zero));
+
+ switch (_effect_axis)
+ {
+ case CameraMotionSpace.World:
+ {
+ target_pos += delta;
+ } break;
+ case CameraMotionSpace.Self:
+ {
+ target_pos += (_follow_position ? Quaternion.identity : q_self_r) * delta;
+ } break;
+ }
+
+ _cameraTransform.position = target_pos;
+ if (_look_at) _cameraTransform.LookAt(_hoster.transform.position + _dummyObject.transform.position);
+ }
+
+ public void EndEffect(object o)
+ {
+ if (_status == XCameraExStatus.Idle) return;
+
+ _trigger = "ToIdle";
+
+ _motion.Follow_Position = true;
+ _motion.Coordinate = CameraMotionSpace.World;
+ _motion.AutoSync_At_Begin = false;
+ _motion.LookAt_Target = true;
+
+ _motion.Motion = null;
+ }
+
+ public void Effect(XCameraMotionData motion, bool overrideclip)
+ {
+ //must be called from UPDATE pass
+ AnimationClip clip = XResourceLoaderMgr.singleton.GetSharedResource<AnimationClip>(motion.Motion3D, ".anim");
+
+ if (clip != null)
+ {
+ _trigger = "ToEffect";
+ if (overrideclip && _overrideController["CameraEffect"] != clip) _overrideController["CameraEffect"] = clip;
+
+ _motion.LookAt_Target = motion.LookAt_Target;
+ _motion.Follow_Position = true;
+ _motion.Coordinate = CameraMotionSpace.World;
+
+ switch (motion.Motion3DType)
+ {
+ case CameraMotionType.AnchorBased:
+ {
+ _motion.AutoSync_At_Begin = true;
+ _motion.LookAt_Target = false;
+ }break;
+ case CameraMotionType.CameraBased:
+ {
+ _motion.AutoSync_At_Begin = false;
+ }break;
+ }
+
+ _motion.Motion = motion.Motion3D;
+ }
+ }
+
+ public void Effect(XCameraMotionData motion, string trigger)
+ {
+ //must be called from UPDATE pass
+ //AnimationClip clip = Resources.Load(motion.Motion3D);
+
+ //if (clip != null)
+ {
+ _trigger = trigger;
+
+ _motion.LookAt_Target = motion.LookAt_Target;
+ _motion.Follow_Position = true;
+ _motion.Coordinate = CameraMotionSpace.World;
+
+ switch (motion.Motion3DType)
+ {
+ case CameraMotionType.AnchorBased:
+ {
+ _motion.AutoSync_At_Begin = true;
+ _motion.LookAt_Target = false;
+ } break;
+ case CameraMotionType.CameraBased:
+ {
+ _motion.AutoSync_At_Begin = false;
+ } break;
+ }
+
+ _motion.Motion = motion.Motion3D;
+ }
+ }
+
+ private void TriggerEffect()
+ {
+ if (_trigger != null && !_ator.IsInTransition(0))
+ {
+ switch (_trigger)
+ {
+ case "ToIdle":
+ {
+ _status = XCameraExStatus.Idle;
+ _idle_root_pos_inited = false;
+ } break;
+ case "ToEffect": _status = XCameraExStatus.Effect; break;
+ case "ToDash": _status = XCameraExStatus.Dash; break;
+ case "ToUltraShow": _status = XCameraExStatus.UltraShow; break;
+ case "ToUltraEnd": _status = XCameraExStatus.UltraEnd; break;
+ }
+
+ XTimerMgr.singleton.KillTimer(_token);
+
+ _follow_position = _motion.Follow_Position;
+ _effect_axis = _motion.Coordinate;
+ _sync_begin = _motion.AutoSync_At_Begin;
+ _look_at = _motion.LookAt_Target;
+
+ if (_sync_begin) AutoSync();
+
+ _ator.SetTrigger(_trigger);
+ _root_pos_inited = false;
+
+ _status_changed = true;
+ _trigger = null;
+ }
+ }
+ }
+}
+#endif
\ No newline at end of file diff --git a/Client/Assets/Scripts/XEditor/XSkillEditor/XSkillCamera.cs.meta b/Client/Assets/Scripts/XEditor/XSkillEditor/XSkillCamera.cs.meta new file mode 100644 index 00000000..435677ae --- /dev/null +++ b/Client/Assets/Scripts/XEditor/XSkillEditor/XSkillCamera.cs.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2
+guid: 99a4f88638219ec4ba012de9b971a65a
+MonoImporter:
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
diff --git a/Client/Assets/Scripts/XEditor/XSkillEditor/XSkillCharge.cs b/Client/Assets/Scripts/XEditor/XSkillEditor/XSkillCharge.cs new file mode 100644 index 00000000..8faa78bc --- /dev/null +++ b/Client/Assets/Scripts/XEditor/XSkillEditor/XSkillCharge.cs @@ -0,0 +1,200 @@ +#if UNITY_EDITOR
+using System;
+using UnityEngine;
+using XUtliPoolLib;
+
+namespace XEditor
+{
+ public class XSkillCharge
+ {
+ public XSkillCharge(XSkillHoster host, XCurve curve_forward, XCurve curve_side, XCurve curve_up, bool using_up, float time_offset, bool aim, bool standon, bool control)
+ {
+ if (time_offset >= curve_forward.Curve[curve_forward.Curve.length - 1].time)
+ {
+ _timeElapsed = 0.1f;
+ _span = 0;
+
+ return;
+ }
+
+ _using_curve = true;
+ _using_up = using_up;
+ _aim_target = aim;
+ _stand_on = standon;
+ _control_towards = control;
+
+ _curve_forward = curve_forward.Curve;
+ _curve_side = curve_side.Curve;
+ _curve_up = curve_up == null ? null : curve_up.Curve;
+
+ _xcurve_up = curve_up;
+
+ _host = host;
+
+ _span = _curve_forward[_curve_forward.length - 1].time;
+
+ _distance = 0;
+
+ _last_offset_forward = 0;
+ _last_offset_side = 0;
+ _last_offset_up = 0;
+
+ _timeElapsed = time_offset;
+
+ Prepare();
+ }
+
+ public XSkillCharge(XSkillHoster host, float span, float offset, float height, float time_offset, float rotation, bool aim, bool standon, bool control)
+ {
+ if (time_offset >= span)
+ {
+ _timeElapsed = 0.1f;
+ _span = 0;
+
+ return;
+ }
+
+ _using_curve = false;
+ _control_towards = control;
+ _aim_target = aim;
+ _stand_on = standon;
+
+ _span = span;
+ _height = height;
+
+ _host = host;
+
+ _distance = offset;
+ _timeElapsed = time_offset;
+
+ _rotation_speed = _aim_target ? 0 : rotation;
+
+ Prepare();
+ }
+
+ private XSkillHoster _host = null;
+
+ private XCurve _xcurve_up = null;
+
+ private AnimationCurve _curve_forward = null;
+ private AnimationCurve _curve_side = null;
+ private AnimationCurve _curve_up = null;
+
+ private bool _using_curve = false;
+ private bool _using_up = false;
+ private bool _aim_target = false;
+ private bool _stand_on = true;
+ private bool _control_towards = false;
+
+ private float _scale = 1;
+ private float _last_offset_forward = 0;
+ private float _last_offset_side = 0;
+ private float _last_offset_up = 0;
+
+ private float _distance = 0;
+ private float _height = 0;
+ private float _span = 0;
+ private float _height_drop = 0;
+ private float _land_time = 0;
+
+ private float _timeElapsed = 0;
+ private float _gravity = 0;
+ private float _rticalV = 0;
+
+ private float _step_speed = 0;
+ private float _rotation_speed = 0;
+ private Vector2 _step_dir = Vector2.zero;
+
+ public bool Update(float deltaTime)
+ {
+ if (XCommon.singleton.IsGreater(_timeElapsed, _span))
+ return true;
+
+ float v1 = _rticalV - _gravity * _timeElapsed;
+ _timeElapsed += deltaTime;
+ float v2 = _rticalV - _gravity * _timeElapsed;
+
+ float dis = (_aim_target && _host.Target != null) ? (_host.Target.gameObject.transform.position - _host.gameObject.transform.position).magnitude : Mathf.Infinity;
+ Vector3 forward = (_control_towards && _host.ControlDir.sqrMagnitude > 0) ? _host.ControlDir : ((_aim_target && _host.Target != null) ? XCommon.singleton.Horizontal(_host.Target.gameObject.transform.position - _host.gameObject.transform.position) : _host.gameObject.transform.forward);
+
+ _step_dir.x = forward.x;
+ _step_dir.y = forward.z;
+ _step_dir.Normalize();
+
+ Vector2 delta;
+ float h = 0;
+
+ if (_using_curve)
+ {
+ float offset_forward = _curve_forward.Evaluate(_timeElapsed) * _scale;
+ float delta_offset_forward = offset_forward - _last_offset_forward;
+ _last_offset_forward = offset_forward;
+
+ float offset_side = _curve_side.Evaluate(_timeElapsed) * _scale;
+ float delta_offset_side = offset_side - _last_offset_side;
+ _last_offset_side = offset_side;
+
+ Vector3 right = XCommon.singleton.Horizontal(Vector3.Cross(_host.gameObject.transform.up, _step_dir));
+ delta = delta_offset_forward * _step_dir + delta_offset_side * new Vector2(right.x, right.z);
+
+ if (_using_up)
+ {
+ float offset_up = _curve_up.Evaluate(_timeElapsed) * _scale;
+ h = offset_up - _last_offset_up;
+ _last_offset_up = offset_up;
+ }
+ }
+ else
+ {
+ delta = _step_speed * deltaTime * _step_dir;
+
+ h = (v1 + v2) / 2.0f * deltaTime;
+
+ if (_rotation_speed > 0)
+ {
+ _host.gameObject.transform.forward = XCommon.singleton.HorizontalRotateVetor3(_host.gameObject.transform.forward, _rotation_speed * deltaTime);
+ }
+ }
+
+ h -= _land_time > 0 ? (deltaTime) * (_height_drop / _land_time) : _height_drop;
+
+ if (dis - 0.5f < delta.magnitude) delta.Set(0, 0);
+ _host.gameObject.transform.Translate(delta.x, h, delta.y, Space.World);
+
+ return false;
+ }
+
+ protected void Prepare()
+ {
+ Vector3 dir = _host.GetRotateTo();
+
+ _step_dir.x = dir.x;
+ _step_dir.y = dir.z;
+
+ _step_dir.Normalize();
+
+ _land_time = 0;
+
+ if (_using_curve)
+ {
+ if (_using_up)
+ {
+ _land_time = _xcurve_up.GetLandValue();
+ }
+ }
+ else
+ {
+ _step_speed = _distance / _span;
+
+ _rticalV = (_height * 4.0f) / _span;
+ _gravity = _rticalV / _span * 2.0f;
+ }
+
+ _height_drop = _stand_on ? _host.transform.position.y : 0;
+ if (_height_drop < 0) _height_drop = 0;
+
+ _scale = XAnimationLibrary.AssociatedAnimations((uint)_host.ConfigData.Player).Scale;
+ }
+ }
+}
+#endif
\ No newline at end of file diff --git a/Client/Assets/Scripts/XEditor/XSkillEditor/XSkillCharge.cs.meta b/Client/Assets/Scripts/XEditor/XSkillEditor/XSkillCharge.cs.meta new file mode 100644 index 00000000..d7210f10 --- /dev/null +++ b/Client/Assets/Scripts/XEditor/XSkillEditor/XSkillCharge.cs.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2
+guid: 235dca4a82363e147ae6be42befd528f
+MonoImporter:
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
diff --git a/Client/Assets/Scripts/XEditor/XSkillEditor/XSkillHit.cs b/Client/Assets/Scripts/XEditor/XSkillEditor/XSkillHit.cs new file mode 100644 index 00000000..5026eea4 --- /dev/null +++ b/Client/Assets/Scripts/XEditor/XSkillEditor/XSkillHit.cs @@ -0,0 +1,545 @@ +#if UNITY_EDITOR
+using System;
+using UnityEngine;
+using XUtliPoolLib;
+using System.Collections.Generic;
+
+namespace XEditor
+{
+ public class XSkillHit : MonoBehaviour
+ {
+ [SerializeField]
+ public int PresentID = 0;
+
+ private XEntityPresentation.RowData _present_data = null;
+
+ private XHitData _data = null;
+ private AnimatorOverrideController _oVerrideController = null;
+
+ void Start()
+ {
+ _present_data = XAnimationLibrary.AssociatedAnimations((uint)PresentID);
+
+ if (_oVerrideController == null) BuildOverride();
+ _oVerrideController["Idle"] = XResourceLoaderMgr.singleton.GetSharedResource<AnimationClip>("Animation/" + _present_data.AnimLocation + _present_data.AttackIdle, ".anim");
+ _oVerrideController["HitLanding"] = _present_data.HitFly!=null&&_present_data.HitFly.Length == 0 ? null : XResourceLoaderMgr.singleton.GetSharedResource<AnimationClip>("Animation/" + _present_data.AnimLocation + _present_data.HitFly[1], ".anim");
+
+ _radius = _present_data.BoundRadius;
+ _dummy_height = _present_data.BoundHeight;
+ }
+
+ private void BuildOverride()
+ {
+ _oVerrideController = new AnimatorOverrideController();
+
+ _ator = GetComponent<Animator>();
+ _oVerrideController.runtimeAnimatorController = _ator.runtimeAnimatorController;
+ _ator.runtimeAnimatorController = _oVerrideController;
+ }
+
+ private float _radius = 0;
+ private float _dummy_height = 0;
+
+ private string _trigger = null;
+
+ private Vector2 _pos = Vector2.zero;
+ private Vector2 _des = Vector2.zero;
+
+ private Vector3 _dir = Vector3.zero;
+
+ private float _last_offset = 0;
+ private float _last_height = 0;
+
+ private float _delta_x = 0;
+ private float _delta_y = 0;
+ private float _delta_z = 0;
+
+ private float _deltaH = 0;
+
+ private float _gravity = 0;
+ private float _rticalV = 0;
+
+ private float _factor = 0;
+ private float _elapsed = 0;
+
+ private float _time_total = 0;
+
+ //private bool _running = false;
+ private bool _bcurve = false;
+ private bool _loop_hard = true;
+ private bool _change_to_fly = false;
+
+ private float _present_straight = 1;
+ private float _hard_straight = 1;
+ private float _height = 0;
+ private float _offset = 0;
+
+ private float _present_animation_factor = 1;
+
+ private float _present_anim_time = 0;
+ private float _landing_time = 0;
+ private float _hard_straight_time = 0;
+ private float _getup_time = 0;
+
+ private XBeHitPhase _phase = XBeHitPhase.Hit_Present;
+
+ private Animator _ator = null;
+
+ private XSkillHoster _hoster = null;
+
+ private GameObject _hit_fx = null;
+ private Transform _binded_bone = null;
+
+ private IXCurve _curve_h = null;
+ private IXCurve _curve_v = null;
+
+ private float _curve_height_scale = 1;
+ private float _curve_offset_scale = 1;
+ private float _curve_height_time_scale = 1;
+ private float _curve_offset_time_scale = 1;
+
+ public Animator XAnimator { get { return _ator; } }
+ public float Height { get { return _dummy_height; } }
+ public float Radius { get { return _radius; } }
+ public Vector3 RadiusCenter
+ {
+ get { return transform.position + transform.rotation * ((_present_data.BoundRadiusOffset != null && _present_data.BoundRadiusOffset.Length > 0) ? new Vector3(_present_data.BoundRadiusOffset[0], 0, _present_data.BoundRadiusOffset[1]) : Vector3.zero); }
+ }
+
+ void Update()
+ {
+ if (_hoster == null) return;
+
+ //trigger and present
+ if (null != _trigger && !_ator.IsInTransition(0))
+ {
+ if (_trigger == "ToBeHit")
+ {
+ _ator.Play("Present", 0);
+ }
+ else
+ _ator.SetTrigger(_trigger);
+
+ _trigger = null;
+ }
+ else
+ {
+ float last_elapsed = _elapsed;
+ _elapsed += Time.deltaTime;
+
+ if (_data.State == XBeHitState.Hit_Freezed)
+ {
+ float deltaH = -(_deltaH / _present_straight) * Time.deltaTime;
+ transform.Translate(0, deltaH, 0, Space.World);
+
+ if (_elapsed > _time_total)
+ {
+ Cancel();
+ }
+ }
+ else
+ {
+ switch (_phase)
+ {
+ case XBeHitPhase.Hit_Present:
+ {
+ if (_elapsed > _present_straight)
+ {
+ _elapsed = _present_straight;
+ _ator.speed = 1;
+
+ if ((_change_to_fly || _data.State == XBeHitState.Hit_Fly) && _present_data.HitFly!=null&&_present_data.HitFly.Length > 0)
+ {
+ _ator.SetTrigger("ToBeHit_Landing");
+ _phase = XBeHitPhase.Hit_Landing;
+ }
+ else
+ {
+ _ator.SetTrigger("ToBeHit_Hard");
+ _phase = XBeHitPhase.Hit_Hard;
+ }
+ }
+
+ CalcDeltaPos(Time.deltaTime, last_elapsed);
+ float deltaH = -(_deltaH / _present_straight) * Time.deltaTime;
+
+ if (_offset < 0)
+ {
+ float move = Mathf.Sqrt(_delta_x * _delta_x + _delta_z * _delta_z);
+ float dis = (_hoster.gameObject.transform.position - gameObject.transform.position).magnitude;
+
+ if (move > dis - 0.5)
+ {
+ _delta_x = 0;
+ _delta_z = 0;
+ }
+ }
+ transform.Translate(_delta_x, _delta_y + deltaH, _delta_z, Space.World);
+
+ } break;
+ case XBeHitPhase.Hit_Landing:
+ {
+ if (_elapsed > _present_straight + _landing_time)
+ {
+ _ator.SetTrigger("ToBeHit_Hard");
+ _phase = XBeHitPhase.Hit_Hard;
+ }
+ } break;
+ case XBeHitPhase.Hit_Hard:
+ {
+ if (_elapsed > _present_straight + _landing_time + _hard_straight)
+ {
+ _ator.speed = 1;
+ _ator.SetTrigger("ToBeHit_GetUp");
+ _phase = XBeHitPhase.Hit_GetUp;
+ }
+ else
+ {
+ if (!_loop_hard) _ator.speed = _hard_straight_time / _hard_straight;
+ }
+ } break;
+ case XBeHitPhase.Hit_GetUp:
+ {
+ if (_elapsed > _time_total)
+ {
+ Cancel();
+ }
+ } break;
+ }
+ }
+ }
+ }
+
+ protected void Cancel()
+ {
+ _elapsed = 0;
+
+ _rticalV = 0;
+ _gravity = 0;
+
+ _deltaH = 0;
+
+ _ator.speed = 1;
+
+ DestroyFx();
+
+ _data = null;
+ _hoster = null;
+
+ _ator.SetTrigger("ToStand");
+ }
+
+ public void Begin(XSkillHoster hoster, XHitData data, Vector3 dir, bool bAttackOnHitDown)
+ {
+ if (data.State == XBeHitState.Hit_Free) return;
+
+ _hoster = hoster;
+ /*if (!bAttackOnHitDown && data.Hit_State == XBeHitState.Hit_Fly)
+ {
+ if (_elapsed > _land_time) return;
+ }*/
+
+ _deltaH = transform.position.y;
+
+ _data = data;
+ _change_to_fly = (_data.State == XBeHitState.Hit_Back || _data.State == XBeHitState.Hit_Roll) && _deltaH > 0.1f;
+
+ DestroyFx();
+ BuildAnimation(data);
+
+ if (_data.State == XBeHitState.Hit_Freezed)
+ {
+ _time_total = _data.FreezeDuration;
+ _present_animation_factor = 1;
+ }
+ else
+ {
+ float OffsetTimeScale_Offset = 1;
+ float OffsetTimeScale_Height = 1;
+ float OffsetTimeScale_Present = 1;
+ float OffsetTimeScale_Hard = 1;
+
+ switch (_data.State)
+ {
+ case XBeHitState.Hit_Back:
+ {
+ if (_change_to_fly)
+ {
+ OffsetTimeScale_Offset = _present_data.HitFlyOffsetTimeScale[0] == 0 ? 1 : _present_data.HitFlyOffsetTimeScale[0];
+ OffsetTimeScale_Height = _present_data.HitFlyOffsetTimeScale[1] == 0 ? 1 : _present_data.HitFlyOffsetTimeScale[1];
+ OffsetTimeScale_Present = _present_data.HitFlyOffsetTimeScale[2] == 0 ? 1 : _present_data.HitFlyOffsetTimeScale[2];
+ OffsetTimeScale_Hard = _present_data.HitFlyOffsetTimeScale[3] == 0 ? 1 : _present_data.HitFlyOffsetTimeScale[3];
+ }
+ else
+ {
+ OffsetTimeScale_Offset = _present_data.HitBackOffsetTimeScale[0] == 0 ? 1 : _present_data.HitBackOffsetTimeScale[0];
+ OffsetTimeScale_Present = _present_data.HitBackOffsetTimeScale[1] == 0 ? 1 : _present_data.HitBackOffsetTimeScale[1];
+ OffsetTimeScale_Hard = _present_data.HitBackOffsetTimeScale[2] == 0 ? 1 : _present_data.HitBackOffsetTimeScale[2];
+ }
+ } break;
+ case XBeHitState.Hit_Fly:
+ {
+ OffsetTimeScale_Offset = _present_data.HitFlyOffsetTimeScale[0] == 0 ? 1 : _present_data.HitFlyOffsetTimeScale[0];
+ OffsetTimeScale_Height = _present_data.HitFlyOffsetTimeScale[1] == 0 ? 1 : _present_data.HitFlyOffsetTimeScale[1];
+ OffsetTimeScale_Present = _present_data.HitFlyOffsetTimeScale[2] == 0 ? 1 : _present_data.HitFlyOffsetTimeScale[2];
+ OffsetTimeScale_Hard = _present_data.HitFlyOffsetTimeScale[3] == 0 ? 1 : _present_data.HitFlyOffsetTimeScale[3];
+ } break;
+ case XBeHitState.Hit_Roll:
+ {
+ if (_change_to_fly)
+ {
+ OffsetTimeScale_Offset = _present_data.HitFlyOffsetTimeScale[0] == 0 ? 1 : _present_data.HitFlyOffsetTimeScale[0];
+ OffsetTimeScale_Height = _present_data.HitFlyOffsetTimeScale[1] == 0 ? 1 : _present_data.HitFlyOffsetTimeScale[1];
+ OffsetTimeScale_Present = _present_data.HitFlyOffsetTimeScale[2] == 0 ? 1 : _present_data.HitFlyOffsetTimeScale[2];
+ OffsetTimeScale_Hard = _present_data.HitFlyOffsetTimeScale[3] == 0 ? 1 : _present_data.HitFlyOffsetTimeScale[3];
+ }
+ else
+ {
+ OffsetTimeScale_Offset = _present_data.HitRollOffsetTimeScale[0] == 0 ? 1 : _present_data.HitRollOffsetTimeScale[0];
+ OffsetTimeScale_Present = _present_data.HitRollOffsetTimeScale[1] == 0 ? 1 : _present_data.HitRollOffsetTimeScale[1];
+ OffsetTimeScale_Hard = _present_data.HitRollOffsetTimeScale[2] == 0 ? 1 : _present_data.HitRollOffsetTimeScale[2];
+ }
+ } break;
+ }
+
+ _present_straight = (_change_to_fly ? (data.Additional_Using_Default ? XGloabelConfLibrary.Hit_PresentStraight : data.Additional_Hit_Time_Present_Straight) : data.Time_Present_Straight) * OffsetTimeScale_Present;
+ _hard_straight = (_change_to_fly ? (data.Additional_Using_Default ? XGloabelConfLibrary.Hit_HardStraight : data.Additional_Hit_Time_Hard_Straight) : data.Time_Hard_Straight) * OffsetTimeScale_Hard;
+ _height = (_change_to_fly ? (data.Additional_Using_Default ? XGloabelConfLibrary.Hit_Height : data.Additional_Hit_Height) : data.Height) * OffsetTimeScale_Height;
+ _offset = (_change_to_fly ? (data.Additional_Using_Default ? XGloabelConfLibrary.Hit_Offset : data.Additional_Hit_Offset) : data.Offset) * OffsetTimeScale_Offset;
+
+ _dir = dir;
+ _time_total = _present_straight + _landing_time + _hard_straight + _getup_time;
+ _bcurve = data.CurveUsing;
+
+ _present_animation_factor = _present_anim_time / _present_straight;
+
+ //need re-calculate between hurt and broken
+ {
+ if (_bcurve)
+ {
+ if (_present_data.HitFly != null && _present_data.HitCurves != null)
+ {
+ IXCurve raw_h = ((_change_to_fly || _data.State == XBeHitState.Hit_Fly) && _present_data.HitFly.Length > 0) ? XResourceLoaderMgr.singleton.GetCurve("Curve/" + _present_data.CurveLocation + _present_data.HitCurves[4]) : null;
+ IXCurve raw_v = ((_change_to_fly || _data.State == XBeHitState.Hit_Fly) && _present_data.HitFly.Length > 0) ?
+ XResourceLoaderMgr.singleton.GetCurve("Curve/" + _present_data.CurveLocation + _present_data.HitCurves[3]) :
+ ((_data.State == XBeHitState.Hit_Roll && _present_data.Hit_Roll.Length > 0) ?
+ XResourceLoaderMgr.singleton.GetCurve("Curve/" + _present_data.CurveLocation + _present_data.HitCurves[5]) :
+ (_data.State == XBeHitState.Hit_Back ? XResourceLoaderMgr.singleton.GetCurve("Curve/" + _present_data.CurveLocation + _present_data.HitCurves[(int)data.State_Animation]) :
+ XResourceLoaderMgr.singleton.GetCurve("Curve/" + _present_data.CurveLocation + _present_data.HitCurves[0])));
+
+
+
+ _curve_h = raw_h != null ? raw_h : null;
+ _curve_v = raw_v;
+
+ _curve_height_scale = (raw_h == null || raw_h.GetMaxValue() == 0) ? 1 : _height / raw_h.GetMaxValue();
+ _curve_offset_scale = raw_v.GetMaxValue() == 0 ? 1 : _offset / raw_v.GetMaxValue();
+ }
+ }
+ }
+ }
+
+ //play fx here
+ if (data.Fx != null) PlayHitFx(data.Fx, data.Fx_Follow);
+
+ _elapsed = 0;
+
+ ReadyToGo(data);
+
+ _trigger = _data.State == XBeHitState.Hit_Freezed ? (_data.FreezePresent ? "ToFreezed" : null) : "ToBeHit";
+ _ator.speed = _trigger == null ? 0 : _present_animation_factor;
+
+ _phase = XBeHitPhase.Hit_Present;
+ }
+
+ protected void ReadyToGo(XHitData data)
+ {
+ if (_data.State == XBeHitState.Hit_Freezed) return;
+
+ _pos.x = transform.position.x;
+ _pos.y = transform.position.z;
+
+ Vector3 destination = transform.position + _dir * _offset;
+
+ _des.x = destination.x;
+ _des.y = destination.z;
+
+ if (_bcurve)
+ {
+ _curve_height_time_scale = _curve_h == null ? 1 : _present_straight / _curve_h.GetTime(_curve_h.length - 1);
+ _curve_offset_time_scale = _present_straight / _curve_v.GetTime(_curve_v.length - 1);
+
+ _last_offset = 0;
+ _last_height = 0;
+ }
+ else
+ {
+ _factor = XCommon.singleton.GetSmoothFactor((_pos - _des).magnitude, _present_straight, 0.01f);
+
+ _rticalV = ((!_change_to_fly && _data.State != XBeHitState.Hit_Fly)) ? 0 : (_height * 4.0f) / _present_straight;
+ _gravity = _rticalV / _present_straight * 2.0f;
+ }
+ }
+
+ private void BuildAnimation(XHitData data)
+ {
+ string[] anims = null;
+ switch (data.State)
+ {
+ case XBeHitState.Hit_Back:
+ {
+ if (_change_to_fly)
+ {
+ anims = _present_data.HitFly != null && _present_data.HitFly.Length > 0 ? _present_data.HitFly : _present_data.Hit_f;
+ }
+ else
+ {
+ switch (data.State_Animation)
+ {
+ case XBeHitState_Animation.Hit_Back_Front: anims = _present_data.Hit_f; break;
+ case XBeHitState_Animation.Hit_Back_Left: anims = _present_data.Hit_l; break;
+ case XBeHitState_Animation.Hit_Back_Right: anims = _present_data.Hit_r; break;
+ }
+ }
+ } break;
+ case XBeHitState.Hit_Roll:
+ {
+ anims = _change_to_fly ?
+ _present_data.HitFly != null && _present_data.HitFly.Length > 0 ? _present_data.HitFly : _present_data.Hit_f :
+ _present_data.HitFly != null && _present_data.HitFly.Length > 0 ? _present_data.Hit_Roll : _present_data.Hit_f;
+ } break;
+ case XBeHitState.Hit_Fly:
+ {
+ anims = _present_data.HitFly != null && _present_data.HitFly.Length > 0 ? _present_data.HitFly : _present_data.Hit_f;
+ } break;
+ case XBeHitState.Hit_Freezed:
+ {
+ if (_data.FreezePresent)
+ {
+ string freeze = "Animation/" + _present_data.AnimLocation + _present_data.Freeze;
+ AnimationClip freeze_clip = XResourceLoaderMgr.singleton.GetSharedResource<AnimationClip>(freeze, ".anim");
+ _present_anim_time = freeze_clip.length;
+ _oVerrideController["Freezed"] = freeze_clip;
+ }
+ return;
+ }
+ }
+ if (anims == null)
+ return;
+ int idx = 0;
+
+ string clipname = "Animation/" + _present_data.AnimLocation + anims[idx++];
+ AnimationClip clip = XResourceLoaderMgr.singleton.GetSharedResource<AnimationClip>(clipname, ".anim");
+ _present_anim_time = clip.length;
+ _oVerrideController["PresentStraight"] = clip;
+
+ if ((_change_to_fly || data.State == XBeHitState.Hit_Fly) && _present_data.HitFly != null && _present_data.HitFly.Length > 0)
+ {
+ clipname = "Animation/" + _present_data.AnimLocation + anims[idx++];
+ clip = XResourceLoaderMgr.singleton.GetSharedResource<AnimationClip>(clipname, ".anim");
+ _landing_time = clip.length;
+ }
+ else
+ {
+ _landing_time = 0;
+ }
+
+ clipname = "Animation/" + _present_data.AnimLocation + anims[idx++];
+ clip = XResourceLoaderMgr.singleton.GetSharedResource<AnimationClip>(clipname, ".anim");
+ _oVerrideController["HardStraight"] = clip;
+ _loop_hard = (clip.wrapMode == WrapMode.Loop);
+ _hard_straight_time = clip.length;
+
+ clipname = "Animation/" + _present_data.AnimLocation + anims[idx++];
+ clip = XResourceLoaderMgr.singleton.GetSharedResource<AnimationClip>(clipname, ".anim");
+ _getup_time = clip.length;
+ _oVerrideController["GetUp"] = clip;
+ }
+
+ private void PlayHitFx(string fx, bool follow)
+ {
+ if (fx.Length == 0) return;
+
+ GameObject o = Resources.Load(fx) as GameObject;
+ _hit_fx = GameObject.Instantiate(o) as GameObject;
+
+ _binded_bone = transform.Find("Bip001/Bip001 Pelvis/Bip001 Spine");
+ Transform parent = (_binded_bone == null) ? gameObject.transform : _binded_bone;
+
+ if (follow)
+ {
+ _hit_fx.transform.parent = parent;
+ _hit_fx.transform.localPosition = Vector3.zero;
+ _hit_fx.transform.localRotation = Quaternion.identity;
+ _hit_fx.transform.localScale = Vector3.one;
+ }
+ else
+ {
+ _hit_fx.transform.position = parent.position;
+ _hit_fx.transform.rotation = parent.rotation;
+ }
+
+ ParticleSystem[] systems = _hit_fx.GetComponentsInChildren<ParticleSystem>();
+ foreach (ParticleSystem system in systems)
+ {
+ system.Play();
+ }
+ }
+
+ private void DestroyFx()
+ {
+ if (_hit_fx != null)
+ {
+ ParticleSystem[] systems = _hit_fx.GetComponentsInChildren<ParticleSystem>();
+ foreach (ParticleSystem system in systems)
+ {
+ system.Stop();
+ }
+
+ _hit_fx.transform.parent = null;
+ GameObject.Destroy(_hit_fx);
+ }
+ _hit_fx = null;
+ }
+
+ private void CalcDeltaPos(float deltaTime, float last_elapsed)
+ {
+ Vector2 delta = Vector2.zero;
+ float h = 0;
+
+ if (_bcurve)
+ {
+ float ev = (_elapsed) / _curve_offset_time_scale;
+ float eh = (_elapsed) / _curve_height_time_scale;
+
+ float c_v = _curve_v.Evaluate(ev) * _curve_offset_scale;
+ float c_h = _curve_h == null ? 0 : _curve_h.Evaluate(eh) * _curve_height_scale;
+
+ Vector3 v = _dir * (c_v - _last_offset);
+ delta.x = v.x; delta.y = v.z;
+
+ h = c_h - _last_height;
+
+ _last_height = c_h;
+ _last_offset = c_v;
+ }
+ else
+ {
+ float v1 = _rticalV - _gravity * (last_elapsed);
+ float v2 = _rticalV - _gravity * (_elapsed);
+
+ h = (v1 + v2) / 2.0f * deltaTime;
+
+ _pos.x = transform.position.x;
+ _pos.y = transform.position.z;
+
+ delta = (_des - _pos) * Mathf.Min(1.0f, _factor * deltaTime);
+ }
+
+ _delta_x = delta.x;
+ _delta_y = h;
+ _delta_z = delta.y;
+ }
+ }
+}
+#endif
\ No newline at end of file diff --git a/Client/Assets/Scripts/XEditor/XSkillEditor/XSkillHit.cs.meta b/Client/Assets/Scripts/XEditor/XSkillEditor/XSkillHit.cs.meta new file mode 100644 index 00000000..db4c006a --- /dev/null +++ b/Client/Assets/Scripts/XEditor/XSkillEditor/XSkillHit.cs.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2
+guid: 014e229e082733a4fa0f8dc5ff4e592a
+MonoImporter:
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
diff --git a/Client/Assets/Scripts/XEditor/XSkillEditor/XSkillHoster.cs b/Client/Assets/Scripts/XEditor/XSkillEditor/XSkillHoster.cs new file mode 100644 index 00000000..f8d091a9 --- /dev/null +++ b/Client/Assets/Scripts/XEditor/XSkillEditor/XSkillHoster.cs @@ -0,0 +1,2081 @@ +#if UNITY_EDITOR
+using System;
+using UnityEngine;
+using System.Collections.Generic;
+using UnityEditor;
+using XUtliPoolLib;
+using UnityEditorInternal;
+
+namespace XEditor
+{
+ public class XSkillHoster : MonoBehaviour
+ {
+ public class XChargeSetting
+ {
+ public XChargeData data;
+ public float offset;
+ }
+
+ [SerializeField]
+ private XSkillData _xData = null;
+ [SerializeField]
+ private XSkillDataExtra _xDataExtra = null;
+ [SerializeField]
+ private XEditorData _xEditorData = null;
+ [SerializeField]
+ private XConfigData _xConfigData = null;
+
+ private XSkillData _xOuterData = null;
+
+ private enum DummyState { Idle, Move, Fire };
+ private DummyState _state = DummyState.Idle;
+
+ private Animator _ator = null;
+ private XSkillCamera _camera = null;
+
+ private int _combined_id = 0;
+
+ private float _to = 0;
+ private float _from = 0;
+
+ private float _delta = 0;
+ private float _fire_time = 0;
+ private float _time_offset = 0;
+
+ private string _trigger = null;
+ private bool _execute = false;
+ private bool _anim_init = false;
+ //private bool _effectual = false;
+ private bool _freezed = false;
+ private XSkillCharge _update = null;
+ private XSkillManipulate _manipulate = null;
+
+ GameObject _target = null;
+ List<GameObject> _mob_unit = new List<GameObject>();
+
+ AudioSource _audio_motion = null;
+ AudioSource _audio_action = null;
+ AudioSource _audio_skill = null;
+ AudioSource _audio_behit = null;
+
+ XFmod _emitter = null;
+
+ private XCameraShake _xcamera_effect = null;
+
+ private List<uint> _combinedToken = new List<uint>();
+ private List<uint> _presentToken = new List<uint>();
+ private List<uint> _logicalToken = new List<uint>();
+ private List<XSkillData> _combinedlist = new List<XSkillData>();
+
+ private XSkillData _current = null;
+
+ private float _last_swype_time = 0;
+ private int _jaCount = 0;
+ private bool _skill_when_move = false;
+
+ public float defaultFov = 45;
+
+ [HideInInspector]
+ public XSkillCamera Camera { get { return _camera; } }
+ [HideInInspector]
+ public GameObject Target { get { return _target; } }
+ [HideInInspector]
+ public XFmod Emitter { get { return _emitter; } set { _emitter = value; } }
+ [HideInInspector]
+ public static bool Quit { get; set; }
+ [HideInInspector]
+ public static XSerialized<XSkillData> sData = new XSerialized<XSkillData>();
+ [HideInInspector]
+ public static XSerialized<XEditorData> sEditorData = new XSerialized<XEditorData>();
+ [HideInInspector]
+ public static XSerialized<XConfigData> sConfigData = new XSerialized<XConfigData>();
+ [HideInInspector]
+ public List<XSkillData> ComboSkills = new List<XSkillData>();
+ [HideInInspector]
+ public int nHotID = 0;
+ [HideInInspector]
+ public Vector3 nResultForward = Vector3.zero;
+ [HideInInspector]
+ public Transform ShownTransform = null;
+ [HideInInspector]
+ public AnimatorOverrideController oVerrideController = null;
+ [HideInInspector]
+ public float ir = 0;
+ [HideInInspector]
+ public float or = 0;
+
+ [HideInInspector]
+ public Vector3 ControlDir = Vector3.zero;
+
+ private XEntityPresentation.RowData _present_data = null;
+
+ void Awake()
+ {
+ ShownTransform = transform;
+ }
+
+ void Start()
+ {
+ _state = DummyState.Idle;
+
+ if (oVerrideController == null) BuildOverride();
+
+ _camera = new XSkillCamera(gameObject);
+
+ _camera.Initialize();
+ _camera.UnityCamera.fieldOfView = defaultFov;
+
+ AudioListener audiolistener = _camera.UnityCamera.gameObject.GetComponent<AudioListener>();
+ Component.DestroyImmediate(audiolistener);
+
+ _camera.UnityCamera.gameObject.AddComponent<FMOD_Listener>();
+
+ Light light = _camera.UnityCamera.gameObject.AddComponent<Light>() as Light;
+ light.type = LightType.Directional;
+ light.intensity = 0.5f;
+
+ RebuildSkillAniamtion();
+
+ Application.targetFrameRate = 60;
+
+ if (!string.IsNullOrEmpty(SkillData.CameraPostEffect.Effect))
+ {
+ //ImageEffectBase iebase = _camera.UnityCamera.gameObject.AddComponent<RadialBlur>() as ImageEffectBase;
+ //ImageEffectBase iebase = UnityEngineInternal.APIUpdaterRuntimeServices.AddComponent(_camera.UnityCamera.gameObject, "Assets/Scripts/XEditor/XSkillEditor/XSkillHoster.cs (135,42)", SkillData.CameraPostEffect.Effect) as ImageEffectBase;
+ //iebase.shader = SkillDataExtra.PostEffectEx.Shader;
+
+ Behaviour o = _camera.UnityCamera.GetComponent(SkillData.CameraPostEffect.Effect) as Behaviour;
+ if(o!=null)
+ o.enabled = false;
+ }
+ }
+
+ public void RebuildSkillAniamtion()
+ {
+ AnimationClip clip = Resources.Load(SkillData.ClipName) as AnimationClip;
+
+ if (oVerrideController == null) BuildOverride();
+
+ if (SkillData.TypeToken == 0)
+ {
+ string motion = XSkillData.JaOverrideMap[SkillData.SkillPosition];
+ oVerrideController[motion] = clip;
+
+ foreach (XJADataExtraEx ja in SkillDataExtra.JaEx)
+ {
+ if (SkillData.SkillPosition == 15) //ToJA_QTE
+ continue;
+
+ if (ja.Next != null && ja.Next.Name.Length > 0) oVerrideController[XSkillData.JaOverrideMap[ja.Next.SkillPosition]] = Resources.Load(ja.Next.ClipName) as AnimationClip;
+ if (ja.Ja != null && ja.Ja.Name.Length > 0) oVerrideController[XSkillData.JaOverrideMap[ja.Ja.SkillPosition]] = Resources.Load(ja.Ja.ClipName) as AnimationClip;
+ }
+ }
+ else if (SkillData.TypeToken == 3)
+ {
+ for (int i = 0; i < SkillData.Combined.Count; i++)
+ {
+ oVerrideController[XSkillData.CombinedOverrideMap[i]] = SkillDataExtra.CombinedEx[i].Clip;
+ }
+ }
+ else
+ {
+ oVerrideController["Art"] = clip;
+ }
+
+ _present_data = XAnimationLibrary.AssociatedAnimations((uint)_xConfigData.Player);
+
+ oVerrideController["Idle"] = Resources.Load("Animation/" + _present_data.AnimLocation + _present_data.AttackIdle) as AnimationClip;
+ oVerrideController["Run"] = Resources.Load("Animation/" + _present_data.AnimLocation + _present_data.AttackRun) as AnimationClip;
+ oVerrideController["Walk"] = Resources.Load("Animation/" + _present_data.AnimLocation + _present_data.AttackWalk) as AnimationClip;
+ }
+
+ private void BuildOverride()
+ {
+ oVerrideController = new AnimatorOverrideController();
+
+ _ator = GetComponent<Animator>();
+ if (_ator == null)
+ {
+ _ator = gameObject.AddComponent<Animator>();
+ _ator.runtimeAnimatorController = AssetDatabase.LoadAssetAtPath<UnityEditor.Animations.AnimatorController>("Assets/Resources/Controller/XAnimator.controller");
+ }
+ oVerrideController.runtimeAnimatorController = _ator.runtimeAnimatorController;
+ _ator.runtimeAnimatorController = oVerrideController;
+
+ }
+
+ void OnDrawGizmos()
+ {
+ DrawManipulationFileds();
+
+ if (nHotID < 0 || CurrentSkillData.Result == null || nHotID >= CurrentSkillData.Result.Count) return;
+
+ if (ShownTransform == null) ShownTransform = transform;
+
+ float offset_x = CurrentSkillData.Result[nHotID].LongAttackEffect ? CurrentSkillData.Result[nHotID].LongAttackData.At_X : CurrentSkillData.Result[nHotID].Offset_X;
+ float offset_z = CurrentSkillData.Result[nHotID].LongAttackEffect ? CurrentSkillData.Result[nHotID].LongAttackData.At_Z : CurrentSkillData.Result[nHotID].Offset_Z;
+
+ Vector3 offset = ShownTransform.rotation * new Vector3(offset_x, 0, offset_z);
+
+ Color defaultColor = Gizmos.color;
+ Gizmos.color = Color.red;
+
+ Matrix4x4 defaultMatrix = Gizmos.matrix;
+ if (ShownTransform == transform)
+ {
+ ShownTransform.position += offset;
+ Gizmos.matrix = ShownTransform.localToWorldMatrix;
+ ShownTransform.position -= offset;
+ }
+ else //bullet
+ Gizmos.matrix = ShownTransform.localToWorldMatrix;
+
+ if (CurrentSkillData.Result[nHotID].LongAttackEffect)
+ {
+ if (CurrentSkillData.Result[nHotID].LongAttackData.TriggerAtEnd)
+ {
+ float m_Theta = 0.01f;
+
+ Vector3 beginPoint = Vector3.zero;
+ Vector3 firstPoint = Vector3.zero;
+
+ for (float theta = 0; theta < 2 * Mathf.PI; theta += m_Theta)
+ {
+ float x = CurrentSkillData.Result[nHotID].Range / ShownTransform.localScale.y * Mathf.Cos(theta);
+ float z = CurrentSkillData.Result[nHotID].Range / ShownTransform.localScale.y * Mathf.Sin(theta);
+ Vector3 endPoint = new Vector3(x, 0, z);
+ if (theta == 0)
+ {
+ firstPoint = endPoint;
+ }
+ else
+ {
+ Gizmos.DrawLine(beginPoint, endPoint);
+ }
+ beginPoint = endPoint;
+ }
+
+ Gizmos.DrawLine(firstPoint, beginPoint);
+
+ if (CurrentSkillData.Result[nHotID].Low_Range > 0)
+ {
+ m_Theta = 0.01f;
+
+ beginPoint = Vector3.zero;
+ firstPoint = Vector3.zero;
+
+ for (float theta = 0; theta < 2 * Mathf.PI; theta += m_Theta)
+ {
+ float x = CurrentSkillData.Result[nHotID].Low_Range / ShownTransform.localScale.y * Mathf.Cos(theta);
+ float z = CurrentSkillData.Result[nHotID].Low_Range / ShownTransform.localScale.y * Mathf.Sin(theta);
+ Vector3 endPoint = new Vector3(x, 0, z);
+ if (theta == 0)
+ {
+ firstPoint = endPoint;
+ }
+ else
+ {
+ Gizmos.DrawLine(beginPoint, endPoint);
+ }
+ beginPoint = endPoint;
+ }
+
+ Gizmos.DrawLine(firstPoint, beginPoint);
+ }
+ }
+ else
+ {
+ if (CurrentSkillData.Result[nHotID].LongAttackData.Type == XResultBulletType.Ring)
+ {
+ float m_Theta = 0.01f;
+
+ Vector3 beginPoint = Vector3.zero;
+ Vector3 firstPoint = Vector3.zero;
+
+ for (float theta = 0; theta < 2 * Mathf.PI; theta += m_Theta)
+ {
+ float x = ir / ShownTransform.localScale.y * Mathf.Cos(theta);
+ float z = ir / ShownTransform.localScale.y * Mathf.Sin(theta);
+ Vector3 endPoint = new Vector3(x, 0, z);
+ if (theta == 0)
+ {
+ firstPoint = endPoint;
+ }
+ else
+ {
+ Gizmos.DrawLine(beginPoint, endPoint);
+ }
+ beginPoint = endPoint;
+ }
+
+ Gizmos.DrawLine(firstPoint, beginPoint);
+
+ Vector3 beginPoint2 = Vector3.zero;
+ Vector3 firstPoint2 = Vector3.zero;
+
+ for (float theta = 0; theta < 2 * Mathf.PI; theta += m_Theta)
+ {
+ float x = or / ShownTransform.localScale.y * Mathf.Cos(theta);
+ float z = or / ShownTransform.localScale.y * Mathf.Sin(theta);
+ Vector3 endPoint = new Vector3(x, 0, z);
+ if (theta == 0)
+ {
+ firstPoint2 = endPoint;
+ }
+ else
+ {
+ Gizmos.DrawLine(beginPoint2, endPoint);
+ }
+ beginPoint2 = endPoint;
+ }
+
+ Gizmos.DrawLine(firstPoint2, beginPoint2);
+ }
+ else
+ {
+ float m_Theta = 0.01f;
+
+ Vector3 beginPoint = Vector3.zero;
+ Vector3 firstPoint = Vector3.zero;
+
+ for (float theta = 0; theta < 2 * Mathf.PI; theta += m_Theta)
+ {
+ float x = CurrentSkillData.Result[nHotID].LongAttackData.Radius / ShownTransform.localScale.y * Mathf.Cos(theta);
+ float z = CurrentSkillData.Result[nHotID].LongAttackData.Radius / ShownTransform.localScale.y * Mathf.Sin(theta);
+ Vector3 endPoint = new Vector3(x, 0, z);
+ if (theta == 0)
+ {
+ firstPoint = endPoint;
+ }
+ else
+ {
+ Gizmos.DrawLine(beginPoint, endPoint);
+ }
+ beginPoint = endPoint;
+ }
+
+ Gizmos.DrawLine(firstPoint, beginPoint);
+ }
+ }
+ }
+ else
+ {
+ if (CurrentSkillData.Result[nHotID].Sector_Type)
+ {
+ float m_Theta = 0.01f;
+
+ Vector3 beginPoint = Vector3.zero;
+ Vector3 firstPoint = Vector3.zero;
+
+ for (float theta = 0; theta < 2 * Mathf.PI; theta += m_Theta)
+ {
+ float x = CurrentSkillData.Result[nHotID].Range / ShownTransform.localScale.y * Mathf.Cos(theta);
+ float z = CurrentSkillData.Result[nHotID].Range / ShownTransform.localScale.y * Mathf.Sin(theta);
+ Vector3 endPoint = new Vector3(x, 0, z);
+ if (theta == 0)
+ {
+ firstPoint = endPoint;
+ }
+ else
+ {
+ Gizmos.DrawLine(beginPoint, endPoint);
+ }
+ beginPoint = endPoint;
+ }
+
+ Gizmos.DrawLine(firstPoint, beginPoint);
+
+ if (CurrentSkillData.Result[nHotID].Low_Range > 0)
+ {
+ m_Theta = 0.01f;
+
+ beginPoint = Vector3.zero;
+ firstPoint = Vector3.zero;
+
+ for (float theta = 0; theta < 2 * Mathf.PI; theta += m_Theta)
+ {
+ float x = CurrentSkillData.Result[nHotID].Range / ShownTransform.localScale.y * Mathf.Cos(theta);
+ float z = CurrentSkillData.Result[nHotID].Range / ShownTransform.localScale.y * Mathf.Sin(theta);
+ Vector3 endPoint = new Vector3(x, 0, z);
+ if (theta == 0)
+ {
+ firstPoint = endPoint;
+ }
+ else
+ {
+ Gizmos.DrawLine(beginPoint, endPoint);
+ }
+ beginPoint = endPoint;
+ }
+
+ Gizmos.DrawLine(firstPoint, beginPoint);
+ }
+ }
+ else
+ {
+ Vector3 fr = new Vector3(CurrentSkillData.Result[nHotID].Scope / 2.0f, 0, CurrentSkillData.Result[nHotID].Range / 2.0f);
+ Vector3 fl = new Vector3(CurrentSkillData.Result[nHotID].Scope / 2.0f, 0, CurrentSkillData.Result[nHotID].Rect_HalfEffect ? 0 : (-CurrentSkillData.Result[nHotID].Range / 2.0f));
+ Vector3 br = new Vector3(-CurrentSkillData.Result[nHotID].Scope / 2.0f, 0, CurrentSkillData.Result[nHotID].Range / 2.0f);
+ Vector3 bl = new Vector3(-CurrentSkillData.Result[nHotID].Scope / 2.0f, 0, CurrentSkillData.Result[nHotID].Rect_HalfEffect ? 0 : (-CurrentSkillData.Result[nHotID].Range / 2.0f));
+
+ Gizmos.DrawLine(fr, fl);
+ Gizmos.DrawLine(fl, bl);
+ Gizmos.DrawLine(bl, br);
+ Gizmos.DrawLine(br, fr);
+ }
+ }
+
+ Gizmos.matrix = defaultMatrix;
+ Gizmos.color = defaultColor;
+ }
+
+ void DrawManipulationFileds()
+ {
+ if (_state == DummyState.Fire)
+ {
+ if (_manipulate != null)
+ {
+ foreach (XManipulationData data in _manipulate.Set.Values)
+ {
+ Vector3 offset = transform.rotation * new Vector3(data.OffsetX, 0, data.OffsetZ);
+
+ Color defaultColor = Gizmos.color;
+ Gizmos.color = Color.red;
+
+ Matrix4x4 defaultMatrix = Gizmos.matrix;
+ transform.position += offset;
+ Gizmos.matrix = transform.localToWorldMatrix;
+ transform.position -= offset;
+
+ float m_Theta = 0.01f;
+
+ Vector3 beginPoint = Vector3.zero;
+ Vector3 firstPoint = Vector3.zero;
+
+ for (float theta = 0; theta < 2 * Mathf.PI; theta += m_Theta)
+ {
+ float x = data.Radius / transform.localScale.y * Mathf.Cos(theta);
+ float z = data.Radius / transform.localScale.y * Mathf.Sin(theta);
+ Vector3 endPoint = new Vector3(x, 0, z);
+ if (theta == 0)
+ {
+ firstPoint = endPoint;
+ }
+ else
+ {
+ if (Vector3.Angle(endPoint, transform.forward) < data.Degree * 0.5f)
+ Gizmos.DrawLine(beginPoint, endPoint);
+ }
+ beginPoint = endPoint;
+ }
+
+ if (data.Degree == 360)
+ Gizmos.DrawLine(firstPoint, beginPoint);
+ else
+ {
+ Gizmos.DrawLine(Vector3.zero, XCommon.singleton.HorizontalRotateVetor3(transform.forward, data.Degree * 0.5f, true) * (data.Radius / transform.localScale.y));
+ Gizmos.DrawLine(Vector3.zero, XCommon.singleton.HorizontalRotateVetor3(transform.forward, -data.Degree * 0.5f, true) * (data.Radius / transform.localScale.y));
+ }
+
+ Gizmos.matrix = defaultMatrix;
+ Gizmos.color = defaultColor;
+ }
+ }
+ }
+ else
+ {
+ if (_xData.Manipulation != null)
+ {
+ foreach (XManipulationData data in _xData.Manipulation)
+ {
+ if (data.Radius <= 0 || !_xDataExtra.ManipulationEx[data.Index].Present) continue;
+
+ Vector3 offset = transform.rotation * new Vector3(data.OffsetX, 0, data.OffsetZ);
+
+ Color defaultColor = Gizmos.color;
+ Gizmos.color = Color.red;
+
+ Matrix4x4 defaultMatrix = Gizmos.matrix;
+ transform.position += offset;
+ Gizmos.matrix = transform.localToWorldMatrix;
+ transform.position -= offset;
+
+ float m_Theta = 0.01f;
+
+ Vector3 beginPoint = Vector3.zero;
+ Vector3 firstPoint = Vector3.zero;
+
+ for (float theta = 0; theta < 2 * Mathf.PI; theta += m_Theta)
+ {
+ float x = data.Radius / transform.localScale.y * Mathf.Cos(theta);
+ float z = data.Radius / transform.localScale.y * Mathf.Sin(theta);
+ Vector3 endPoint = new Vector3(x, 0, z);
+ if (theta == 0)
+ {
+ firstPoint = endPoint;
+ }
+ else
+ {
+ if (Vector3.Angle(endPoint, transform.forward) < data.Degree * 0.5f)
+ Gizmos.DrawLine(beginPoint, endPoint);
+ }
+ beginPoint = endPoint;
+ }
+
+ if (data.Degree == 360)
+ Gizmos.DrawLine(firstPoint, beginPoint);
+ else
+ {
+ Gizmos.DrawLine(Vector3.zero, XCommon.singleton.HorizontalRotateVetor3(transform.forward, data.Degree * 0.5f, true) * (data.Radius / transform.localScale.y));
+ Gizmos.DrawLine(Vector3.zero, XCommon.singleton.HorizontalRotateVetor3(transform.forward, -data.Degree * 0.5f, true) * (data.Radius / transform.localScale.y));
+ }
+
+ Gizmos.matrix = defaultMatrix;
+ Gizmos.color = defaultColor;
+ }
+ }
+ }
+ }
+
+ private float _action_framecount = 0;
+ private Rect _rect = new Rect(10, 10, 150, 20);
+
+ void OnGUI()
+ {
+ GUI.Label(_rect, "Action Frame: " + _action_framecount);
+ }
+
+ private int _comboskill_index = 0;
+
+ void Update()
+ {
+ XTimerMgr.singleton.Update(Time.deltaTime);
+ XGesture.singleton.Update();
+ XBulletMgr.singleton.Update(Time.deltaTime);
+
+ if (_update != null)
+ {
+ if (_update.Update(Time.deltaTime)) _update = null;
+ }
+
+ if (_manipulate != null)
+ {
+ _manipulate.Update(Time.deltaTime);
+ }
+
+ ControlDir = Vector3.zero;
+
+ int nh = 0; int nv = 0;
+
+ if (Input.GetKey(KeyCode.W)) nv++;
+ if (Input.GetKey(KeyCode.S)) nv--;
+ if (Input.GetKey(KeyCode.A)) nh--;
+ if (Input.GetKey(KeyCode.D)) nh++;
+
+ Vector3 h = Vector3.right;
+ Vector3 up = Vector3.up;
+ Vector3 v = SceneView.lastActiveSceneView != null ? SceneView.lastActiveSceneView.rotation * Vector3.forward : Vector3.forward; v.y = 0;
+ if (Vector3.Angle (Vector3.forward, v) > 90)
+ nh = -nh;
+
+ Vector3.OrthoNormalize(ref v, ref up, ref h);
+
+ if (_state != DummyState.Fire)
+ {
+ _action_framecount = 0;
+ _comboskill_index = 0;
+
+ //fire skill
+ if (Input.GetKeyDown(KeyCode.Space))
+ {
+ if (_xData.TypeToken == 1 && ComboSkills.Count > 0) oVerrideController["Art"] = Resources.Load(_xData.ClipName) as AnimationClip;
+ _xOuterData = _xData;
+ _combinedlist.Clear();
+ _combined_id = 0;
+ foreach (XCombinedDataExtraEx data in _xDataExtra.CombinedEx)
+ _combinedlist.Add(data.Skill);
+
+ Fire();
+ }
+ else
+ {
+ if (nh != 0 || nv != 0)
+ {
+ ControlDir = h * nh + v * nv;
+ Move(ControlDir);
+
+ if (_state != DummyState.Move) _trigger = "ToMove";
+ _state = DummyState.Move;
+ }
+ else
+ {
+ if (_state == DummyState.Move)
+ _trigger = "ToStand";
+ _state = DummyState.Idle;
+ }
+ }
+ }
+ else
+ {
+ if (_execute || _xOuterData.TypeToken == 3)
+ {
+ if (!_freezed) _delta += Time.deltaTime;
+ _action_framecount = _delta / XCommon.singleton.FrameStep;
+
+ if (_delta > (_xOuterData.TypeToken == 3 ? _xOuterData.Time : _current.Time))
+ {
+ StopFire();
+ }
+ else
+ {
+ if (nh != 0 || nv != 0)
+ {
+ ControlDir = h * nh + v * nv;
+ if (CanAct(ControlDir))
+ {
+ Move(ControlDir);
+ }
+ }
+ else if (_skill_when_move)
+ {
+ _trigger = "ToStand";
+ _skill_when_move = false;
+ }
+ }
+
+ if (Input.GetKeyDown(KeyCode.Space))
+ {
+ if (_comboskill_index < ComboSkills.Count )
+ {
+ XSkillData data = ComboSkills[_comboskill_index];
+
+ if (CanReplacedBy(data))
+ {
+ _comboskill_index++;
+ StopFire();
+
+ _xOuterData = data;
+ _current = data;
+
+ if (data.TypeToken != 3)
+ {
+ oVerrideController["Art"] = XResourceLoaderMgr.singleton.GetSharedResource<AnimationClip>(data.ClipName, ".anim");
+ _trigger = "ToArtSkill";
+ }
+ else
+ {
+ _combinedlist.Clear();
+ for (int i = 0; i < data.Combined.Count; i++)
+ {
+ XSkillData x = XResourceLoaderMgr.singleton.GetData<XSkillData>("SkillPackage/" + XAnimationLibrary.AssociatedAnimations((uint)_xConfigData.Player).SkillLocation + data.Combined[i].Name, ".txt");
+ AnimationClip c = Resources.Load(x.ClipName) as AnimationClip;
+ oVerrideController[XSkillData.CombinedOverrideMap[i]] = c;
+ _combinedlist.Add(x);
+ }
+ _trigger = XSkillData.Combined_Command[0];
+ Combined(0);
+ }
+
+ _state = DummyState.Fire;
+ _fire_time = Time.time;
+ _delta = 0;
+ if (_ator != null)
+ _ator.speed = 0;
+ }
+ }
+ }
+ }
+
+ if (_anim_init)
+ Execute();
+
+ _anim_init = false;
+ }
+ }
+
+ void OnApplicationQuit()
+ {
+ Quit = true;
+
+ sData.Set(_xData);
+ sEditorData.Set(_xEditorData);
+ sConfigData.Set(_xConfigData);
+
+ ir = 0;
+ or = 0;
+ }
+
+ private float _move_follow_speed = 0;
+ private void CameraSkillRotate()
+ {
+ if (_state == DummyState.Fire)
+ {
+ float move_follow_speed_basic = _xOuterData.CameraTurnBack * Time.deltaTime;
+
+ Vector3 playerLookat = GetRotateTo();
+ Vector3 viewForward = XCommon.singleton.Horizontal(_camera.UnityCamera.GetComponent<Camera>().transform.forward);
+
+ float sin = Mathf.Sin(Mathf.Deg2Rad * Vector3.Angle(playerLookat, viewForward) * 0.5f);
+ float move_follow_speed_target = move_follow_speed_basic * sin;
+
+ if (XCommon.singleton.Clockwise(playerLookat, viewForward))
+ move_follow_speed_target *= -1;
+
+ _move_follow_speed += (move_follow_speed_target - _move_follow_speed) * Mathf.Min(1.0f, Time.deltaTime * 6);
+ _camera.YRotate(_move_follow_speed);
+ }
+ }
+
+ void LateUpdate()
+ {
+ _camera.UnityCamera.fieldOfView = defaultFov;
+ CameraSkillRotate();
+ _camera.PostUpdate(Time.deltaTime);
+
+ //face to
+ UpdateRotation();
+
+ if (_xcamera_effect != null) _xcamera_effect.Update(Time.deltaTime);
+
+ if (null != _trigger && _ator != null && !_ator.IsInTransition(0))
+ {
+ if ("ToStand" != _trigger && "ToMove" != _trigger && "EndSkill" != _trigger && "ToUltraShow" != _trigger)
+ _anim_init = true;
+
+ _ator.speed = 1;
+
+ if (SkillData.TypeToken == 3)
+ {
+ int i = 0;
+ for (; i < XSkillData.Combined_Command.Length; i++)
+ {
+ if (_trigger == XSkillData.Combined_Command[i]) break;
+ }
+
+ if (i < XSkillData.Combined_Command.Length)
+ _ator.Play(XSkillData.CombinedOverrideMap[i], 1, _time_offset);
+ else
+ _ator.SetTrigger(_trigger);
+ }
+ else
+ {
+ _ator.SetTrigger(_trigger);
+ }
+
+ _trigger = null;
+ }
+ }
+
+ public void FetchDataBack()
+ {
+ _xData = sData.Get();
+ _xEditorData = sEditorData.Get();
+ _xConfigData = sConfigData.Get();
+
+ XDataBuilder.singleton.HotBuild(this, _xConfigData);
+ XDataBuilder.singleton.HotBuildEx(this, _xConfigData);
+ }
+
+ public XSkillData SkillData
+ {
+ get
+ {
+ if (_xData == null) _xData = new XSkillData();
+ return _xData;
+ }
+ set
+ {
+ //for load data from file.
+ _xData = value;
+ }
+ }
+
+ public XSkillData CurrentSkillData
+ {
+ get
+ {
+ return _state == DummyState.Fire ? _current : SkillData;
+ }
+ }
+
+ public XConfigData ConfigData
+ {
+ get
+ {
+ if (_xConfigData == null) _xConfigData = new XConfigData();
+ return _xConfigData;
+ }
+ set
+ {
+ //for load data from file.
+ _xConfigData = value;
+ }
+ }
+
+ public XEditorData EditorData
+ {
+ get
+ {
+ if (_xEditorData == null) _xEditorData = new XEditorData();
+ return _xEditorData;
+ }
+ }
+
+ public XSkillDataExtra SkillDataExtra
+ {
+ get
+ {
+ if (_xDataExtra == null)_xDataExtra = new XSkillDataExtra();
+ return _xDataExtra;
+ }
+ }
+
+ private void Move(Vector3 dir)
+ {
+ PrepareRotation(dir, _xConfigData.RotateSpeed);
+ transform.Translate(dir * Time.deltaTime * ConfigData.Speed, Space.World);
+ }
+
+ public void PrepareRotation(Vector3 targetDir, float speed)
+ {
+ Vector3 from = transform.forward;
+
+ _from = YRotation(from);
+ float angle = Vector3.Angle(from, targetDir);
+
+ if (XCommon.singleton.Clockwise(from, targetDir))
+ {
+ _to = _from + angle;
+ }
+ else
+ {
+ _to = _from - angle;
+ }
+
+ rotate_speed = speed;
+ }
+
+ public Vector3 GetRotateTo()
+ {
+ return XCommon.singleton.FloatToAngle(_to);
+ }
+
+ private float rotate_speed = 0;
+ private void UpdateRotation()
+ {
+ if (_from != _to)
+ {
+ _from += (_to - _from) * Mathf.Min(1.0f, Time.deltaTime * rotate_speed);
+ transform.rotation = Quaternion.Euler(0, _from, 0);
+ }
+ }
+
+ private float YRotation(Vector3 dir)
+ {
+ float r = Vector3.Angle(Vector3.forward, dir);
+
+ if (XCommon.singleton.Clockwise(Vector3.forward, dir))
+ {
+ return r;
+ }
+ else
+ {
+ return 360.0f - r;
+ }
+ }
+
+ private List<HashSet<XSkillHit>> _hurt_target = new List<HashSet<XSkillHit>>();
+ private void AddHurtTarget(XSkillData data, XSkillHit id, int triggerTime)
+ {
+ if (!data.Result[triggerTime].Loop && /*for multiple trigger end*/!data.Result[triggerTime].LongAttackEffect)
+ _hurt_target[triggerTime].Add(id);
+ }
+
+ private bool IsHurtEntity(XSkillHit id, int triggerTime)
+ {
+ /*
+ * this section not as same as client shows
+ * but in editor mode just using it for simple.
+ */
+ return triggerTime < _hurt_target.Count ? _hurt_target[triggerTime].Contains(id) : false;
+ }
+
+ private void MainCoreExecute()
+ {
+ if (_xOuterData.Fx != null)
+ {
+ foreach (XFxData data in _xOuterData.Fx)
+ {
+ AddedCombinedToken(XTimerMgr.singleton.SetTimer(data.At, Fx, data));
+ }
+ }
+
+ if (_xOuterData.Audio != null)
+ {
+ foreach (XAudioData data in _xOuterData.Audio)
+ {
+ AddedCombinedToken(XTimerMgr.singleton.SetTimer(data.At, Audio, data));
+ }
+ }
+
+ if (_xOuterData.CameraEffect != null)
+ {
+ foreach (XCameraEffectData data in _xOuterData.CameraEffect)
+ {
+ AddedCombinedToken(XTimerMgr.singleton.SetTimer(data.At, Shake, data));
+ }
+ }
+
+ if (!string.IsNullOrEmpty(_xOuterData.CameraMotion.Motion3D))
+ {
+ AddedCombinedToken(XTimerMgr.singleton.SetTimer(_xOuterData.CameraMotion.At, CameraMotion, _xOuterData.CameraMotion));
+ }
+
+ if (!string.IsNullOrEmpty(_xOuterData.CameraPostEffect.Effect))
+ {
+ AddedCombinedToken(XTimerMgr.singleton.SetTimer(_xOuterData.CameraPostEffect.At, CameraPostEffect, _xOuterData.CameraPostEffect));
+ }
+ }
+
+ private void Execute()
+ {
+ if(EditorData.XFrameByFrame) Debug.Break();
+
+ //_effectual = false;
+ _freezed = false;
+ _execute = true;
+
+ _jaCount = 0;
+
+ int count = 0;
+ nHotID = 0;
+
+ _fire_time = Time.time;
+
+ if(_xEditorData.XAutoSelected)
+ Selection.activeObject = gameObject;
+
+ _hurt_target.Clear();
+
+ float play_offset = _xOuterData.TypeToken == 3 ? _xOuterData.Combined[_combined_id].At : 0;
+
+ if (_xOuterData.TypeToken == 3 && _combined_id < _xOuterData.Combined.Count)
+ {
+ //specially
+ AddedTimerToken(XTimerMgr.singleton.SetTimer(_xOuterData.Combined[_combined_id].End - _xOuterData.Combined[_combined_id].At, Combined, _combined_id + 1), true);
+ }
+
+ if (_current.Result != null)
+ {
+ foreach (XResultData data in _current.Result)
+ {
+ _hurt_target.Add(new HashSet<XSkillHit>());
+
+ data.Token = count++;
+ AddedTimerToken(XTimerMgr.singleton.SetTimer(data.At - play_offset, Result, data), true);
+ }
+ }
+
+ if (_current.Charge != null)
+ {
+ XChargeSetting[] setting = new XChargeSetting[_current.Charge.Count];
+ int i = 0;
+
+ foreach (XChargeData data in _current.Charge)
+ {
+ float delay = data.Using_Curve ? 0 : data.At;
+ setting[i] = new XChargeSetting();
+ setting[i].data = data;
+
+ if(delay >= play_offset)
+ {
+ setting[i].offset = 0;
+ AddedTimerToken(XTimerMgr.singleton.SetTimer(delay - play_offset, Charge, setting[i]), true);
+ }
+ else
+ {
+ setting[i].offset = play_offset - delay;
+ AddedTimerToken(XTimerMgr.singleton.SetTimer(0, Charge, setting[i]), true);
+ }
+
+ i++;
+ }
+ }
+
+ if (_xOuterData.TypeToken != 3)
+ {
+ if (_current == _xOuterData && _current.Ja != null)
+ {
+ int i = 0;
+ foreach (XJAData data in _current.Ja)
+ {
+ if (data.Point >= play_offset) AddedTimerToken(XTimerMgr.singleton.SetTimer(data.Point - play_offset, Ja, i++), true);
+ }
+ }
+ }
+
+ if (_current.Manipulation != null)
+ {
+ foreach (XManipulationData data in _current.Manipulation)
+ {
+ if (data.At >= play_offset) AddedTimerToken(XTimerMgr.singleton.SetTimer(data.At - play_offset, Manipulate, data), true);
+ }
+ }
+
+ if (_current.Fx != null && (_xOuterData.TypeToken != 3 || _xOuterData.Combined[_combined_id].Override_Presentation))
+ {
+ foreach (XFxData data in _current.Fx)
+ {
+ if (data.At >= play_offset) AddedTimerToken(XTimerMgr.singleton.SetTimer(data.At - play_offset, Fx, data), false);
+ }
+ }
+
+ if (_current.Audio != null && (_xOuterData.TypeToken != 3 || _xOuterData.Combined[_combined_id].Override_Presentation))
+ {
+ foreach (XAudioData data in _current.Audio)
+ {
+ if (data.At >= play_offset) AddedTimerToken(XTimerMgr.singleton.SetTimer(data.At - play_offset, Audio, data), false);
+ }
+ }
+
+ if (_current.Warning != null)
+ {
+ if (_current.Warning.Count > 0) WarningPosAt = new List<Vector3>[_current.Warning.Count];
+ int i = 0;
+ foreach (XWarningData data in _current.Warning)
+ {
+ WarningPosAt[i] = new List<Vector3>(); i++;
+ if (data.At >= play_offset) AddedTimerToken(XTimerMgr.singleton.SetTimer(data.At - play_offset, Warning, data), false);
+ }
+ }
+
+ if (_current == null) return;
+
+ if (_current.CameraEffect != null && (_xOuterData.TypeToken != 3 || _xOuterData.Combined[_combined_id].Override_Presentation))
+ {
+ foreach (XCameraEffectData data in _current.CameraEffect)
+ {
+ if (data.At >= play_offset) AddedTimerToken(XTimerMgr.singleton.SetTimer(data.At - play_offset, Shake, data), false);
+ }
+ }
+
+ if (_current.CameraMotion != null && !string.IsNullOrEmpty(_current.CameraMotion.Motion3D) && (_xOuterData.TypeToken != 3 || _xOuterData.Combined[_combined_id].Override_Presentation))
+ {
+ if (_current.CameraMotion.At >= play_offset) AddedTimerToken(XTimerMgr.singleton.SetTimer(_current.CameraMotion.At - play_offset, CameraMotion, _current.CameraMotion), false);
+ }
+
+ if (_current.CameraPostEffect != null && !string.IsNullOrEmpty(_current.CameraPostEffect.Effect) && (_xOuterData.TypeToken != 3 || _xOuterData.Combined[_combined_id].Override_Presentation))
+ {
+ if (_current.CameraPostEffect.At >= play_offset) AddedTimerToken(XTimerMgr.singleton.SetTimer(_current.CameraPostEffect.At - play_offset, CameraPostEffect, _current.CameraPostEffect), false);
+ }
+
+ if (_current.Mob != null)
+ {
+ for (int i = 0; i < _current.Mob.Count; i++)
+ if (_current.Mob[i].At >= play_offset) AddedTimerToken(XTimerMgr.singleton.SetTimer(_current.Mob[i].At - play_offset, Mob, _current.Mob[i]), true);
+ }
+ }
+
+ private void Fire()
+ {
+ _current = _xOuterData;
+ _fx.Clear();
+
+ _skill_when_move = (_state == DummyState.Move);
+ _state = DummyState.Fire;
+
+ if (_xOuterData.TypeToken == 0)
+ _trigger = _xOuterData.SkillPosition > 0 ? XSkillData.JA_Command[_xOuterData.SkillPosition] : "ToSkill";
+ else if (_xOuterData.TypeToken == 1)
+ _trigger = "ToArtSkill";
+ else if (_xOuterData.TypeToken == 3)
+ Combined(0);
+ else
+ _trigger = "ToUltraShow";
+
+ FocusTarget();
+
+ _anim_init = false;
+ _delta = 0;
+ }
+
+ private void StopFire(bool cleanup = true)
+ {
+ if (_state != DummyState.Fire) return;
+
+ _state = DummyState.Idle;
+ _trigger = "EndSkill";
+
+ _execute = false;
+
+ for (int i = 0; i < _fx.Count; i++)
+ XFxMgr.singleton.DestroyFx(_fx[i], false);
+ _fx.Clear();
+
+ if (_current.Audio != null)
+ {
+ foreach (XAudioData data in _current.Audio)
+ {
+ AudioSource source = GetAudioSourceByChannel(data.Channel);
+ source.Stop();
+ }
+ }
+
+ if (_manipulate != null) _manipulate.Remove(0);
+
+ if (_current.CameraPostEffect != null && _current.CameraPostEffect.Effect != null && _current.CameraPostEffect.Effect.Length > 0)
+ {
+ Behaviour o = _camera.UnityCamera.GetComponent(_current.CameraPostEffect.Effect) as Behaviour;
+ if(o!=null)
+ o.enabled = false;
+ }
+
+ if (_mob_unit.Count > 0)
+ {
+ for (int i = 0; i < _mob_unit.Count; i++)
+ {
+ if (_mob_unit[i].CompareTag("Finish")) GameObject.DestroyImmediate(_mob_unit[i]);
+ }
+ }
+
+ if (cleanup)
+ {
+ _action_framecount = 0;
+
+ for (int i = 0; i < _outer_fx.Count; i++)
+ XFxMgr.singleton.DestroyFx(_outer_fx[i], false);
+ _outer_fx.Clear();
+
+ if (_xOuterData.Audio != null)
+ {
+ foreach (XAudioData data in _xOuterData.Audio)
+ {
+ AudioSource source = GetAudioSourceByChannel(data.Channel);
+ if (source != null)
+ source.Stop();
+ }
+ }
+
+ _camera.EndEffect(null);
+ _xcamera_effect = null;
+
+ if (_xOuterData.CameraPostEffect != null && _xOuterData.CameraPostEffect.Effect != null && _xOuterData.CameraPostEffect.Effect.Length > 0)
+ {
+ Behaviour o = _camera.UnityCamera.GetComponent(_xOuterData.CameraPostEffect.Effect) as Behaviour;
+ if(o!=null)
+ o.enabled = false;
+ }
+
+ foreach (uint token in _combinedToken)
+ {
+ XTimerMgr.singleton.KillTimer(token);
+ }
+ _combinedToken.Clear();
+ }
+
+ foreach (uint token in _presentToken)
+ {
+ XTimerMgr.singleton.KillTimer(token);
+ }
+
+ _presentToken.Clear();
+
+ foreach (uint token in _logicalToken)
+ {
+ XTimerMgr.singleton.KillTimer(token);
+ }
+
+ _logicalToken.Clear();
+
+ _update = null;
+ _manipulate = null;
+
+ nResultForward = Vector3.zero;
+ Time.timeScale = 1;
+ if (_ator != null)
+ _ator.speed = 1;
+
+ _mob_unit.Clear();
+ _current = null;
+ }
+
+ public void Result(object param)
+ {
+ if (_state != DummyState.Fire) return;
+
+ XResultData data = param as XResultData;
+
+ if (data.Loop)
+ {
+ int i = (data.Index << 16) | 0;
+ LoopResults(i);
+ }
+ else
+ {
+ if (data.Group)
+ {
+ int i = (data.Index << 16) | 0;
+ GroupResults(i);
+ }
+ else
+ {
+ if (data.LongAttackEffect)
+ {
+ Project(data);
+ }
+ else
+ {
+ innerResult(data.Index, transform.forward, transform.position, _current);
+ }
+ }
+ }
+ }
+
+ public void LoopResults(object param)
+ {
+ int i = (int)param;
+ int count = i >> 16;
+ int execute_cout = i & 0xFFFF;
+
+ if (!_current.Result[count].Loop || _current.Result[count].Loop_Count <= execute_cout || _current.Result[count].Cycle <= 0)
+ return;
+
+ if (_current.Result[count].Group)
+ GroupResults((count << 16) | (execute_cout << 8) | 0);
+ else if (_current.Result[count].LongAttackEffect)
+ Project(_current.Result[count]);
+ else
+ {
+ innerResult(count, transform.forward, transform.position, _current);
+ }
+
+ ++execute_cout;
+
+ if(_current.Result[count].Loop_Count > execute_cout)
+ AddedTimerToken(XTimerMgr.singleton.SetTimer(_current.Result[count].Cycle, LoopResults, ((count << 16) | execute_cout)), true);
+ }
+
+ private void GroupResults(object param)
+ {
+ if (_state != DummyState.Fire) return;
+
+ int i = (int)param;
+ int count = i >> 16;
+
+ int group_cout = i & 0x00FF;
+ int loop_cout = (i & 0xFF00) >> 8;
+
+ if (!_current.Result[count].Group || group_cout >= _current.Result[count].Group_Count)
+ return;
+
+ Vector3 face = transform.forward;
+
+ int angle = _current.Result[count].Deviation_Angle + _current.Result[count].Angle_Step * group_cout;
+ angle = _current.Result[count].Clockwise ? angle : -angle;
+
+ if (_current.Result[count].LongAttackEffect)
+ Project(_current.Result[count], angle);
+ else
+ innerResult(count, XCommon.singleton.HorizontalRotateVetor3(face, angle), transform.position, _current);
+
+ group_cout++;
+ if (group_cout < _current.Result[count].Group_Count)
+ {
+ i = (count << 16) | (loop_cout << 8) | group_cout;
+ AddedTimerToken(XTimerMgr.singleton.SetTimer(_current.Result[count].Time_Step, GroupResults, i), true);
+ }
+ }
+
+ public void innerResult(int triggerTime, Vector3 forward, Vector3 pos, XSkillData data, XSkillHit hitted = null)
+ {
+ nHotID = triggerTime;
+
+ if (hitted == null)
+ {
+ pos += XCommon.singleton.VectorToQuaternion(transform.forward) * new Vector3(data.Result[triggerTime].Offset_X, 0, data.Result[triggerTime].Offset_Z);
+ nResultForward = forward;
+
+ XSkillHit[] hits = GameObject.FindObjectsOfType<XSkillHit>();
+
+ foreach (XSkillHit hit in hits)
+ {
+ if (IsHurtEntity(hit, triggerTime)) continue;
+
+ Vector3 dir = hit.RadiusCenter - pos; dir.y = 0;
+ float distance = dir.magnitude;
+
+ if (distance > hit.Radius) distance -= hit.Radius;
+
+ if (dir.sqrMagnitude == 0) dir = forward;
+ dir.Normalize();
+
+ if (IsInField(data, triggerTime, pos, forward, hit.RadiusCenter, Vector3.Angle(forward, dir), distance))
+ {
+ Vector3 vHitDir = data.Result[triggerTime].Affect_Direction == XResultAffectDirection.AttackDir ?
+ (hit.RadiusCenter - pos).normalized :
+ GetRotateTo();
+
+ //_effectual = true;
+
+ AddHurtTarget(data, hit, triggerTime);
+
+ hit.Begin(this, data.Hit[triggerTime], vHitDir, data.Logical.AttackOnHitDown);
+ }
+ }
+ }
+ else
+ {
+ Vector3 vHitDir = data.Result[triggerTime].Affect_Direction == XResultAffectDirection.AttackDir ?
+ (hitted.RadiusCenter - pos) :
+ GetRotateTo();
+
+ vHitDir.y = 0; vHitDir.Normalize();
+ hitted.Begin(this, data.Hit[triggerTime], vHitDir, data.Logical.AttackOnHitDown);
+ }
+ }
+
+ private void Charge(object param)
+ {
+ XChargeSetting setting = param as XChargeSetting;
+ XChargeData data = setting.data;
+
+ XSkillCharge charge = null;
+ if (data.Using_Curve)
+ {
+ if (data.Curve_Forward != null && data.Curve_Forward.Length > 0)
+ {
+ GameObject forward = Resources.Load(data.Curve_Forward) as GameObject;
+ GameObject side = Resources.Load(data.Curve_Side) as GameObject;
+ GameObject up = Resources.Load(data.Curve_Up) as GameObject;
+
+ charge = new XSkillCharge(
+ this,
+ forward != null ? forward.GetComponent<XCurve>() : null,
+ side != null ? side.GetComponent<XCurve>() : null,
+ up != null ? up.GetComponent<XCurve>() : null,
+ data.Using_Up,
+ setting.offset,
+ data.AimTarget,
+ data.StandOnAtEnd,
+ data.Control_Towards);
+ }
+ }
+ else
+ {
+ charge = new XSkillCharge(
+ this,
+ data.End - data.At,
+ data.Offset,
+ data.Height,
+ setting.offset,
+ data.Rotation_Speed,
+ data.AimTarget,
+ data.StandOnAtEnd,
+ data.Control_Towards);
+ }
+
+ _update = charge;
+ _update.Update(Time.deltaTime);
+ }
+
+ protected List<XFx> _fx = new List<XFx>();
+ protected List<XFx> _outer_fx = new List<XFx>();
+
+ public List<Vector3>[] WarningPosAt = null;
+
+ private bool IsPickedInRange(int n, int d)
+ {
+ if(n >= d) return true;
+
+ int i = XCommon.singleton.RandomInt(0, d);
+ return i < n;
+ }
+
+ private void Warning(object param)
+ {
+ XWarningData data = param as XWarningData;
+ WarningPosAt[data.Index].Clear();
+
+ if (data.RandomWarningPos || data.Type == XWarningType.Warning_Multiple)
+ {
+ if (data.RandomWarningPos)
+ {
+ List<GameObject> item = new List<GameObject>();
+ switch (data.Type)
+ {
+ case XWarningType.Warning_All:
+ case XWarningType.Warning_Multiple:
+ {
+ XSkillHit[] hits = GameObject.FindObjectsOfType<XSkillHit>();
+ int n = (data.Type == XWarningType.Warning_All) ? hits.Length : data.MaxRandomTarget;
+
+ for (int i = 0; i < hits.Length; i++)
+ {
+ bool counted = (data.Type == XWarningType.Warning_All) ? true : IsPickedInRange(n, hits.Length - i);
+
+ if (counted)
+ {
+ n--;
+ item.Add(hits[i].gameObject);
+ }
+ }
+ }break;
+ case XWarningType.Warning_Target:
+ {
+ if (_target != null) item.Add(_target);
+ }break;
+ }
+
+ for (int i = 0; i < item.Count; i++)
+ {
+ for (int n = 0; n < data.PosRandomCount; n++)
+ {
+ int d = XCommon.singleton.RandomInt(0, 360);
+ float r = XCommon.singleton.RandomFloat(0, data.PosRandomRange);
+
+ Vector3 v = r * XCommon.singleton.HorizontalRotateVetor3(Vector3.forward, d);
+
+ if (!string.IsNullOrEmpty(data.Fx))
+ {
+ XFxMgr.singleton.CreateAndPlay(
+ data.Fx,
+ item[i].transform,
+ new Vector3(v.x, 0.05f - item[i].transform.position.y, v.z),
+ data.Scale * Vector3.one,
+ 1,
+ false,
+ data.FxDuration);
+ }
+
+ WarningPosAt[data.Index].Add(item[i].transform.position + v);
+ }
+ }
+ }
+ else if(data.Type == XWarningType.Warning_Multiple)
+ {
+ XSkillHit[] hits = GameObject.FindObjectsOfType<XSkillHit>();
+ int n = data.MaxRandomTarget;
+
+ for (int i = 0; i < hits.Length; i++)
+ {
+ if (IsPickedInRange(n, hits.Length - i))
+ {
+ n--;
+
+ if (!string.IsNullOrEmpty(data.Fx))
+ {
+ XFxMgr.singleton.CreateAndPlay(
+ data.Fx,
+ hits[i].transform,
+ new Vector3(0, 0.05f - hits[i].transform.position.y, 0),
+ data.Scale * Vector3.one,
+ 1,
+ false,
+ data.FxDuration);
+ }
+
+ WarningPosAt[data.Index].Add(hits[i].transform.position);
+ }
+ }
+ }
+ }
+ else
+ {
+ switch (data.Type)
+ {
+ case XWarningType.Warning_None:
+ {
+ Vector3 offset = transform.rotation * new Vector3(data.OffsetX, data.OffsetY, data.OffsetZ);
+
+ XFxMgr.singleton.CreateAndPlay(
+ data.Fx,
+ transform,
+ offset,
+ data.Scale * Vector3.one,
+ 1,
+ false,
+ data.FxDuration);
+
+ WarningPosAt[data.Index].Add(transform.position + offset);
+ }break;
+ case XWarningType.Warning_Target:
+ {
+ if (_target != null)
+ {
+ if (!string.IsNullOrEmpty(data.Fx))
+ {
+ XFxMgr.singleton.CreateAndPlay(
+ data.Fx,
+ _target.transform,
+ new Vector3(0, 0.05f - _target.transform.position.y, 0),
+ data.Scale * Vector3.one,
+ 1,
+ false,
+ data.FxDuration);
+ }
+
+ WarningPosAt[data.Index].Add(_target.transform.position);
+ }
+ else
+ {
+ Vector3 offset = transform.rotation * new Vector3(data.OffsetX, data.OffsetY, data.OffsetZ);
+
+ XFxMgr.singleton.CreateAndPlay(
+ data.Fx,
+ transform,
+ offset,
+ data.Scale * Vector3.one,
+ 1,
+ false,
+ data.FxDuration);
+
+ WarningPosAt[data.Index].Add(transform.position + offset);
+ }
+ }break;
+ case XWarningType.Warning_All:
+ {
+ XSkillHit[] hits = GameObject.FindObjectsOfType<XSkillHit>();
+
+ for (int i = 0; i < hits.Length; i++)
+ {
+ if (!string.IsNullOrEmpty(data.Fx))
+ {
+ XFxMgr.singleton.CreateAndPlay(
+ data.Fx,
+ hits[i].transform,
+ new Vector3(0, 0.05f - hits[i].transform.position.y, 0),
+ data.Scale * Vector3.one,
+ 1,
+ false,
+ data.FxDuration);
+ }
+
+ WarningPosAt[data.Index].Add(hits[i].transform.position);
+ }
+ }break;
+ }
+ }
+ }
+
+ private void Fx(object param)
+ {
+ XFxData data = param as XFxData;
+
+ if (data.Shield) return;
+
+ Transform trans = transform;
+ Vector3 offset = new Vector3(data.OffsetX, data.OffsetY, data.OffsetZ);
+
+ XFx fx = XFxMgr.singleton.CreateFx(data.Fx);
+ fx.DelayDestroy = data.Destroy_Delay;
+
+ if (data.StickToGround)
+ {
+ switch (data.Type)
+ {
+ case SkillFxType.FirerBased:
+ {
+
+ }break;
+ case SkillFxType.TargetBased:
+ {
+ if (_current.NeedTarget && _target != null)
+ {
+ trans = _target.transform;
+ offset = new Vector3(data.Target_OffsetX, data.Target_OffsetY, data.Target_OffsetZ);
+ }
+ }break;
+ }
+
+ Vector3 pos = trans.position + trans.rotation * offset;
+ pos.y = 0;
+
+ fx.Play(pos, Quaternion.identity, new Vector3(data.ScaleX, data.ScaleY, data.ScaleZ));
+ }
+ else
+ {
+ switch (data.Type)
+ {
+ case SkillFxType.FirerBased:
+ {
+ if (data.Bone != null && data.Bone.Length > 0)
+ {
+ Transform attachPoint = trans.Find(data.Bone);
+ if (attachPoint != null)
+ {
+ trans = attachPoint;
+ }
+ else
+ {
+ int index = data.Bone.LastIndexOf("/");
+ if (index >= 0)
+ {
+ string bone = data.Bone.Substring(index + 1);
+ attachPoint = trans.Find(bone);
+ if (attachPoint != null)
+ {
+ trans = attachPoint;
+ }
+ }
+ }
+ }
+ }break;
+ case SkillFxType.TargetBased:
+ {
+ if (_current.NeedTarget && _target != null)
+ {
+ trans = _target.transform;
+ offset = new Vector3(data.Target_OffsetX, data.Target_OffsetY, data.Target_OffsetZ);
+ }
+ }break;
+ }
+
+ fx.Play(trans, offset, new Vector3(data.ScaleX, data.ScaleY, data.ScaleZ), 1, data.Follow);
+ }
+
+ if (data.Combined)
+ {
+ if (data.End > 0)
+ AddedCombinedToken(XTimerMgr.singleton.SetTimer(data.End - data.At, KillFx, fx));
+ _outer_fx.Add(fx);
+ }
+ else
+ {
+ if (data.End > 0)
+ AddedTimerToken(XTimerMgr.singleton.SetTimer(data.End - data.At, KillFx, fx), false);
+ _fx.Add(fx);
+ }
+ }
+
+ private void AddedTimerToken(uint token, bool logical)
+ {
+ if(logical)
+ _logicalToken.Add(token);
+ else
+ _presentToken.Add(token);
+ }
+
+ private void AddedCombinedToken(uint token)
+ {
+ _combinedToken.Add(token);
+ }
+
+ private void AddChild(Transform parent, GameObject child)
+ {
+ child.transform.parent = parent;
+ child.transform.localPosition = Vector3.zero;
+ child.transform.localRotation = Quaternion.identity;
+ child.transform.localScale = Vector3.one;
+ }
+
+ private void Audio(object param)
+ {
+ XAudioData data = param as XAudioData;
+
+ //FMOD_StudioSystem.instance.PlayOneShot("event:/" + data.Clip, transform.position);
+
+ if (_emitter == null)
+ _emitter = gameObject.AddComponent<XFmod>();
+
+ _emitter.StartEvent("event:/" + data.Clip, data.Channel);
+ }
+
+ private AudioSource GetAudioSourceByChannel(AudioChannel channel)
+ {
+ switch (channel)
+ {
+ case AudioChannel.Action:
+ {
+ if (_audio_action == null)
+ _audio_action = gameObject.AddComponent<AudioSource>();
+
+ return _audio_action;
+ }
+ case AudioChannel.Motion:
+ {
+ if (_audio_motion == null)
+ _audio_motion = gameObject.AddComponent<AudioSource>();
+
+ return _audio_motion;
+ }
+ case AudioChannel.Skill:
+ {
+ if (_audio_skill == null)
+ _audio_skill = gameObject.AddComponent<AudioSource>();
+
+ return _audio_skill;
+ }
+ case AudioChannel.Behit:
+ {
+ if (_audio_behit == null)
+ _audio_behit = gameObject.AddComponent<AudioSource>();
+
+ return _audio_behit;
+ }
+ }
+
+ return _audio_action;
+ }
+
+ private void Manipulate(object param)
+ {
+ XManipulationData data = param as XManipulationData;
+
+ if (_manipulate == null) _manipulate = new XSkillManipulate(this);
+
+ long token = XCommon.singleton.UniqueToken;
+ _manipulate.Add(token, data);
+ AddedTimerToken(XTimerMgr.singleton.SetTimer(data.End - data.At, KillManipulate, token), true);
+ }
+
+ private void KillManipulate(object param)
+ {
+ _manipulate.Remove((long)param);
+ }
+
+ private void Shake(object param)
+ {
+ XCameraEffectData data = param as XCameraEffectData;
+
+ _xcamera_effect = new XCameraShake(gameObject, _camera.UnityCamera);
+
+ _xcamera_effect.OnShake(
+ data.Time,
+ data.FovAmp,
+ data.AmplitudeX,
+ data.AmplitudeY,
+ data.AmplitudeZ,
+ data.Frequency,
+ data.Coordinate,
+ data.ShakeX,
+ data.ShakeY,
+ data.ShakeZ,
+ data.Random);
+ }
+
+ private void Mob(object param)
+ {
+ XMobUnitData mob = param as XMobUnitData;
+
+ uint id = XStatisticsLibrary.AssociatedData((uint)mob.TemplateID).PresentID;
+ XEntityPresentation.RowData data = XAnimationLibrary.AssociatedAnimations(id);
+
+ GameObject mob_unit = GameObject.Instantiate(Resources.Load("Prefabs/" + data.Prefab)) as GameObject;
+
+ Vector3 offset = transform.rotation * new Vector3(mob.Offset_At_X, mob.Offset_At_Y, mob.Offset_At_Z);
+ Vector3 pos = transform.position + offset;
+
+ mob_unit.transform.position = pos;
+ mob_unit.transform.forward = transform.forward;
+
+ if (mob.LifewithinSkill) mob_unit.tag = "Finish";
+
+ _mob_unit.Add(mob_unit);
+ }
+
+ private void CameraMotion(object param)
+ {
+ XCameraMotionData data = param as XCameraMotionData;
+
+ _camera.Effect(data, _current.TypeToken != 2);
+ }
+
+ private void CameraPostEffect(object param)
+ {
+ XCameraPostEffectData data = param as XCameraPostEffectData;
+
+ Behaviour o = _camera.UnityCamera.GetComponent(data.Effect) as Behaviour;
+ if (o != null) o.enabled = true;
+
+ AddedTimerToken(XTimerMgr.singleton.SetTimer(_current.CameraPostEffect.End - _current.CameraPostEffect.At, CameraPostEffectEnd, o), false);
+ }
+
+ private void CameraPostEffectEnd(object param)
+ {
+ Behaviour o = param as Behaviour;
+ if (o != null) o.enabled = false;
+ }
+
+ private bool CanAct(Vector3 dir)
+ {
+ bool can = false;
+ float now = Time.time - _fire_time;
+
+ XLogicalData logic = (SkillData.TypeToken == 3) ? SkillData.Logical : _current.Logical;
+
+ can = true;
+
+ if (XCommon.singleton.IsLess(now, logic.Not_Move_End) &&
+ XCommon.singleton.IsGreater(now, logic.Not_Move_At))
+ {
+ can = false;
+ }
+
+ if (can)
+ StopFire();
+ else
+ {
+ if (XCommon.singleton.IsLess(now, logic.Rotate_End) &&
+ XCommon.singleton.IsGreater(now, logic.Rotate_At))
+ {
+ //perform rotate
+ PrepareRotation(XCommon.singleton.Horizontal(dir), logic.Rotate_Speed > 0 ? logic.Rotate_Speed : _xConfigData.RotateSpeed);
+ }
+ }
+
+ return can;
+ }
+
+ //can replace by other skill
+ private bool CanReplacedBy(XSkillData skill)
+ {
+ /*
+ * Main skill can always be act
+ */
+ bool cancel = (_xOuterData.Logical.CanReplacedby & (1 << skill.TypeToken)) != 0;
+
+ if (!cancel)
+ {
+ cancel = XCommon.singleton.IsGreater(_delta, _xOuterData.Logical.CanCancelAt);
+ }
+
+ return cancel;
+ }
+
+ private void Combined(object param)
+ {
+ int i = (int)param;
+
+ if (i < _xOuterData.Combined.Count && _xOuterData.Combined[i].Name != null && _xOuterData.Combined[i].Name.Length > 0)
+ {
+ _combined_id = i;
+
+ if (_combined_id > 0)
+ StopFire(false);
+ else
+ MainCoreExecute();
+
+ _trigger = XSkillData.Combined_Command[_combined_id];
+
+ _current = _combinedlist[_combined_id];
+
+ _state = DummyState.Fire;
+ _fire_time = Time.time;
+ if (_ator != null)
+ _ator.speed = 0;
+
+ _time_offset = _xOuterData.Combined[_combined_id].At / _combinedlist[i].Time;
+ }
+ else
+ {
+ StopFire();
+ }
+ }
+
+ private void Ja(object param)
+ {
+ if (!EditorData.XAutoJA) return;
+
+ int i = (int)param;
+
+ float swype = XGesture.singleton.LastSwypeAt;
+ float trigger_at = swype - _fire_time - Time.deltaTime;
+
+ XJAData jd = _current.Ja[_jaCount];
+
+ if (!XCommon.singleton.IsEqual(swype, _last_swype_time) &&
+ XCommon.singleton.IsLess(trigger_at, jd.End) &&
+ XCommon.singleton.IsGreater(trigger_at, jd.At))
+ {
+ if (_xOuterData.Ja[i].Name != null && _xOuterData.Ja[i].Name.Length > 0)
+ {
+ StopFire();
+ _trigger = XSkillData.JA_Command[_xDataExtra.JaEx[i].Ja.SkillPosition];
+
+ _current = _xDataExtra.JaEx[i].Ja;
+
+ _state = DummyState.Fire;
+ _fire_time = Time.time;
+ _delta = 0;
+ if (_ator != null)
+ _ator.speed = 0;
+ }
+ }
+ else if (_xOuterData.Ja[i].Next_Name != null && _xOuterData.Ja[i].Next_Name.Length > 0)
+ {
+ StopFire();
+ _trigger = XSkillData.JA_Command[_xDataExtra.JaEx[i].Next.SkillPosition];
+
+ _current = _xDataExtra.JaEx[i].Next;
+
+ _state = DummyState.Fire;
+ _fire_time = Time.time;
+ _delta = 0;
+ if (_ator != null)
+ _ator.speed = 0;
+ }
+
+ _last_swype_time = swype;
+ _jaCount++;
+ }
+
+ private void Project(XResultData param, int additionalAngle = 0)
+ {
+ if (param.Attack_All)
+ {
+ XSkillHit[] hits = GameObject.FindObjectsOfType<XSkillHit>();
+
+ for (int i = 0; i < hits.Length; i++)
+ {
+ XBulletMgr.singleton.ShootBullet(GenerateBullet(param, hits[i].gameObject, additionalAngle));
+ }
+ }
+ else if (param.Warning)
+ {
+ for (int i = 0; i < WarningPosAt[param.Warning_Idx].Count; i++)
+ {
+ XBulletMgr.singleton.ShootBullet(GenerateBullet(param, null, additionalAngle, i));
+ }
+ }
+ else
+ XBulletMgr.singleton.ShootBullet(GenerateBullet(param, _target, additionalAngle));
+ }
+
+ private XBullet GenerateBullet(XResultData data, GameObject target, int additionalAngle, int wid = -1)
+ {
+ return new XBullet(new XBulletData(
+ this,
+ _current,
+ target,
+ data.Index,
+ data.LongAttackData.FireAngle + additionalAngle,
+ wid));
+ }
+
+ private void FocusTarget()
+ {
+ XSkillHit hit = GameObject.FindObjectOfType<XSkillHit>();
+ _target = (_xOuterData.NeedTarget && hit != null) ? hit.gameObject : null;
+
+ if (_target != null && IsInAttckField(_xOuterData, transform.position, transform.forward, _target))
+ {
+ PrepareRotation(XCommon.singleton.Horizontal(_target.transform.position - transform.position), _xConfigData.RotateSpeed);
+ }
+ }
+
+ private void KillFx(object o)
+ {
+ XFx fx = o as XFx;
+
+ _fx.Remove(fx);
+ _outer_fx.Remove(fx);
+
+ XFxMgr.singleton.DestroyFx(fx, false);
+ }
+
+ private bool IsInField(XSkillData data, int triggerTime, Vector3 pos, Vector3 forward, Vector3 target, float angle, float distance)
+ {
+ bool log = true;
+ if (data.Warning != null && data.Warning.Count > 0)
+ {
+ for (int i = 0; i < data.Warning.Count; i++)
+ {
+ if (data.Warning[i].RandomWarningPos || data.Warning[i].Type == XWarningType.Warning_Multiple)
+ {
+ log = false; break;
+ }
+ }
+ }
+
+ if (data.Result[triggerTime].Sector_Type)
+ {
+ if (!(XCommon.singleton.IsEqualGreater(distance, data.Result[triggerTime].Low_Range) &&
+ XCommon.singleton.IsLess(distance, data.Result[triggerTime].Range) &&
+ angle <= data.Result[triggerTime].Scope * 0.5f))
+ {
+ if (log)
+ {
+ Debug.Log("-----------------------------------");
+ Debug.Log("At " + triggerTime + " Hit missing: distance is " + distance.ToString("F3") + " ( >= " + data.Result[triggerTime].Low_Range.ToString("F3") + ")");
+ Debug.Log("At " + triggerTime + " Hit missing: distance is " + distance.ToString("F3") + " ( < " + data.Result[triggerTime].Range.ToString("F3") + ")");
+ Debug.Log("At " + triggerTime + " Hit missing: dir is " + angle.ToString("F3") + " ( < " + (data.Result[triggerTime].Scope * 0.5f).ToString("F3") + ")");
+ }
+
+ return false;
+ }
+ }
+ else
+ {
+ if (!IsInAttackRect(target, pos, forward, data.Result[triggerTime].Range, data.Result[triggerTime].Scope, data.Result[triggerTime].Rect_HalfEffect, data.Result[triggerTime].None_Sector_Angle_Shift))
+ {
+ float d = data.Result[triggerTime].Range;
+ float w = data.Result[triggerTime].Scope;
+
+ Vector3[] vecs = new Vector3[4];
+ vecs[0] = new Vector3(-w / 2.0f, 0, data.Result[triggerTime].Rect_HalfEffect ? 0 : (-d / 2.0f));
+ vecs[1] = new Vector3(-w / 2.0f, 0, d / 2.0f);
+ vecs[2] = new Vector3(w / 2.0f, 0, d / 2.0f);
+ vecs[3] = new Vector3(w / 2.0f, 0, data.Result[triggerTime].Rect_HalfEffect ? 0 : (-d / 2.0f));
+
+ if (log)
+ {
+ Debug.Log("-----------------------------------");
+ Debug.Log("Not in rect " + vecs[0] + " " + vecs[1] + " " + vecs[2] + " " + vecs[3]);
+ }
+
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ private bool IsInAttckField(XSkillData data, Vector3 pos, Vector3 forward, GameObject target)
+ {
+ forward = XCommon.singleton.HorizontalRotateVetor3(forward, data.Cast_Scope_Shift);
+ Vector3 targetPos = target.transform.position;
+
+ if (data.Cast_Range_Rect)
+ {
+ pos.x += data.Cast_Offset_X;
+ pos.z += data.Cast_Offset_Z;
+
+ return IsInAttackRect(targetPos, pos, forward, data.Cast_Range_Upper, data.Cast_Scope, false, 0);
+ }
+ else
+ {
+ Vector3 dir = targetPos - pos; dir.y = 0;
+ float distance = dir.magnitude;
+
+ //normalize
+ dir.Normalize();
+
+ float angle = (distance == 0) ? 0 : Vector3.Angle(forward, dir);
+
+ if (XCommon.singleton.IsEqualLess(distance, data.Cast_Range_Upper) &&
+ XCommon.singleton.IsEqualGreater(distance, data.Cast_Range_Lower) &&
+ angle <= data.Cast_Scope * 0.5f)
+ {
+ return true;
+ }
+
+ return false;
+ }
+ }
+
+ private bool IsInAttackRect(Vector3 target, Vector3 anchor, Vector3 forward, float d, float w, bool half, float shift)
+ {
+ Quaternion rotation = XCommon.singleton.VectorToQuaternion(XCommon.singleton.HorizontalRotateVetor3(forward, shift));
+
+ Rect rect = new Rect();
+
+ rect.xMin = -w / 2.0f;
+ rect.xMax = w / 2.0f;
+ rect.yMin = half ? 0 : (-d / 2.0f);
+ rect.yMax = d / 2.0f;
+
+ return XCommon.singleton.IsInRect(target - anchor, rect, Vector3.zero, rotation);
+ }
+ }
+}
+#endif
\ No newline at end of file diff --git a/Client/Assets/Scripts/XEditor/XSkillEditor/XSkillHoster.cs.meta b/Client/Assets/Scripts/XEditor/XSkillEditor/XSkillHoster.cs.meta new file mode 100644 index 00000000..a7ce52ba --- /dev/null +++ b/Client/Assets/Scripts/XEditor/XSkillEditor/XSkillHoster.cs.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2
+guid: 3295e2c2ba4c26e4785b935b72855f98
+MonoImporter:
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
diff --git a/Client/Assets/Scripts/XEditor/XSkillEditor/XSkillManipulate.cs b/Client/Assets/Scripts/XEditor/XSkillEditor/XSkillManipulate.cs new file mode 100644 index 00000000..1ff6470e --- /dev/null +++ b/Client/Assets/Scripts/XEditor/XSkillEditor/XSkillManipulate.cs @@ -0,0 +1,65 @@ +#if UNITY_EDITOR
+using System;
+using UnityEngine;
+using XUtliPoolLib;
+using System.Collections.Generic;
+
+namespace XEditor
+{
+ class XSkillManipulate
+ {
+ private XSkillHoster _hoster = null;
+
+ private Dictionary<long, XManipulationData> _item = new Dictionary<long, XManipulationData>();
+ public Dictionary<long, XManipulationData> Set { get { return _item; } }
+
+ public XSkillManipulate(XSkillHoster hoster)
+ {
+ _hoster = hoster;
+ }
+
+ public void Add(long token, XManipulationData data)
+ {
+ if (!_item.ContainsKey(token))
+ {
+ _item.Add(token, data);
+ }
+ }
+
+ public void Remove(long token)
+ {
+ if (token == 0) _item.Clear();
+ else
+ {
+ _item.Remove(token);
+ }
+ }
+
+ public void Update(float deltaTime)
+ {
+ XSkillHit[] hits = GameObject.FindObjectsOfType<XSkillHit>();
+
+ foreach (XManipulationData data in _item.Values)
+ {
+ Vector3 center = _hoster.transform.position + _hoster.transform.rotation * new Vector3(data.OffsetX, 0, data.OffsetZ);
+
+ foreach (XSkillHit hit in hits)
+ {
+ Vector3 gap = center - hit.transform.position; gap.y = 0;
+ float dis = gap.magnitude;
+
+ if (dis < data.Radius && (dis == 0 || Vector3.Angle(-gap, _hoster.transform.forward) <= data.Degree * 0.5f))
+ {
+ float len = data.Force * deltaTime;
+
+ Vector3 dir = gap.normalized;
+ Vector3 move = dir * Mathf.Min(dis, len);
+
+ hit.transform.Translate(move, Space.World);
+ }
+ }
+ }
+ }
+ }
+}
+#endif
\ No newline at end of file diff --git a/Client/Assets/Scripts/XEditor/XSkillEditor/XSkillManipulate.cs.meta b/Client/Assets/Scripts/XEditor/XSkillEditor/XSkillManipulate.cs.meta new file mode 100644 index 00000000..767c562c --- /dev/null +++ b/Client/Assets/Scripts/XEditor/XSkillEditor/XSkillManipulate.cs.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2
+guid: b67fb09ff0ab7ba4aa099519d59dbfcc
+MonoImporter:
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
diff --git a/Client/Assets/Scripts/XEditor/XSkillEditor/XTouch.cs b/Client/Assets/Scripts/XEditor/XSkillEditor/XTouch.cs new file mode 100644 index 00000000..6924e395 --- /dev/null +++ b/Client/Assets/Scripts/XEditor/XSkillEditor/XTouch.cs @@ -0,0 +1,130 @@ +#if UNITY_EDITOR
+using System;
+using System.Collections.Generic;
+using XUtliPoolLib;
+using UnityEngine;
+
+namespace XEditor
+{
+ internal class XTouch : XSingleton<XTouch>
+ {
+ private bool _bEditorMode = false;
+ private bool _bHasTouch = false;
+ private Vector3 _lastMousePosition = Vector3.zero;
+
+ private XTouchItem _touch = new XTouchItem();
+
+ public XTouch()
+ {
+ _bEditorMode = (Application.platform == RuntimePlatform.WindowsEditor ||
+ Application.platform == RuntimePlatform.OSXEditor);
+ }
+
+ public XTouchItem GetTouch()
+ {
+ if (_bHasTouch)
+ return _touch;
+ else
+ return null;
+ }
+
+ public void Update()
+ {
+ _bHasTouch = false;
+
+ if (_bEditorMode)
+ {
+ if (Input.GetMouseButton(0))
+ {
+ _touch.faketouch.fingerId = 10;
+ _touch.faketouch.position = Input.mousePosition;
+ _touch.faketouch.deltaTime = Time.deltaTime;
+ _touch.faketouch.deltaPosition = Input.mousePosition - _lastMousePosition;
+ _touch.faketouch.phase = (Input.GetMouseButtonDown(0) ? TouchPhase.Began :
+ (_touch.faketouch.deltaPosition.sqrMagnitude > 1.0f ? TouchPhase.Moved : TouchPhase.Stationary));
+ _touch.faketouch.tapCount = 1;
+
+ _touch.Fake = true;
+
+ HandleTouch();
+ }
+ else if (Input.GetMouseButtonUp(0))
+ {
+ _touch.faketouch.fingerId = 10;
+ _touch.faketouch.position = Input.mousePosition;
+ _touch.faketouch.deltaTime = Time.deltaTime;
+ _touch.faketouch.deltaPosition = Input.mousePosition - _lastMousePosition;
+ _touch.faketouch.phase = TouchPhase.Ended;
+ _touch.faketouch.tapCount = 1;
+
+ _touch.Fake = true;
+
+ HandleTouch();
+ }
+ }
+ else
+ {
+ if (Input.touchCount > 0)
+ {
+ _touch.Fake = false;
+ _touch.touch = Input.GetTouch(0);
+
+ HandleTouch();
+ }
+ }
+ }
+
+ private void HandleTouch()
+ {
+ _bHasTouch = true;
+ }
+ }
+
+ internal class XTouchItem
+ {
+ public bool Fake { get; set; }
+ public Touch touch;
+ public XFakeTouch faketouch = new XFakeTouch();
+
+ public Vector2 DeltaPosition
+ {
+ get { return Fake ? faketouch.deltaPosition : touch.deltaPosition; }
+ }
+ public float DeltaTime
+ {
+ get { return Fake ? faketouch.deltaTime : touch.deltaTime; }
+ }
+ public int FingerId
+ {
+ get { return Fake ? faketouch.fingerId : touch.fingerId; }
+ }
+ public TouchPhase Phase
+ {
+ get { return Fake ? faketouch.phase : touch.phase; }
+ }
+ public Vector2 Position
+ {
+ get { return Fake ? faketouch.position : touch.position; }
+ }
+ public Vector2 RawPosition
+ {
+ get { return Fake ? faketouch.rawPosition : touch.rawPosition; }
+ }
+ public int TapCount
+ {
+ get { return Fake ? faketouch.tapCount : touch.tapCount; }
+ }
+ }
+
+ internal struct XFakeTouch
+ {
+ public Vector2 deltaPosition { get; set; }
+ public float deltaTime { get; set; }
+ public int fingerId { get; set; }
+ public TouchPhase phase { get; set; }
+ public Vector2 position { get; set; }
+ public Vector2 rawPosition { get; set; }
+ public int tapCount { get; set; }
+ }
+}
+#endif
\ No newline at end of file diff --git a/Client/Assets/Scripts/XEditor/XSkillEditor/XTouch.cs.meta b/Client/Assets/Scripts/XEditor/XSkillEditor/XTouch.cs.meta new file mode 100644 index 00000000..38955346 --- /dev/null +++ b/Client/Assets/Scripts/XEditor/XSkillEditor/XTouch.cs.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2
+guid: 9b9ac90abfdf5cc488c6b7074b6ab4f6
+MonoImporter:
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
diff --git a/Client/Assets/Scripts/XEditor/XTableReader.cs b/Client/Assets/Scripts/XEditor/XTableReader.cs new file mode 100644 index 00000000..623faf03 --- /dev/null +++ b/Client/Assets/Scripts/XEditor/XTableReader.cs @@ -0,0 +1,15 @@ +#if UNITY_EDITOR
+using UnityEngine;
+using System.Collections;
+using XUtliPoolLib;
+
+public class XTableReader
+{
+ public static bool ReadFile(string location, CVSReader reader)
+ {
+ CVSReader.Init();
+ XBinaryReader.Init();
+ return XResourceLoaderMgr.singleton.ReadFile(location, reader);
+ }
+}
+#endif
\ No newline at end of file diff --git a/Client/Assets/Scripts/XEditor/XTableReader.cs.meta b/Client/Assets/Scripts/XEditor/XTableReader.cs.meta new file mode 100644 index 00000000..a4c03a7b --- /dev/null +++ b/Client/Assets/Scripts/XEditor/XTableReader.cs.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2
+guid: c2a042550b69a404daf395204840d3b5
+MonoImporter:
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
|