Search Unity

[SOLVED]Adding and Removing GUI elements at runtime

Discussion in 'Immediate Mode GUI (IMGUI)' started by cyangamer, Aug 13, 2010.

  1. cyangamer

    cyangamer

    Joined:
    Feb 17, 2010
    Posts:
    234
    Hi. I'm doing an inventory system where items will be appearing and disappearing from the GUI. I'm getting errors because of this tidbit:
    So it seems the logical choice is to somehow have both the events complete, then change the GUI, and then let the next two events run.

    I have no idea how to time the events like that though.
    Here's my code snippet:
    Code (csharp):
    1. if (equipPossess.getNumItems(Equippable.IronArmor) > 0)
    2.             {
    3.                 GUILayout.BeginHorizontal();
    4.                 GUILayout.Label(equipPossess.getItem(Equippable.IronArmor).itemIcon, GUILayout.Height(30), GUILayout.Width(30));
    5.                 GUILayout.Label(equipPossess.getItem(Equippable.IronArmor).itemName + " (x"
    6.                     + equipPossess.getNumItems(Equippable.IronArmor) + ")");
    7.                 items[1] = GUILayout.Button(equipOrNot[1], GUILayout.Width(70), GUILayout.Height(20));
    8.                 GUILayout.EndHorizontal();
    9.             }
    Essentially, "Iron Armor' is a type of body armor, and if there's at least 1, will be displayed. When this item is equipped to the player, the item is to disappear from the list, so if there was only 1 Iron Armor, then the whole entry should disappear.
     
  2. AkilaeTribe

    AkilaeTribe

    Joined:
    Jul 4, 2010
    Posts:
    1,149
    I don't understand, are you having a bug ? What is it (visual aspect, errors in console...)?
     
  3. cyangamer

    cyangamer

    Joined:
    Feb 17, 2010
    Posts:
    234
    Error:
     
  4. Dreamora

    Dreamora

    Joined:
    Apr 5, 2008
    Posts:
    26,601
    sure its that block of code causing it?

    your problem sounds more like it comes from a block with

    BeginHorizontal
    loop(0 to x) drawelements
    EndHorizontal


    in that case you would need an if around the whole thing, cause in case of 0 elements you must never enter the block (that or not use GUILayout at all, cause guilayout blocks expect that you put something in or burn your ass ;) )


    also you don't need to mess with events, its not like you get anything from them in your case
     
    darwin-brandao likes this.
  5. cyangamer

    cyangamer

    Joined:
    Feb 17, 2010
    Posts:
    234
    I don't have any block like that in my code, but I have nested all my for loops (that use a .Length as the upper bound) inside an if branch. The problem still persists though.

    Like the code snippet showed, the Horizontal group is nested in an if branch, so it should begin nor end if there's nothing to display. :?
     
  6. andeeeee

    andeeeee

    Joined:
    Jul 19, 2005
    Posts:
    8,768
    Can you post the script that defines the class of the equipPossess object? Also, can you post the whole of the OnGUI function?
     
  7. cyangamer

    cyangamer

    Joined:
    Feb 17, 2010
    Posts:
    234
    Sure no problem! Here's the EquipmentPossess class

    Code (csharp):
    1. public class EquipmentPossess : MonoBehaviour
    2. {
    3.     /**** GRAND LIST OF EQUIPMENT *****
    4.      * 0. Bronze Armor
    5.      * 1. Iron Armor
    6.      * 2. Proto Armor
    7.      * 3. Alpha Stone
    8.      * 4. Beta Stone
    9.      */
    10.     int bronze, iron, proto, alpha, beta;
    11.     Dictionary<Transform, int> equipment;
    12.     public Dictionary<Transform, int> Equipment
    13.     {
    14.         get { return equipment; }
    15.     }
    16.  
    17.     public Transform[] objects;
    18.     UnityEngine.Object i;
    19.  
    20.     void Awake()
    21.     {
    22.         //Create a Dictionary mapping Item Prefabs to the amount.
    23.         equipment = new Dictionary<Transform, int>();
    24.         for (int j = 0; j < objects.Length; j++)
    25.         {
    26.             equipment.Add(objects[j], 0);
    27.         }
    28.  
    29.         //Map the integers to the Equippable enums
    30.         bronze = (int)Equippable.BronzeArmor;
    31.         iron = (int)Equippable.IronArmor;
    32.         proto = (int)Equippable.ProtoArmor;
    33.         alpha = (int)Equippable.AlphaStone;
    34.         beta = (int)Equippable.BetaStone;
    35.     }
    36.  
    37.     void Start()
    38.     {
    39.         equipment[objects[proto]] = 1;
    40.         equipment[objects[bronze]] = 2;
    41.         equipment[objects[alpha]] = 1;
    42.         equipment[objects[beta]] = 2;
    43.     }
    44.  
    45.     //This will return the quantity of a given item 'a'.
    46.     public int getNumItems(Equippable a)
    47.     {
    48.         return equipment[objects[(int)a]];
    49.     }
    50.  
    51.     //This will return the item that's used.
    52.     public Equipment getItem(Equippable a)
    53.     {
    54.         return objects[(int)a].GetComponent<Equipment>();
    55.     }
    56.  
    57.     //This will adjust the quantity of an item
    58.     public void setNumItems(Equippable a, int amount)
    59.     {
    60.         equipment[objects[(int)a]] += amount;
    61.     }
    62.  
    63.     //This will return the item that's used.
    64.     public Equipment getItem(int a)
    65.     {
    66.         return objects[a].GetComponent<Equipment>();
    67.     }
    68.  
    69.     public bool anyItems()
    70.     {
    71.         int result = 0;
    72.         for (int i = 0; i < 17; i++)
    73.         {
    74.             result += equipment[objects[i]];
    75.         }
    76.         if (result == 0)
    77.         { return false; }
    78.         else { return true; }
    79.     }
    80. }
    The OnGUI method's quite lengthy, so it was divided into several methods based on the purpose and all called with the OnGUI method. Just to be safe though, here's the code:

    Code (csharp):
    1. void OnGUI()
    2.     {
    3.         GUI.skin = thisCyanSkin;
    4.         Setup();
    5.     }
    6.  
    7. void Setup()
    8.     {
    9.         /* SET UP OF VARIABLES */
    10.         skills[0] = SP1_level1_On ? cyanColored : normal;
    11.         skills[1] = SP1_level2_On ? cyanColored : normal;
    12.         skills[2] = SP1_level3_On ? cyanColored : normal;
    13.         skills[3] = SP2_level1_On ? cyanColored : normal;
    14.         skills[4] = SP2_level2_On ? cyanColored : normal;
    15.         skills[5] = SP2_level3_On ? cyanColored : normal;
    16.  
    17.         //Set up the menu
    18.         GUILayout.BeginArea(new Rect(xWindow, yWindow, lWin, hWin));
    19.         BasicStats();
    20.         Skills();
    21.         Equipment();
    22.         GUILayout.EndArea();
    23.     }
    24.  
    25. /* BASIC STATS */
    26.     void BasicStats()
    27.     {
    28.         GUILayout.BeginArea(new Rect(0, 0, 640, 160), style);
    29.         GUILayout.Label("Basic Stats", boldened);
    30.         GUILayout.BeginHorizontal();
    31.         GUILayout.BeginVertical(GUILayout.Width(120));
    32.         GUILayout.Label(statsIcon, normal);
    33.         GUILayout.EndVertical();
    34.         GUILayout.BeginVertical(GUILayout.Width(60));
    35.         GUILayout.Label("Name: ", normal);
    36.         GUILayout.Label("Level: ", normal);
    37.         GUILayout.Label("EXP: ", normal);
    38.         GUILayout.Label("Next: ", normal);
    39.         GUILayout.Label("Status: ", normal);
    40.         GUILayout.EndVertical();
    41.         GUILayout.BeginVertical(GUILayout.Width(160));
    42.         GUILayout.Label(player.chara.name, normal);
    43.         GUILayout.Label(player.level.ToString(), normal);
    44.         GUILayout.Label(player.Experience.ToString(), normal);
    45.         GUILayout.Label(player.ToNextL.ToString(), normal);
    46.         GUILayout.Label(player.chara.status.ToString(), normal);
    47.         GUILayout.EndVertical();
    48.         GUILayout.BeginVertical(GUILayout.Width(60));
    49.         GUILayout.Label("HP: ", normal);
    50.         GUILayout.Label("MP: ", normal);
    51.         GUILayout.Label("Attack: ", normal);
    52.         GUILayout.Label("Wisdom: ", normal);
    53.         GUILayout.Label("Defense: ", normal);
    54.         GUILayout.Label("Agility: ", normal);
    55.         GUILayout.EndVertical();
    56.         GUILayout.BeginVertical(GUILayout.Width(100));
    57.         GUILayout.Label(player.chara.hp.ToString() + " / " + player.chara.maxHP.ToString(), normal);
    58.         GUILayout.Label(player.chara.mp.ToString() + " / " + player.chara.maxMP.ToString(), normal);
    59.         GUILayout.Label(player.chara.attack.ToString(), normal);
    60.         GUILayout.Label(player.chara.wisdom.ToString(), normal);
    61.         GUILayout.Label(player.chara.defense.ToString(), normal);
    62.         GUILayout.Label(player.chara.agility.ToString(), normal);
    63.         GUILayout.EndVertical();
    64.         GUILayout.EndHorizontal();
    65.         GUILayout.EndArea();
    66.     }
    67.  
    68.     /* SKILLS ( KANOHI) CONFIGURATION */
    69.     void Skills()
    70.     {
    71.         GUILayout.BeginArea(new Rect(0, 160, 640, 160), style);
    72.         GUILayout.Label("Kanohi and Skills", boldened);
    73.         GUILayout.BeginHorizontal();
    74.         //Kanohi Panel
    75.         GUILayout.BeginVertical(GUILayout.Width(280));
    76.         GUILayout.Space(20);
    77.         GUILayout.BeginHorizontal();
    78.         for (int i = 0; i < 6; i++)
    79.         {
    80.             kanohi[i] = GUILayout.Toggle(kanohi[i], "", kanohiMasks[i], GUILayout.Width(40), GUILayout.Height(40));
    81.         }
    82.         GUILayout.EndHorizontal();
    83.         GUILayout.Space(10);
    84.         GUILayout.BeginHorizontal();
    85.         for (int i = 6; i < 12; i++)
    86.         {
    87.             kanohi[i] = GUILayout.Toggle(kanohi[i], "", kanohiMasks[i], GUILayout.Width(40), GUILayout.Height(40));
    88.         }
    89.         GUILayout.EndHorizontal();
    90.         GUILayout.EndVertical();
    91.         //Skill Points Panel
    92.         GUILayout.BeginVertical(GUILayout.Width(120));
    93.         GUILayout.Label("\nSkill Points", normal);
    94.         GUILayout.Label(player.SkillPoints.ToString(), big, GUILayout.Width(100));
    95.         GUILayout.EndVertical();
    96.         GUILayout.BeginVertical(GUILayout.Width(120));
    97.         GUILayout.Label("\nSkill Level", normal);
    98.         //The Skill level for the first skill
    99.         GUILayout.BeginHorizontal();
    100.         SP1_level1_On = GUILayout.Toggle(SP1_level1_On, "", level1, GUILayout.Width(20), GUILayout.Height(20));
    101.         GUILayout.Space(10);
    102.         if (SP1_level1_On)
    103.         {
    104.             SP1_level2_On = GUILayout.Toggle(SP1_level2_On, "", level2, GUILayout.Width(20), GUILayout.Height(20));
    105.         }
    106.         else
    107.         {
    108.             GUILayout.Label("", level2, GUILayout.Width(20), GUILayout.Height(20));
    109.             SP1_level2_On = false;
    110.         }
    111.         GUILayout.Space(10);
    112.         if (SP1_level1_On  SP1_level2_On)
    113.         {
    114.             SP1_level3_On = GUILayout.Toggle(SP1_level3_On, "", level3, GUILayout.Width(20), GUILayout.Height(20));
    115.         }
    116.         else
    117.         {
    118.             GUILayout.Label("", level3, GUILayout.Width(20), GUILayout.Height(20));
    119.             SP1_level3_On = false;
    120.         }
    121.         GUILayout.EndHorizontal();
    122.         GUILayout.Space(5);
    123.         //The Skill level for the second skill
    124.         GUILayout.BeginHorizontal();
    125.         SP2_level1_On = GUILayout.Toggle(SP2_level1_On, "", level1, GUILayout.Width(20), GUILayout.Height(20));
    126.         GUILayout.Space(10);
    127.         if (SP2_level1_On)
    128.         {
    129.             SP2_level2_On = GUILayout.Toggle(SP2_level2_On, "", level2, GUILayout.Width(20), GUILayout.Height(20));
    130.         }
    131.         else
    132.         {
    133.             GUILayout.Label("", level2, GUILayout.Width(20), GUILayout.Height(20));
    134.             SP2_level2_On = false;
    135.         }
    136.         GUILayout.Space(10);
    137.         if (SP2_level1_On  SP2_level2_On)
    138.         {
    139.             SP2_level3_On = GUILayout.Toggle(SP2_level3_On, "", level3, GUILayout.Width(20), GUILayout.Height(20));
    140.         }
    141.         else
    142.         {
    143.             GUILayout.Label("", level3, GUILayout.Width(20), GUILayout.Height(20));
    144.             SP2_level3_On = false;
    145.         }
    146.         GUILayout.EndHorizontal();
    147.         GUILayout.EndVertical();
    148.         //The list of skills
    149.         GUILayout.BeginVertical(GUILayout.Width(120));
    150.         GUILayout.Label("Wateraga", skills[2]);
    151.         GUILayout.Label("Watera", skills[1]);
    152.         GUILayout.Label("Water", skills[0]);
    153.         GUILayout.Label("", normal);
    154.         GUILayout.Label("Toa", skills[3]);
    155.         GUILayout.Label("Toara", skills[4]);
    156.         GUILayout.Label("Toaraga", skills[5]);
    157.         GUILayout.EndVertical();
    158.         GUILayout.EndHorizontal();
    159.         GUILayout.EndArea();
    160.     }
    161.  
    162.     /* EQUIPMENT */
    163.     void Equipment()
    164.     {
    165.         GUILayout.BeginArea(new Rect(0, 320, 640, 160), style);
    166.         GUILayout.Label("Equipment", boldened);
    167.         GUILayout.BeginHorizontal();
    168.         GUILayout.BeginVertical(GUILayout.Width(60));
    169.         GUILayout.Label("Weapon: ", normal);
    170.         GUILayout.Space(6);
    171.         GUILayout.Label("Kanohi: ", normal);
    172.         GUILayout.Space(6);
    173.         GUILayout.Label("Armor: ", normal);
    174.         GUILayout.Space(6);
    175.         GUILayout.Label("Stone: ", normal);
    176.         GUILayout.Space(6);
    177.         GUILayout.Label("Accessory: ", normal);
    178.         GUILayout.Space(6);
    179.         GUILayout.EndVertical();
    180.         GUILayout.BeginVertical(GUILayout.Width(100));
    181.         GUILayout.Label("Cyan Sword", normal);
    182.         GUILayout.Space(6);
    183.         GUILayout.Label(mask, normal);
    184.         GUILayout.Space(6);
    185.         GUILayout.Label(armor, normal);
    186.         GUILayout.Space(6);
    187.         GUILayout.Label(stone, normal);
    188.         GUILayout.Space(6);
    189.         GUILayout.Label(extra, normal);
    190.         GUILayout.Space(6);
    191.         GUILayout.EndVertical();
    192.         GUILayout.BeginVertical(GUILayout.Width(160));
    193.         for (int i = 0; i < 5; i++)
    194.         {
    195.             changeEquipment[i] = GUILayout.Button("Change", GUILayout.Width(60), GUILayout.Height(16));
    196.         }
    197.         GUILayout.EndVertical();
    198.         ChangeEquipment();
    199.         GUILayout.EndHorizontal();
    200.         GUILayout.EndArea();
    201.     }
    202.  
    203.     /* This method handles the right side of the equipment
    204.      * panel. You choose which item you want to equip
    205.      * from a list */
    206.     void ChangeEquipment()
    207.     {
    208.         //If the Weapons panel is activated
    209.         if (changeEquipment[5])
    210.         {
    211.             GUILayout.BeginVertical(GUILayout.Width(320));
    212.             scrollPosition = GUILayout.BeginScrollView(scrollPosition, GUILayout.Width(280), GUILayout.Height(120));
    213.             GUILayout.EndScrollView();
    214.             GUILayout.EndVertical();
    215.         }
    216.  
    217.         //If the Kanohi panel is activated
    218.         if (changeEquipment[6])
    219.         {
    220.             GUILayout.BeginVertical(GUILayout.Width(320));
    221.             scrollPosition = GUILayout.BeginScrollView(scrollPosition, GUILayout.Width(280), GUILayout.Height(120));
    222.             GUILayout.EndScrollView();
    223.             GUILayout.EndVertical();
    224.         }
    225.  
    226.         //If the Armor panel is activated, then display all of the armor equipment ([Icon][Name][Equip Button]).
    227.         //The 'if' blocks below handle what happen if the Equip button is pressed.
    228.         if (changeEquipment[7])
    229.         {
    230.             GUILayout.BeginVertical(GUILayout.Width(320));
    231.             scrollPosition = GUILayout.BeginScrollView(scrollPosition, GUILayout.Width(280), GUILayout.Height(120));
    232.  
    233.             //BRONZE ARMOR
    234.             if (equipPossess.getNumItems(Equippable.BronzeArmor) > 0)
    235.             {
    236.                 GUILayout.BeginHorizontal();
    237.                 GUIContent bronzeArm = new GUIContent(equipPossess.getItem(Equippable.BronzeArmor).itemName + " (x"
    238.                     + equipPossess.getNumItems(Equippable.BronzeArmor) + ")", equipPossess.getItem(Equippable.BronzeArmor).itemIcon);
    239.                 GUILayout.Label(bronzeArm, GUILayout.Height(30));
    240.                 items[0] = GUILayout.Button(equipOrNot[0], GUILayout.Width(70), GUILayout.Height(20));
    241.                 GUILayout.EndHorizontal();
    242.             }
    243.  
    244.             //IRON ARMOR
    245.             if (equipPossess.getNumItems(Equippable.IronArmor) > 0)
    246.             {
    247.  
    248.             }
    249.  
    250.             //PROTO ARMOR
    251.             if (equipPossess.getNumItems(Equippable.ProtoArmor) > 0)
    252.             {
    253.                 GUILayout.BeginHorizontal();
    254.                 GUIContent protoArm = new GUIContent(equipPossess.getItem(Equippable.ProtoArmor).itemName + " (x"
    255.                     + equipPossess.getNumItems(Equippable.ProtoArmor) + ")", equipPossess.getItem(Equippable.ProtoArmor).itemIcon);
    256.                 GUILayout.Label(protoArm, GUILayout.Height(30));
    257.                 items[2] = GUILayout.Button(equipOrNot[2], GUILayout.Width(70), GUILayout.Height(20));
    258.                 GUILayout.EndHorizontal();
    259.             }
    260.  
    261.             //This is the default Unequip button. This is for if there's only one armor equipment in the inventory.
    262.             items[3] = GUILayout.Button("Unequip", GUILayout.Width(70), GUILayout.Height(20));
    263.  
    264.             GUILayout.EndScrollView();
    265.             GUILayout.EndVertical();
    266.  
    267.             //These if blocks decide what happens with the Equip or Unequip button is pressed
    268.             if (items[0])
    269.             {
    270.                 if (!itemsEquipped[0])
    271.                 {
    272.                     if (player.Armor == null)
    273.                     {
    274.                         player.Armor = equipPossess.getItem(Equippable.BronzeArmor);
    275.                         equipPossess.setNumItems(Equippable.BronzeArmor, -1);
    276.                         armor = equipPossess.getItem(Equippable.BronzeArmor).itemName;
    277.                     }
    278.                 }
    279.                 else
    280.                 {
    281.                     equipPossess.setNumItems(Equippable.BronzeArmor, 1);
    282.                     armor = "";
    283.                     player.Armor = null;
    284.                 }
    285.             }
    286.  
    287.             if (items[1])
    288.             {
    289.                 if (!itemsEquipped[1])
    290.                 {
    291.                     if (player.Armor == null)
    292.                     {
    293.                         player.Armor = equipPossess.getItem(Equippable.IronArmor);
    294.                         equipPossess.setNumItems(Equippable.IronArmor, -1);
    295.                         armor = equipPossess.getItem(Equippable.IronArmor).itemName;
    296.                     }
    297.                 }
    298.                 else
    299.                 {
    300.                     equipPossess.setNumItems(Equippable.IronArmor, 1);
    301.                     armor = "";
    302.                     player.Armor = null;
    303.                 }
    304.             }
    305.  
    306.             if (items[2])
    307.             {
    308.                 if (!itemsEquipped[2])
    309.                 {
    310.                     if (player.Armor == null)
    311.                     {
    312.                         player.Armor = equipPossess.getItem(Equippable.ProtoArmor);
    313.                         equipPossess.setNumItems(Equippable.ProtoArmor, -1);
    314.                         armor = equipPossess.getItem(Equippable.ProtoArmor).itemName;
    315.                     }
    316.                 }
    317.                 else
    318.                 {
    319.                     equipPossess.setNumItems(Equippable.ProtoArmor, 1);
    320.                     armor = "";
    321.                     player.Armor = null;
    322.                 }
    323.             }
    324.  
    325.             //The Default Unequip button
    326.             if (items[3])
    327.             {
    328.                 if (player.Armor == equipPossess.getItem(Equippable.ProtoArmor)) equipPossess.setNumItems(Equippable.ProtoArmor, 1);
    329.                 if (player.Armor == equipPossess.getItem(Equippable.BronzeArmor)) equipPossess.setNumItems(Equippable.BronzeArmor, 1);
    330.                 if (player.Armor == equipPossess.getItem(Equippable.IronArmor)) equipPossess.setNumItems(Equippable.IronArmor, 1);
    331.                 player.Armor = null;
    332.                 armor = "";
    333.             }
    334.         }
    335.  
    336.         //If the Stone panel is activated. See Armor for full description
    337.         if (changeEquipment[8])
    338.         {
    339.             GUILayout.BeginVertical(GUILayout.Width(320));
    340.             scrollPosition = GUILayout.BeginScrollView(scrollPosition, GUILayout.Width(280), GUILayout.Height(120));
    341.  
    342.             //ALPHA STONE
    343.             if (equipPossess.getNumItems(Equippable.AlphaStone) > 0)
    344.             {
    345.                 GUILayout.BeginHorizontal();
    346.                 GUILayout.Label(equipPossess.getItem(Equippable.AlphaStone).itemIcon, GUILayout.Height(30), GUILayout.Width(30));
    347.                 GUILayout.Label(equipPossess.getItem(Equippable.AlphaStone).itemName + " ("
    348.                     + equipPossess.getNumItems(Equippable.BronzeArmor) + ")");
    349.                 items[0] = GUILayout.Button(equipOrNot[0], GUILayout.Width(70), GUILayout.Height(20));
    350.                 GUILayout.EndHorizontal();
    351.             }
    352.  
    353.             //BETA STONE
    354.             if (equipPossess.getNumItems(Equippable.BetaStone) > 0)
    355.             {
    356.                 GUILayout.BeginHorizontal();
    357.                 GUILayout.Label(equipPossess.getItem(Equippable.BetaStone).itemIcon, GUILayout.Height(30), GUILayout.Width(30));
    358.                 GUILayout.Label(equipPossess.getItem(Equippable.BetaStone).itemName + " ("
    359.                     + equipPossess.getNumItems(Equippable.BetaStone) + ")");
    360.                 items[1] = GUILayout.Button(equipOrNot[1], GUILayout.Width(70), GUILayout.Height(20));
    361.                 GUILayout.EndHorizontal();
    362.             }
    363.             GUILayout.EndScrollView();
    364.             GUILayout.EndVertical();
    365.         }
    366.  
    367.         //If the Accessory panel is activated
    368.         if (changeEquipment[9])
    369.         {
    370.             GUILayout.BeginVertical(GUILayout.Width(320));
    371.             scrollPosition = GUILayout.BeginScrollView(scrollPosition, GUILayout.Width(280), GUILayout.Height(120));
    372.             GUILayout.EndScrollView();
    373.             GUILayout.EndVertical();
    374.         }
    375.     }
     
  8. andeeeee

    andeeeee

    Joined:
    Jul 19, 2005
    Posts:
    8,768
    Nothing stands out as being particularly disastrous here so the problem is probably something subtle. The general approach I would recommend is to comment out the three function calls (not counting the BeginArea/EndArea) one by one to see if one of them in particular is generating the errors. You can then continue this to narrow down the exact sections of code that are causing trouble. With this information, it should be much easier to establish what is going wrong.
     
  9. tomvds

    tomvds

    Joined:
    Oct 10, 2008
    Posts:
    1,028
    I believe your own assessment of the problem is completely correct.

    The way I would implement this (besides using a lot less magic numbers :p), is by not changing the state of the inventory directly. Instead of setting (for instance) item[2] like this:
    Code (csharp):
    1. items[2] = GUILayout.Button(equipOrNot[2], GUILayout.Width(70), GUILayout.Height(20));
    I would use a Coroutine like this:
    Code (csharp):
    1. if (GUILayout.Button(equipOrNot[2], GUILayout.Width(70), GUILayout.Height(20)))
    2.     StartCoroutine("SetItem", 2);
    The Coroutine would look like this:
    Code (csharp):
    1. IEnumerator SetItem(int num)
    2. {
    3.     // wait for end of frame to make sure all OnGUI stuff is done.
    4.     yield return new WaitForEndOfFrame();
    5.  
    6.     // now follows a minor modification of the handling code you already have
    7.    
    8.     //These if blocks decide what happens with the Equip or Unequip button is pressed
    9.     if (num == 0)
    10.     {
    11.         if (!itemsEquipped[0])
    12.         {
    13.             if (player.Armor == null)
    14.             {
    15.                 player.Armor = equipPossess.getItem(Equippable.BronzeArmor);
    16.                         equipPossess.setNumItems(Equippable.BronzeArmor, -1);
    17.                 armor = equipPossess.getItem(Equippable.BronzeArmor).itemName;
    18.             }
    19.         }
    20.         else
    21.         {
    22.          //insert the rest of your items code here
    23.          // ...
    24. }
    This will separate the drawing from the actual modifications.

    And unrelated to your problem:
    I'd highly recommend to switching to an array based approach (or at the very least to use an enum instead of ints to identify your different equip slots), as your current implementation looks very difficult to maintain or extend.
     
  10. cyangamer

    cyangamer

    Joined:
    Feb 17, 2010
    Posts:
    234
    Hey guys, thanks for your help. I've taken all your suggestions into consideration, and I've decided to rewrite my inventory script, with the help of the drag-and-drop inventory script that's in Showcase. Now, everything's more modular and a lot easier to maintain, AND it works! :)

    Solution for anyone else who has this problem: See if you can make any GUILayout elements that may disappear a GUI element. Thanks to GUILayoutUtility.GetRect(), mixing GUILayout and GUI elements together is not that hard.

    Thanks again!
     
  11. dkozar

    dkozar

    Joined:
    Nov 30, 2009
    Posts:
    1,410
    This error happens when using the GUILayout container and removing any of its children within OnGUI().

    Seems the GUILayout takes into account the whole sub-hierarchy before it starts drawing, and expects the hierarchy to stay the same until it finishes the pass. It doesn't like any of the child components to be removed until the OnGUI pass is finished.

    The fix would be setting a flag within OnGUI (e.g. _removedElementIndex = 3) and process the change later (removing this element inside the Update method).
     
    Last edited: Jun 14, 2013
    samana1407 likes this.
  12. Woj_Gabel_FertileSky

    Woj_Gabel_FertileSky

    Joined:
    Jun 18, 2012
    Posts:
    61
    Solutiuon did not work for me.

    But I got another:

    Actually, if this error is from a mismatch in some data between repaint and some other events, caused by recompile happening in a bad moment(somewhere between those events), there is a simple haxor that could fix this:

    Code (CSharp):
    1.  
    2.  
    3. public class SomeEditorWindow : EditorWindow
    4. {
    5.     //your declared variables, etc...
    6.  
    7.     bool handleRepaintErrors;
    8.  
    9.     void OnGUI()
    10.     {
    11.         if(Event.current.type == EventType.repaint && !handleRepaintErrors)
    12.         {
    13.             handleRepaintErrors = true;
    14.             return;
    15.         }
    16.  
    17.         //your ongui code goes here
    18.     }
    19. }
    20.  
    This way, if there is a recompile, the bool will reset to false value. With that, you just skip the first update, where the error occurs, and draw your onGUI code in the next frame.