# SetScreenToPanelSpaceFunction(Func<Vector2, Vector2>)

> Sets the function that handles the transformation from screen space to panel space. For overlay panels, this function returns the input value.

## Definition

* **Type:** Method
* **Namespace:** [UnityEngine.UIElements](/engine/6000.3/script-reference/unityengine/uielements.md)
* **Assembly:** UnityEngine.UIElementsModule

```csharp
public void SetScreenToPanelSpaceFunction(Func<Vector2, Vector2> screenToPanelSpaceFunction)
```

### Parameters

**** (\[Func\<Vector2, Vector2>]\(https\://learn.microsoft.com/dotnet/api/system.func-1)): The translation function. Set to `null` to revert to the default behavior.

### Remarks

If the panel's targetTexture is applied to 3D objects, use a function that raycasts against MeshColliders in the Scene. The function can first check whether the GameObject that the ray hits has a MeshRenderer with a shader that uses this panel's target texture. It can then return the transformed `RaycastHit.textureCoord` in the texture's pixel space. Return a coordinate outside the panel to skip incoming pointer events if the ray doesn't hit a valid target or location.

If the panel contains elements with 3-D transformations that make them overflow forward or backward out of the panel's surface, use the other [PanelSettings.SetScreenToPanelSpaceFunction3D](/engine/6000.3/script-reference/unityengine/uielements/panelsettings/setscreentopanelspacefunction3d.md) method instead.

### Examples

```csharp
#if Include_UITextureProjection_Sample
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UIElements;

namespace Samples.Runtime.Rendering
{
    public class UITextureProjection : MonoBehaviour
    {
        public Camera m_TargetCamera;

        /// <summary>
        /// When using a render texture, this camera will be used to translate screencoodinates to the panel's coordinates
        /// </summary>
        /// <remarks>
        /// If none is set, it will be initialized with Camera.main
        /// </remarks>
        public Camera targetCamera
        {
            get
            {
                if (m_TargetCamera == null)
                    m_TargetCamera = Camera.main;
                return m_TargetCamera;
            }
            set => m_TargetCamera = value;
        }

        public PanelSettings TargetPanel;

        private Func<Vector2, Vector2> m_DefaultRenderTextureScreenTranslation;

        void OnEnable()
        {
            if (TargetPanel != null)
            {
                if (m_DefaultRenderTextureScreenTranslation == null)
                {
                    m_DefaultRenderTextureScreenTranslation = (pos) => ScreenCoordinatesToRenderTexture(pos);
                }

                TargetPanel.SetScreenToPanelSpaceFunction(m_DefaultRenderTextureScreenTranslation);
            }
        }

        void OnDisable()
        {
            //we reset it back to the default behavior
            if (TargetPanel != null)
            {
                TargetPanel.SetScreenToPanelSpaceFunction(null);
            }
        }

        /// <summary>
        /// Transforms a screen position to a position relative to render texture used by a MeshRenderer.
        /// </summary>
        /// <param name="screenPosition">The position in screen coordinates.</param>
        /// <param name="currentCamera">Camera used for 3d object picking</param>
        /// <param name="targetTexture">The texture used by the panel</param>
        /// <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>
        private Vector2 ScreenCoordinatesToRenderTexture(Vector2 screenPosition)
        {
            var invalidPosition = new Vector2(float.NaN, float.NaN);

            screenPosition.y = Screen.height - screenPosition.y;
            var cameraRay = targetCamera.ScreenPointToRay(screenPosition);

            RaycastHit hit;
            if (!Physics.Raycast(cameraRay, out hit))
            {
                return invalidPosition;
            }

            var targetTexture = TargetPanel.targetTexture;
            MeshRenderer rend = hit.transform.GetComponent<MeshRenderer>();

            if (rend == null || rend.sharedMaterial.mainTexture != targetTexture)
            {
                return invalidPosition;
            }

            Vector2 pixelUV = hit.textureCoord;

            //since y screen coordinates are usually inverted, we need to flip them
            pixelUV.y = 1 - pixelUV.y;

            pixelUV.x *= targetTexture.width;
            pixelUV.y *= targetTexture.height;

            return pixelUV;
        }
    }
}
#endif
```
