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. Dismiss Notice

Interact with UI button through Render Texture

Discussion in 'Editor & General Support' started by jeppe79, Jan 17, 2020.

  1. jeppe79

    jeppe79

    Joined:
    Sep 17, 2019
    Posts:
    74
    DragonCoder and Neos_ like this.
  2. Shinobi1507

    Shinobi1507

    Joined:
    Sep 8, 2010
    Posts:
    220
    I know it is a super long shot but.... did you ever figure this out? I have a setup that because of certain pixel processing requires a stacked camera be sent through a render texture before final output. I NEED the UI to exist behind the render texture.

    Basically I have a UICAM which renders the UI, it is in the stack with the Base "GameCam". GameCam renders to a render texture and then the RenderCam is an orthographic camera pointing to a plane with the render texture applied to it.

    I _KNOW_ its a scuffed setup but I can't find another way to both force low resolution pixel perfection on a UI, while ALSO preventing that UI from receiving post processing effects.
     
  3. TD350

    TD350

    Joined:
    Jul 31, 2019
    Posts:
    1
    Code (CSharp):
    1. ....
    2. private bool PointerInImage()
    3.     {
    4.         if (targetGraphic == null)
    5.         {
    6.             return false;
    7.         }
    8.  
    9.         //get mouse pos
    10.         Vector3 mv = Camera.main.ScreenToWorldPoint(MouseScreenPosition);
    11.         //get world rect
    12.         Rect worldRect = GetWorldRect(targetGraphic.rectTransform);
    13.  
    14.         //if mouse is in rect, find relative position in rect and compare to targetTexture
    15.         if (worldRect.Contains(mv))
    16.         {
    17.             Texture2D tex = targetGraphic.mainTexture as Texture2D;
    18.             float x = FindRelativePercentage(mv.x, worldRect.xMin, worldRect.xMax);
    19.             float y = FindRelativePercentage(mv.y, worldRect.yMin, worldRect.yMax);
    20.  
    21.             //Multiply by texture dimensions to get position relative to texture
    22.             x *= tex.width;
    23.             y *= tex.height;
    24.  
    25.             //check if relative pos falls on non-transparent texture coord
    26.             Color c = tex.GetPixel((int)x, (int)y);
    27.             if (c.a > 0)
    28.             {
    29.                 //If so then our pointer is over the targetGraphic
    30.                 return true;
    31.             }
    32.         }
    33.         return false;
    34.     }
    35.    
    36.     //Returns a value between 0 and 1 which is the percentage x is between a and b
    37.     private float FindRelativePercentage(float x, float a, float b)
    38.     {
    39.         return (x - a) / (b - a);
    40.     }
    41.  
    42.     //Returns a Rect relative to world coordinates. Very useful!
    43.     private Rect GetWorldRect(RectTransform rectTransform)
    44.     {
    45.         Vector3[] corners = new Vector3[4];
    46.         rectTransform.GetWorldCorners(corners);
    47.         // Get the bottom left corner.
    48.         Vector3 position = corners[0];
    49.  
    50.         Vector2 size = new Vector2(
    51.             rectTransform.lossyScale.x * rectTransform.rect.size.x,
    52.             rectTransform.lossyScale.y * rectTransform.rect.size.y);
    53.  
    54.         return new Rect(position, size);
    55.     }
    56.  
    This function will tell you if the mouse is currently over a targetGraphic, which can be a texture2D, or texture from a button (in which case you'll need to cast it to tex2D) also make sure to enable read-write of the texture in texture import settings. I'm sure there's a way to get around that but that's for you to figure out. If you extend the button, you can call the EventSystem methods OnPointerDown, Up, Enter, Exit. You can also use
      EventSystem.current.IsPointerOverGameObject()
    if you want the button to behave like a unity button raycasting-wise.Though it's a let response, hopefully, it can help anyone in the future!
     
    Last edited: Aug 25, 2022