using System.Collections.Generic; using System.IO; using UnityEditor; using UnityEngine; using UnityEngine.AI; 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 &%#q", 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 &%#w", 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/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, ObstacleAvoidanceType.LowQualityObstacleAvoidance, 0, "Actor"); //} } [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, ObstacleAvoidanceType.NoObstacleAvoidance, 99, "Actor"); //} } [MenuItem("Edit/PCSetting", false, -1003)] static void PCSetting() { //var selectedObjects = Selection.gameObjects; //foreach (var go in selectedObjects) //{ // // 프리팹 에셋 경로 가져오기 // string prefabPath = PrefabUtility.GetPrefabAssetPathOfNearestInstanceRoot(go); // // Prefab인지 확인 // if (!string.IsNullOrEmpty(prefabPath)) // { // // Prefab Asset 가져오기 // var prefabAsset = PrefabUtility.LoadPrefabContents(prefabPath); // var ma = prefabAsset.GetComponent(); // if (ma == null) ma = prefabAsset.AddComponent(); // ma.m_Role = eRole.PC; // var navmesh = prefabAsset.GetComponent(); // if (navmesh == null) navmesh = prefabAsset.AddComponent(); // navmesh.speed = 6f; // navmesh.angularSpeed = 300f; // navmesh.acceleration = 140f; // navmesh.stoppingDistance = 4f; // navmesh.autoBraking = true; // navmesh.radius = 0.4f; // navmesh.height = 2f; // navmesh.avoidancePriority = 50; // navmesh.obstacleAvoidanceType = ObstacleAvoidanceType.LowQualityObstacleAvoidance; // Set_CommonRigidBody(prefabAsset, "Actor"); // var cc = prefabAsset.GetComponent(); // if (cc == null) cc = prefabAsset.AddComponent(); // cc.center = Vector3.up * 0.79f; // cc.radius = 0.55f; // cc.height = 1.58f; // cc.direction = 1; // var pcactor = prefabAsset.GetComponent(); // List list_tr = new List(); // // 프리팹 내부 수정 // var wristL = FindDeepChild(prefabAsset.transform, "Wrist_L"); // var wristR = FindDeepChild(prefabAsset.transform, "Wrist_R"); // if (wristL != null) // { // var strName = "w_shield"; // var shield = FindDeepChild(prefabAsset.transform, strName); // if (shield == null) shield = new GameObject(strName).transform; // shield.parent = wristL; // shield.localPosition = new Vector3(0.0184f, -0.0158f, 0.0261f); // shield.localEulerAngles = new Vector3(-21.84897f, 162.9937f, -171.4406f); // shield.localScale = Vector3.one * 0.6f; // list_tr.Add(shield); // } // if (wristR != null) // { // var strName = "w_righthand"; // var mace = FindDeepChild(prefabAsset.transform, strName); // if (mace == null) mace = new GameObject(strName).transform; // mace.parent = wristR; // mace.localPosition = new Vector3(-0.0749f, 0.1431f, -0.024f); // mace.localEulerAngles = new Vector3(0, 0, 10.6f); // mace.localScale = new Vector3(1f, 0.7f, 1f); // list_tr.Add(mace); // } // if (wristR != null) // { // var strName = "w_onehand"; // var onehand = FindDeepChild(prefabAsset.transform, strName); // if (onehand == null) onehand = new GameObject(strName).transform; // onehand.parent = wristR; // onehand.localPosition = new Vector3(-0.0546f, -0.001f, -0.0271f); // onehand.localEulerAngles = new Vector3(0f, 107.83f, 0f); // onehand.localScale = Vector3.one * 0.8f; // list_tr.Add(onehand); // } // if (wristL != null) // { // var strName = "w_bladedancer_l"; // var bd_l = FindDeepChild(prefabAsset.transform, strName); // if (bd_l == null) bd_l = new GameObject(strName).transform; // bd_l.parent = wristL; // bd_l.localPosition = new Vector3(0.0413f, 0.015f, 0.0255f); // bd_l.localEulerAngles = new Vector3(6.747354f, -168.0254f, 157.2563f); // bd_l.localScale = Vector3.one; // list_tr.Add(bd_l); // } // if (wristR != null) // { // var strName = "w_bladedancer_r"; // var bd_r = FindDeepChild(prefabAsset.transform, strName); // if (bd_r == null) bd_r = new GameObject(strName).transform; // bd_r.parent = wristR; // bd_r.localPosition = new Vector3(-0.0546f, -0.001f, -0.0271f); // bd_r.localEulerAngles = new Vector3(0f, 107.83f, 0f); // bd_r.localScale = Vector3.one * 0.8f; // list_tr.Add(bd_r); // } // if (wristR != null) // { // var strName = "w_orb"; // var bd_r = FindDeepChild(prefabAsset.transform, strName); // if (bd_r == null) bd_r = new GameObject(strName).transform; // bd_r.parent = wristR; // bd_r.localPosition = new Vector3(-0.05439695f, -0.00136376f, -0.02748983f); // bd_r.localEulerAngles = new Vector3(-1.791351f, 107.4387f, 1.349683f); // bd_r.localScale = Vector3.one * 0.1f; // list_tr.Add(bd_r); // } // if (wristL != null) // { // var strName = "w_archer_l"; // var bow_l = FindDeepChild(prefabAsset.transform, strName); // if (bow_l == null) bow_l = new GameObject(strName).transform; // bow_l.parent = wristL; // bow_l.localPosition = new Vector3(0.069f, -0.01f, 0.034f); // bow_l.localEulerAngles = new Vector3(-2.139496f, 0f, -3.480011f); // bow_l.localScale = Vector3.one * 1.3f; // list_tr.Add(bow_l); // } // pcactor.tfs_weapon = list_tr.ToArray(); // // 수정한 프리팹 저장 // PrefabUtility.SaveAsPrefabAsset(prefabAsset, prefabPath); // PrefabUtility.UnloadPrefabContents(prefabAsset); // } // else // { // Debug.LogError($"{go.name}은(는) 프리팹 인스턴스가 아닙니다!"); // } //} } static Transform FindDeepChild(Transform parent, string name) { foreach (Transform child in parent) { if (child.name == name) return child; var result = FindDeepChild(child, name); if (result != null) return result; } return null; } static void CommonSetting(GameObject go, ObstacleAvoidanceType avoid, int avoidancePriority, string layer) { Set_Collideer(go); 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.avoidancePriority = avoidancePriority; navmesh.obstacleAvoidanceType = avoid; Set_CommonRigidBody(go, layer); } static void Set_CommonRigidBody(GameObject go, string layer) { go.layer = LayerMask.NameToLayer(layer); var rigidbody = go.GetComponent(); if (rigidbody == null) rigidbody = go.AddComponent(); rigidbody.useGravity = false; rigidbody.mass = 1; rigidbody.linearDamping = 0; rigidbody.angularDamping = 0.05f; rigidbody.automaticCenterOfMass = true; rigidbody.automaticInertiaTensor = true; rigidbody.collisionDetectionMode = CollisionDetectionMode.Discrete; rigidbody.constraints = RigidbodyConstraints.FreezeAll; } 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 + Vector3.up; settings.m_smr.updateWhenOffscreen = false; settings.go.transform.localScale = settings.m_Scale; objectSettingsList.RemoveAt(i); } else { settings.tick--; } } if (objectSettingsList.Count == 0) { EditorApplication.update -= UpdateAllObjects; } } private class ObjectSettings { public GameObject go; public Vector3 m_Scale; public BoxCollider m_bc; public SkinnedMeshRenderer m_smr; public int tick; } [MenuItem("Edit/SetCollider", false, -2000)] static void SetCollider() { foreach (var go in Selection.gameObjects) Set_Collideer(go); } static void Set_Collideer(GameObject go) { var objData = new ObjectSettings { go = go, m_Scale = go.transform.localScale, tick = 10 }; go.transform.localScale = Vector3.one; var m_bc = go.GetComponent(); if (m_bc == null) m_bc = go.AddComponent(); objData.m_bc = m_bc; 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; objData.m_smr = m_smr; objectSettingsList.Add(objData); EditorApplication.update += UpdateAllObjects; } [MenuItem("Tools/Del_AddrResource")] static void Del_AddrResource() { bool result = EditorUtility.DisplayDialog( "경고!", // 제목 "모든 어드레서블 데이터를 삭제하시겠습니까?", // 메시지 "확인", // 확인 버튼 "취소" // 취소 버튼 ); if (result) { Caching.ClearCache(); EditorUtility.DisplayDialog("알림", "삭제 완료", "확인"); } } [MenuItem("Tools/MobActorImageFill", false, 1)] static void MobActorImageFill() { var srs = Selection.activeGameObject.GetComponentsInChildren(); for (int i = 0; i < srs.Length; i++) { var child = srs[i]; if (child.name == "sr_actor") child.GetComponent().sprite = AssetDatabase.LoadAssetAtPath("Assets/Res_Addr/Monster/10001.png"); } } [MenuItem("Tools/MobActorImageEmpty", false, 2)] static void MobActorImageEmpty() { var srs = Selection.activeGameObject.GetComponentsInChildren(); for (int i = 0; i < srs.Length; i++) { var child = srs[i]; if (child.name == "sr_actor") child.GetComponent().sprite = null; } } //[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); //} // 자식까지 포함해서 레이어를 재귀적으로 설정하는 함수 }