Stores player UI scale preferences for plugins to utilize

Supported Games
GameServerKingsGameServerKings

This plug-in helps the HUD UI adjusts the UI scale settings of the player

test video

Feature

  • Ask the user and save UIScale and AspectRatio.
  • API for HUD developers.

Chat Commands

  • /setui -- Opens a window that sets the UI size

Configuration

  • InitPlayer -- Decide if you want to ask the player the UI scale when the player first enters the game
{
  "InitPlayer": true,
  "ConfigVersion": {
    "Major": 2,
    "Minor": 2,
    "Patch": 2
  }
}

Stored Data

The plugin data are stored in data/UIScaleManagerPlayerData.json. Deleting this file would wipe all players UIScaleData

Localization

{
  "UI Scale Data Changed": "Your UI data is setted to {0} {1}:{2}.",
  "Cancel": "Canceled.",
  "Error": "Unexpected Parameter.",
  "YourCurrentAspectRatio": "Your Current Aspect Ratio Is",
  "YourCurrentUISize": "Your Current UI Size Is",
  "FitBelt": "<color=yellow>Please fit this rectangle to the item belt</color>",
  "FitStatusW": "<color=yellow>Please fit this rectangle to the status window</color>"
}

API Example

The code below here is the UI plug-in that we basically create.

using System.Linq;
using Oxide.Core.Libraries.Covalence;
using Oxide.Game.Rust.Cui;

namespace Oxide.Plugins
{
    [Info("UI Example", "noname", "0.1.0")]
    class UIExample : CovalencePlugin
    {
        private void OnServerInitialized() => BasePlayer.activePlayerList.ToList().ForEach(player => {
            CuiElementContainer UIInstance = new CuiElementContainer();
            UIInstance.Add(new CuiPanel
            {
                CursorEnabled = false,
                Image = { Color = "0 0 0 0.7" },
                RectTransform = {
                    AnchorMin = "0.1 0.024", AnchorMax = "0.34 0.106"
                },
            }, "Overlay", "ExampleUI");
            CuiHelper.DestroyUi(player, "ExampleUI");
            CuiHelper.AddUi(player, UIInstance);
        });

        private void Unload() => BasePlayer.activePlayerList.ToList().ForEach(player => CuiHelper.DestroyUi(player, "ExampleUI"));
    }
}

The code below shows the UI plug-in that supports UIScaleManager.

using System.Linq;
using Oxide.Core.Plugins;// <- added!
using Oxide.Core.Libraries.Covalence;
using Oxide.Game.Rust.Cui;

namespace Oxide.Plugins
{
    [Info("UI Example", "noname", "0.1.0")]
    class UIExample : CovalencePlugin
    {
        [PluginReference] Plugin UIScaleManager;// <- added!
        private void OnServerInitialized() => BasePlayer.activePlayerList.ToList().ForEach(player => {
            CuiElementContainer UIInstance = new CuiElementContainer();
            float[] result = (float[])UIScaleManager?.Call("API_AutoAnchorScaling", 0.1f, 0.024f, 0.34f, 0.106f, 5, 12, player.UserIDString);// <- added!
            UIInstance.Add(new CuiPanel
            {
                CursorEnabled = false,
                Image = { Color = "0 0 0 0.7" },
                RectTransform = {
                    AnchorMin = $"{result[0]} {result[1]}", AnchorMax = $"{result[2]} {result[3]}"// <- modified!
                },
            }, "Overlay", "ExampleUI");
            CuiHelper.DestroyUi(player, "ExampleUI");
            CuiHelper.AddUi(player, UIInstance);
        });

        private void Unload() => BasePlayer.activePlayerList.ToList().ForEach(player => CuiHelper.DestroyUi(player, "ExampleUI"));
    }
}

By adding 4 lines like this, your UI can be matched to the screen ratio and UIscale of all clients.

Developer API

//All method are caching optimized, so you can call them multiple times.

private float[] API_CheckPlayerUIInfo(string playerID) 
//Return null if player data does not exist
//returnvalue[0] = AspectRatioX
//returnvalue[1] = AspectRatioY
//returnvalue[2] = UIScale

private float[] API_GetItemBeltAnchor(int ratioX, int ratioY, float uiSize)
//Returns an anchor that matches the screen ratio and size information
//returnvalue[0] = AnchorMinX
//returnvalue[1] = AnchorMinY
//returnvalue[2] = AnchorMaxX
//returnvalue[3] = AnchorMaxY

private float[] API_GetItemBeltAnchor(string playerID)
//Returns an anchor that matches the user's screen ratio and size information
//Return null if player data does not exist
//returnvalue[0] = AnchorMinX
//returnvalue[1] = AnchorMinY
//returnvalue[2] = AnchorMaxX
//returnvalue[3] = AnchorMaxY

private float[] API_GetStatusWindowAnchor(int ratioX, int ratioY, float uiSize)
//Returns an anchor that matches the screen ratio and size information
//returnvalue[0] = AnchorMinX
//returnvalue[1] = AnchorMinY
//returnvalue[2] = AnchorMaxX
//returnvalue[3] = AnchorMaxY

private float[] API_GetStatusWindowAnchor(string playerID)
//Returns an anchor that matches the user's screen ratio and size information
//Return null if player data does not exist
//returnvalue[0] = AnchorMinX
//returnvalue[1] = AnchorMinY
//returnvalue[2] = AnchorMaxX
//returnvalue[3] = AnchorMaxY

