-
-
Save FlaShG/ac3afac0ef65d98411401f2b4d8a43a5 to your computer and use it in GitHub Desktop.
using UnityEngine; | |
/// <summary> | |
/// Small helper class to convert viewport, screen or world positions to canvas space. | |
/// Only works with screen space canvases. | |
/// </summary> | |
/// <example> | |
/// <code> | |
/// objectOnCanvasRectTransform.anchoredPosition = specificCanvas.WorldToCanvasPoint(worldspaceTransform.position); | |
/// </code> | |
/// </example> | |
public static class CanvasPositioningExtensions | |
{ | |
public static Vector3 WorldToCanvasPosition(this Canvas canvas, Vector3 worldPosition, Camera camera = null) | |
{ | |
if (camera == null) | |
{ | |
camera = Camera.main; | |
} | |
var viewportPosition = camera.WorldToViewportPoint(worldPosition); | |
return canvas.ViewportToCanvasPosition(viewportPosition); | |
} | |
public static Vector3 ScreenToCanvasPosition(this Canvas canvas, Vector3 screenPosition) | |
{ | |
var viewportPosition = new Vector3(screenPosition.x / Screen.width, | |
screenPosition.y / Screen.height, | |
0); | |
return canvas.ViewportToCanvasPosition(viewportPosition); | |
} | |
public static Vector3 ViewportToCanvasPosition(this Canvas canvas, Vector3 viewportPosition) | |
{ | |
var centerBasedViewPortPosition = viewportPosition - new Vector3(0.5f, 0.5f, 0); | |
var canvasRect = canvas.GetComponent<RectTransform>(); | |
var scale = canvasRect.sizeDelta; | |
return Vector3.Scale(centerBasedViewPortPosition, scale); | |
} | |
} |
Ohoo, my bad, sorry.
I haven't really noticed that this was a requirement as my use case was something different.
I was looking for something that could convert a point on the screen to a point on the canvas, but not for anchoring it.
Anyway, thank you for your patience, (feeling like a jerk for saying you had a bug)
No worries ๐
Hi ๐,
awesome gist you have here, just tried it and it works without any issues ๐
How is this licensed, does a specific one apply?
Hi @Kellojo,
they all have no license, you may use them however you want ๐
awesome! saved me a lot of time ๐ฏ
Hey excellent work! it saved me a lot!
This is great! I have a big need to know what a UI Image on the canvas would be in World Space. Could someone please help me with this? A CanvasToWorldPosition. Thank you. -- Jeff
I needed world coordinates of different UI elements that was on a Canvas set to Screen Space - Camera. That was I could move the game objects to the location in the HUD and make them disappear once they reached the location. My game is 2D and it works exactly as I needed now. I hope this helps.
UICamera is my camera used for the UI (Screen Space - Camera) setting. I don't use Overlay or World canvas.
thisCanvas is the canvas in the scene.
var position = UICamera.WorldToScreenPoint(MyUIObject.transform.position); position.z = (thisCanvas.transform.position - UICamera.transform.position).magnitude; theLocationOfUIObjectInWorldSpace = Camera.main.ScreenToWorldPoint(position);
Hello!
This is a little modification in case that the camera is not drawn in the 100% of the screen, using the viewport rect
public static Vector3 WorldToCanvasPosition(this Canvas canvas, Vector3 worldPosition, Camera camera = null, bool useNormalizeViewPort = false)
{
if (camera == null)
{
camera = Camera.main;
}
var viewportPosition = camera.WorldToViewportPoint(worldPosition);
if (useNormalizeViewPort)
{
Rect normalizedViewPort = camera.rect;
viewportPosition.x = viewportPosition.x * normalizedViewPort.width + normalizedViewPort.x;
viewportPosition.y = viewportPosition.y * normalizedViewPort.height + normalizedViewPort.y;
}
return canvas.ViewportToCanvasPosition(viewportPosition);
}
Thanks!
Awsome it works for me, just be care about your canvas anchor point. (from ViewportToCanvasPosition its currently using 0.5 0.5), but in my case its 0 1).
You are not using the class as intended. As the summary states, you're supposed to set the resulting values to the
RectTransform.anchoredPosition
property. Your example usesInstantiate
, which has different semantics for itsposition
parameter.To instantiate objects on the canvas at your mouse position, use
Using your version breaks my
WorldToCanvasPosition
test case.