From 6eb915c129fc90c6f4c82ae097dd6ffad5239efc Mon Sep 17 00:00:00 2001 From: chai Date: Mon, 25 Jan 2021 14:28:30 +0800 Subject: +scripts --- Client/Assets/Scripts/XEditor/AssetModify.cs | 11389 +++++++++++++++++++ Client/Assets/Scripts/XEditor/AssetModify.cs.meta | 12 + Client/Assets/Scripts/XEditor/CombineConfig.cs | 65 + .../Assets/Scripts/XEditor/CombineConfig.cs.meta | 8 + Client/Assets/Scripts/XEditor/LoadGameAtHere.cs | 15 + .../Assets/Scripts/XEditor/LoadGameAtHere.cs.meta | 8 + Client/Assets/Scripts/XEditor/MainFbx.cs | 65 + Client/Assets/Scripts/XEditor/MainFbx.cs.meta | 12 + Client/Assets/Scripts/XEditor/Render2Texture.cs | 84 + .../Assets/Scripts/XEditor/Render2Texture.cs.meta | 12 + Client/Assets/Scripts/XEditor/ReplaceEquip.cs | 399 + Client/Assets/Scripts/XEditor/ReplaceEquip.cs.meta | 12 + Client/Assets/Scripts/XEditor/SceneConfig.cs | 62 + Client/Assets/Scripts/XEditor/SceneConfig.cs.meta | 8 + Client/Assets/Scripts/XEditor/XBehaviorTree.cs | 225 + .../Assets/Scripts/XEditor/XBehaviorTree.cs.meta | 8 + .../Assets/Scripts/XEditor/XCharacterMaterial.cs | 45 + .../Scripts/XEditor/XCharacterMaterial.cs.meta | 8 + Client/Assets/Scripts/XEditor/XCutSceneEditor.meta | 5 + .../Scripts/XEditor/XCutSceneEditor/XActor.cs | 169 + .../Scripts/XEditor/XCutSceneEditor/XActor.cs.meta | 8 + .../XEditor/XCutSceneEditor/XCutSceneCamera.cs | 175 + .../XCutSceneEditor/XCutSceneCamera.cs.meta | 8 + .../Scripts/XEditor/XCutSceneEditor/XCutSceneUI.cs | 77 + .../XEditor/XCutSceneEditor/XCutSceneUI.cs.meta | 8 + .../XEditor/XCutSceneEditor/XScriptStandalone.cs | 191 + .../XCutSceneEditor/XScriptStandalone.cs.meta | 8 + Client/Assets/Scripts/XEditor/XResourceHelp.cs | 32 + .../Assets/Scripts/XEditor/XResourceHelp.cs.meta | 8 + Client/Assets/Scripts/XEditor/XSkillEditor.meta | 5 + .../Scripts/XEditor/XSkillEditor/Effect.meta | 5 + .../XEditor/XSkillEditor/Effect/ImageEffectBase.cs | 56 + .../XSkillEditor/Effect/ImageEffectBase.cs.meta | 8 + .../XEditor/XSkillEditor/Effect/RadialBlur.cs | 49 + .../XEditor/XSkillEditor/Effect/RadialBlur.cs.meta | 8 + .../Assets/Scripts/XEditor/XSkillEditor/XBullet.cs | 443 + .../Scripts/XEditor/XSkillEditor/XBullet.cs.meta | 8 + .../Scripts/XEditor/XSkillEditor/XBulletData.cs | 85 + .../XEditor/XSkillEditor/XBulletData.cs.meta | 8 + .../Scripts/XEditor/XSkillEditor/XBulletMgr.cs | 34 + .../XEditor/XSkillEditor/XBulletMgr.cs.meta | 8 + .../Scripts/XEditor/XSkillEditor/XCameraShake.cs | 157 + .../XEditor/XSkillEditor/XCameraShake.cs.meta | 8 + .../Scripts/XEditor/XSkillEditor/XDataBuilder.cs | 347 + .../XEditor/XSkillEditor/XDataBuilder.cs.meta | 8 + .../Assets/Scripts/XEditor/XSkillEditor/XDataIO.cs | 95 + .../Scripts/XEditor/XSkillEditor/XDataIO.cs.meta | 8 + .../Scripts/XEditor/XSkillEditor/XEditorData.cs | 695 ++ .../XEditor/XSkillEditor/XEditorData.cs.meta | 8 + .../Scripts/XEditor/XSkillEditor/XEditorPath.cs | 85 + .../XEditor/XSkillEditor/XEditorPath.cs.meta | 8 + .../Scripts/XEditor/XSkillEditor/XGesture.cs | 205 + .../Scripts/XEditor/XSkillEditor/XGesture.cs.meta | 8 + .../Scripts/XEditor/XSkillEditor/XSerialized.cs | 70 + .../XEditor/XSkillEditor/XSerialized.cs.meta | 8 + .../Scripts/XEditor/XSkillEditor/XSkillCamera.cs | 389 + .../XEditor/XSkillEditor/XSkillCamera.cs.meta | 8 + .../Scripts/XEditor/XSkillEditor/XSkillCharge.cs | 200 + .../XEditor/XSkillEditor/XSkillCharge.cs.meta | 8 + .../Scripts/XEditor/XSkillEditor/XSkillHit.cs | 545 + .../Scripts/XEditor/XSkillEditor/XSkillHit.cs.meta | 8 + .../Scripts/XEditor/XSkillEditor/XSkillHoster.cs | 2081 ++++ .../XEditor/XSkillEditor/XSkillHoster.cs.meta | 8 + .../XEditor/XSkillEditor/XSkillManipulate.cs | 65 + .../XEditor/XSkillEditor/XSkillManipulate.cs.meta | 8 + .../Assets/Scripts/XEditor/XSkillEditor/XTouch.cs | 130 + .../Scripts/XEditor/XSkillEditor/XTouch.cs.meta | 8 + Client/Assets/Scripts/XEditor/XTableReader.cs | 15 + Client/Assets/Scripts/XEditor/XTableReader.cs.meta | 8 + 69 files changed, 19034 insertions(+) create mode 100644 Client/Assets/Scripts/XEditor/AssetModify.cs create mode 100644 Client/Assets/Scripts/XEditor/AssetModify.cs.meta create mode 100644 Client/Assets/Scripts/XEditor/CombineConfig.cs create mode 100644 Client/Assets/Scripts/XEditor/CombineConfig.cs.meta create mode 100644 Client/Assets/Scripts/XEditor/LoadGameAtHere.cs create mode 100644 Client/Assets/Scripts/XEditor/LoadGameAtHere.cs.meta create mode 100644 Client/Assets/Scripts/XEditor/MainFbx.cs create mode 100644 Client/Assets/Scripts/XEditor/MainFbx.cs.meta create mode 100644 Client/Assets/Scripts/XEditor/Render2Texture.cs create mode 100644 Client/Assets/Scripts/XEditor/Render2Texture.cs.meta create mode 100644 Client/Assets/Scripts/XEditor/ReplaceEquip.cs create mode 100644 Client/Assets/Scripts/XEditor/ReplaceEquip.cs.meta create mode 100644 Client/Assets/Scripts/XEditor/SceneConfig.cs create mode 100644 Client/Assets/Scripts/XEditor/SceneConfig.cs.meta create mode 100644 Client/Assets/Scripts/XEditor/XBehaviorTree.cs create mode 100644 Client/Assets/Scripts/XEditor/XBehaviorTree.cs.meta create mode 100644 Client/Assets/Scripts/XEditor/XCharacterMaterial.cs create mode 100644 Client/Assets/Scripts/XEditor/XCharacterMaterial.cs.meta create mode 100644 Client/Assets/Scripts/XEditor/XCutSceneEditor.meta create mode 100644 Client/Assets/Scripts/XEditor/XCutSceneEditor/XActor.cs create mode 100644 Client/Assets/Scripts/XEditor/XCutSceneEditor/XActor.cs.meta create mode 100644 Client/Assets/Scripts/XEditor/XCutSceneEditor/XCutSceneCamera.cs create mode 100644 Client/Assets/Scripts/XEditor/XCutSceneEditor/XCutSceneCamera.cs.meta create mode 100644 Client/Assets/Scripts/XEditor/XCutSceneEditor/XCutSceneUI.cs create mode 100644 Client/Assets/Scripts/XEditor/XCutSceneEditor/XCutSceneUI.cs.meta create mode 100644 Client/Assets/Scripts/XEditor/XCutSceneEditor/XScriptStandalone.cs create mode 100644 Client/Assets/Scripts/XEditor/XCutSceneEditor/XScriptStandalone.cs.meta create mode 100644 Client/Assets/Scripts/XEditor/XResourceHelp.cs create mode 100644 Client/Assets/Scripts/XEditor/XResourceHelp.cs.meta create mode 100644 Client/Assets/Scripts/XEditor/XSkillEditor.meta create mode 100644 Client/Assets/Scripts/XEditor/XSkillEditor/Effect.meta create mode 100644 Client/Assets/Scripts/XEditor/XSkillEditor/Effect/ImageEffectBase.cs create mode 100644 Client/Assets/Scripts/XEditor/XSkillEditor/Effect/ImageEffectBase.cs.meta create mode 100644 Client/Assets/Scripts/XEditor/XSkillEditor/Effect/RadialBlur.cs create mode 100644 Client/Assets/Scripts/XEditor/XSkillEditor/Effect/RadialBlur.cs.meta create mode 100644 Client/Assets/Scripts/XEditor/XSkillEditor/XBullet.cs create mode 100644 Client/Assets/Scripts/XEditor/XSkillEditor/XBullet.cs.meta create mode 100644 Client/Assets/Scripts/XEditor/XSkillEditor/XBulletData.cs create mode 100644 Client/Assets/Scripts/XEditor/XSkillEditor/XBulletData.cs.meta create mode 100644 Client/Assets/Scripts/XEditor/XSkillEditor/XBulletMgr.cs create mode 100644 Client/Assets/Scripts/XEditor/XSkillEditor/XBulletMgr.cs.meta create mode 100644 Client/Assets/Scripts/XEditor/XSkillEditor/XCameraShake.cs create mode 100644 Client/Assets/Scripts/XEditor/XSkillEditor/XCameraShake.cs.meta create mode 100644 Client/Assets/Scripts/XEditor/XSkillEditor/XDataBuilder.cs create mode 100644 Client/Assets/Scripts/XEditor/XSkillEditor/XDataBuilder.cs.meta create mode 100644 Client/Assets/Scripts/XEditor/XSkillEditor/XDataIO.cs create mode 100644 Client/Assets/Scripts/XEditor/XSkillEditor/XDataIO.cs.meta create mode 100644 Client/Assets/Scripts/XEditor/XSkillEditor/XEditorData.cs create mode 100644 Client/Assets/Scripts/XEditor/XSkillEditor/XEditorData.cs.meta create mode 100644 Client/Assets/Scripts/XEditor/XSkillEditor/XEditorPath.cs create mode 100644 Client/Assets/Scripts/XEditor/XSkillEditor/XEditorPath.cs.meta create mode 100644 Client/Assets/Scripts/XEditor/XSkillEditor/XGesture.cs create mode 100644 Client/Assets/Scripts/XEditor/XSkillEditor/XGesture.cs.meta create mode 100644 Client/Assets/Scripts/XEditor/XSkillEditor/XSerialized.cs create mode 100644 Client/Assets/Scripts/XEditor/XSkillEditor/XSerialized.cs.meta create mode 100644 Client/Assets/Scripts/XEditor/XSkillEditor/XSkillCamera.cs create mode 100644 Client/Assets/Scripts/XEditor/XSkillEditor/XSkillCamera.cs.meta create mode 100644 Client/Assets/Scripts/XEditor/XSkillEditor/XSkillCharge.cs create mode 100644 Client/Assets/Scripts/XEditor/XSkillEditor/XSkillCharge.cs.meta create mode 100644 Client/Assets/Scripts/XEditor/XSkillEditor/XSkillHit.cs create mode 100644 Client/Assets/Scripts/XEditor/XSkillEditor/XSkillHit.cs.meta create mode 100644 Client/Assets/Scripts/XEditor/XSkillEditor/XSkillHoster.cs create mode 100644 Client/Assets/Scripts/XEditor/XSkillEditor/XSkillHoster.cs.meta create mode 100644 Client/Assets/Scripts/XEditor/XSkillEditor/XSkillManipulate.cs create mode 100644 Client/Assets/Scripts/XEditor/XSkillEditor/XSkillManipulate.cs.meta create mode 100644 Client/Assets/Scripts/XEditor/XSkillEditor/XTouch.cs create mode 100644 Client/Assets/Scripts/XEditor/XSkillEditor/XTouch.cs.meta create mode 100644 Client/Assets/Scripts/XEditor/XTableReader.cs create mode 100644 Client/Assets/Scripts/XEditor/XTableReader.cs.meta (limited to 'Client/Assets/Scripts/XEditor') 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 obj, I assetImporter, string path) + where T : UnityEngine.Object where I : UnityEditor.AssetImporter; + + public delegate void EnumAssetCallback(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 GetObjects(string dir); + + void PreProcess(string path); + bool Process(UnityEngine.Object asset, string path); + void PostProcess(string path); + } + public class BaseAssetLoadCallback where T : UnityEngine.Object + { + public bool is_verbose = true; + public string extFilter = ""; + public string extFilter1 = ""; + protected List m_Objects = new List(); + 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(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 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 : BaseAssetLoadCallback, IAssetLoadCallback + where T : UnityEngine.Object where I : UnityEditor.AssetImporter + { + public EnumAssetPreprocessCallback preprocess = null; + public EnumAssetImportCallback 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 : BaseAssetLoadCallback, IAssetLoadCallback where T : UnityEngine.Object + { + public EnumAssetCallback 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 fbx, ModelImporter modelImporter, string path); + public delegate bool EnumTex2DCallback(Texture2D tex, TextureImporter textureImporter, string path); + + private static AssetLoadCallback enumFbx = new AssetLoadCallback("*.fbx"); + public static AssetLoadCallback enumTex2D = new AssetLoadCallback("*.png", "*.tga"); + + public delegate void EnumPrefabCallback(GameObject prefab, string path); + public delegate void EnumTxtCallback(TextAsset txt, string path); + public delegate void EnumMaterialCallback(Material mat, string path); + public delegate void EnumMeshCallback(Mesh mesh, string path); + public delegate void EnumAnimationCallback(AnimationClip animClip, string path); + public delegate void EnumBytesCallback(TextAsset bytes, string path); + + private static AssetLoadCallback enumPrefab = new AssetLoadCallback("*.prefab"); + private static AssetLoadCallback enumTxt = new AssetLoadCallback("*.bytes", "*.txt"); + private static AssetLoadCallback enumMat = new AssetLoadCallback("*.mat"); + private static AssetLoadCallback enumMesh = new AssetLoadCallback("*.asset"); + private static AssetLoadCallback enumAnimationClip = new AssetLoadCallback("*.anim"); + + public static T CreateOrReplaceAsset(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(path); + } + else + { + existingAsset = AssetDatabase.LoadAssetAtPath(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(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(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(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(GameObject go, List lst) where T : Component + { + T com = go.GetComponent(); + if (com != null) + { + lst.Add(com); + } + Transform t = go.transform; + for (int i = 0; i < t.childCount; ++i) + { + Transform child = t.GetChild(i); + GetGameObjectComponent(child.gameObject, lst); + } + } + + public static void EnumAsset(IAssetLoadCallback cb, string title, string dir = "") where T : UnityEngine.Object + { + if (cb != null) + { + List 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(enumTex2D, "DefaultCompress"); + } + [MenuItem(@"Assets/Tool/Texture/DefaultCompressNoSeperate %5", false, 0)] + private static void DefaultCompressNoSeperate() + { + isSeperateAlpha = false; + enumTex2D.cb = _DefaultCompress; + EnumAsset(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(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(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(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(newMat, "Assets/Resources/" + ci.resourcePath + "Half.mat"); + + GameObject newAtlas = GameObject.Instantiate(atlas) as GameObject; + UIAtlas a = newAtlas.GetComponent(); + 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(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(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(enumTex2D, "SeparateAlpha"); + onlyAtlas = false; + } + + [MenuItem(@"Assets/Tool/UI/Compress&SeparateAlphaHere", false, 0)] + private static void CompressSeparateAlphaHere() + { + enumTex2D.cb = _CompressSeparateAlpha; + EnumAsset(enumTex2D, "CompressSeparateAlphaHere"); + } + + //[MenuItem(@"Assets/Tool/UI/SeparateAlphaHere")] + //private static void SeparateAlphaHere() + //{ + // XImageImporterSet dataSet = XDataIO.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> names = new Dictionary>(); + 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 list; + string name = tex.name.ToLower(); + if (!names.TryGetValue(name, out list)) + { + list = new List(); + names.Add(name, list); + } + list.Add(AssetDatabase.GetAssetPath(tex)); + } + } + } + foreach (KeyValuePair> 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.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.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.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.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> atlasTasks = new Dictionary>(); + private static Dictionary> texTasks = new Dictionary>(); + 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(); + atlasTasks[512] = new List(); + atlasTasks[256] = new List(); + atlasTasks[128] = new List(); + atlasTasks[64] = new List(); + atlasTasks[32] = new List(); + + texTasks[1024] = new List(); + texTasks[512] = new List(); + texTasks[256] = new List(); + texTasks[128] = new List(); + texTasks[64] = new List(); + texTasks[32] = new List(); + } + + 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> pair in atlasTasks) + { + int size = pair.Key; + List 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 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.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(enumFbx, "MakeFbxReadOnly"); + } + //private static void CheckMeshVertex(Mesh mesh) + //{ + // List newPos = ListPool.Get(); + // List newUV = ListPool.Get(); + // List newUV2 = ListPool.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 newIndex = ListPool.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.Release(newIndex); + // } + + // ListPool.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 renderLst = ListPool.Get(); + go.GetComponentsInChildren(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(); + 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); + 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(newMesh, meshPath); + } + } + ListPool.Release(renderLst); + if (hasSkin) + { + Animator ator = go.GetComponent(); + if (ator != null && ator.avatar != null) + { + string avatarPath = dir + "/" + fbx.name + "_avatar.asset"; + Avatar avatar = UnityEngine.Object.Instantiate(ator.avatar); + avatar.name = fbx.name + "_avatar"; + CreateOrReplaceAsset(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(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(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(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(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 removeIndex = ListPool.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.Release(removeIndex); + } + + [MenuItem(@"Assets/Tool/Animation/ReduceKeyFrame", false, 0)] + private static void ReduceKeyFrame() + { + enumAnimationClip.cb = _ReduceKeyFrame; + EnumAsset(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(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(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(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(enumMat, "Cutoff2RMat"); + } + + [MenuItem(@"Assets/Tool/Material/Cutoff2RMat", false, 0)] + private static void Cutoff2RMat() + { + scaleSize = 1; + enumMat.cb = _Cutoff2RMat; + EnumAsset(enumMat, "Cutoff2RMat"); + scaleSize = 2; + } + + private static HashSet matName = new HashSet(); + private static Dictionary> matTexName = new Dictionary>(); + 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 matList = null; + if (matTexName.TryGetValue(tex.name, out matList)) + { + matList.Add(mat.name); + } + else + { + matList = new List(); + 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(enumMat, "FindSameMat"); + foreach (KeyValuePair> 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(enumMat, "FixMat"); + //} + + + + private static List shaderValue = new List(); + 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(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 shaderUse = new Dictionary(); + 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(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(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(enumMat, "FindMat"); + } + public static void GetMatTex(Material mat, List 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(); + if (modleLink != null && modleLink.Models.Count > 0) + { + XColliderRenderLinker renderLink = child.gameObject.GetComponent(); + if (renderLink == null) + { + renderLink = child.gameObject.AddComponent(); + } + if (renderLink != null) + { + List tmp = new List(); + for (int j = 0, jmax = modleLink.Models.Count; j < jmax; ++j) + { + Renderer r = modleLink.Models[j].GetComponent(); + 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 processedMat = new HashSet(); + 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(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(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(); + 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(); + 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(fbxPath); + if (fbx != null) + { + GameObject fbxObj = GameObject.Instantiate(fbx); + List renderLst = ListPool.Get(); + fbxObj.GetComponentsInChildren(true, renderLst); + if (meshIndex < renderLst.Count) + { + Renderer r = renderLst[meshIndex]; + if (r is MeshRenderer) + { + MeshFilter fbxMf = r.GetComponent(); + if (fbxMf != null && fbxMf.sharedMesh != null) + { + mf.sharedMesh = fbxMf.sharedMesh; + find = true; + } + } + } + ListPool.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 processedMesh = new HashSet(); + //private static void InnerProcessMat(Transform t,bool bake,bool processMesh, bool processMat) + //{ + // InnerProcessSceneObject(t, bake); + // MeshRenderer meshRender = t.GetComponent(); + // 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(); + // 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(enumFbx, "MeshInFolder2Original"); + // bAccordingSettings = true; + + // processedMat.Clear(); + // enumMat.cb = _MaterialInFolder2Original; + // EnumAsset(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(enumFbx, "MeshInFolder2Compress"); + + // processedMat.Clear(); + // enumMat.cb = _MaterialInFolder2Compress; + // EnumAsset(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(); + 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(); + //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(); + // 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(); + //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(); + // if (fxPro != null && fxPro.enabled) + // { + // errorLog += "fxPro未优化\r\n"; + // if (needFix) + // fxPro.enabled = false; + // change = true; + // } + // FMOD_Listener fmod_Listener = camera.GetComponent(); + // 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(); + // 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(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(); + 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> matMesh) + //{ + // int flag = (int)GameObjectUtility.GetStaticEditorFlags(child.gameObject); + // if ((flag & (int)StaticEditorFlags.BatchingStatic) != 0) + // { + // MeshRenderer mr = child.GetComponent(); + // if (mr != null) + // { + // Material mat = mr.sharedMaterial; + // if (mat != null) + // { + // MeshFilter mf = child.GetComponent(); + // if (mf != null) + // { + // Mesh mesh = mf.sharedMesh; + // if (mesh != null && mesh.isReadable) + // { + // List meshList = null; + // if (!matMesh.TryGetValue(mat, out meshList)) + // { + // meshList = new List(); + // 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> meshs) + //{ + // int flag = (int)GameObjectUtility.GetStaticEditorFlags(child.gameObject); + // if ((flag & (int)StaticEditorFlags.BatchingStatic) != 0) + // { + // MeshRenderer mr = child.GetComponent(); + // if (mr != null) + // { + // Material mat = mr.sharedMaterial; + // if (mat != null) + // { + // MeshFilter mf = child.GetComponent(); + // if (mf != null) + // { + // Mesh mesh = mf.sharedMesh; + // if (mesh != null && mesh.name.StartsWith("Combined Mesh")) + // { + // List meshList = null; + // if (!meshs.TryGetValue(mesh, out meshList)) + // { + // meshList = new List(); + // 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> matMesh = new Dictionary>(); + // Dictionary> meshs = new Dictionary>(); + // UnityEngine.SceneManagement.Scene s = EditorSceneManager.GetActiveScene(); + // GameObject go = GameObject.Find("Scene"); + // if(go!=null) + // { + // Transform t = go.transform; + // for(int i=0;i(mesh, Path); + // List meshList = it.Current.Value; + // for (int i = 0; i < meshList.Count; ++i) + // { + // MeshFilter mf = meshList[i]; + // mf.sharedMesh = mesh; + // } + // } + // //List ciList = new List(); + // //var it = matMesh.GetEnumerator(); + // //while(it.MoveNext()) + // //{ + // // List 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(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(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(); + // 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(); + // 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(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(); + // 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(path); + // } + // if (newMesh == null) + // { + // Debug.LogError(string.Format("Collider Mesh not found:{0} scene:{1}", t.name, sceneName)); + // } + // mc.sharedMesh = newMesh; + // } + // } + + // } + // List notVisibleNode = new List(); + // 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(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 lst = new List(); + // 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(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(meshPath); + string name = fbx.name.ToLower(); + if (name.EndsWith("_bandpose")) + { + name = name.Replace("_bandpose", ""); + } + GameObject go = GameObject.Instantiate(fbx) as GameObject; + List renderLst = ListPool.Get(); + go.GetComponentsInChildren(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(); + srcMesh = mf.sharedMesh; + } + } + if (srcMesh != null) + { + Mesh findMesh = CompareMesh(srcMesh, mesh, dir, name, i); + if (findMesh != null) + { + newMesh = findMesh; + break; + } + } + } + ListPool.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(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(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(); + + List renderLst = ListPool.Get(); + prefab.GetComponentsInChildren(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(); + if (mf != null) + mesh = mf.sharedMesh; + } + else if (render is ParticleSystemRenderer) + { + psr = render as ParticleSystemRenderer; + + ParticleSystem ps = render.GetComponent(); + 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(); + 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.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(); + if (box != null && ator != null) + { + Rigidbody rb = prefab.GetComponent(); + if (rb == null) + { + errorLog += "Rigidbody没有优化\r\n"; + if (needFix) + { + rb = prefab.AddComponent(); + 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(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(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(@"Table/PetInfo"); + TextAsset ta1 = Resources.Load(@"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(path); + if (go != null) + { + bool change = false; + List renderLst = ListPool.Get(); + GameObject mount = GameObject.Instantiate(go); + mount.GetComponentsInChildren(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.Release(renderLst); + if (change) + PrefabUtility.ReplacePrefab(mount, go, ReplacePrefabOptions.ReplaceNameBased); + GameObject.DestroyImmediate(mount); + } + } + } + } + + } + + private static void AddCCPrefab(BuffTable buff, XEntityStatistics entityStatistics, XEntityPresentation entityPresentation, HashSet 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(@"Table/BuffList"); + TextAsset ta1 = Resources.Load(@"Table/BuffListPVP"); + TextAsset ta2 = Resources.Load(@"Table/XEntityStatistics"); + TextAsset ta3 = Resources.Load(@"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 transformPrefab = new HashSet(); + 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(path); + if (prefab.name.StartsWith("Mount_")) + { + CharacterController cc = prefab.GetComponent(); + 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(); + 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, 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(targetTexPath); + Texture2D alphaTex = null; + if (mat.renderQueue > 2000) + { + alphaTex = ConvertTexRtex(mainTex); + } + DefaultCompressTex(AssetDatabase.LoadAssetAtPath(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, weaponMeshPath); + + GameObject weaponGo = new GameObject(mesh.name); + SkinnedMeshRenderer newSmr = weaponGo.AddComponent(); + 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 usedTex = new Dictionary(); + + 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 smrList = ListPool.Get(); + go.GetComponentsInChildren(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.Release(smrList); + modelImporter.isReadable = false; + AssetDatabase.ImportAsset(path, ImportAssetOptions.ForceUpdate); + List meshList = ListPool.Get(); + go.GetComponentsInChildren(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(); + 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, 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.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(); + if (s_meshPartLis.replaceMeshPartsInfo == null) + s_meshPartLis.replaceMeshPartsInfo = new Dictionary(); + if (s_meshPartLis.replaceTexPartsInfo == null) + s_meshPartLis.replaceTexPartsInfo = new Dictionary(); + + } + [MenuItem(@"Assets/Tool/Equipment/SaveSkinAsset %3", false, 0)] + private static void SaveSkinAsset() + { + s_CombineConfig = CombineConfig.GetConfig(); + LoadMeshPartInfo(); + enumFbx.cb = _SaveSkinAsset; + EnumAsset(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(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 smrList = ListPool.Get(); + go.GetComponentsInChildren(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.Release(smrList); + GameObject.DestroyImmediate(go); + } + private static void _RefreshExtraConfig(GameObject fbx, string path) + { + GameObject go = GameObject.Instantiate(fbx) as GameObject; + ReplaceEquip re = go.GetComponent(); + 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(); + s_meshPartLis.replaceMeshPartsInfo = new Dictionary(); + s_meshPartLis.replaceTexPartsInfo = new Dictionary(); + + List meshParts = new List(); + 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(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(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(@"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(@"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); + newMesh.name = "CombineMesh"; + newMesh.Clear(true); + CreateOrReplaceAsset(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 renderLst = ListPool.Get(); + go.GetComponentsInChildren(true, renderLst); + foreach (Renderer r in renderLst) + { + ProcessRender(r); + } + ListPool.Release(renderLst); + Animator animator = go.GetComponent(); + 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(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 stringTable = new List(); + Dictionary stringHash = new Dictionary(); + 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 animators = new List(); + newGo.GetComponentsInChildren(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(); + if (animaton == null) + animaton = animGo.AddComponent(); + 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(enumPrefab, "ConvertAnimator2Legacy"); + } + + public static void GetAssetPath(string dir, List 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(); + 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(); + 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 assetPath = ListPool.Get(); + + Dictionary> shareAnimFx = new Dictionary>(); + //Dictionary> missAimFx = new Dictionary>(); + 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(prefab); + Transform clipTrans = null; + AnimationClip clip = null; + FindAnimClip(instance, ref clipTrans, ref clip); + if (clip != null && clipTrans != null) + { + string animPath = AssetDatabase.GetAssetPath(clip); + List fxList = null; + if (!shareAnimFx.TryGetValue(animPath, out fxList)) + { + fxList = new List(); + 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(prefab); + Transform clipTrans = null; + AnimationClip clip = null; + string animPath = ""; + List missAnim = null; + List 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(); + } + 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 renderLst = ListPool.Get(); + instance.GetComponentsInChildren(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(); + } + ari.go = render.gameObject; + ari.missingType = 1; + missAnim.Add(ari); + } + } + } + } + ListPool.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(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.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 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("查找资源", 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 Child = new List(); + } + + 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 exposedBones = new List(); + protected List exExposedBones = new List(); + 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 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.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(); + //MeshRenderer mesh = t.GetComponent(); + 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 components) + { + SkinnedMeshRenderer comp = t.GetComponent(); + 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 components) + { + MeshRenderer comp = t.GetComponent(); + 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(GameObject srcGO, GameObject destGO) where T : Component + { + T srcCC = srcGO.GetComponent(); + if (srcCC == null) + return false; + + T destCC = destGO.GetComponent(); + if (destCC == null) + destCC = destGO.AddComponent(); + + 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 srcSkins = new List(); + List srcMeshs = new List(); + + + 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 skins = new List(); + FindComponentSkinnedMesh(newGo.transform, skins); + foreach (SkinnedMeshRenderer skin in skins) + { + AssetModify.ProcessSkinMesh(skin); + } + List meshs = new List(); + FindComponentMesh(newGo.transform, meshs); + foreach (MeshRenderer mesh in meshs) + { + AssetModify.ProcessRender(mesh); + } + Animator srcAni = null; + if (srcPrefab != null) + { + CopyValue(srcPrefab, newGo); + if (CopyValue(srcPrefab, newGo)) + { + CopyValue(srcPrefab, newGo); + } + SetLayer(newGo.transform, srcPrefab.layer); + srcAni = srcPrefab.GetComponent(); + 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(); + 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(@"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() != null || + child.GetComponent() != null) + { + GameObject.DestroyImmediate(child.gameObject); + } + } + + SkinnedMeshRenderer smr = newGo.GetComponent(); + if (smr == null) + smr = newGo.AddComponent(); + 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 textures = new List(); + private List sprite = new List(); + private List texs = new List(); + //private List texs = new List(); + public void ScanGameObject() + { + textures.Clear(); + GameObject go = Selection.activeGameObject; + if (go != null) + { + sprite.Clear(); + go.GetComponentsInChildren(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(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(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(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 meshParts = new List(); + // protected List meshList = new List(); + // 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 equipSuitList = new List(); + private List[] 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 ciList = new List(); + 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("Assets/Resources/Equipments/" + location + ".prefab"); + if (weapon != null) + { + GameObject go = GameObject.Instantiate(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(meshResPath); + Texture2D tex = null; + + if (File.Exists(texResPath)) + { + tex = AssetDatabase.LoadAssetAtPath(texResPath); + } + else + { + texResPath = texResPath.Replace("_a", "") + ".tga"; + tex = AssetDatabase.LoadAssetAtPath(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(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(skinPrfab); + roleGO = GameObject.Instantiate(prefab); + roleGO.name = prefab.name; + CharacterController cc = roleGO.GetComponent(); + if (cc != null) + { + cc.enabled = false; + } + roleGO.transform.position = new Vector3(x, y, z); + + Animator ator = roleGO.GetComponent(); + AnimatorOverrideController aoc = new AnimatorOverrideController(); + aoc.runtimeAnimatorController = ator.runtimeAnimatorController; + ator.runtimeAnimatorController = aoc; + aoc["Idle"] = Resources.Load(anim); + roleData.role = roleGO; + } + else + { + roleGO = roleData.role; + } + + roleSmr = roleGO.GetComponent(); + 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(@"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[professionCount]; + for (int i = 0; i < professionCount; ++i) + { + declList[i] = new List(); + 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 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(roleData.role); + SkinnedMeshRenderer smr = newGo.GetComponent(); + if (smr != null && smr.sharedMesh != null) + { + Mesh mesh = UnityEngine.Object.Instantiate(smr.sharedMesh); + mesh.name = meshName; + Material mat = UnityEngine.Object.Instantiate(smr.sharedMaterial); + mat.name = meshName; + string folderName = combineConfig.SkillFolderName[m_professionIndex]; + AssetModify.CreateOrReplaceAsset(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, 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 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 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 scriptList = new List(); + // 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.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.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 Fields = new List(); + } + public class TableInfo + { + public List tables = new List(); + } + 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 tableData = new List(); + 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 findLine = new List(); + + 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)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 prefabs = new List(); + // // public string Name + // // { + // // get + // // { + // // return mat != null ? mat.name : ""; + // // } + // // } + // //} + // //private Dictionary> m_Shaders = new Dictionary>(); + // //private List 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 matSort = new NameSort(); + // //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 matPrefabs = null; + // // if (!m_Shaders.TryGetValue(shader, out matPrefabs)) + // // { + // // matPrefabs = new List(); + // // 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 renders = new List(); + + // // 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(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 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 results = new List(); + // // 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 : IComparer 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 m_MatPrefabSort = new NameSort(); + 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 mfList = new List(); + List smrList = new List(); + List renderList = new List(); + List uiTextureList = new List(); + 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 prefabs = new List(); + public string Name + { + get + { + return mat != null ? mat.name : ""; + } + } + } + private Dictionary m_MatPrefabList = new Dictionary(); + + private Vector2 m_MatScrollPos = Vector2.zero; + private Vector2 m_PrefabScrollPos = Vector2.zero; + private List m_SelectMatPrefabs = null; + private List m_FindMaterial = new List(); + private MatPrefab m_SelectMatPrefab = null; + private void OnEnable() + { + Init(); + } + #region Shader + + private Dictionary> m_Shaders = new Dictionary>(); + 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 = new List(); + 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 texList = new List(); + 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 m_TexFormatAndroidList = new List(); + private List m_TexFormatiPhoneList = new List(); + private List m_TexSizeAndroidList = new List(); + private List m_TexSizeiPhoneList = new List(); + + private Dictionary m_TexTexInfoMap = new Dictionary(); + 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 m_TexFindCache = new List(); + private NameSort m_TexSort = new NameSort(); + private SizeSort m_TexListSort = new SizeSort(); + #endregion + #region Mesh + public enum EMeshInfoCategory + { + Vertex = 0, + UV2, + Optimize, + Readable, + OptimizeGameObject, + Fbx, + Normal, + Tangents, + } + + + private class MeshInfo : ISizeCompare + { + public List PrefabList = new List(); + 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 : IComparer 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 MeshList = new List(); + public bool sorted = false; + public void Clear() + { + MeshList.Clear(); + sorted = false; + } + } + private EMeshInfoCategory m_MeshInfoCategory = EMeshInfoCategory.Vertex; + private List m_MeshSizeList = new List(); + 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 m_SizeSort = new SizeSort(); + 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 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(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 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 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(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(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(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(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(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(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 mpList = null; + if (!m_Shaders.TryGetValue(shader, out mpList)) + { + mpList = new List(); + 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(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(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", true); + // window.position = new Rect(100, 100, 1200, 800); + //} + private void ExportTerrainBlendTex(TerrainData td, List 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 vertex = new List(); + List index = new List(); + List uv = new List(); + //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(terrainMesh, terrainMehsPath); + List texs = new List(); + 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(); + 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(); + } +} +#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(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(); + 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(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("Assets/Editor/EditorRes/Render2Tex.prefab"); + if(prefab!=null) + { + GameObject render2Tex = GameObject.Instantiate(prefab); + Render2Texture r2t = render2Tex.GetComponent(); + 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("Assets/Editor/EditorRes/Render2Tex.prefab"); + if (prefab != null) + { + GameObject render2Tex = GameObject.Instantiate(prefab); + Render2Texture r2t = render2Tex.GetComponent(); + 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 smrList = new List(); + static List mfList = new List(); + static List rpList = new List(); + 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(fbx); + rpList.Clear(); + smrList.Clear(); + fbxIns.GetComponentsInChildren(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(targetTexPath); + } + rpList.Add(rp); + } + smrList.Clear(); + mfList.Clear(); + fbxIns.GetComponentsInChildren(mfList); + foreach (MeshFilter mf in mfList) + { + ReplacePair rp = new ReplacePair(); + rp.srcMeshName = mf.name; + rp.replaceEquipName = AssetModify.MakeWeaponName(profession); + MeshRenderer mr = mf.GetComponent(); + 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(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(); + } + else if (path.EndsWith(".fbx")) + { + replaceEquip = new GameObject(obj.name); + re = replaceEquip.AddComponent(); + 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(srcWeaponPrefab); + if (srcWeapon != null) + { + + Renderer render = srcWeapon.GetComponent(); + if (render != null) + { + GameObject targetWeapon = GameObject.Instantiate(srcWeapon); + Renderer targetRender = targetWeapon.GetComponent(); + 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(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(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(); + } + 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(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 +{ + 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; + public List 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.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 BehaviorCache = new Dictionary(); + + public bool Deprecated + { + get; + set; + } + + void Awake() + { + _behavior_tree = gameObject.AddComponent(); + } + 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 castingSkills = _behavior_tree.FindTasks(); + + //for (int i = 0; i < castingSkills.Count; i++) + // castingSkills[i].IsCastingSkill = true; + + //List trySkills = _behavior_tree.FindTasks(); + //for (int i = 0; i < trySkills.Count; i++) + // trySkills[i].CastSkillId = skillid; + } + + public void OnEndSkill(uint skillid) + { + //List castingSkills = _behavior_tree.FindTasks(); + + //for (int i = 0; i < castingSkills.Count; i++) + // castingSkills[i].IsCastingSkill = false; + } + + public void OnSkillHurt() + { + //List isCasting = _behavior_tree.FindTasks(); + + //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(); + + } + + 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(); + + AnimatorOverrideController overrideController = new AnimatorOverrideController(); + + overrideController.runtimeAnimatorController = _ator.runtimeAnimatorController; + _ator.runtimeAnimatorController = overrideController; + + overrideController["Idle"] = XResourceLoaderMgr.singleton.GetSharedResource(clip, ".anim"); + + _shadow = _actor.transform.Find("Shadow"); + if (_shadow != null) _shadow.GetComponent().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(); + DisablePhysic(); + if (_ator != null) + { + AnimatorOverrideController overrideController = new AnimatorOverrideController(); + + overrideController.runtimeAnimatorController = _ator.runtimeAnimatorController; + _ator.runtimeAnimatorController = overrideController; + + overrideController["Idle"] = XResourceLoaderMgr.singleton.GetSharedResource(clip, ".anim"); + + _shadow = _actor.transform.Find("Shadow"); + if (_shadow != null) _shadow.GetComponent().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(); + DisablePhysic(); + AnimatorOverrideController overrideController = new AnimatorOverrideController(); + + overrideController.runtimeAnimatorController = _ator.runtimeAnimatorController; + _ator.runtimeAnimatorController = overrideController; + + overrideController["Idle"] = XResourceLoaderMgr.singleton.GetSharedResource(clip, ".anim"); + + _shadow = _actor.transform.Find("Shadow"); + if (_shadow != null) _shadow.GetComponent().enabled = true; + + _ator.cullingMode = AnimatorCullingMode.AlwaysAnimate; + } + private void DisablePhysic() + { + if (_actor != null) + { + CharacterController cc = _actor.GetComponent(); + 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(); + + return _audio_action; + } + case AudioChannel.Motion: + { + if (_audio_motion == null) + _audio_motion = _actor.AddComponent(); + + return _audio_motion; + } + case AudioChannel.Skill: + { + if (_audio_skill == null) + _audio_skill = _actor.AddComponent(); + + 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(); + _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(); + + _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(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(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 +{ + 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(); + rt.scalingStyle = UIRoot.Scaling.FixedSize; + rt.manualHeight = 1148; + + m_Text = _objUI.transform.Find("_canvas/DownBG/Text").GetComponent(); + + m_Name = _objUI.transform.Find("_canvas/Intro/Name").GetComponent(); + m_IntroTween = _objUI.transform.Find("_canvas/Intro").GetComponent(); + + 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 _actors = new List(); + + 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(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(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(clip.Clip); + //AudioSource source = _actors[clip.BindIdx].GetAudioSourceByChannel(clip.Channel); + + XFmod fmod = _actors[clip.BindIdx].Actor.GetComponent(); + if(fmod == null) + fmod = _actors[clip.BindIdx].Actor.AddComponent(); + + 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 _hurt_target = new Dictionary(); + + 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(); + + _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(); + + _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(); + + 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(); + + 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(); + + 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(); + + 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 + { + private List _bullets = new List(); + + 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 + { + 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.singleton.DeserializeData(XEditorPath.GetCfgFromSkp(pathwithname)); + GameObject prefab = XAnimationLibrary.GetDummy((uint)conf.Player); + + if (prefab == null) + { + Debug.Log("Prefab not found by id: " + conf.Player + ""); + } + + ColdBuild(prefab, conf); + + prefixPath = pathwithname.Substring(0, pathwithname.IndexOf("/SkillPackage")); + Time = File.GetLastWriteTime(pathwithname); + } + catch (Exception e) + { + Debug.Log("Error occurred during loading config file: " + pathwithname + " with error " + e.Message + ""); + } + } + + 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.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.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.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().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().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().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(); + + CharacterController cc = hoster.GetComponent(); + if (cc != null) cc.enabled = false; + + UnityEngine.AI.NavMeshAgent agent = hoster.GetComponent(); + if (agent != null) agent.enabled = false; + + XSkillHoster component = hoster.GetComponent(); + + 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.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.singleton.DeserializeData(XEditorPath.GetCfgFromSkp(pathwithname)); + hoster.SkillData = XDataIO.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 : XSingleton> + { + 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 NameList = null; + public static List KeyList = null; + + static XQTEStatusLibrary() + { + XTableReader.ReadFile(@"Table/QteStatusList", _table); + + NameList = new List(); + KeyList = new List(); + + 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(); + // _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 Result = new List(); + [SerializeField] + public List Charge = new List(); + [SerializeField] + public List Ja = new List(); + [SerializeField] + public List Combined = new List(); + [SerializeField] + public List CameraEffect = new List(); + [SerializeField] + public XLogicalDataExtra Logical = new XLogicalDataExtra(); + [SerializeField] + public XUltraDataExtra Ultra = new XUltraDataExtra(); + [SerializeField] + public XCameraPostEffectDataExtra PostEffect = new XCameraPostEffectDataExtra(); + + public void Add(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(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 ResultEx = new List(); + [SerializeField] + public List ChargeEx = new List(); + [SerializeField] + public List Fx = new List(); + [SerializeField] + public List ManipulationEx = new List(); + [SerializeField] + public List Warning = new List(); + [SerializeField] + public List Audio = new List(); + [SerializeField] + public List Mob = new List(); + [SerializeField] + public XCameraMotionDataExtra MotionEx = new XCameraMotionDataExtra(); + [SerializeField] + public XChainCastExtra Chain = new XChainCastExtra(); + [SerializeField] + public XCameraPostEffectDataExtraEx PostEffectEx = new XCameraPostEffectDataExtraEx(); + [SerializeField] + public List JaEx = new List(); + [SerializeField] + public List HitEx = new List(); + [SerializeField] + public List CombinedEx = new List(); + + public void Add(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 QTEDataEx = new List(); + [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 + { + 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 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(); + _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(); + + _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(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(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("Animation/" + _present_data.AnimLocation + _present_data.AttackIdle, ".anim"); + _oVerrideController["HitLanding"] = _present_data.HitFly!=null&&_present_data.HitFly.Length == 0 ? null : XResourceLoaderMgr.singleton.GetSharedResource("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(); + _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(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(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(clipname, ".anim"); + _landing_time = clip.length; + } + else + { + _landing_time = 0; + } + + clipname = "Animation/" + _present_data.AnimLocation + anims[idx++]; + clip = XResourceLoaderMgr.singleton.GetSharedResource(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(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(); + foreach (ParticleSystem system in systems) + { + system.Play(); + } + } + + private void DestroyFx() + { + if (_hit_fx != null) + { + ParticleSystem[] systems = _hit_fx.GetComponentsInChildren(); + 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 _mob_unit = new List(); + + 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 _combinedToken = new List(); + private List _presentToken = new List(); + private List _logicalToken = new List(); + private List _combinedlist = new List(); + + 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 sData = new XSerialized(); + [HideInInspector] + public static XSerialized sEditorData = new XSerialized(); + [HideInInspector] + public static XSerialized sConfigData = new XSerialized(); + [HideInInspector] + public List ComboSkills = new List(); + [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(); + Component.DestroyImmediate(audiolistener); + + _camera.UnityCamera.gameObject.AddComponent(); + + Light light = _camera.UnityCamera.gameObject.AddComponent() 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() 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(); + if (_ator == null) + { + _ator = gameObject.AddComponent(); + _ator.runtimeAnimatorController = AssetDatabase.LoadAssetAtPath("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(data.ClipName, ".anim"); + _trigger = "ToArtSkill"; + } + else + { + _combinedlist.Clear(); + for (int i = 0; i < data.Combined.Count; i++) + { + XSkillData x = XResourceLoaderMgr.singleton.GetData("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().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> _hurt_target = new List>(); + 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()); + + 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[_current.Warning.Count]; + int i = 0; + foreach (XWarningData data in _current.Warning) + { + WarningPosAt[i] = new List(); 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(); + + 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() : null, + side != null ? side.GetComponent() : null, + up != null ? up.GetComponent() : 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 _fx = new List(); + protected List _outer_fx = new List(); + + public List[] 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 item = new List(); + switch (data.Type) + { + case XWarningType.Warning_All: + case XWarningType.Warning_Multiple: + { + XSkillHit[] hits = GameObject.FindObjectsOfType(); + 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(); + 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(); + + 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(); + + _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(); + + return _audio_action; + } + case AudioChannel.Motion: + { + if (_audio_motion == null) + _audio_motion = gameObject.AddComponent(); + + return _audio_motion; + } + case AudioChannel.Skill: + { + if (_audio_skill == null) + _audio_skill = gameObject.AddComponent(); + + return _audio_skill; + } + case AudioChannel.Behit: + { + if (_audio_behit == null) + _audio_behit = gameObject.AddComponent(); + + 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(); + + 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(); + _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 _item = new Dictionary(); + public Dictionary 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(); + + 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 + { + 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: -- cgit v1.1-26-g67d0