階層ビューを整理する

少し前まで、Unity開発者は新しいバージョン4.5を喜んでくれました(そして4.6では、すぐに新しいGUIが待っています、乾杯!)、そして、変更リストの中で、1つの項目は階層ウィンドウでのソートに関するものです。名前の」。



これはどういう意味ですか? 階層ウィンドウ内のアイテムを必要な順序で手動でドラッグできます。 また、以前に名前による自動ソートに基づいてシーンを収集した場合、ステージ上のオブジェクトのリストは混乱に変わりました。



私たちはそのままでしたが...私たちはもっとうまくやるでしょう。



この図では、下にある3つの補助オブジェクトを除き、通常の名前によるソートが表示されます。 さらに、アイコンパンツの色の違いにより、複雑なシーンをナビゲートしやすくなります。



そもそも、Unityは非常に柔軟なツールであり、必要に応じて変更したり、1,000以上の既製の変更を使用したりできると言いたいです。 これを行うには、 UnityEditor名前空間にあるタイプを使用してスクリプトを作成し、スクリプト自体を(作成後) Editorフォルダーに配置する必要があります。



まず、 BaseHierarchySortを見てみましょう。 C#でIComparableインターフェイスを使用した場合、その仕組みをすぐに理解できます。 Unityでは、 BaseHierarchySortクラスを継承し、2つのオブジェクトを比較するint Compareメソッド GameObjectGameObject)をオーバーライドするスクリプトを作成する必要があります。 最初の要素が2番目の要素の前にある場合、メソッドは-1の後に-1を返し、そうでない場合は-0を返します。



ドキュメントで既製のEditorUtility.NaturalCompare(文字列、文字列)メソッドを使用することをお勧めします。このメソッドは、2つの文字列を「人間」の方法で比較します(次の数字を次々と数えます)。 したがって、「xx11」は「xx2」の後に続きます。

私は標準の非人道的な Windowsソートに慣れているので、標準のString.Compare(string、string)メソッドを使用します。



public class CustomHierarchySorting : BaseHierarchySort { public override int Compare(GameObject lhs, GameObject rhs) { if (lhs == rhs) return 0; if (lhs == null) return -1; if (rhs == null) return 1; if (lhs.tag == "Auxiliary" && rhs.tag != "Auxiliary") return 1; if (lhs.tag != "Auxiliary" && rhs.tag == "Auxiliary") return -1; return String.Compare(lhs.name, rhs.name); } }
      
      







私の例では、ソート時に「Auxiliary」タグの付いたオブジェクトがリストの最後に表示されます。



このスクリプトがEditorフォルダーに表示されるとすぐに、Hierarchyウィンドウにボタンが表示され、並べ替えに使用するスクリプトを選択できます。





さて、私たちはいくつかの行で必要な機能をすばやく実装しました。 アイコンを使用すると、もう少し複雑になります。



急いで、いくつかのマルチカラーアイコンを描いて、それらをEditor \ Iconsフォルダに追加しました。











アイコンとさまざまな種類の並べ替えの追加は、実装のためにUnityユーザーに任され、このためのメソッドとイベントのセットを提供しました。



階層ウィンドウが更新されるたびに発生するEditorApplication.hierarchyWindowChanged()イベント、および要素が階層ウィンドウに描画されるときに呼び出されるEditorApplication.hierarchyWindowItemOnGUI(int、Rect イベントを使用します。



また、 InitializeOnLoadクラスの属性を使用します。これにより、Unityの起動時にクラスコンストラクター(これらのイベントをサブスクライブする)が自動的に呼び出されます。



 [InitializeOnLoad] public class HierarchyIcons { static readonly Texture2D Cyan; static readonly Texture2D Orange; static readonly Texture2D Yellow; static readonly Texture2D Gray; static readonly List<int> CyanMarked = new List<int>(); static readonly List<int> OrangeMarked = new List<int>(); static readonly List<int> YellowMarked = new List<int>(); static readonly List<int> GrayMarked = new List<int>(); static HierarchyIcons() { Cyan = AssetDatabase.LoadAssetAtPath("Assets/Editor/Icons/IconCyan.png", typeof(Texture2D)) as Texture2D; Orange = AssetDatabase.LoadAssetAtPath("Assets/Editor/Icons/IconOrange.png", typeof(Texture2D)) as Texture2D; Yellow = AssetDatabase.LoadAssetAtPath("Assets/Editor/Icons/IconYellow.png", typeof(Texture2D)) as Texture2D; Gray = AssetDatabase.LoadAssetAtPath("Assets/Editor/Icons/IconGray.png", typeof(Texture2D)) as Texture2D; EditorApplication.hierarchyWindowChanged += Update; EditorApplication.hierarchyWindowItemOnGUI += DrawHierarchyItemIcon; } static void Update() { CyanMarked.Clear(); OrangeMarked.Clear(); YellowMarked.Clear(); GrayMarked.Clear(); GameObject[] go = Object.FindObjectsOfType(typeof(GameObject)) as GameObject[]; foreach (GameObject g in go) { if (g == null) continue; int instanceId = g.GetInstanceID(); if (g.tag == "Player") OrangeMarked.Add(instanceId); else if (g.tag == "Interactive") CyanMarked.Add(instanceId); else if (g.tag == "Auxiliary") YellowMarked.Add(instanceId); else GrayMarked.Add(instanceId); } } static void DrawHierarchyItemIcon(int instanceId, Rect selectionRect) { Rect r = new Rect(selectionRect); rx += r.width - 25; r.width = 18; if (CyanMarked.Contains(instanceId)) GUI.Label(r, Cyan); if (OrangeMarked.Contains(instanceId)) GUI.Label(r, Orange); if (YellowMarked.Contains(instanceId)) GUI.Label(r, Yellow); if (GrayMarked.Contains(instanceId)) GUI.Label(r, Gray); } }
      
      







この例では、HierarchyViewが更新されるたびに、異なるアイコンに対応するオブジェクトのリストが再構築されます。 これらのリストをコンパイルするには、タグによる定義を使用しますが、オブジェクトのコンポーネントの検索を使用できます。 そのため、たとえば、プロパティisTrigger = trueのコライダーを持つすべてのオブジェクトにアイコンを割り当てることができます。



できた!



また、アイコンを使用したこのような操作は、特にオブジェクトのコンポーネントの検索を使用する場合、エディターでの作業中にパフォーマンスに重大な影響を与える可能性があることに注意してください。 必要に応じてアイコンのレンダリングを一時的に無効にするには、ゲームのパフォーマンスをテストします。階層ウィンドウの更新イベントにサブスクライブ/サブスクライブ解除するためのHierarchyIconsクラスの静的メソッドを追加できます。



All Articles