Ways to make HUD scale on different resoultions

Hi all,

Today I was making a HUD and it looked great. I tested it out at 1920x1080 and didn’t think it would be a problem on other resoultions as I was multiplying the width/height of the screen by a decimal ( e.g. 0.4 )
But I then had problems when I downscaled the resoultion where the elements started to overlap oneanother.

Can anyone suggest the proper way to make a HUD that scales properly with other resoultions,

Thank you,
Computer600

PS: Happy new year

You will need design the HUD around percentages of the screen. You will need to use ScrW() and ScrH() in calculating sizes and positions.

I can’t give you specific tips without seeing the HUD at least. Avoid static numbers in the size and position variables and you will be fine.

Here is what i do first

draw.RoundedBox

[lua]
draw.RoundedBox( number cornerRadius, number x, number y, number width, number height, table color)
[/lua]

[lua]draw.RoundedBox(0, 500, 800, 200, 500, Color(255,255,255) ) [/lua]

[lua]draw.RoundedBox(0, ScrW()(500/1920), ScrW()(800/1920), ScrW()(200/1920), ScrW()(500/1920), Color(255,255,255) ) [/lua]

NEVER USE ScrH(), else players using a 4:3 screen/resolution will have a … well look like a bad photoshop.

Oh, and be careful, if you want to also add Triple monitor support, your lines will quickly look like that :

[lua]
draw.BoxRotated(GryMod.EyeFinityScrW()-(GryMod.EyeFinityScrW()(269/1920))+ ((GryMod.EyeFinityScrW()(40/1920))-(math.MapSimple(math.Min(LocalPlayer():GetNWInt(“GryEnergy”),20 ), 20, (GryMod.EyeFinityScrW()(40/1920)))))+ GryModXDistance:GetInt() + GryModXDistance2:GetInt(),ScrH()-(GryMod.EyeFinityScrW()(133/1920)), math.MapSimple(math.Min(LocalPlayer():GetNWInt(“GryEnergy”),20 ), 20, (GryMod.EyeFinityScrW()*(40/1920))),(GryMod.EyeFinityScrW()/84), Color(20,150,230,alpha_ch[1]), 3.5)
[/lua]

Yes, this is one line.

You will maybe make your own drawing function, so you can code without changing your code, i’m thing about something like

[lua]local function draw_RoundedBox( cornerRadius, x, y, width,height, color)
return draw.RoundedBox( ScrW()(cornerRadius/1920), ScrW()(x/1920), ScrW()(y/1920), ScrW()(width/1920), ScrW()*(height/1920), color)
end
[/lua]

(Did not test)

Or maybe

at the top of your file :

[lua]
local draw = draw
local draw_RoundedBox = draw.RoundedBox

function draw.RoundedBox(( cornerRadius, x, y, width,height, color)
return draw_RoundedBox( ScrW()(cornerRadius/1920), ScrW()(x/1920), ScrW()(y/1920), ScrW()(width/1920), ScrW()*(height/1920), color)
end
[/lua]

So you can update an old code with that
(did not test)

I don’t think ExtReMLapin’s “advises” are very good.

Never use ScrH()?

What the hell is this?


draw.RoundedBox(0, ScrW()*(500/1920), ScrW()*(800/1920), ScrW()*(200/1920), ScrW()*(500/1920), Color(255,255,255) ) 

Not the best coding practice.

Here’s example of how I do HUD:

Benefits are:

  1. I can easily change size and position of the element
  2. Less code
  3. Possibly faster
  4. Scales properly on all resolutions

It does not have support for triple monitor setups, but lets be realistic, such setups are very rare.

Here: https://dl.dropboxusercontent.com/u/26074909/tutoring/vgui/understanding_hardcoding_of_screensizes.lua.html

Application: https://dl.dropboxusercontent.com/u/26074909/tutoring/hud/basic_healthbar.lua.html

If you’re just randomly multiplying 0.4 to some width / height then you’re going to get the same result regardless of resolution. If you plan on hard-coding the sizes you’ll need a modifier to adjust those values based on the hard-coded resolution and the current resolution.

So, if I hard-code something at 1600 x 1200 and someone visits using 800 x 600 then the x modifier needs to be 0.5 and so does the y modifier. The xmod gets applied to x and width whereas ymod gets applied to y and height; unless we use ScrW or ScrH in any of those calculations… We only want to apply the modifier once. If we use ScrW / ScrH in any calculations and we apply the modifier incorrectly it’ll give us a bad result… which is why you commit to hard-coding for one resolution and when it looks right modify the values…

Example, say we want something to be 50 units from the right side of the screen… ScrW( ) - 50; Now, if we applied a modifier to the entire thing we’d modify the users resolution var instead of the hard-coded distance which we want to change. ScrW( ) - 50 * xMod would be what we want where we modify 50, the hard-coded value so it can change in relation to our change in resolution.

Also don’t forget to scale your font sizes as well, 13px tall text on a 4K screen is rather small.

I mean, if you’re using what i said (with the ScrW()* (px/yourresulution.x)

and if you’re using ScrW AND ScrH, it will look okay on your monitor (16/9) but when you’ll move on a 4:3 monitor, it will look like shit.

Let me explain myself, let’s say you have this picture.

http://www.ibst.org/img/building-science-city.png

If you want to scale it, you’ll need to resize the W and the H with the same ratio so it will look like this :

http://puu.sh/dVpyn/156b6534a6.jpg

If you try to resize the W and the H with its own ratio, it’s okay only if every monitors in the world are in the same format.

BUT, if some players have a 4:3 monitor, your hud_part will look like this

http://puu.sh/dVpKr/b6c4317a71.jpg

So yeah, i was right.

Did you even read ?

Yes, I did read, you just didn’t specify as you should have that you shouldn’t use ScrH() if you are designing the HUD as one big image using your method, which is not a good idea to do because of the point you provided in your post.

Oh, ok

I still don’t see the point about scaling the picture. It’s obvious you won’t scale the picture by BOTH ScrW() and ScrH(). You’d pick one of those to determine the (width or height) of the image, then multiply that by the ratio of the image itself to get the other dimension so that the image retains its own ratio, not 16:9 or 4:3 or whatever.