Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Procedurally populated icons, keep in center of the screen?

Discussion in 'UGUI & TextMesh Pro' started by Jesse_Pixelsmith, Aug 23, 2014.

  1. Jesse_Pixelsmith

    Jesse_Pixelsmith

    Joined:
    Nov 22, 2009
    Posts:
    295
    I'm basically trying to make some functionality to emulate the below image. When a player looks at an object (say in this case, a door) a little option bar will pop up in the lower center area of the screen. The bar will have a horizontal width scaled by how many options (icons) the player has.

    Layout Groups seem to be a good option, but I'm having a hard time finding something that will anchor the Group/panel as well as the icons inside of it in the center. At least messing around a bit with the Layout Groups sample scene anyways.

    What would I go about doing to accomplish this? Also, when I procedurally add the icons through code, would I just instantiate a game object and position it as a child of the "Grid" game object?

    I don't see any tutorials on this yet, but feel free to direct me if I missed one. Cheers :)

    Coming in as a user of DF-GUI for reference, it was very easy to snap panels to horizontal center etc.


     
  2. Senshi

    Senshi

    Joined:
    Oct 3, 2010
    Posts:
    556
    I'm currently doing something kind-of similar, though without Layout Groups. There may be nicer ways to do this, but just in case this might help someone, here's what my code (adapted for this example) looks roughly like:

    Code (csharp):
    1. public Canvas canvas;
    2. public GameObject buttonPrefab;
    3.  
    4. int btnSize = 120; //fetch or calculate somehow
    5. int numIcons = 3;
    6. float relativeWidthButton = btnSize / Camera.main.pixelWidth;
    7. float relativeHeightButton = btnSize / Camera.main.pixelHeight;
    8. float relativeWidthTotal = (Size * numIcons) / Camera.main.pixelWidth;
    9. float startX = 0.5f - relativeWidthTotal / 2; //First icon's X coordinate (relative)
    10. float yPos = 0.9f;
    11.  
    12. public void repositionIcons(){
    13.     for(int i=0; i<numIcons; i++){ //just position them manually
    14.         RectTransform btn = ((GameObject)Object.Instantiate(buttonPrefab)).GetComponent<RectTransform>();
    15.         btn.SetParent(canvas.transform, false);
    16.         btn.anchorMin = newVector2(startX + i*btnWidth, yPos); //using anchors in the buttons' corners
    17.         btn.anchorMax = newVector2(startX + i*btnWidth, yPos - relativeHeightButton);
    18.         btn.offsetMin = btn.offsetMax = new Vector2(0, 0); //make sure the button is stretched by the anchors.
    19.         btn.GetComponent<Image>().overrideSprite = ...;//set image here
    20.     }
    21. }
    It would be nice if this could be done more automagically, but I haven't figured out a better way yet. I've tried setting a panel as the buttons' parents and resizing (and anchoring) that instead, but this led to some weird scaling/ stretching issues that I haven't bothered to fix yet.
     
  3. Jesse_Pixelsmith

    Jesse_Pixelsmith

    Joined:
    Nov 22, 2009
    Posts:
    295
    Thanks for the input! I'll try to replicate something like that into my own system. That was kind of how I imagined I would do it via code, I just wasn't sure if Unity had an automagic system like you said. Will try to post my results if I get success, and curious to see if others have different methods.
    Cheers!
     
  4. Legi

    Legi

    Joined:
    Jul 25, 2013
    Posts:
    20
    That's rather easy.
    I assume your icons have the background as their parent obejct.

    Do the following:
    Add a Horizontal Layout Group and a Content Size Fitter to your background.
    On every child object add a Layout Element component

    Now apply these settings:
    Horizontal Layout Group:
    Child Alignment: Middle Center

    Content Size Fitter:
    Both: PreferredSize

    Layout Element:
    Flexible Width: Enabled & 0
    Flexible Height: Enabled & 0

    The Layout Group positions the child objects and the Size Fitter adjusts the width and height of your background based child objects.
    If you dont add the Layout Element Component to a child object, it will resize to fit.
     
    sergi-herrero and Seraphic572 like this.
  5. Jesse_Pixelsmith

    Jesse_Pixelsmith

    Joined:
    Nov 22, 2009
    Posts:
    295
    Awesome! Yeah I used MinSize instead of preferred because preferred was causing some inconsistency issues. -- actually scratch that now it seems to be working with preferred... I'm reading up in the docs about the difference

    Where did you learn this - have you been using the beta for a while or is it on a video/doc somewhere or just experimenting like crazy? :)
     
    Last edited: Aug 24, 2014
  6. Legi

    Legi

    Joined:
    Jul 25, 2013
    Posts:
    20
    No, i just looked at the layout scene in the example project and after a few hours i finally understood how the layout system works :D
     
  7. Jesse_Pixelsmith

    Jesse_Pixelsmith

    Joined:
    Nov 22, 2009
    Posts:
    295
    Looks like this is my issue with Perferred - when I try to set the child object to be 100x100 preferred, and delete all but one of them, it looks like the image doesn't want to size down quite that small, maybe due to the background sprite?




    However if I add padding onto it, it seems to get the room it wants for the background, and the child object sizes itself to 100x100


    But MinSize just seems to work to do what I want (though in this case it seems like the term "FixedSize" is more appropriate, and minsize implies that it could get bigger?
    You can see here that the background is totally shrunk to fit the button size, and it's exactly 100x100.




    Not sure the logic behind Preferred size and why it's scaling the button like that, maybe because of the pixel size or aspect ratio of the background image sprite...

    Anyways I'll stick to min size for now :) Thanks!
     
  8. Legi

    Legi

    Joined:
    Jul 25, 2013
    Posts:
    20
    When you set PreferredWidth or Height Values, you have to disable Flexible Width or Height ;)
    Enable those 2 options also and set their value to 0

    Edit: Above the Preview section of your gameobject ("Window" in the last picture, right below the content size fitter) there's a button.
    Change that to Layout Properties to get more information about whats happening :)
     
  9. Jesse_Pixelsmith

    Jesse_Pixelsmith

    Joined:
    Nov 22, 2009
    Posts:
    295
    Ah ok thanks that Layout Properties window is helpful!

    Have to say though, that current workflow seems like a bug on Unity's end. In order to disable it, I need to enable the checkbox and set the value to 0? Shouldn't having it unchecked make it disabled by default?

     
  10. Ben-BearFish

    Ben-BearFish

    Joined:
    Sep 6, 2011
    Posts:
    1,204
    Could I ask is this still the same solution? I can't seem to get this working.
     
    krisventure likes this.
  11. krisventure

    krisventure

    Joined:
    Mar 24, 2016
    Posts:
    118
    No it definitely doesn't work any more.