-
-
Save caneva20/5c5b8950601aac269d34eefbf1be01e9 to your computer and use it in GitHub Desktop.
A small Unity helper class to convert viewport, screen or world positions to canvas space.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using UnityEngine; | |
/// <summary> | |
/// Small helper class to convert viewport, screen or world positions to canvas space. | |
/// Only works with screen space canvases. | |
/// </summary> | |
/// <example> | |
/// objectOnCanvasRectTransform.anchoredPosition = specificCanvas.WorldToCanvasPoint(worldspaceTransform.position); | |
/// </example> | |
public static class CanvasPositioningExtensions { | |
public static Vector3 WorldToCanvasPosition(this UnityEngine.Canvas canvas, Vector3 worldPosition, Camera camera) { | |
var viewportPosition = camera.WorldToViewportPoint(worldPosition); | |
return canvas.ViewportToCanvasPosition(viewportPosition); | |
} | |
public static Vector3 ScreenToCanvasPosition(this UnityEngine.Canvas canvas, Vector2 screenPosition) { | |
var viewportPosition = new Vector2(screenPosition.x / Screen.width, screenPosition.y / Screen.height); | |
return canvas.ViewportToCanvasPosition(viewportPosition); | |
} | |
public static Vector3 ViewportToCanvasPosition(this UnityEngine.Canvas canvas, Vector2 viewportPosition) { | |
//Gets the canvas's RectTransform | |
//canvas.GetComponent<RectTransform>() would work too, | |
//but since Transform of a UI Element is already a RectTransform | |
//I prefer to use cast instead to avoid the overhead of a GetComponent | |
var canvasTransform = (RectTransform) canvas.transform; | |
//Viewport positions ranges from 0 to 1 | |
//Being (0, 0) the bottom left corner | |
//and (1, 1) the top right corner of the viewport. | |
// | |
//The sizeDelta of a canvas is the same as the screen resolution it is currently on. | |
//In a screen of 800x600, the canvas would have a sizeDelta of (x:800, y:600) too! | |
// | |
//With that information, we can "cast" a value from a viewport to its relative position on an (Unscaled) canvas | |
//Vector2.Scale or Vector3.Scale does just that (by simple multiplying each axis from A with the same axis from B) | |
var scaled = Vector2.Scale(viewportPosition, canvasTransform.sizeDelta); | |
//If a CanvasScaler is being used, by just doing the above is not enough. | |
//By scaling the result from above (again) with the scale of the canvas we can fix the position to account for canvas scaling | |
return Vector2.Scale(scaled, canvasTransform.localScale); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment