Forum rules - please read before posting.

Menu in Worldspace

Greetings!

I am trying to put my menus into worldspace but am confused about how to do that.

I'd tried a couple of approaches:

1) I simply changed the UnityUI prefab on the menu to be "worldspace". When I do this the menu instantiates but the camera isn't transferred to look at the menu and I have no way to position or interact with the menu

2) I tried instantiating the menu myself (attached it to a game object). After it is instantiated I change the camera to point at the menu. This does seems to work, but I can't seem to get the cursor working. The code I used to instantiate it is:

pauseMenu = Instantiate(pauseMenuPrefab);
GameCamera cam = pauseMenu .GetComponentInChildren();
AC.KickStarter.mainCamera.SetGameCamera(cam, 0f);

You can see pictures of my prefab on this link: https://imgur.com/a/Z2cjg6w

The reason I want to put the menu into worldspace is so that I can run in a VR environment where there is no 2d overlay.

Any suggestions for me?

-Ken W

Comments

  • edited October 2021

    The "intended" way of having a 3D menu is to do as you have in 1) - put the Canvas in World Space and have AC bring it up as normal. I'd recommend sticking with this approach for the time being.

    The Menu's "Position" property should still apply to Canvases in World Space, but if you want to position it manually you'll need to set this to Manual and then call the Menu's SetCentre3D function:

    AC.PlayerMenus.GetMenuWithName ("MyMenu").SetPosition3D (myPosition);
    

    Alternatively, or as well as, you can also switch to a GameCamera that's facing it by placing one inside your prefab as you've done. Switching to this as the Menu turns on/off could feasibly be automated by hooking into the OnMenuTurnOn / Off events. Something like this, attached to the Canvas:

    using UnityEngine;
    using AC;
    
    public class SetCameraOnMenu : MonoBehaviour
    {
    
        [SerializeField] private Canvas menuCanvas;
        [SerializeField] private _Camera menuGameCamera;
    
        private void OnValidate ()
        {
            if (menuCanvas == null) menuCanvas = GetComponent<Canvas>();
            if (menuGameCamera == null) menuGameCamera = GetComponentInChildren<_Camera>();
        }
    
        private void OnEnable ()
        {
            EventManager.OnMenuTurnOn += OnMenuTurnOn;
            EventManager.OnMenuTurnOff += OnMenuTurnOff;
        }
    
        private void OnDisable ()
        {
            EventManager.OnMenuTurnOn -= OnMenuTurnOn;
            EventManager.OnMenuTurnOff -= OnMenuTurnOff;
        }
    
        private void OnMenuTurnOn (AC.Menu menu, bool isInstant)
        {
            if (menu.RuntimeCanvas == menuCanvas)
            {
                KickStarter.mainCamera.SetGameCamera (menuGameCamera);
            }
        }
    
        private void OnMenuTurnOff (AC.Menu menu, bool isInstant)
        {
            if (menu.RuntimeCanvas == menuCanvas)
            {
                _Camera lastCamera = KickStarter.mainCamera.GetLastGameplayCamera ();
                KickStarter.mainCamera.SetGameCamera (lastCamera);
            }
        }
    
    }
    

    If you want to instantiate a UI Canvas that's linked to AC's Menu Manager (as in 2), you'll need to use the Menu class to do so to ensure the two are still connected. This is mainly intended for situations like making multiple instances of a given menu etc:

    Menu menuToCopy = PlayerMenus.GetMenuWithName (menuName);
    Menu myMenu = ScriptableObject.CreateInstance <Menu>();
    myMenu.CreateDuplicate (menuToCopy); // Copy from the default Menu
    myMenu.title += " (Duplicate)";
    myMenu.TurnOn ();
    

    The third way would be to disconnect the Canvas from AC's Menu Manager, and then manually set the click-behaviour of its various Buttons etc to call AC functions directly. Though, if you're involving dynamic things like inventory etc this may be yet more hassle.

    On the menu's interactivity: AC relies on its own EventSystem component by default, which allows for use of AC's simulated cursor with UnityUI and a few other AC-related settings.

    You can replace this by assigning a custom EventSystem prefab at the top of the Menu Manager. To revert back to Unity's default behaviour, create a new EventSystem from the GameObject toolbar menu and assign it as a prefab.

    Oculus have their own EventSystem replacement covered here, but a more generic approach can be found on Unity's Learn pages here. Either way, I'd recommend ensuring that regular World-Space Canvases are responsive in VR in a non-AC scene / linked menu first, so that we can pinpoint any further issues as being AC-related.

Sign In or Register to comment.

Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Welcome to the official forum for Adventure Creator.