- Home /
Changing Aspect Ration on Different Resolutions
Hello, everyone! I have a GUI code that is working fine! The problem comes when I change the resolution (for example in editor from 16:9 to 4:3). The GUI elements stay in the places they have to be, but depending on the resolution sometimes the texture gets crushed horizonatally or vertically (It does not look right) . I have read a lot of topics here but I am not able to fix the problem. I hope that you will be able to help me. Here is my code -
using UnityEngine;
using System.Collections;
public class HeroStatusBar : MonoBehaviour {
private Vector2 defaultScreenRes; //Screen Resolution
[System.Serializable]
public class GUISetting
{
public Vector2 position;
public Vector2 size;
public Texture2D[] texture;
}
[System.Serializable]
public class LabelSetting
{
public Vector2 position;
public GUIStyle labelStyle;
}
[System.Serializable]
public class HerofaceSetting
{
public Vector2 position;
public Vector2 size;
public Texture texture;
public Material renderMaterial;
}
[System.Serializable]
public class BuffSetting
{
public Vector2 position;
public Vector2 size;
public float rangeBetweenBuff;
}
public GUISetting hp,sta,hg,faceFrame,nameBar; //GUI setting
public HerofaceSetting heroFace; //Hero face setting
public LabelSetting heroInfo,hpText,staText, hgText; //Text setting
public BuffSetting buffIconSetting; //Buff icon setting
//Private variable
private HeroController heroControl;
private PlayerSkill playerSkill;
private PlayerStatus playerStatus;
// Use this for initialization
void Start () {
defaultScreenRes.x = 1920; //declare max screen ratio
defaultScreenRes.y = 1080; //declare max screen ratio
GameObject go = GameObject.FindGameObjectWithTag("Player"); //Find player
heroControl = go.GetComponent<HeroController>();
playerStatus = go.GetComponent<PlayerStatus>();
playerSkill = go.GetComponent<PlayerSkill>();
}
// Update is called once per frame
void OnGUI () {
// Resize GUI Matrix according to screen size
ResizeGUIMatrix();
//Hero face
if(!GameSetting.Instance.disableFaceRender)
{
Graphics.DrawTexture(new Rect(heroFace.position.x,heroFace.position.y,heroFace.size.x ,heroFace.size.y),heroFace.texture,heroFace.renderMaterial);
}
else
{
GUI.DrawTexture(new Rect(faceFrame.position.x,faceFrame.position.y, faceFrame.size.x ,faceFrame.size.y), heroControl.heroImage);
}
//HP bar
GUI.BeginGroup(new Rect(hp.position.x, hp.position.y,hp.size.x,hp.size.y));
GUI.DrawTexture(new Rect(0,0, hp.size.x ,hp.size.y), hp.texture[0], ScaleMode.ScaleToFit);
GUI.BeginGroup(new Rect(0,0,Convert(hp.size.x,playerStatus.hpMax,playerStatus.statusCal.hp),hp.size.y));
GUI.DrawTexture(new Rect(0,0,hp.size.x,hp.size.y), hp.texture[1], ScaleMode.ScaleToFit);
GUI.EndGroup();
GUI.EndGroup();
//ST bar
GUI.BeginGroup(new Rect(sta.position.x, sta.position.y,sta.size.x,sta.size.y));
GUI.DrawTexture(new Rect(0,0, sta.size.x ,sta.size.y), sta.texture[0]);
GUI.BeginGroup(new Rect(0,0,Convert(sta.size.x,playerStatus.staMax,playerStatus.statusCal.sta),sta.size.y));
GUI.DrawTexture(new Rect(0,0,sta.size.x,sta.size.y), sta.texture[1]);
GUI.EndGroup();
GUI.EndGroup();
//Hunger bar
GUI.BeginGroup(new Rect(hg.position.x, hg.position.y, hg.size.x, hg.size.y));
GUI.DrawTexture(new Rect(0, 0, hg.size.x, hg.size.y), hg.texture[0]);
GUI.BeginGroup(new Rect(0, 0, Convert(hg.size.x, playerStatus.hgMax, playerStatus.statusCal.hg), hg.size.y));
GUI.DrawTexture(new Rect(0, 0, hg.size.x, hg.size.y), hg.texture[1]);
GUI.EndGroup();
GUI.EndGroup();
//Face Frame
GUI.DrawTexture(new Rect(faceFrame.position.x,faceFrame.position.y, faceFrame.size.x ,faceFrame.size.y), faceFrame.texture[0]);
//Name bar
GUI.DrawTexture(new Rect(nameBar.position.x,nameBar.position.y,nameBar.size.x,nameBar.size.y),nameBar.texture[0]);
//Name info
TextFilter.DrawOutline(new Rect(heroInfo.position.x ,heroInfo.position.y, 1000 , 1000)
,"Level " + playerStatus.status.lv.ToString() + " " + playerStatus.playerName,heroInfo.labelStyle,Color.black,Color.white,2f);
//HP text
TextFilter.DrawOutline(new Rect(hpText.position.x ,hpText.position.y, 1000 , 1000)
,playerStatus.statusCal.hp.ToString() + "/" + playerStatus.hpMax.ToString(),hpText.labelStyle,Color.black,Color.white,2f);
//ST text
TextFilter.DrawOutline(new Rect(staText.position.x ,staText.position.y, 1000 , 1000)
,playerStatus.statusCal.sta.ToString() + "/" + playerStatus.staMax.ToString(),staText.labelStyle,Color.black,Color.white,2f);
//Hunger text
TextFilter.DrawOutline(new Rect(hgText.position.x, hgText.position.y, 1000, 1000)
, playerStatus.statusCal.hg.ToString() + "/" + playerStatus.hgMax.ToString(), hgText.labelStyle, Color.black, Color.white, 2f);
//Effect Icon
for (int i=0;i<playerSkill.durationBuff.Length;i++)
{
if(playerSkill.durationBuff[i].isCount)
{
GUI.DrawTexture(new Rect(buffIconSetting.position.x + (i*buffIconSetting.rangeBetweenBuff) ,buffIconSetting.position.y,buffIconSetting.size.x,buffIconSetting.size.y),playerSkill.durationBuff[i].skillIcon);
}
}
// Reset matrix after finish
GUI.matrix = Matrix4x4.identity;
}
void ResizeGUIMatrix()
{
// Set matrix
Vector2 ratio = new Vector2(Screen.width/defaultScreenRes.x , Screen.height/defaultScreenRes.y );
Matrix4x4 guiMatrix = Matrix4x4.identity;
guiMatrix.SetTRS(new Vector3(1, 1, 1), Quaternion.identity, new Vector3(ratio.x, ratio.y, 1));
GUI.matrix = guiMatrix;
}
float Convert(float maxWidthGUI, float maxValue, float curValue) //Calculate hp bar-st bar
{
float val = maxWidthGUI/maxValue;
float load = curValue*val;
return load;
}
}
Answer by FortisVenaliter · Apr 11, 2017 at 03:49 PM
There's generally no one right way to get the aspect ratios to work, so it's unlikely anyone will be able to address your code directly and give you a fix.
Making UIs work for multiple resolutions is a design problem, not a programming problem. You need to design the UI to work for all resolutions you allow. If something ends up squished, you need to move it to somewhere where it won't.
For the extreme fringe cases, you can just run an if check for whether the aspect ratio is wide enough, and otherwise switch to a narrower layout. Try to avoid that if you can, though, because it usually means two code paths for the same functionality, which makes later maintenance more expensive.
There are a lot of good guides online for developing reactive UIs. Check them out, read up on the subject, and tackle it with new eyes.
Thank you for this comment, @FortisVenaliter ! So you cannot give me some guidence on where should I find the solution for my problem?
No, I can't fix it, but I can point you in the right direction.
Thank you for this! I have read this article, but I am not sure wheather its for my case. I am using interface that is generated from the code. I cannot modify the different elements like when for example I add an image from the UI unity menu.
Your answer