Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice

Writing an Editor Window that mimics the Scene View

Discussion in 'Immediate Mode GUI (IMGUI)' started by gilley033, Jan 15, 2019.

  1. NosorozecKaszle

    NosorozecKaszle

    Joined:
    Dec 3, 2019
    Posts:
    9
    @gilley033

    I had that issue with small preview area. That's why I set preview camera pixelRect and aspect in Layout pass.


    screenRect = new Rect(GUIUtility.GUIToScreenPoint(new Vector2(previewRect.x, previewRect.y)),new Vector2(previewRect.width, previewRect.height));


    looks suspicious to me. Try:

    screenRect = EditorGUIUtility.GUIToScreenRect(previewRect);
     
  2. gilley033

    gilley033

    Joined:
    Jul 10, 2012
    Posts:
    1,153
    I need this code to work on pre 2019.1 where GUIToScreenRect is not available. I looked at the source code and that methdod just calls GUIToScreenPoint internally so I don't think this is an issue.
     
  3. gilley033

    gilley033

    Joined:
    Jul 10, 2012
    Posts:
    1,153
    I went back to drawing the windows before EndAndDrawPreview is called. It's the only way I can get the handles to work correctly. I also changed how the previewRect dimensions are calculated to this:

    Code (CSharp):
    1. if(position.width < 1024)
    2.     previewRect = new Rect(0, 0, position.width + (1024 - position.width), position.height);
    3.  else
    4.     previewRect = new Rect(0, 0, position.width, position.height);
    This fixes the issue with the scene being cut off and the mouse position being off for the handles.

    I still have the issue with all my window controls being off by (I'm fairly certain) 22 pixels, due to the toolbar at the top of the screen.

    If anyone has any ideas on how to disable the toolbar I'd love to hear it. Adding an offset to Event.Current.mousePosition doesn't work for whatever reason.
     
  4. gilley033

    gilley033

    Joined:
    Jul 10, 2012
    Posts:
    1,153
    And I figured it out. I didn't think this would work as previous attempts to provide a negative value for the window position have failed, but this code works:

    Code (CSharp):
    1. if(position.width < 1024)
    2.      previewRect = new Rect(0, -22, position.width + (1024 - position.width), position.height);
    3. else
    4.      previewRect = new Rect(0, -22, position.width, position.height);
    Edit: With this change you also have to offset the mouse by 22 pixels before drawing and using the handles, like so:

    Code (CSharp):
    1. mouseOffset = new Vector2(0f, 22f);
    2. Event.current.mousePosition += mouseOffset;
    3.  
    4. Handles.SetCamera(SceneCamera);
    5. DrawHandles();
    6.  
    7. Event.current.mousePosition -= mouseOffset;
     
  5. gilley033

    gilley033

    Joined:
    Jul 10, 2012
    Posts:
    1,153
    Does anyone know the best way to go about drawing lots of meshes in the scene view created by the PreviewRenderUtility. I know there is a DrawMesh method available, but I would love to use DrawMeshInstanced instead. Unfortunatley, it is not working for me!

    Here's the code I'm trying:

    Code (CSharp):
    1.  
    2. Mesh mesh;
    3. Vector3 size = new Vector3(.9f, .9f, .9f), location = new Vector3(.5f, .5f, 10f);
    4.  
    5. void OnGUI()
    6. {
    7.     //a lot of other code
    8.     if(event == EventType.Repaint)
    9.     {
    10.         BeginPreview(previewRect);
    11.         Render();
    12.         EndAndDrawPreview(previewRect);
    13.     }
    14.     //more code . . .
    15. }
    16.  
    17. void BeginPreview(Rect pos)
    18. {
    19.     preview.BeginPreview(pos, GUIStyle.none);
    20. }
    21.  
    22. void Render()
    23. {
    24.     foreach (var light in preview.lights)
    25.         light.enabled = true;
    26.     var oldAllowPipes = Unsupported.useScriptableRenderPipeline;
    27.     Unsupported.useScriptableRenderPipeline = false;
    28.     RenderInstanced();
    29.     SceneCamera.Render();
    30.     Unsupported.useScriptableRenderPipeline = oldAllowPipes;
    31. }
    32.  
    33. void EndAndDrawPreview(Rect pos)
    34. {
    35.     preview.EndAndDrawPreview(pos);
    36. }
    37.  
    38. void RenderInstanced()
    39. {
    40.     if (mesh == null)
    41.         mesh = (Mesh)AssetDatabase.LoadAssetAtPath("Assets/TerrainSlicing/EditorResources/Bevel_Cube.fbx", typeof(Mesh));
    42.  
    43.     Matrix4x4[] mArr = new Matrix4x4[1];
    44.     Matrix4x4 m = Matrix4x4.TRS(location, Quaternion.identity, size);
    45.     mArr[0] = m;
    46.  
    47.     //preview.DrawMesh(mesh, m, SharedLoadingPatternStatics.cellMaterial_InstancedOpaque, 0);
    48.     //Graphics.DrawMesh(mesh, m, SharedLoadingPatternStatics.cellMaterial_InstancedOpaque, 1, SceneCamera);
    49.     Graphics.DrawMeshInstanced(mesh, 0, SharedLoadingPatternStatics.cellMaterial_InstancedOpaque, mArr, 1, null, UnityEngine.Rendering.ShadowCastingMode.Off, false, 1, SceneCamera);
    50. }
    The two lines preview.DrawMesh and Grahics.DrawMesh both work. I don't know a lot about rendering, I think it's because DrawMeshInstanced does not get rendered with Camera.Render (which renders to a RenderTexture).

    Any help would be great!