Convert Unity UI Screen Space position to World position

All credit goes to tosiabunio over on this forum post for this great solution.

Using Unity’s Canvas UI is excellent when you want your UI elements to scale and position correctly across different devices and aspect ratios. Learning to work with the Canvas UI properly is a bit of a nightmare but that’s a different story.

My issue was that while I do want UI elements to reposition across different aspect ratios I also want some GameObjects to have animations that seemingly interact with the UI elements. For instance, I wanted the Deck and Discard piles (UI Elements in Screen Space) to have Cards (Game Objects in World Space) come in/out of them.

GameObject Cards in World Space coming out of UI element Images in Screen Space. Works even as the UI elements move due to aspect ratio changes.

The problem is that you cannot simply have your World Space objects get the transform position of the Screen Space UI objects, the positions will not translate properly and you’ll end up with your World Space objects flying off the screen. This is where Tosiabunio’s solution comes into play when you want to ” Translate anchored overlay UI element to world position. “

var screenToWorldPosition = Camera.main.ScreenToWorldPoint(rectTransform.transform.position);

Basically, all you have to do is use the ScreenToWorldPoint method and pass it the desired UI object’s transform.position. It’s a simple one liner but this solution had evaded me for months where I was doing all kinds of crazy hacks trying to get these two positioning systems to play nice together.

Tosiabunio’s post also mentions a way to convert in the opposite direction, World Space into Screen Space:

Translate game object position from the world to overlay position in order to place UI element near that object.

To which he suggests:

RectTransformUtility.WorldToScreenPoint(Camera.main, obj.transform.position)

I haven’t tried this yet but it might be handy for others. Also, user karma0413 points out that WorldToScreenPoint can be slightly off in some situations and offers a solution which involves performing position calculations off the scale factor. Again, I haven’t tried it yet as the original one liner works perfectly for my purposes.

Let me know if this helps you and if you have any other Unity Canvas issues that you need help resolving. I’ve been working with it a lot lately and perhaps I can help or write more about common issues people face.

Events

In Nano, Events are the primary way the player interacts with the game world. Events are also the most direct way the player learns about the environment they are taking part in, meaning Events play double duty by providing game play and story elements. While the story is something that will develop overtime, the functionality of Events is something that the game needs right away. Events are also the feature that I wrestled with the most when trying to come up with a solid development design.

It was clear what Events had to be, they were to display some story text to the player, a few buttons with text on them representing the player’s available choices, and upon selecting a choice a result is shown that also has story text as well as displaying any rewards the player is given. Think of the event system in games like FTL. This type of system is generally referred to as a dialog tree, decision tree, or most specifically a simple directed graph. There are many plugins for Unity that provide varying levels of decision tree functionality, but I wanted to take a stab at rolling my own first.

So far a very simple Event model is in place along with Choices and Results. When a player enters a new location an Event is chosen from the list of possible Events which is then displayed on screen. To manage the Event’s display is the Event UI Controller class which is attached to prefab in Unity. This Event prefab uses Unity’s new UI features to display text and buttons. This is my first attempt at working with this new UI system, before this all objects displaying text used Text Mesh components which I find to be clunky and lacking a lot of features that are needed for displaying even a modest amount of text.

The early Event UI screen.
The early Event UI screen.

There is still a lot to be done to get Events fully functional. The player still needs to be able to select one of the choices and be presented with the result. Events will also be the primary way that combat is triggered. Some choices should only be available to the player if certain conditions are met, like having a particular item equipped. There is also the daunting task of creating a large amount of Events all with multiple choices which in turn have a variety of rewards.