Search Unity

  1. Unity Asset Manager is now available in public beta. Try it out now and join the conversation here in the forums.
    Dismiss Notice

SRP API issue: Matching an editor preview camera with corresponding game camera

Discussion in 'Graphics Experimental Previews' started by syscrusher, Jan 26, 2020.

  1. syscrusher

    syscrusher

    Joined:
    Jul 4, 2015
    Posts:
    1,104
    I have discovered what appears to be an API limitation for C# scripts running in the editor, and I'm looking for a workaround. I've observed this with HDRP, but since the relevant APIs are part of SRP core, I believe this would also occur in URP.

    When the editor is inspecting one or more Camera components, the CameraEditor class presents a preview of the target(s). Sometimes these are overlays in a scene view, and sometimes they are shown on the game view.

    My code needs to behave the same on a preview for a given camera as it would on the actual camera being previewed. Within each callback from RenderPipelineManager.beginCameraRendering, I need to determine two things about the current camera:
    1. Is it an editor preview of some other camera?
    2. If so, what is the camera being previewed?
    Initially, I had tried to detect the editor's cameras by looking at the cameraType property of the current camera. This works for SceneCamera, which is CameraTypes.SceneView. However, even the camera(s) created by the editor with "Preview Camera" in their names show up as CameraTypes.Game. My working hypothesis is that SRP is trying very hard (and succeeding) in making the previews match exactly the game mode for each camera, with respect to shaders, post processing, etc. But this is also an API limitation because it's hiding information from C# scripts that the API documentation says should be exposed.

    I even went as far as grabbing some likely-identifiable properties from each camera and hashing them to try to detect when one camera is effectively equivalent to another even if they are different Camera instances. This fails because the preview cameras aren't actually matched to the position and rotation of the real cameras -- from what I can tell, the system uses render textures, and all the preview cameras are at more-or-less arbitrary and apparently constant positions.

    I've also followed the proverbial rabbit into the rabbit hole of the SRP APIs, to see if there is anything related to the pipeline, context, etc., that might be the data I need. So far I've found nothing along those lines -- and again, I believe this is because Unity is [wisely] trying to prevent SRP implementations from needing to "know" they are in the editor or are being used for a preview camera.

    With some debug logging, and examination of the reference source code (thanks for providing that, Unity!), I found that the editor creates cameras called "Preview Camera", "SceneCamera", and "Scene Preview Camera". Those three are in a test scene where I've tried various combinations of single and multiple Cameras selected, various window layouts (docked, standalone, single or dual monitors, more than one scene view, etc.).

    Using the name as an indicator fails for several reasons:
    1. Nothing prevents a project from having its own camera with one of those names; they're not reserved.
    2. Nothing prevents Unity from renaming one or more of those internal cameras later.
    3. There is no way to be sure no other internal cameras exist (for example, introducing Cinemachine to the project might very well impact this).
    4. Even absent the preceding issues, the name would at best tell me it's an internal camera -- it gives no mapping back to which project-defined camera is being previewed (if any).
    At this point, I'm basically stuck. I've created a really crude workaround that looks at the camera array passed by RenderPipelineManager.beginFrameRendering. This callback happens more than once per actual "frame" in the editor, with some of the calls being for the editor's own rendering. My prototype detects the camera array having only one element and that element *not* matching the scene's main camera.

    Crude though it is, my prototype works for most instances -- so far! -- except that the same beginFrameRendering that includes all the project-defined cameras also includes that "Preview Camera" (for reasons unknown), so again I'm unable to rule out that camera except unreliably by its name.

    And my workaround isn't really a workaround, because I still have no way to match up the previewing camera with the previewed target camera.

    I would really appreciate any suggestions here on what else I can look at. Thanks!
     
    spellizzari and ekakiya like this.
  2. kodra_dev

    kodra_dev

    Joined:
    Oct 31, 2022
    Posts:
    108
    Well... CameraTypes.Preview is for the model/animation preview under inspector, as far as I know. You can use this workaround to detect that little preview camera at the bottom right corner:

    Code (CSharp):
    1.  
    2. if(!Application.isPlaying && camera.name == "Preview Camera")
    3. {
    4.     Debug.Log("This is a preview camera");
    5. }
    Quite stupid but it works.
     
    Last edited: Feb 23, 2023