using System.Collections.Generic; using System.IO; using TMPro; using UnityEditor; using UnityEditor.AddressableAssets.Settings; using UnityEngine; using UnityEngine.AI; using UnityEngine.UI; public static class MyEditorUtil { struct TransformData { public Vector3 localPosition; public Quaternion localRotation; public Vector3 localScale; public TransformData(Vector3 localPosition, Quaternion localRotation, Vector3 localScale) { this.localPosition = localPosition; this.localRotation = localRotation; this.localScale = localScale; } } private static TransformData _data; [MenuItem("Edit/Copy Transform Values &c", false, -101)] public static void CopyTransformValues() { if (Selection.gameObjects.Length == 0) return; var selectionTr = Selection.gameObjects[0].transform; _data = new TransformData(selectionTr.localPosition, selectionTr.localRotation, selectionTr.localScale); } [MenuItem("Edit/Paste Transform Values &v", false, -101)] public static void PasteTransformValues() { foreach (var selection in Selection.gameObjects) { Transform selectionTr = selection.transform; Undo.RecordObject(selectionTr, "Paste Transform Values"); selectionTr.localPosition = _data.localPosition; selectionTr.localRotation = _data.localRotation; selectionTr.localScale = _data.localScale; } } [MenuItem("Edit/Del All Child", false, -102)] public static void DelAllChild() { foreach (var selection in Selection.gameObjects) { Transform selectionTr = selection.transform; for (int i = 0; i < selectionTr.childCount; i++) { GameObject.DestroyImmediate(selectionTr.GetChild(i).gameObject); --i; } } } [MenuItem("Edit/Set Mob Data", false, -103)] public static void SetMobData() { // 설정된 몹 프리팹을 지우고 몹 데이터만 남긴다. 해당 데이터로 게임 내에서 몹을 동적 로딩한다. foreach (var selection in Selection.gameObjects) { var mobs = selection.GetComponentsInChildren(); var dic_wave = new Dictionary(); for (int i = 0; i < mobs.Length; i++) { var parent = mobs[i].transform.parent; if (!dic_wave.ContainsKey(parent.name)) { var loaddata = parent.GetComponent(); if (loaddata == null) loaddata = parent.gameObject.AddComponent(); dic_wave.Add(parent.name, loaddata); } var detaildata = new LoadMobDetailData { m_Position = mobs[i].transform.position, m_Rotation = mobs[i].transform.rotation, m_Role = mobs[i].m_Role, m_SubRole = mobs[i].m_SubRole, m_MagicID = (mobs[i] as MobActor).MagicID, }; if (mobs[i].name.Contains("(")) { var split = mobs[i].name.Split(' '); detaildata.m_PrefabName = ""; if (split.Length == 2) detaildata.m_PrefabName = split[0]; else for (int j = 0; j < split.Length - 1; j++) { if (j == split.Length - 2) detaildata.m_PrefabName += split[j]; else detaildata.m_PrefabName += split[j] + " "; } } else detaildata.m_PrefabName = mobs[i].name; var witch = mobs[i] as WitchEnemyActor; if (witch != null) detaildata.list_MagicID = witch.list_MagicID; dic_wave[parent.name].list_mobdata.Add(detaildata); GameObject.DestroyImmediate(mobs[i].gameObject); } } } [MenuItem("Edit/Optimize Mesh", false, -104)] public static void OptimizeMesh() { // 메쉬 렌더러를 찾아서 최적화 한다. if (Selection.activeObject) { var meshrenderer = (Selection.activeObject as GameObject).GetComponentsInChildren(); for (int i = 0; i < meshrenderer.Length; i++) { if (meshrenderer[i].tag.Equals("Untagged")) { var om = meshrenderer[i].GetComponent(); if (om == null) om = meshrenderer[i].gameObject.AddComponent(); om.Start(); om.DecimateMesh_byPath(); om.SaveMesh("Assets/ResWork/Optimized/"); GameObject.DestroyImmediate(om); } } EditorUtility.DisplayDialog("메시 최적화", "완료", "알았다"); } } [MenuItem("Edit/GetFolderFileNames", false, -105)] public static void GetFolderFileNames() { DirectoryInfo di = new DirectoryInfo("Assets/ResWork/UIPrefabs/Title"); var ext = ".prefab"; // ".mat"; var filenames = ""; foreach (FileInfo file in di.GetFiles("*" + ext)) filenames += file.Name.Replace(ext, "") + "\n"; Debug.Log(filenames); } private static List objectSettingsList = new List(); [MenuItem("Edit/MobSetting &s", false, -1001)] static void MobSetting() { var selectedObjects = Selection.gameObjects; foreach (var go in selectedObjects) { var ma = go.GetComponent(); if (ma == null) ma = go.AddComponent(); var m_bc = go.GetComponent(); if (m_bc == null) m_bc = go.AddComponent(); CommonSetting(go, 51); } } [MenuItem("Edit/PetSetting", false, -1002)] static void PetSetting() { var selectedObjects = Selection.gameObjects; foreach (var go in selectedObjects) { var ma = go.GetComponent(); if (ma == null) ma = go.AddComponent(); ma.m_Role = eRole.Pet; CommonSetting(go, 51); } } static void CommonSetting(GameObject go, int avoidancePriority) { var m_bc = go.GetComponent(); if (m_bc == null) m_bc = go.AddComponent(); var navmesh = go.GetComponent(); if (navmesh == null) navmesh = go.AddComponent(); navmesh.speed = 4.5f; navmesh.angularSpeed = 300f; navmesh.acceleration = 140f; navmesh.stoppingDistance = 0.1f; navmesh.autoBraking = true; navmesh.radius = 0.25f; navmesh.height = 2f; navmesh.avoidancePriority = avoidancePriority; navmesh.obstacleAvoidanceType = ObstacleAvoidanceType.GoodQualityObstacleAvoidance; var rigidbody = go.GetComponent(); if (rigidbody == null) rigidbody = go.AddComponent(); rigidbody.useGravity = false; rigidbody.mass = 1; rigidbody.drag = 0; rigidbody.angularDrag = 0.05f; rigidbody.automaticCenterOfMass = true; rigidbody.automaticInertiaTensor = true; rigidbody.collisionDetectionMode = CollisionDetectionMode.Discrete; rigidbody.constraints = RigidbodyConstraints.FreezeAll; var rds = go.GetComponentsInChildren(); SkinnedMeshRenderer m_smr = null; if (rds.Length == 1) m_smr = rds[0]; else { for (int i = 0; i < rds.Length; i++) { if (rds[i].name.ToLower().Contains("skin")) { m_smr = rds[i]; break; } } if (m_smr == null) m_smr = rds[0]; } m_smr.updateWhenOffscreen = true; objectSettingsList.Add(new ObjectSettings { m_bc = m_bc, m_smr = m_smr, tick = 10 }); EditorApplication.update += UpdateAllObjects; } private static void UpdateAllObjects() { for (int i = objectSettingsList.Count - 1; i >= 0; i--) { var settings = objectSettingsList[i]; if (settings.tick < 0) { var bounds = settings.m_smr.bounds; settings.m_bc.center = bounds.center; settings.m_bc.size = bounds.size; settings.m_smr.updateWhenOffscreen = false; objectSettingsList.RemoveAt(i); } else { settings.tick--; } } if (objectSettingsList.Count == 0) { EditorApplication.update -= UpdateAllObjects; } } private class ObjectSettings { public BoxCollider m_bc; public SkinnedMeshRenderer m_smr; public int tick; } [MenuItem("Edit/FairySetting", false, -1000)] static void FairySetting() { foreach (var selectedObject in Selection.objects) { var go = selectedObject as GameObject; if (go == null) continue; var fa = go.GetComponent(); if (fa == null) fa = go.AddComponent(); var navmesh = go.GetComponent(); if (navmesh == null) navmesh = go.AddComponent(); // NavMeshAgent 설정 navmesh.speed = 3.5f; navmesh.angularSpeed = 120f; navmesh.acceleration = 1000f; navmesh.stoppingDistance = 0; navmesh.autoBraking = false; navmesh.radius = 0.05f; navmesh.height = 1f; navmesh.obstacleAvoidanceType = ObstacleAvoidanceType.NoObstacleAvoidance; navmesh.avoidancePriority = 51; } } //[MenuItem("Edit/Find All Particle", false, -103)] //public static void FindAllParticle() //{ // foreach (var selection in Selection.gameObjects) // { // var pats = selection.transform.GetComponentsInChildren(); // for (int i = 0; i < pats.Length; i++) // Debug.Log(pats[i].name); // } //} //[MenuItem("Ino/Test %g")] //static void Ino_Test() //{ // ModelImporter modelImporter = (ModelImporter)AssetImporter.GetAtPath("Assets/ResWork/Quirky Series Vol.1 [v1.3]/Arctic Vol.1/Animations/Penguin_Animations.fbx"); // for (int i = 0; i < modelImporter.clipAnimations.Length; i++) // { // switch(modelImporter.clipAnimations[i].name) // { // case "Attack": // break; // } // } //} //[MenuItem("Ino/Test")] //static void FindHUD() //{ // Debug.Log("시작"); // for (int i = 0; i < Selection.gameObjects.Length; i++) // { // var hud = Selection.gameObjects[i].transform.Find("HUD"); // if (hud == null) Debug.Log(Selection.gameObjects[i]); // } // Debug.Log("끝"); //} //[MenuItem("Ino/Bip001 to Bip002")] //static void ChangeBip01Bip02() //{ // var tf = Selection.activeGameObject.transform; // ChangeName(tf); //} // 자식까지 포함해서 레이어를 재귀적으로 설정하는 함수 static void SetLayerRecursively(GameObject obj, string newLayer = "UI") { obj.layer = LayerMask.NameToLayer(newLayer); foreach (Transform child in obj.transform) SetLayerRecursively(child.gameObject, newLayer); // 재귀 호출로 자식까지 처리 } [MenuItem("GameObject/UI/New Image &i")] // &i는 Alt + I를 의미 static void CreateUIImage() { GameObject imageObject = new GameObject("New Image", typeof(Image)); // 생성된 오브젝트에 대한 Undo 기록 추가 Undo.RegisterCreatedObjectUndo(imageObject, "New Image"); var img = imageObject.GetComponent(); img.raycastTarget = false; img.sprite = AssetDatabase.LoadAssetAtPath("Assets/ResWork/UI/NewRes/bg/whitebg.png"); if (Selection.activeGameObject != null) { imageObject.transform.SetParent(Selection.activeGameObject.transform, false); SetLayerRecursively(imageObject); // 새로 생성된 오브젝트를 선택 Selection.activeGameObject = imageObject; // 씬 뷰에서 해당 오브젝트에 포커스 맞추기 //SceneView.lastActiveSceneView.FrameSelected(); } } [MenuItem("GameObject/UI/Text Only &t")] // &t는 Alt + T를 의미 static void CreateUITextMeshPro() { GameObject textObject = new GameObject("New TMP", typeof(TextMeshProUGUI)); // 생성된 오브젝트에 대한 Undo 기록 추가 Undo.RegisterCreatedObjectUndo(textObject, "New TMP"); var tm = textObject.GetComponent(); tm.alignment = TextAlignmentOptions.Midline; if (Selection.activeGameObject != null) { textObject.transform.SetParent(Selection.activeGameObject.transform, false); SetLayerRecursively(textObject); // 새로 생성된 오브젝트를 선택 Selection.activeGameObject = textObject; // 씬 뷰에서 해당 오브젝트에 포커스 맞추기 //SceneView.lastActiveSceneView.FrameSelected(); } } [MenuItem("GameObject/UI/Text - Local &y")] static void CreateUITextMeshProWithLocal() { GameObject textObject = new GameObject("Local TMP", typeof(TextMeshProUGUI)); // 생성된 오브젝트에 대한 Undo 기록 추가 Undo.RegisterCreatedObjectUndo(textObject, "Local TMP"); textObject.AddComponent(); var tm = textObject.GetComponent(); tm.alignment = TextAlignmentOptions.Midline; if (Selection.activeGameObject != null) { textObject.transform.SetParent(Selection.activeGameObject.transform, false); SetLayerRecursively(textObject); // 새로 생성된 오브젝트를 선택 Selection.activeGameObject = textObject; // 씬 뷰에서 해당 오브젝트에 포커스 맞추기 //SceneView.lastActiveSceneView.FrameSelected(); } } [MenuItem("GameObject/UI/Button &b")] // Alt + B: Button 생성 (Image, Button, PlayClickSound_Only 추가) static void CreateUIButton() { // 버튼 오브젝트 생성 (Image, Button 컴포넌트 포함) GameObject buttonObject = new GameObject("btn_"); // 생성된 오브젝트에 대한 Undo 기록 추가 Undo.RegisterCreatedObjectUndo(buttonObject, "btn_"); buttonObject.AddComponent().sprite = AssetDatabase.LoadAssetAtPath("Assets/ResWork/UI/NewRes/bg/whitebg.png"); buttonObject.AddComponent