unity-game-engineinspector

Unity Custom Editor Like 'Layer Collision Matrix'


I'm trying to show a two-dimensional array in the editor like the "Layer Collision Matrix" is shown in Unity: enter image description here

Though instead of checkboxes I need ints, and a full grid (not the triangle shape.) I can't seem to figure out how to do this though... I can get a custom editor, though making the grid fails. So, is there any way I can see the code of the Physics Manager's editor (the Layer Collision Matrix is in there) or maybe someone knows a good way to do this?

Note: Preferred language is c#, though any will do.

Thanks.


Solution

  • The code involved in what you're looking for is pretty complex, so I'm going to rely on you to know what I'm talking about here. The Unity docs are your friend.

    1. Create a GUIArea where your special editor tool will be. Inside it, place a function call that will then call the other rendering functions. I suspect you'll want to do some encapsulation here. Encapsulating the gui in another function will allow you to duplicate its functionality (within the limits of your abstraction) and move things around on screen more easily.

    2. Design three anchor points (Vector2). They should each represent the top-left coord of your row labels, column labels, and data field. Note that the columns anchor needs to be directly above (same x-value as) the row anchor, since rotating (next step) will transform the anchor.

    3. Use GUIUtility.RotateAroundPivot() to rotate the GUI transform matrix by 90° around the column anchor point.

    4. Write a long GUI.Label (or several of them) for your labels. Anchor them at the column anchor. Per the image above, your label string could read something like "Default\nTransparentFX\nIgnoreRaycast\nWater" where the \n creates a newline.

    5. Rotate again, -90° back to the original matrix. Alternatively, you can copy GUI.matrix prior to step 3, then assign it back for a guaranteed matrix reset. Rotating back and forth may have some error due to floating-point and other imprecision.

    6. Write labels for the rows. Same method as two steps back. Anchor them at the row anchor.

    7. This is the harder part. Iterate through your data field, creating a small EditorGUI.IntField() or StringField() or even ObjectField() for each element in your data. Each element will need its own anchor, which is then summed with the data field anchor. If your data field is a square 2D array, deriving the anchors will be easy – though you'll also have empty elements in your array (if you want the exact functionality described above). If you want to conserve memory, you'll have to transform the element indexes into coordinates using some tricky math. I'm not sure off the top of my head how I'd do it.

    Hope I'm not forgetting anything. Unity's GUI is a b----. Comment and I'll do my best to help you.