New Plugin UI

  • We've implemented the UI part of the new API, so we can finally share more information about it. Please let us know if you're interested in a preview version of the API (specifically for the UI).


    If you have any questions or feedback, don't hesitate to post here :)



    Workflow


    The new version internally uses Unitys new UI Toolkit (formerly known as "UI Elements"), which is inspired by CSS. This means the new API no longer maintains a UI based on absolute and relative coordinates, instead they will use a flex layout. You can update the Style of a UI element directly - it determines the visual appearance and position of the element and is mostly based on Unitys IStyle class. However, you can still work with absolute and relative coordinates if you like.


    The new API has two workflows, and both can be combined. The main workflow is the Style-based workflow, while all UIElements also offer some simplified helper methods (like setPosition(), setSize(), setPivot() etc). The latter resembles the old GUI workflow, but internally these methods just update the underlying style.


    When using absolute coordinates, the reference resolution is always FullHD (1920x1080). The positions will be identical on other 16:9 resolutions, so if you place an element at the center using absolute coordinates (X: 960 Y: 560), it will be also centered on 1280x720 or 3840x2160 (4K) (and other 16:9 resolutions). The size will also be identical on all screens, i.e. if the element has an absolute width and height of 128 pixels, the game will resize the element on other resolutions as well.


    The initial API release will provide at least a base UIElement class, a UILabel and a UITextField.


    UIElement is the base class for all UI elements (similar to the old GuiElement class). You can use it as a container or panel. You can also add a background image to them, so they automatically replace the old "GuiImage" class. In other words, the UIElement class is now a combination of the old GuiElement, GuiPanel and GuiImage classes. UILabel is very much like the old GuiLabel class, while UITextField is very much like the old GuiTextField class.


    Note: When using the simplified workflow methods, the origin of the screen (0, 0) will be in the top left corner (unlike the Java version, where the screen origin was in the lower left corner). When working with the style, however, that doesn't matter, because you set the top, left, right and bottom distance on the style directly.

    When using relative values (percent values), the game now uses values between 0-100 instead of 0-1. So if you were using 0.5 in the Java version, this now becomes 50.



    Style and HoverStyle


    In addition to the regular style, all UI elements also have an additional, optional hoverStyle field: It determines the style of the element when it gets hovered with the mouse cursor. This way you could change properties like the color, size etc (e.g. when hovering the element, the color may change to blue or the font size of of the label may become bigger to achieve a hover effect).

    The game handles this automatically under the hood, so when the mouse enters the element, it automatically sets the hoverStyle, and when the mouse leaves the element, it automatically sets the original style.


    The hoverStyle is only used if the element is marked as "clickable" (so the element reacts to the mouse and mouse input). This is done through the setClickable() method (similar to how it worked in the Java version). In addition to the "clickable" flag, there is also a "pickable" flag: It determines if an element should "block" mouse clicks (irrespective of the clickable flag). If "picakble" is set to false, the mouse cursor will ignore the element, so you could click on another element which is behind the panel. If set to true, the panel will block the mouse input, so you couldn't click on elements behind it.



    Childs and Parents


    The new UI also supports childs and parents, like the old GuiElements. You can attach a UIElement to any other UIElement (which then becomes the new parent). The style (position, size etc) of a child then depends on the parent style. Childs also inherit certain style properties (like the font size) - unless they explicitly set them on their style. Moving a parent moves all childs automatically.


    Unlike the Java version, you no longer have to call Player.addUIElement() for all childs - you only have to call it for the parent now, and the game handles all childs (and childs of childs) automatically.



    Modify Game UI


    The Internals class will provide a way to modify the Style of any game UI element. E.g. change the color of the health bar or the background color or image of any game menus. However, you have to use this with caution.



    Message boxes


    The new UI will also provide a simple way to show message boxes to the player. The Player class will provide various showMessageBox() methods for this, where you could provide a callback to get the user selection. There are also similar methods to bring up a color picker or an input dialog, for example.



    Examples


    This is a basic example which creates a black panel centered on the screen with a size of 500x300 pixels containing a centered label. It uses the simplified workflow, which resembles UI creation in the Java version:





    With the new UI, we have a lot more control over our UI elements. We could have round edges on our panels, for example, or rotate elements. The next example uses almost the same code as above, but modifies some style properties (to have rounded upper left corner on the panel and also to rotate the label by 90 degree):





    The next example uses the new flex layout: We want 10 panels to be evenly positioned around the center. We first create an invisible container (we call it "screen") which covers the whole screen. We set "pickable" to false, so it does not block our mouse clicks. We set absolute coordinates, and set top, left, right and bottom to 0 (in other words: the distance to the top, left, right and bottom will be 0 px, so the element covers the whole screen).


    We set the alignItems property to "Center" (because we want our child elements to be centered), justifyContent will be set to "SpaceAround" (so the elements will be evenly positioned in the panel) and flexDirection will be set to "Row" (so they're aligned vertically instead of horizontally).


    For the child elements, there is not much we have to change: We set the width and height to 128 pixels, set a random background color (using a util method) and add them as childs to the "screen" parent. That's it!





    Legacy GUI


    We're thinking about providing a plugin which brings back the old GuiElements from the Java version. They will be based on UIElements. This is mostly for reasons of compatibility (so if you have a big complex UI, you don't have to recreate it from scratch). Please let us know if this is important for you.

  • HoverStyle is a game changer for plugin UXs :love:

    Please let us know if you're interested in a preview version of the API (specifically for the UI).

    Hi red51 , by this do you mean we could start testing out the UI on a test server even if the UI doesn't have any method calls to update? If so, I would certainly be interested in this.

  • Hi red51 , by this do you mean we could start testing out the UI on a test server even if the UI doesn't have any method calls to update? If so, I would certainly be interested in this.

    We could prepare a preview version of the API for the next update :) It wouldn't be a full API release, i.e. some things (like model loading, database handling etc) don't work, and some events are not wired yet - but the UI part is almost ready now (we still have to implement image loading, but that should be ready in time for the update). Basically you could even use it in production (although there is still a chance that the API may cause crashes, especially if you use non-UI related events and methods) ^^

  • Please let us know if you're interested in a preview version of the API (specifically for the UI).

    Yes, we are interested in this :)
    Even if API is not complete it is a good way to start adapting to the new API together with new UI experiments


    The Internals class will provide a way to modify the Style of any game UI element. E.g. change the color of the health bar or the background color or image of any game menus.

    Will it make possible to change, for example, inventory size of a player or his hotbar? Or this will only affect visuals and API for inventory interactions will be separated?

  • An early (incomplete) API release will be available with the next update :) The main focus of that release will be the UI, so some other things may not work fully yet^^


    Will it make possible to change, for example, inventory size of a player or his hotbar? Or this will only affect visuals and API for inventory interactions will be separated?

    Changing the style through the Internals class will only affect visuals ^^ The Style class is mostly based on Unitys IStyle interface, so you can change almost all properties which are listed in their docs.

    I've added a new example image above showing the inventory with a replaced background image (just used the wooden Java background image in this case) ;)


    However, you can't add new inventory slots that way. We may add a method to attach new UI elements to any existing game elements, so in theory, you could add new slots then, but they won't work at all (because the inventory code isn't aware of these additional slots)

  • Yes, but Red later the Unity function "through the Program might have to" then be added via the Unity Editor and other writings.
    This will happen at the Earliest, after the "Unity 1.0.0", I think ^^

  • ..seems you cant use those in font for a GUI. Any ideas on how to get different fonts in a GUI like Medieval or Gothic?

    The Font enum (mentioned by james1bow ) is indeed the correct one - it contains all fonts of the game. It can be used for signs and UI elements ;) You can pass it to a label using the setFont() method (or alternatively set the style.font property on the label). Example:

    Java
    UILabel label = new UILabel("Hello World");
    label.setFont(Font.Medieval);
    label.setFontSize(64f);
    label.setFontColor(0xFFFFFFFF); // <- white
    label.setBackgroundColor(0x000000FF); // <- black (optional)
    label.setTextAlign(TextAnchor.MiddleCenter);
    player.addUIElement(label);
  • The Font enum (mentioned by james1bow ) is indeed the correct one - it contains all fonts of the game. It can be used for signs and UI elements ;) You can pass it to a label using the setFont() method (or alternatively set the style.font property on the label). Example:

    Java
    UILabel label = new UILabel("Hello World");
    label.setFont(Font.Medieval);
    label.setFontSize(64f);
    label.setFontColor(0xFFFFFFFF); // <- white
    label.setBackgroundColor(0x000000FF); // <- black (optional)
    label.setTextAlign(TextAnchor.MiddleCenter);
    player.addUIElement(label);

    Thanks Red. I actually found this through your API Javadocs but because of my old nemisis. I had had not implemented the important import bit.

    import net.risingworld.api.ui.style.Font;


    I should have come back here and corrected that for those coming behind with the question. "Always think of the next guy"

Participate now!

Don’t have an account yet? Create a new account now and be part of our community!