Opinion on some code...

Hey all,

I’ve just made a quick, rough cutt stat system in Unity. Problem is, it looks so messy! I was wondering if anyone could provide some input on how I could clean up this code? I mean, the code works as it should, but I want to learn about better ways to do things so I can use it for future reference :smile:

The code…

            // Unlock that cursor
            Cursor.lockState = CursorLockMode.None;

            // Begin that group
            GUI.BeginGroup(new Rect(Screen.width / 2 - 175, Screen.height / 2 - 175, 350, 350), "");
               
                // Draw them labels and boxes
                GUI.Box(new Rect(0, 0, 350, 350), "Stats: ");
                GUI.Label(new Rect(10, 20, 200, 30), "Additonal Points: " + aditionalPoints);
               
                // Strength
                GUI.Label(new Rect(10, 60, 100, 30), "STR: " + str);
                    if(GUI.Button(new Rect(200, 60, 20, 20), " + "))
                    {
                        if(aditionalPoints > 0)
                        {
                            str = str + 1;
                            aditionalPoints = aditionalPoints - 1;
                        }
                    }

                // Intelligence
                GUI.Label(new Rect(10, 100, 100, 30), "INT: " + intel);
                    if(GUI.Button(new Rect(200, 100, 20, 20), " + "))
                    {
                        if(aditionalPoints > 0)
                        {
                            intel = intel + 1;
                            aditionalPoints = aditionalPoints - 1;
                        }
                    }

                // Vitality
                GUI.Label(new Rect(10, 140, 100, 30), "VIT: " + vit);
                    if(GUI.Button(new Rect(200, 140, 20, 20), " + "))
                    {
                        if(aditionalPoints > 0)
                        {
                            vit = vit + 1;
                            aditionalPoints = aditionalPoints - 1;
                        }
                    }

                // Defense
                GUI.Label(new Rect(10, 180, 100, 30), "DEF: " + def);
                    if(GUI.Button(new Rect(200, 180, 20, 20), " + "))
                    {
                        if(aditionalPoints > 0)
                        {
                            def = def + 1;
                            aditionalPoints = aditionalPoints - 1;
                        }
                    }
            GUI.EndGroup();

You could use GUILayout.BeginVertical() and consequently GUILayout.Button() etc to automatically layout the elements. That way you can more easily reposition them later if need be. Also, you should consider checking out the new GUI system.

As for the code itself, the code consists of repeating blocks, so you can refactor methods out of this.

private int _additionalPoints, _strength, _intelligence, _charisma;
   
void OnGUI()
{
    GUILayout.BeginVertical();
    DrawStatGUI("STR", ref _strength);
    GUILayout.Space(20);
    DrawStatGUI("INT", ref _intelligence);
    GUILayout.Space(20);
    DrawStatGUI("CHA", ref _charisma);
    GUILayout.EndVertical();
}

void DrawStatGUI(string name, ref int stat)
{
    GUILayout.BeginHorizontal();
    GUILayout.Label(name + ":");
    if (GUILayout.Button("+"))
        IncrementStat(ref stat);
    GUILayout.EndHorizontal();
}

private void IncrementStat(ref int stat)
{
    stat++;
    _additionalPoints--;
}
1 Like

Thanks :smile: I’ll give the code a try and also look at the new GUI System in more depth :smile:

Okay, I’ve tried the new code you suggested and it worked! A few tweaks, and I got it to how I want :slight_smile:

There is one slight problem though. From the sceenshot, the + button is wayyyy to far over to the right. I’ve been trying different things to move it back over to the left, but no luck xD

Could you show us your code, have you made any modifications to the example code ThomasCreate provided?
I copy and pasted his code into a blank scene, and there is no large spacing between the attributes and the + buttons for me.

Sure, here we go :smile: I added a new button, the minus button which gets rid of the gap. But I may not keep it in there. So when I remove it, it just puts the boxes back to the right again.

I’m also have the same problem with my options screen which I am doing the same way as the stat window. I’m not sure how I get GUILayout.BeginVertical(); to move all of what it contains, to the left or right (some sort of offset)

public Rect statWindowRect = new Rect(Screen.width / 2 - 175, Screen.height / 2 - 175, 350, 350);

        if(openStatsWindow)
        {

            statWindowRect = GUILayout.Window(0, statWindowRect, OpenStatWindow, "", GUILayout.Width(250), GUILayout.Height(400));

        }

/* STAT WINDOW */
    void OpenStatWindow(int windowID)
    {
        // Unlock the cursor
        Cursor.lockState = CursorLockMode.None;

        // Wrap it up GUI
        GUILayout.BeginVertical();
            GUILayout.Space (45);
                GUILayout.Label ("STATS", GUI.skin.GetStyle("StatWindow"), GUILayout.Width (150), GUILayout.Height(32));
            GUILayout.Space(20);
                GUILayout.Label("Points: " + aditionalPoints, GUI.skin.GetStyle("StatWindow"), GUILayout.Width(150), GUILayout.Height(32));
            GUILayout.Space(20);
                DrawStatGUI("STR: ", ref str);
            GUILayout.Space(15);
                DrawStatGUI("INT: ", ref intel);
            GUILayout.Space(15);
                DrawStatGUI("VIT: ", ref vit);
            GUILayout.Space(15);
                DrawStatGUI("DEF: ", ref def);
            GUILayout.Space (5);
                if(GUILayout.Button("Close", GUILayout.Width(100), GUILayout.Height(31)))
                {
                    openStatsWindow = false;
                }
        GUILayout.EndVertical();
        GUI.DragWindow();
    }
  
    void DrawStatGUI(string name, ref int stat)
    {
        GUILayout.BeginHorizontal ();
        GUILayout.Label (name + stat, GUILayout.Width(100));
        GUILayout.FlexibleSpace ();

        if(GUILayout.Button("+", GUILayout.Width(50)))
        {
            if(aditionalPoints > 0)
            {
                IncrementStat(ref stat);
            }
        }
        if(GUILayout.Button("-", GUILayout.Width(50)))
        {
            if(aditionalPoints > 0)
            {
                DecrementStat(ref stat);
            }
        }
        GUILayout.EndHorizontal ();
    }

    private void IncrementStat(ref int stat)
    {
        stat++;
        aditionalPoints--;
    }

    private void DecrementStat(ref int stat)
    {
        if(stat != 5)
        {
            stat--;
            aditionalPoints++;
        }
    }

Hey all,

I think I might no what my problem is…I guess I was looking for something along the lines of “GUI.BeginArea()” so I could shift each element to where I wanted it instead of having it automatically place everything for me. e.g. A slider bar with a label next to it on the same Y axis.

However, I’ve found out GUI.BeginArea() and GUILayout.Window don’t play ball together as GUILayout.Window thinks there is no content in there, causing there to be a dot of a texture if I try and use GUI.BeginArea()

Therefore, I’ve opted to just use the GUI.Window option and just use regular ol’ GUI.Label etc… as I know of no other way to fix the problem xD

Have you tried changing the number in the following line?
GUILayout.Label (name + stat, GUILayout.Width(100));

I have, yeah :slight_smile: