Search Unity

Issue with inventory/unit listing

Discussion in 'Scripting' started by wilhelmscream, May 16, 2015.

  1. wilhelmscream

    wilhelmscream

    Joined:
    Jun 5, 2013
    Posts:
    223
    So here we go again.....

    New type of problem this time. Basically what I want is this - when a unit (let's say, a fleet) is positioned at/parented to a base (let's call it a planet) a button should appear within a specified area on the planet's GUI display. On the button are a symbol and brief details on the fleet (i.e., "1st Fleet" or something similar).''

    I have the display side down (it's clunky and probably not ideal or efficient but it works). What I can't figure out is how to get the planet script to read the details off each fleet (keeping in mind the fleets/units will be moving around, not staying stationary) without also limiting the number of fleets that can be at any one planet.

    Any thoughts?
     
  2. GroZZleR

    GroZZleR

    Joined:
    Feb 1, 2015
    Posts:
    3,201
    Since you specifically mention that you parent the fleet to the planet object, you can just loop through the children:

    Code (csharp):
    1.  
    2. foreach(Transform child in planet.transform)
    3. {
    4.      if(child.CompareTag("Fleet") == true)
    5.      {
    6.           Debug.Log("Found a fleet");
    7.      }
    8. }
    9.  
    An alternative is when you do the parenting, call a function on a planet script to notify the planet that a new fleet has arrived. Something like:

    Code (csharp):
    1.  
    2. if(fleet has arrived)
    3. {
    4.     fleet.SetParent(planet);
    5.    
    6.     PlanetScript script = planet.GetComponent<PlanetScript>();
    7.     script.AddFleet(fleet);
    8. }
    9.  
     
  3. wilhelmscream

    wilhelmscream

    Joined:
    Jun 5, 2013
    Posts:
    223
    Could that work on multiple objects at once though?
     
  4. GroZZleR

    GroZZleR

    Joined:
    Feb 1, 2015
    Posts:
    3,201
    Sure, why not? Once you find the fleets, you can loop through GameObject's children and find all the ships too.
     
  5. wilhelmscream

    wilhelmscream

    Joined:
    Jun 5, 2013
    Posts:
    223
    The problem is, how would I draw specific information from each unique unit?

    Using this code (with 4 fleets attached) :

    Code (JavaScript):
    1.                    GUI.BeginGroup (Rect (2.5, 16, 80*fleetCount, 30));
    2.                    if (fleetCount >= 1) {
    3.                        var fleet : Transform;
    4.                        var fleetName : String;
    5.                        fleet = transform.FindChild("Fleet");
    6.                        fleetName = fleet.GetComponent(Fleet).fleetName;
    7.                        if (GUI.Button (Rect (0, 0, 80, 30), GUIContent (fleetName.ToString (), aTextureFleet), regStyle)) {
    8.                        }
    9.                    }
    10.                    if (fleetCount >= 2) {
    11.                        var fleet2 : Transform;
    12.                        var fleet2Name : String;
    13.                        fleet2 = transform.FindChild("Fleet");
    14.                        fleet2Name = fleet.GetComponent(Fleet).fleetName;
    15.                        if (GUI.Button (Rect (80, 0, 80, 30), GUIContent (fleet2Name.ToString (), aTextureFleet), regStyle)) {
    16.                        }
    17.                    }
    18.                    if (fleetCount >= 3) {
    19.                        var fleet3 : Transform;
    20.                        var fleet3Name : String;
    21.                        fleet3 = transform.FindChild("Fleet");
    22.                        fleet3Name = fleet.GetComponent(Fleet).fleetName;
    23.                        if (GUI.Button (Rect (160, 0, 80, 30), GUIContent (fleet3Name.ToString (), aTextureFleet), regStyle)) {
    24.                        }
    25.                    }
    26.                    if (fleetCount >= 4) {
    27.                        var fleet4 : Transform;
    28.                        var fleet4Name : String;
    29.                        fleet4 = transform.FindChild("Fleet");
    30.                        fleet4Name = fleet.GetComponent(Fleet).fleetName;
    31.                        if (GUI.Button (Rect (240, 0, 80, 30), GUIContent (fleet4Name.ToString (), aTextureFleet), regStyle)) {
    32.                        }
    33.                    }
    34.                    GUI.EndGroup ();
    35.  
    I get this ......




    Note how each button is labeled the same? They should each correspond to one of the attached fleets (which are numbered 1 - 4).
     

    Attached Files:

  6. GroZZleR

    GroZZleR

    Joined:
    Feb 1, 2015
    Posts:
    3,201
    transform.FindChild("Fleet") is finding the same fleet every time, that's why.

    Try this instead:
    Code (csharp):
    1.  
    2. int x = 0;
    3.  
    4. GUI.BeginGroup (Rect (2.5, 16, 80 * fleetCount, 30));
    5.  
    6. foreach(Transform child in transform)
    7. {
    8.    Fleet fleet = child.GetComponent<Fleet>();
    9.    
    10.    if(fleet != null) // it's a fleet if the script is there
    11.    {
    12.      if (GUI.Button (Rect (x, 0, 80, 30), GUIContent (fleet.fleetName.ToString(), aTextureFleet), regStyle))
    13.      {
    14.      
    15.      }
    16.      
    17.      x += 80;
    18.    }
    19. }
    20.  
    21. GUI.EndGroup ();
    22.  
    23.  
     
  7. wilhelmscream

    wilhelmscream

    Joined:
    Jun 5, 2013
    Posts:
    223
    And again my lack of C# knowledge rears it's ugly head :(

    thanks though!
     
  8. wilhelmscream

    wilhelmscream

    Joined:
    Jun 5, 2013
    Posts:
    223
    Near as I can get it.....

    Code (JavaScript):
    1.                    GUI.BeginGroup (Rect (2.5, 16, 80*fleetCount, 30));
    2.                        for each (child in transform) {
    3.                            var fleetName = transform.GetComponentInChildren(Fleet).fleetName;
    4.                            if (fleetCount > 0) {
    5.                             if (GUI.Button (Rect (fleetX, 0, 80, 30), GUIContent (fleetName.ToString(), aTextureFleet), regStyle)) {
    6.                             }
    7.                         }
    8.                         fleetX += 80;
    9.                        }
    10.                    GUI.EndGroup ();
    11.  
    Which generates no error messages.... or, really, anything positive either
     
    Last edited: May 18, 2015
  9. GroZZleR

    GroZZleR

    Joined:
    Feb 1, 2015
    Posts:
    3,201
    I didn't even notice you were using JavaScript. Sorry about that.

    Change this:
    Code (csharp):
    1.  
    2. for each (child in transform) {
    3.      var fleetName = transform.GetComponentInChildren(Fleet).fleetName;
    4.  
    To this:
    Code (csharp):
    1.  
    2. for (var child : Transform in transform) {
    3.     var fleetName =child.GetComponent(Fleet).fleetName;
    4.  
    And you should be good.
     
  10. wilhelmscream

    wilhelmscream

    Joined:
    Jun 5, 2013
    Posts:
    223
    For some reason that generates a "pushing more GUI clips than popping" message...... despite there being a balance of BeginGroups and EndGroups. If I remove that code altogether the error goes away.....
     
  11. LeftyRighty

    LeftyRighty

    Joined:
    Nov 2, 2012
    Posts:
    5,148
    not to sidetrack too much but why aren't you using the new UI? panel with a layout component, loop through the planet's children looking for fleets and add a button for each as the panel's child... done.
     
  12. wilhelmscream

    wilhelmscream

    Joined:
    Jun 5, 2013
    Posts:
    223
    Because I have no idea what that means. Also, the fact that there's children other than just the fleets (space stations, industrial facilities, army units, etc)
     
  13. LeftyRighty

    LeftyRighty

    Joined:
    Nov 2, 2012
    Posts:
    5,148
    unity 4.6 or higher has a new UI system which improved functionality. You build a lot more of it in scene rather than all through code. If you've got an established project using the old GUI I can imagine it's a sizeable job to move across to the new approach. Mostly just curious :D (old gui never made much sense to me anyway lol )

    new ui tutorials here if you want to check it out
    https://unity3d.com/learn/tutorials/modules/beginner/ui
     
  14. wilhelmscream

    wilhelmscream

    Joined:
    Jun 5, 2013
    Posts:
    223
    Ah well I'm still using an older version so.....
     
  15. LeftyRighty

    LeftyRighty

    Joined:
    Nov 2, 2012
    Posts:
    5,148
    are you using unity 5 editor? (not talking gui vs ui, the IDE) they took out

    Code (csharp):
    1.  
    2. GetComponent(Fleet);
    3.  
    you have to use one of these
    Code (csharp):
    1.  
    2. GetComponent.<Fleet>(); // note the "." in there
    3. GetComponent("Fleet");
    4.  
    http://docs.unity3d.com/ScriptReference/Component.GetComponent.html

    if that is failing the code never gets to the endgroup and might complain about the popping clips :)
     
  16. wilhelmscream

    wilhelmscream

    Joined:
    Jun 5, 2013
    Posts:
    223
    Nope. The first generates a "No appropriate argument" error, and the second changes nothing so far as I can tell.
     
  17. GroZZleR

    GroZZleR

    Joined:
    Feb 1, 2015
    Posts:
    3,201
    Can you post the updated code? That's a weird one.
     
  18. wilhelmscream

    wilhelmscream

    Joined:
    Jun 5, 2013
    Posts:
    223
    Code (JavaScript):
    1. var fleetName : String;
    2. var fleet : Transform;
    3. var fleetX : int;
    4.  
    5. function OnGUI () {
    6.     GUI.BeginGroup (Rect (2.5, 16, 320, 30));
    7.         if (fleetCount != null) {
    8.                    for (var fleet : Transform in transform) {
    9.                        fleetX += 80;
    10.                 fleetName = fleet.GetComponent(Fleet).fleetName;
    11.                        if (GUI.Button (Rect (fleetX, 0, 80, 30), GUIContent (fleetName, aTextureFleet), regStyle)) {
    12.             }
    13.         }
    14.     }
    15. }
    16.  
     
  19. GroZZleR

    GroZZleR

    Joined:
    Feb 1, 2015
    Posts:
    3,201
    You're missing a GUI.EndGroup() at the bottom.
     
  20. wilhelmscream

    wilhelmscream

    Joined:
    Jun 5, 2013
    Posts:
    223
    I just didnt copy it right, it's there in the script. sorry.
     
  21. wilhelmscream

    wilhelmscream

    Joined:
    Jun 5, 2013
    Posts:
    223
    The issue has to lie somewhere in this line.....

    Code (JavaScript):
    1. fleetName = fleet.GetComponent(Fleet).fleetName;
    2.  
    If I move it into Update ()...... the GUI error message goes away, and one button shows up (regardless of how many fleets I have).

    Granted, it's still not reading the variable fleetName in the Fleet script, but still, it's progress, right?
     
  22. wilhelmscream

    wilhelmscream

    Joined:
    Jun 5, 2013
    Posts:
    223
    Using

    Code (JavaScript):
    1.     fleet = transform.FindChild("Fleet");
    2.  
    in Update () will allow it to read the info from the last fleet attached..... is there a way to gather all children of type, in a list or array or some such? I've been hunting through forums and answers, tried a dozen different things a dozen different ways, nothing seems to work.
     
  23. GroZZleR

    GroZZleR

    Joined:
    Feb 1, 2015
    Posts:
    3,201
    That's what the for each loop is supposed to do. I don't know the JavaScript side of Unity at all, so I'm not sure why it's not working.
     
  24. wilhelmscream

    wilhelmscream

    Joined:
    Jun 5, 2013
    Posts:
    223
    Here's the full script after I found a few other answers.....

    Code (JavaScript):
    1. var fleetX : float;
    2. var fleetName : String;
    3. var fleet : GameObject;
    4. var allFleets : GameObject [];
    5. var aTextureFleet : Texture;
    6. var regStyle : GUIStyle;
    7. var fleetCount : int;
    8.  
    9. function NewFleet () { //sent by each fleet as it arrives
    10.     fleetCount ++;
    11.     fleetX +=80;
    12. }
    13.  
    14. function OnGUI () {
    15.     GUI.BeginGroup (Rect (2.5, 16, 320, 30));
    16.          if (fleetCount > 0) {
    17.             for (var fleet : GameObject in allFleets) {
    18.                 if (new GUI.Button (Rect (fleetX, 0, 80, 30), GUIContent (fleetName, aTextureFleet), regStyle)) {
    19.                 }
    20.             }
    21.         }
    22.     GUI.EndGroup ();
    23. }
    24.  
    25. function Update () {
    26.     allFleets = GameObject.FindGameObjectsWithTag("Fleet");
    27.     fleetName = fleet.GetComponent(Fleet).fleetID+" Fleet";
    28. }
    So far.... it finds all fleets, assigns them to the array allFleets, and keeps track of how many there are.

    What I'm missing is .....

    - creating one button for each fleet (as of now it creates one total, albeit in the proper place).
    - using GetComponent (I assume) to gather the var fleetName from each fleet and assign it to each button.