俺はEditor拡張で行く ~ゼロから便利機能を作るまで

A6ba8150ec3d9e5f2c675ef8bd652ff5?s=47 vailKAKO
October 09, 2020

俺はEditor拡張で行く ~ゼロから便利機能を作るまで

ゼロからEditor拡張をやるための足がかりになるかなと思いLTしました。

A6ba8150ec3d9e5f2c675ef8bd652ff5?s=128

vailKAKO

October 09, 2020
Tweet

Transcript

  1. Զ͸Editor֦ுͰߦ͘ θϩ͔ΒศརػೳΛ࡞Δ·Ͱ Speaker : Kako Time : about 10m

  2. ࣗݾ঺հ Ճݹ(27)……Ұࣇͷ෕ ϑϦʔϥϯεˠࠓ݄ήʔϜձࣾೖࣾ༧ఆ ࠷ۙͷϒʔϜ͸ϛχήʔϜ࡞ΓͱྉཧͷऔΓճ͠ࢥߟ

  3. ͜Μͳ͜ͱ͋Γ·͢ΑͶ???Ͷ?????? • ϓϩδΣΫτͰԿ͔͠ΒͷίϯϙʔωϯτΛ୳͍ͨ͠ • ಉ͡ܗࣜͷ΋ͷΛԿ౓΋ೖྗ͢Δ͔Βָʹ͍ͨ͠ • ඪ४ػೳͰͰ͖Δ͚Ͳɺ΋͏ͪΐͬͱ΍Γ͍ͨ͜ͱ͕͋Δ • ΤσΟλͰ࣮ߦதͰ΋อଘ͕͍ͨ͠! etc.

  4. େମEditor֦ுͰͰ͖·͢!

  5. Editor֦ுͬͯ? • ࣗ࡞ͷWindowग़ͤͨΓ͢Δ • ޷͖ͳػೳΛ݁ߏ͚ͭΒΕΔ • ௨ৗͰ͖ͳ͍͜ͱ΋Ͱ͖ΔΑ͏ʹͳͬͨΓ͢Δ • खಈͰ΍Δ͜ͱΛҰ෦ࣗಈԽͰ͖ͨΓ͢Δ

  6. ͱ͋ΔUnityΤϯδχΞ1໊(2018೥౰࣌)ͷ੠ • ฉ͍ͨ͜ͱ͋Δ͚ͲΑ͘Θ͔Μͳ͍ • ΰϦϥͳਓͨͪͷ͍ٕ͢͝ज़Ͱ͠ΐ? • ·͊खಈͰͰ͖Δ͠…… • Ͳ͏ͤීஈͱશ͘ҧ͏͜ͱΛ͢ΔΜͰ͠ΐ?

  7. ݁ߏָʹͰ͖·͢!

  8. ࣮ࡍͷྲྀΕ ᶃ C#εΫϦϓτΛ࡞Δ ᶄ ͱΓ͋͑ͣWindowΛग़͢ ᶅ ϘλϯͰͳʹ͔͢Δ ᶆ ศར!

  9. ᶄͱΓ͋͑ͣWindowΛग़͢ using UnityEditor; public class StartEditor : EditorWindow { //։͔Εํͱɺ։͔Εͨͱ͖ͷڍಈ

    [MenuItem("StartEditor/OpenDAZE")] private static void Open() { GetWindow<StartEditor>("Start editor DAZE"); } }
  10. ᶄͱΓ͋͑ͣWindowΛग़͢

  11. ᶄϘλϯͰͳʹ͔͢Δ private void OnGUI() { if (GUILayout.Button("Nanikoe?")) { Debug.Log("Shiranai!"); }

    }
  12. ᶄϘλϯͰͳʹ͔͢Δ

  13. ᶄϘλϯͰͳʹ͔͢Δ2 private void OnGUI() { if (GUILayout.Button("Nanikoe?")) { var objs

    = FindObjectsOfType<Transform>(); Debug.Log($"{objs.Length}"); foreach (var obj in objs) { Debug.Log(obj.name); } } }
  14. ᶄϘλϯͰͳʹ͔͢Δ2

  15. ศར!!!!!!!Ҏ্!!!!

  16. ศར!!!!!!!Ҏ্!!!! Ͱ΋͜ͷ··ͩͱTransform͚ͩͩ͠ ͋ͱ͔Βม͍͑ͨͳΒϋʔυίʔσΟϯά?

  17. ೖྗͰγʔϯ͔Βऔಘͯ͠ΈΔαϯϓϧ ᶃ ೖྗ૭Λ࡞Δ ᶄ ComponentࣗମΛऔಘ ᶅ ComponentΛؚΉ΋ͷΛग़͢ ᶆ ຐվ଄ͱ঺հ

  18. ᶄೖྗ૭Λ࡞Δ private string _targetComponentName; private void OnGUI() { //Editorʹ࿮Λग़ͯ͠ɺೖྗΛ_targetComponentNameʹ֨ೲ͢Δ EditorGUILayout.BeginHorizontal();

    _targetComponentName = EditorGUILayout.TextField("Target Component Name: ", _targetComponentName); EditorGUILayout.EndHorizontal(); . . .
  19. ᶄೖྗ૭Λ࡞Δ

  20. ᶄComponentࣗମΛऔಘ private static IEnumerable<Type> GetTypes() { //Unityඪ४ͷΫϥελΠϓΛऔಘ͢Δ var types =

    AppDomain.CurrentDomain.GetAssemblies() .SelectMany(asm => asm.GetTypes()) .Where(type => type != null && ! string.IsNullOrEmpty(type.Namespace)) .Where(type => type.Namespace.Contains("UnityEngine")); return types; }
  21. ᶅComponentΛؚΉ΋ͷΛग़͢ private static Dictionary<string, List<Type>> _typeDict; private static Type GetType(string

    className) { if (_typeDict == null) { // Dictionary࡞੒ _typeDict = new Dictionary<string, List<Type>>(); var components = GetTypes(); foreach (var type in components) { if (!_typeDict.ContainsKey(type.Name)) { _typeDict.Add(type.Name, new List<Type>()); } _typeDict[type.Name].Add(type); } } return _typeDict[className][0]; }
  22. ᶅComponentΛؚΉ΋ͷΛग़͢ if (GUILayout.Button("Search?")) { var objs = FindObjectsOfType(GetType(_targetComponentName) ?? null);

    Debug.Log($"{objs.Length}"); foreach (var obj in objs) { Debug.Log(obj.name); } }
  23. ׬੒……?

  24. ᩵୔ʹ!!! ᶃ ࣗ࡞Ϋϥε΋औಘͰ͖ΔΑ͏ʹ͢Δ ᶄ ॲཧΛܰ͘͢Δ ᶅ ΫϦοΫͨ͠Βࢀরݩʹඈͼ͍ͨΑͶ? ᶆ ͍ͬͦͷ͜ͱγʔϯʹͳ͍Prefab΋औಘ͠Α͏ͥ

  25. ͏͓͓͓͓͓͓͓͓͓͓͓͓͓͓͓ using System; using System.Collections.Generic; using System.Linq; using UnityEditor; using

    UnityEngine; using UnityEngine.SceneManagement; public class ReferenceFinder : EditorWindow { private string _targetComponentName; private List<GameObject> _foundAssets = new List<GameObject>(); private Vector2 _currentScrollPosition; private static IEnumerable<Type> _cashedComponents; private static Dictionary<string, List<Type>> _typeDict; static MonoScript[] _monoScripts; private static bool _isFirstTime = true; //։͔Εํͱɺ։͔Εͨͱ͖ͷڍಈ [MenuItem("ReferenceFinder/Search")] private static void Open() { //։͔ΕΔࡍʹ͸ҰԠऔಘ _cashedComponents = GetAllTypes(); GetWindow<ReferenceFinder>("Components Reference Finder."); } private void OnGUI() { EditorGUILayout.BeginHorizontal(); EditorGUILayout.LabelField("Never change Scene before reset this window"); EditorGUILayout.EndHorizontal(); EditorGUILayout.BeginHorizontal(); EditorGUILayout.LabelField("This window can search active scene objects and all prefabs"); EditorGUILayout.EndHorizontal(); //Editorʹ࿮Λग़ͯ͠ɺೖྗΛ_targetComponentNameʹ֨ೲ͢Δ EditorGUILayout.BeginHorizontal(); _targetComponentName = EditorGUILayout.TextField("Target Component Name: ", _targetComponentName); EditorGUILayout.EndHorizontal(); if (_foundAssets.Count > 0) { _currentScrollPosition = EditorGUILayout.BeginScrollView(_currentScrollPosition); foreach (var asset in _foundAssets) { EditorGUILayout.ObjectField(asset.name, asset, typeof(GameObject), false); } EditorGUILayout.EndScrollView(); } if (GUILayout.Button("Search")) { _foundAssets.Clear(); var guids = AssetDatabase.FindAssets("t:GameObject", null); foreach (var guid in guids) { string path = AssetDatabase.GUIDToAssetPath(guid); var loadAsset = AssetDatabase.LoadAssetAtPath<GameObject>(path); var typeCash = GetType(_targetComponentName) ?? null; if (typeCash == null) { Debug.Log("No Type Found."); return; } var tmp = loadAsset.GetComponentsInChildren(GetType(_targetComponentName) ?? null); foreach (var kari in tmp) { _foundAssets.Add(kari.gameObject); } } var allObj = GetObjectsInAllScene(); foreach (var obj in allObj) { var typeCash = GetType(_targetComponentName) ?? null; var tmp = obj.GetComponentsInChildren(GetType(_targetComponentName) ?? null); if (typeCash == null) { Debug.Log("No Type Found."); return; } foreach (var kari in tmp) { _foundAssets.Add(kari.gameObject);
  26. ͏͓͓͓͓͓͓(Unityͷίϯϙʔωϯτ)

  27. ͏͓͓͓͓͓͓(ࣗ࡞Ϋϥε)

  28. ׬੒ͨ͠΋ͷ͕ͪ͜ΒͰ͢(൒෼એ఻) https://www.kakovail.info/entry/2020/03/09/170855

  29. ໰୊఺ ։͍ͯͳ͍γʔϯ͸औಘͰ͖ͳ͍(γʔϯʹͳ͍Prefab͸औΕΔ) • ಡΈࠐΜͰͳ͍͔Βͳʹ΋ಡΈࠐΊͳ͍(౰વ) • SceneσʔλΛจࣈͱͯ͠GUID͔Βऔಘ͢Δ……? • Ұ౓։͘ͷ͸ͨ͘͠ͳ͍

  30. ໰୊఺ ͝ଘ஌ͷํɺώϯτԼ͍͞

  31. ͋Γ͕ͱ͏͍͟͝·ͨ͠