• vgui screen scaling not working
    5 replies, posted
Hi All, I'm pretty new to Lua so trying my best to get my head around how everything works, so far I think I've got a grip of the basics quite well. My problem is I'm making a plugin heavily reliant on vgui elements and for some reason they're not scaling with other resolutions as I expected them to. I've read the wiki and other posts here on the forums and it seems I'm doing it right but not getting the result I expect. See code below: surface.SetFont("Panels") local healPriceW = surface.GetTextSize("Heal Price: " .. HealPrice .. "") local armorPriceW = surface.GetTextSize("Armor Price: " .. ArmorPrice .. "") local health = LocalPlayer():Health() local ScreenW = ScrW() / 1920 local ScreenH = ScrH() / 1080 local HighHPText = [[    Hey, I'm the local Doctor! You don't look like you're in very  bad shape but I can patch you         up anyway for a fee..]] local LowHPText = [[    Hey, I'm the local Doctor! You look like you've been in an     accident, let me heal you!]] local triangle = { { x = ScreenW * 270, y = ScreenH * 167 }, { x = ScreenW * 279, y = ScreenH * 177 }, { x = ScreenW * 259, y = ScreenH * 186 } } local frame = vgui.Create("DFrame") frame.btnMaxim:SetVisible(false) frame.btnMinim:SetVisible(false) frame:ShowCloseButton(false) frame:SetTitle("") frame:SetDraggable(false) //frame:SetSize(ScreenW * 600, ScreenH * 650) frame:SetSize(ScreenW * 600, ScreenW * 650) frame:Center() frame:MakePopup() local healthBoxPosW = ScreenW * 5 local healthBoxW = ScreenW * (healPriceW + ScreenW * 21) local armorBoxPosW = (healthBoxPosW + healthBoxW) + ScreenW * 5 local armorBoxW = ScreenW * (armorPriceW + ScreenW * 23) frame.Paint = function(self, w, h) draw.RoundedBox(0, 0, 0, w, h, Color(50, 50, 50)) // Main Frame draw.RoundedBox(0, ScreenW * 5, ScreenH * 45, w - ScreenW * 10, ScreenH * 600, Color(70, 70, 70)) // Secondary Frame draw.RoundedBox(0, healthBoxPosW, ScreenH * 5, healthBoxW, ScreenH * 35, Color(210, 0, 0)) // Heal price W = 173 draw.RoundedBox(0, armorBoxPosW, ScreenH * 5, armorBoxW, ScreenH * 35, Color(0, 0, 210)) // Armor price w == 193 draw.RoundedBox(0, ScreenW * 355, ScreenH * 320, ScreenW * 210, ScreenH * 75, Color(160, 0, 0)) // Heal border draw.RoundedBox(0, ScreenW * 355, ScreenH * 435, ScreenW * 210, ScreenH * 75, Color(0, 0, 160)) // Armor border draw.RoundedBox(10, ScreenW * 270, ScreenH * 60, ScreenW * 320, ScreenH * 118, Color(255, 255, 255)) // Speech bubble surface.SetDrawColor(255, 255, 255) // Speech corner draw.NoTexture() surface.DrawPoly(triangle) end I've been writing the code based on my native resolution 1920 x 1080 and implementing the scaling code however it seems when I change the resolution the padding doesn't quite work.. The Secondary frame should have 5 pixel padding either side of the main frame and this works on my native resolution but with any other resolution it's positioned more to the left than the right. Does anyone have any ideas of what I'm doing wrong? Been at it for a while now and can't seem to get my head around why it isn't scaling as intended. Thanks in advance!
When working with UI scaling, try to use percentage instead of number values when setting the size and position. For example you could get 50% of the screen's width by doing the following: ScrH() * 0.5
Why is that preferable over my method thought? From what I've read and watched when trying to learn Lua as far as I'm aware there's no reason this shouldn't be working :S
Your method works for scaling the objects (you're effectively making a percentage of the screen width/height, but using fractions instead e.g. ScrW() * 270 / 1920 - this is fine). The issue is when it comes to aligning those objects with different screen resolutions. You can't just factor in the screen size, you have to factor in how the VGUI elements are going to scale as well. To centre something (let's say horizontally) you need to divide the screen width by 2, and then subtract half the width of the panel, since all positions are relative to the top left corners. The same goes to get the y coordinate.
Hi Freeman, thanks for the explanation! I think I found a resolution in the end from another thread. It's not 100% perfect but I think that's mainly due to the size of the frame (it doesn't divide evenly, it divides more like 0.555555 which is causing a slight offset) Resolution I found (for others reference): local width = 1920 local height = 1080 local function scaleW(sw) return ScrW() * ((sw or 0) / width) end local function scaleH(sh) return ScrH() * ((sh or 0) / height) end (Added as a qoute to retain formatting)
I just think that it's a way easier way of doing UI. When you want to get 50% of your screen you have to calculate 1920 / 2 = 960. When you use the option I provided you only do ScrW() * 0.5
Sorry, you need to Log In to post a reply to this thread.