private float[] API_AutoAnchorScaling(float anchorMinX, float anchorMinY, float anchorMaxX, float anchorMaxY, int center, int parent, int ratioX, int ratioY, float uiSize)
//Returns an converted anchor that matches the user's screen ratio and size information
//int center 0 = UpperLeft
//int center 1 = UpperCenter
//int center 2 = UpperRight
//int center 3 = MiddleLeft
//int center 4 = MiddleCenter
//int center 5 = MiddleRight
//int center 6 = LowerLeft
//int center 7 = LowerCenter
//int center 8 = LowerRight
//int parent 0 = MainUpperLeft
//int parent 1 = MainUpperCenter
//int parent 2 = MainUpperRight
//int parent 3 = MainMiddleLeft
//int parent 4 = MainMiddleCenter
//int parent 5 = MainMiddleRight
//int parent 6 = MainLowerLeft
//int parent 7 = MainLowerCenter
//int parent 8 = MainLowerRight
//int parent 9 = ItemBeltUpperLeft
//int parent 10 = ItemBeltUpperCenter
//int parent 11 = ItemBeltUpperRight
//int parent 12 = ItemBeltMiddleLeft
//int parent 13 = ItemBeltMiddleCenter
//int parent 14 = ItemBeltMiddleRight
//int parent 15 = ItemBeltLowerLeft
//int parent 16 = ItemBeltLowerCenter
//int parent 17 = ItemBeltLowerRight
//int parent 18 = StatusWindowUpperLeft
//int parent 19 = StatusWindowUpperCenter
//int parent 20 = StatusWindowUpperRight
//int parent 21 = StatusWindowMiddleLeft
//int parent 22 = StatusWindowMiddleCenter
//int parent 23 = StatusWindowMiddleRight
//int parent 24 = StatusWindowLowerLeft
//int parent 25 = StatusWindowLowerCenter
//int parent 26 = StatusWindowLowerRight
//returnvalue[0] = AnchorMinX
//returnvalue[1] = AnchorMinY
//returnvalue[2] = AnchorMaxX
//returnvalue[3] = AnchorMaxY

private float[] API_AutoAnchorScaling(float anchorMinX, float anchorMinY, float anchorMaxX, float anchorMaxY, int center, int parent, string playerID)
//Returns an converted anchor that matches the user's screen ratio and size information
//Return null if player data does not exist
//int center 0 = UpperLeft
//int center 1 = UpperCenter
//int center 2 = UpperRight
//int center 3 = MiddleLeft
//int center 4 = MiddleCenter
//int center 5 = MiddleRight
//int center 6 = LowerLeft
//int center 7 = LowerCenter
//int center 8 = LowerRight
//int parent 0 = MainUpperLeft
//int parent 1 = MainUpperCenter
//int parent 2 = MainUpperRight
//int parent 3 = MainMiddleLeft
//int parent 4 = MainMiddleCenter
//int parent 5 = MainMiddleRight
//int parent 6 = MainLowerLeft
//int parent 7 = MainLowerCenter
//int parent 8 = MainLowerRight
//int parent 9 = ItemBeltUpperLeft
//int parent 10 = ItemBeltUpperCenter
//int parent 11 = ItemBeltUpperRight
//int parent 12 = ItemBeltMiddleLeft
//int parent 13 = ItemBeltMiddleCenter
//int parent 14 = ItemBeltMiddleRight
//int parent 15 = ItemBeltLowerLeft
//int parent 16 = ItemBeltLowerCenter
//int parent 17 = ItemBeltLowerRight
//int parent 18 = StatusWindowUpperLeft
//int parent 19 = StatusWindowUpperCenter
//int parent 20 = StatusWindowUpperRight
//int parent 21 = StatusWindowMiddleLeft
//int parent 22 = StatusWindowMiddleCenter
//int parent 23 = StatusWindowMiddleRight
//int parent 24 = StatusWindowLowerLeft
//int parent 25 = StatusWindowLowerCenter
//int parent 26 = StatusWindowLowerRight
//returnvalue[0] = AnchorMinX
//returnvalue[1] = AnchorMinY
//returnvalue[2] = AnchorMaxX
//returnvalue[3] = AnchorMaxY

private void OnUIScaleChanged(IPlayer player, float uiScale, int aspectRatioX, int aspectRatioY)
{
    Puts("The UI size of the player has changed!");
}

When you using AutoAchorScaling, i recommend using the enum below.


public enum RectCenter
{
    UpperLeft,
    UpperCenter,
    UpperRight,
    MiddleLeft,
    MiddleCenter,
    MiddleRight,
    LowerLeft,
    LowerCenter,
    LowerRight
}

public enum ScalingParent
{
    MainUpperLeft,
    MainUpperCenter,
    MainUpperRight,
    MainMiddleLeft,
    MainMiddleCenter,
    MainMiddleRight,
    MainLowerLeft,
    MainLowerCenter,
    MainLowerRight,

    ItemBeltUpperLeft,
    ItemBeltUpperCenter,
    ItemBeltUpperRight,
    ItemBeltMiddleLeft,
    ItemBeltMiddleCenter,
    ItemBeltMiddleRight,
    ItemBeltLowerLeft,
    ItemBeltLowerCenter,
    ItemBeltLowerRight,

    StatusWindowUpperLeft,
    StatusWindowUpperCenter,
    StatusWindowUpperRight,
    StatusWindowMiddleLeft,
    StatusWindowMiddleCenter,
    StatusWindowMiddleRight,
    StatusWindowLowerLeft,
    StatusWindowLowerCenter,
    StatusWindowLowerRight
}
MIT License

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.