11

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.

The Oddler
  • 6,314
  • 7
  • 51
  • 94

3 Answers3

7

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.

cjcurrie
  • 624
  • 1
  • 4
  • 15
  • 1
    Thanks, looks good. I didn't know about the RotateAroundPivot thing (and clearly didn't search thoroughly enough to find it.) The rest seems relatively straightforward (though, as you said, the GUI can be a little annoying a times.) Thanks! When I make it I'll post my code, though don't have time atm, so might be a while. – The Oddler Jan 09 '13 at 12:06
  • Glad it's still relevant. I noticed that the question is two months old :P – cjcurrie Jan 10 '13 at 05:56
  • 1
    Yea, currently I solved it in a less user-friendly way, but it was ok since it's just me who has to use it. – The Oddler Jan 10 '13 at 11:07
  • @TheOddler - you did not post your solution - were you able to come up with one (or at least more concrete psuedocode than the answer presented above)? – az2tonez Jul 06 '16 at 20:41
  • @az2tonez Ooh old question, but what I did (if I remember correctly) was just a super simple double for-loop, calculating the x,y position for each matrix element. Not sure anymore why it didn't work at first, seems so easy now. Is there anything specific that's not working? I used this for an old project, but the code should still be somewhere in a git repo of mine, so I could look it up if you want. – The Oddler Jul 07 '16 at 07:33
  • Thanks @TheOddler! I ended up circumventing the whole thing - I really just needed the info in the PhysicsSettings editor, so I just have a button in my inspector that sync's all the settings. – az2tonez Oct 22 '16 at 07:52
0

As I just come here from the Google... There is source code for Unity editor available here: https://github.com/Unity-Technologies/UnityCsReference/blob/master/Editor/Mono/Inspector/PhysicsManagerInspector.cs

Surprisingly it is using GUILayout.BeginScrollView with calculated height, so it is compatible with EditorGUILayout style and utilize GUI.matrix for text rotation. I will not go thought entire code (lines 40 to 95), but I recommend checking it out.

PiotrK
  • 4,210
  • 6
  • 45
  • 65
  • access is denied :( – shieldgenerator7 Dec 19 '21 at 07:18
  • @shieldgenerator7 Interesting! I searched archive.org and entire github. It looks like the code for Physics Manager Inspector was not pushed purposely and is now removed. Unfortunately I did not made any copy for that... – PiotrK Dec 21 '21 at 22:04
0

PiotrK's answer included a link to an outdated version of the Unity LayerCollisionMatrix setting. However as mentioned in the Comments the provided link is not valid anymore. I'm not able to post in the comments so I needed to post this as new answer:

The repository is still valid so I assume they restructured the repository. A new version of the Physics2D Layer Collision Matrix code can be found here:

https://github.com/Unity-Technologies/UnityCsReference/blob/master/Modules/Physics2DEditor/Managed/Settings/LayerCollisionMatrix2D.cs

Symbroson
  • 1
  • 5
  • As it’s currently written, your answer is unclear. Please [edit] to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Nov 01 '22 at 09:20