Search Unity

What transforms are in effect in OnSceneGUI for DrawMeshNow?

Discussion in 'Immediate Mode GUI (IMGUI)' started by Alex_May, Oct 28, 2020.

  1. Alex_May

    Alex_May

    Joined:
    Dec 29, 2013
    Posts:
    198
    I'm trying to draw buttons in the scene view and in-scene stuff for a level editor. I have a level editor that's a monobehaviour and I'm doing my drawing in OnSceneGUI. I'm totally happy to do it somewhere else with the editor as a different kind of object if that's how it should be done! But I don't know what that way is so I'm doing it this way right now.

    I have a bunch of meshes, let's say 5 meshes, and I want to draw a button for each mesh and then draw the mesh on the button. The AssetPreview.GetAssetPreview function is nice, but it is rendering my objects out as black silhouettes so I want to use DrawMeshNow with a material to draw them properly. I also want to draw the currently selected mesh (whatever button was clicked last) at the mouse pointer in the scene view after drawing a collision ray into the screen.

    Here's my current OnSceneGUI, which I've boiled down to remove some of the stuff that isn't relevant...

    Code (CSharp):
    1.  
    2.     private void OnSceneGUI()
    3.     {
    4.         Handles.BeginGUI();
    5.  
    6.         int y = 60;
    7.         int size = 100;
    8.         int scrollBarWidth = 24;
    9.         int fieldHeight = (int)SceneView.lastActiveSceneView.position.height - y - 40;
    10.         Vector2 scrol = GUI.BeginScrollView(new Rect(10, y, size + scrollBarWidth, fieldHeight), new Vector2(0, scroll), new Rect(0, 0, size, size * available.Count));
    11.         scroll = scrol.y;
    12.         int localY = 0;
    13.         int xGutter = 10;
    14.         foreach (var collectable in available)
    15.         {
    16.             if (localY > scroll- size && localY < fieldHeight + scroll + size)
    17.             {
    18.                 if (GUI.Button(new Rect(xGutter, localY, size, size), AssetPreview.GetAssetPreview(collectable.prefab)))
    19.                 {
    20.                     selected = collectable;                  
    21.                 }
    22.  
    23.                 Mesh mesh = collectable.prefab.GetComponent<MeshFilter>().sharedMesh;
    24.                 collectable.prefab.GetComponent<MeshRenderer>().sharedMaterial.SetPass(0);
    25.                 Bounds bounds = mesh.bounds;
    26.                 Matrix4x4 matrix =
    27.                 //Camera.current.worldToCameraMatrix;
    28.                 //Matrix4x4.TRS(new Vector3(xGutter + size/2, localY + scroll + size/2, 0), Quaternion.identity, Vector3.one * 100 / mesh.bounds.size.magnitude);
    29.                 //Matrix4x4.TRS(new Vector3(xGutter + size/2, localY + scroll + size/2, 0), Quaternion.identity, Vector3.one * 100 / mesh.bounds.size.magnitude);
    30.                 //Matrix4x4.Ortho(-bounds.extents.x,bounds.extents.x,-bounds.extents.y,bounds.extents.y,-bounds.extents.z,bounds.extents.z);
    31.                 //GUI.matrix;
    32.                 //matrix *= Camera.current.worldToCameraMatrix.inverse;
    33.                 Camera.current.worldToCameraMatrix.inverse;
    34.                 matrix *= GUI.matrix.inverse;
    35.                 matrix *= Matrix4x4.Ortho(-10,10,-10,10,-10,10);
    36.                 matrix *= Matrix4x4.TRS(new Vector3(xGutter + size/2, localY + scroll + size/2, 0), Quaternion.identity, Vector3.one * 100 / mesh.bounds.size.magnitude);
    37.                 matrix *= Matrix4x4.Scale(Vector3.one * 10);
    38.                 Graphics.DrawMeshNow(mesh, matrix);
    39.             }
    40.             localY += size;
    41.         }
    42.         GUI.EndScrollView();
    43.  
    44.         Handles.EndGUI();
    45.     }
    46.  
    47.  
    That's just for the buttons, I'm happy to just sort the buttons first. I got the current camera's inverse matrix idea from @Nothke and that's really good, it gets rid of the scene view camera's rotation, but there still seems to be a GUI matrix involved. When I scroll my scroll view the meshes I'm drawing move with it. Setting the GUI matrix to identity does nothing. Multiplying with inverse of gui matrix doesn't seem to work either. Same with the handles matrix and the GL matrix. What matrices are left to destroy?? How can I control the rendering at this particular time?
     
  2. Alex_May

    Alex_May

    Joined:
    Dec 29, 2013
    Posts:
    198
    please help me matrix this my family is dying
     
  3. kaarrrllll

    kaarrrllll

    Unity Technologies

    Joined:
    Aug 24, 2017
    Posts:
    552
  4. Alex_May

    Alex_May

    Joined:
    Dec 29, 2013
    Posts:
    198
    OK thanks Karl! That would take care of the buttons. I actually started on a similar plan - allocate a temporary rendertexture and render the object out to that. But again, the matrix was interfering with my drawing.
    It would be useful to be able to render it real time as I would like ideally to be able to change the asset's material and have that reflected in the button.

    For rendering the object in the scene, I was going to avoid OnSceneGUI and just have a dummy gameobject and change the mesh in the object's meshfilter to the currently selected asset's mesh, assign a semi transparent material and move the object to a mouse cursor raycast's hitpoint. I could still draw the handles in OnSceneGUI.
     
  5. Alex_May

    Alex_May

    Joined:
    Dec 29, 2013
    Posts:
    198
    Okay, I am using an Odin editor window for this now, and using a dummy GameObject to draw the potential object in the scene view.

    The lesson to learn from this is do not try to draw things in the scene view imo.