Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Question Rendering a UIDocument to a RenderTexture keep screen space events enabled

Discussion in 'UI Toolkit' started by Anthelmed, Nov 30, 2022.

  1. Anthelmed

    Anthelmed

    Joined:
    Mar 2, 2017
    Posts:
    15
    Hello,
    I'm trying to do a WorldSpaceUIDocument system, but I'm stuck by a weird behavior.
    Setting a target texture in the UIDocument panelSettings doesn't disable the screen space events (CF first video below), is there a way to avoid that?



    The only work around I found is rendering the document to another display, but obviously I need to keep a second game view opened and that's not going to work in a build (CF second video)



    Thanks!
     
  2. SimonDufour

    SimonDufour

    Unity Technologies

    Joined:
    Jun 30, 2020
    Posts:
    567
    mcaisw likes this.
  3. Anthelmed

    Anthelmed

    Joined:
    Mar 2, 2017
    Posts:
    15
  4. SimonDufour

    SimonDufour

    Unity Technologies

    Joined:
    Jun 30, 2020
    Posts:
    567
    If you want to do a raycast against a mesh renderer this could be helpfull:
    Code (CSharp):
    1.  public class UITextureProjection : MonoBehaviour
    2.     {
    3.         public Camera m_TargetCamera;
    4.  
    5.         /// <summary>
    6.         /// When using a render texture, this camera will be used to translate screencoodinates to the panel's coordinates
    7.         /// </summary>
    8.         /// <remarks>
    9.         /// If none is set, it will be initialized with Camera.main
    10.         /// </remarks>
    11.         public Camera targetCamera
    12.         {
    13.             get
    14.             {
    15.                 if (m_TargetCamera == null)
    16.                     m_TargetCamera = Camera.main;
    17.                 return m_TargetCamera;
    18.             }
    19.             set => m_TargetCamera = value;
    20.         }
    21.  
    22.         public PanelSettings TargetPanel;
    23.  
    24.         private Func<Vector2, Vector2> m_DefaultRenderTextureScreenTranslation;
    25.  
    26.         void OnEnable()
    27.         {
    28.             if (TargetPanel != null)
    29.             {
    30.                 if (m_DefaultRenderTextureScreenTranslation == null)
    31.                 {
    32.                     m_DefaultRenderTextureScreenTranslation = (pos) => ScreenCoordinatesToRenderTexture(pos);
    33.                 }
    34.  
    35.                 TargetPanel.SetScreenToPanelSpaceFunction(m_DefaultRenderTextureScreenTranslation);
    36.             }
    37.         }
    38.  
    39.         void OnDisable()
    40.         {
    41.             //we reset it back to the default behavior
    42.             if (TargetPanel != null)
    43.             {
    44.                 TargetPanel.SetScreenToPanelSpaceFunction(null);
    45.             }
    46.         }
    47.  
    48.         /// <summary>
    49.         /// Transforms a screen position to a position relative to render texture used by a MeshRenderer.
    50.         /// </summary>
    51.         /// <param name="screenPosition">The position in screen coordinates.</param>
    52.         /// <param name="currentCamera">Camera used for 3d object picking</param>
    53.         /// <param name="targetTexture">The texture used by the panel</param>
    54.         /// <returns>Returns the coordinates in texel space, or a position containing NaN values if no hit was recorded or if the hit mesh's material is not using the render texture as their mainTexture</returns>
    55.         private Vector2 ScreenCoordinatesToRenderTexture(Vector2 screenPosition)
    56.         {
    57.             var invalidPosition = new Vector2(float.NaN, float.NaN);
    58.  
    59.             screenPosition.y = Screen.height - screenPosition.y;
    60.             var cameraRay = targetCamera.ScreenPointToRay(screenPosition);
    61.  
    62.             RaycastHit hit;
    63.             if (!Physics.Raycast(cameraRay, out hit))
    64.             {
    65.                 return invalidPosition;
    66.             }
    67.  
    68.             var targetTexture = TargetPanel.targetTexture;
    69.             MeshRenderer rend = hit.transform.GetComponent<MeshRenderer>();
    70.  
    71.             if (rend == null || rend.sharedMaterial.mainTexture != targetTexture)
    72.             {
    73.                 return invalidPosition;
    74.             }
    75.  
    76.             Vector2 pixelUV = hit.textureCoord;
    77.  
    78.             //since y screen coordinates are usually inverted, we need to flip them
    79.             pixelUV.y = 1 - pixelUV.y;
    80.  
    81.             pixelUV.x *= targetTexture.width;
    82.             pixelUV.y *= targetTexture.height;
    83.  
    84.             return pixelUV;
    85.         }
    86.     }
     
    unity_3Vgvc20-AT9hew likes this.
  5. Anthelmed

    Anthelmed

    Joined:
    Mar 2, 2017
    Posts:
    15
    Thanks I already saw it inside a unitypackage and made my own version: https://gist.github.com/Anthelmed/5fcc49a402ad5c81136c73ce96ba004f
     
    mdrotar and SimonDufour like this.