0
\$\begingroup\$

I want to show a menu next to an item in an inventory. This is what I try to rebuild: enter image description here

I do this by placing a canvas in 3D world space next to the inventory: enter image description here

As I don't want the menu to be rotated, I rotated the menu the opposite X value as the camera. The camera has an X rotation of -11, so I rotate the menu by 11 to make it look straight:

enter image description here

Since I don't want the menu to get stuck in the case, I move it closer to the camera:

enter image description here

One can see that the menu is now offset to the left and to the top because of the camera perspective.

How could I offset the menu in such a way that it still aligns with the right top corner of the item?

Thank you!

\$\endgroup\$
3
  • 2
    \$\begingroup\$ You were on a much better track with your previous question, when you said you thought a screen space overlay canvas could be a good way to go. What made you go back to using a world space canvas? Note that again here, you're asking about your guessed-at solution ("apply rotation and shift offsets to the world space canvas so it looks like a screen space canvas") instead of asking about the problem you want to solve ("how do I draw a context menu next to my object") - this is another case of the X/Y problem, which can lead to you getting worse answers. \$\endgroup\$
    – DMGregory
    Commented Jul 21, 2019 at 15:53
  • \$\begingroup\$ @DMGregory Since nobody replied, I thought that my approach of a Screen Space Canvas is so absurd that nobody has experience with it and is therefore the wrong approach. \$\endgroup\$
    – tmighty
    Commented Jul 21, 2019 at 15:59
  • 2
    \$\begingroup\$ I replied, telling you that you don't need to ask StackExchange for permission to try using screen space overlay, or any other mode/setting. The settings are there for you to play with to your heart's content, no matter whether some internet stranger thinks you "should" do it that way or not. If you'd just tried what your hunch was saying could work, you might have found the solution on your own. So, your first step should always be: try it. Then, if things go wrong, and you can't find a way to solve it, ask for help. You don't need preemptive help if nothing's gone wrong yet. \$\endgroup\$
    – DMGregory
    Commented Jul 21, 2019 at 16:08

1 Answer 1

2
\$\begingroup\$

Don't put a UI element in perspective only to fight and counter that perspective. You're just making your life more complicated that way.

Instead you can use a canvas in "Screen Space - Overlay" mode like you'd asked about previously.

Then place the position of your menu to match the on-screen position of the object you want it to follow, something like this:

void PlaceMenuAtWorldPosition(Vector3 wordPosition, RectTransform menu, Camera camera) {
    Vector2 screenPoint = camera.WorldToScreenPoint(worldPosition);

    Vector2 uiPoint;
    RectTransformUtility.ScreenPointToLocalPointInRectangle(
        (RectTransform)menu.parent, // Local space to place the point into.
        screenPoint,
        null,         // We're in screen space overlay, no need for camera perspective.
        out uiPoint   // The resulting point in the container's space. 
    );

    menu.anchoredPosition = uiPoint;
}
\$\endgroup\$
5
  • \$\begingroup\$ A question, please: What do you mean by "point in the container's space"? What is the container? Also, a spello: "wordPosition" should be "worldPosition". You typed that flying blind. Wow. :-) \$\endgroup\$
    – tmighty
    Commented Jul 22, 2019 at 22:31
  • \$\begingroup\$ The container is the parent object, likely your canvas, but it could be a different object if you have additional levels of hierarchy in your setup. \$\endgroup\$
    – DMGregory
    Commented Jul 22, 2019 at 22:33
  • \$\begingroup\$ My setup seems to be different than what you had in mind. Do you think you could describe what ScreenPointToLocalPointInRectangle does in this case? I have read the doc, but I don't understand why you use it. \$\endgroup\$
    – tmighty
    Commented Jul 22, 2019 at 22:54
  • \$\begingroup\$ It takes a point on the screen, and transforms it to a point in a RectTransform's local space. We use it to translate between the pixel coordinates of the screen and the UI coordinate system of your canvas or layout container. \$\endgroup\$
    – DMGregory
    Commented Jul 22, 2019 at 22:55
  • \$\begingroup\$ Thank you, fully understood now! \$\endgroup\$
    – tmighty
    Commented Jul 22, 2019 at 23:16

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .