Search Unity

Scroll view starts at bottom instead of top... how to fix?

Discussion in 'UGUI & TextMesh Pro' started by JoeStrout, May 14, 2015.

  1. JoeStrout

    JoeStrout

    Joined:
    Jan 14, 2011
    Posts:
    9,859
    I'm trying Scrollview for the first time. After a bit of stumbling about and watching tutorials (it was not obvious to me that my "scroll view" needs an Image component in addition to Scroll Rect and Mask... I hope they add that as one of the built-in UI presets in a future release), I've got a scrolling area set up and working. There's just one problem: it always starts at the bottom of the content, and I want it to start at the top.

    Here's my setup:
    1. My "Scrollview" object has the default (centered) anchors and pivot, and the size of the scrolling area. It also has ScrollRect, Mask, and Image components as mentioned above.
    2. Under that is a "Content" object using the Top-Left anchor preset, and pivot set to 0,0. This is initially empty and has full width, but an arbitrary height of 300.
    3. A script attached to Content creates a bunch of child objects in the Start method, from a prefab. This involves doing more math than I expected, because the coordinate system goes from 0 at the bottom of the content area, to +1000 or whatever at the top of the content area (i.e. it's bottom-up instead of top-down). The child objects are created from a prefab that also has Top-Left anchors and 0,0 pivot.
    Here are the relevant bits of code.
    Code (CSharp):
    1.     void Start() {
    2.         rowHeight = entryPrefab.GetComponent<RectTransform>().rect.size.y;
    3.         rows = 10;
    4.         contentHeight = rowHeight * rows;
    5.  
    6.         Vector2 size = GetComponent<RectTransform>().sizeDelta;
    7.         GetComponent<RectTransform>().sizeDelta = new Vector2(size.x, contentHeight);
    8.  
    9.         for (int i=0; i<rows; i++) {
    10.             AddEntry(i);
    11.         }
    12.     }
    13.  
    14.     void AddEntry(int row) {
    15.         GameObject entry = Object.Instantiate(entryPrefab, Vector3.zero, Quaternion.identity) as GameObject;
    16.         entry.transform.parent = transform;
    17.         entry.name = "Achievement " + row.ToString();
    18.         entry.transform.localPosition = new Vector3(0, contentHeight - rowHeight - rowHeight*row, 0);
    19.         entry.transform.Find("TitleText").GetComponent<Text>().text = entry.name;
    20.         Debug.Log("Instantiated " + entry.name + " at " + entry.transform.localPosition);
    21.     }
    There is also a Scrollbar hooked up to the ScrollRect component, which behaves very oddly: I can set its default Value to 1, but as soon as I hit Run, it goes to 0... and it stays at 0 even after quitting the run! (How rude.)

    I suspect there's something wrong in my setup that is causing this, perhaps related to the inverted coordinate system (with 0 meaning "bottom" and 1 meaning "top"). But I've googled and experimented, and I'm stumped. Can somebody throw me a clue?
     
  2. JoeStrout

    JoeStrout

    Joined:
    Jan 14, 2011
    Posts:
    9,859
    Nobody? Have I stumped the interwebs?
     
    Lohoris2 likes this.
  3. JoeStrout

    JoeStrout

    Joined:
    Jan 14, 2011
    Posts:
    9,859
    Fine then, I'll just solve it myself. ;)

    It turns out that the key is the pivot on the content object. With a pivot set to 0,0, the pivot is in the bottom-left corner. I then had to position everything bottom-up, with that weird math in the code above, and the scroll position started at bottom.

    But if I set the pivot to 0,1, i.e. the top-left corner, then things are more sensible. Content now builds from the top down. I still have to use negative numbers (because +Y is "up" in the Unity GUI coordinate system), but at least they're more sensible negative numbers — each entry is simply positioned at -row * rowHeight. And the scroll view starts at the top, instead of the bottom. Huzzah.

    Unity, if you're listening, you really need to add a preset for a scroll view (Create > UI > Scroll View), including a properly configured content view. There are way too many hoops to jump through, and too many easy mistakes to make, in setting one of these things up, and it's going to be a frequent stumbling block for newbies (such as myself).

    But I've got it sorted out now, so it's back to work for me... and hopefully, the next poor sap to run into this problem will find this thread, and waste less time than I did!
     
    Viole, Joy-less, hessex and 36 others like this.
  4. bobbymcsteels

    bobbymcsteels

    Joined:
    Mar 15, 2013
    Posts:
    12
    Thanks, this helped me out although I was looking for the opposite of you, I was trying to make my scrollview start from the bottom and the user has to scroll upwards... it's for a chat room.
     
  5. vahi4m

    vahi4m

    Joined:
    Apr 27, 2014
    Posts:
    1
    It my be late, but try setting the position of the content of scrollview.
     
    PloyGTM and CoughE like this.
  6. guneyozsan

    guneyozsan

    Joined:
    Feb 1, 2012
    Posts:
    99
    I generate scroll content on the fly. In my case I also needed to set Anchor Y to 1. Here is my setup:
    upload_2019-5-18_12-51-37.png
     
  7. ImperativeGames

    ImperativeGames

    Joined:
    Dec 11, 2016
    Posts:
    34
    Yep, had to manipulate Pivot of Content object, set it to 0 or 1. Shame on Unity, still didn't implement basic things like that!
    Thank you for the help guys)
     
    sumpfkraut, Ony, phuthanhvo and 3 others like this.
  8. officialfonee

    officialfonee

    Joined:
    May 22, 2018
    Posts:
    44
    I Just rotated my view on the z axis by 180 and then the items I put inside content I rotate another 180.
     
  9. Tanza3D

    Tanza3D

    Joined:
    May 2, 2018
    Posts:
    1
    oh my, thank you so much, this saved me hours of pain and suffering
     
  10. LilGames

    LilGames

    Joined:
    Mar 30, 2015
    Posts:
    570
    Don't do this.
     
  11. TheFastLane

    TheFastLane

    Joined:
    Aug 27, 2018
    Posts:
    5
    Haha I was waiting for someone to say that...
     
    LilGames and nquangvu like this.
  12. unity_uCAh1YGgjxXPOw

    unity_uCAh1YGgjxXPOw

    Joined:
    Feb 10, 2021
    Posts:
    6
    Definitely solved my problem. Thank you so much for answering your own question. I was looking for this for hours....
     
    prakyath_unity and JoeStrout like this.
  13. Geri860

    Geri860

    Joined:
    Aug 25, 2018
    Posts:
    5
    For me it was as simple as changing the scrollbar direction from Top to bottom to Bottom to top
     
  14. Astirian

    Astirian

    Joined:
    Apr 28, 2018
    Posts:
    15
    You, Sir, are a Saint. Nothing worse than something like this tripping you up for a whole day. I guess that's how we earn our stripes though.
     
  15. huulong

    huulong

    Joined:
    Jul 1, 2013
    Posts:
    224
    They added a Scroll View widget template in the meantime! It can help setting up your scrollbar even if you only use one direction. I'd recommend starting with that and removing elements you don't need, then fill the content.

    In my case, it helped my spot that I needed Bottom to Top direction. Disabling vertical dragging while not disabling mouse wheel scrolling and keeping authentic button behaviour is another issue though, handled in other forum threads and Q&A...
     
  16. huulong

    huulong

    Joined:
    Jul 1, 2013
    Posts:
    224
    I tested my project again today and for some reason, I know need to set Top to Bottom direction again, and even my OnScroll eventData.scrollDelta.y sign was reversed... as if they changed the Y convention completely. Did this happen in Unity 2022? Or did I change an EventSystem/UI/input setting by accident?

    In any case, reverting all vertical axes now works fine.

    Note: if you're editing the Scrollbar on a prefab, make sure to either edit the prefab instance then apply override, or edit the direction in Inspector in Debug mode. Otherwise, the change is not registered by the editor (not saved in prefab). I've reported this bug, and it has been confirmed.
     
  17. drorco

    drorco

    Joined:
    Nov 20, 2020
    Posts:
    19
    If you're still having trouble, make sure you don't have a scaling animator anywhere near the scrollview!
    The scaling animator will somehow cause the scrollview to scroll to the bottom. Took me lots of time to figure that out (and then forget about it again).
     
  18. alphdevcode

    alphdevcode

    Joined:
    Nov 10, 2020
    Posts:
    7
    For anyone facing this problem, just disable the ScrollRect Component, then scale the object, and re-enable it again after the scaling.
     
    Last edited: Jul 8, 2023
  19. jakesee

    jakesee

    Joined:
    Jan 7, 2020
    Posts:
    72
    This saved me!! Thanks.

    To summarise for the next guy, the scrollbar value will be messed up if the UI is trying to build its layout at runtime. Set pivot on vertical y-axis to 1 and enable scrollrect only when all animations done.
     
    LilGames likes this.
  20. j4y1450

    j4y1450

    Joined:
    Mar 22, 2022
    Posts:
    3
    I'm having this problem even after trying all these solutions. I'm not building the scroll view in a script, just in editor. I'll move the content to the top and save the project. Going into play mode, the scroll view works as intended, but when exiting play mode the content is now at the bottom. This just suddenly started happening, I don't even know what I could have done, I'm not doing anything crazy.
     
  21. j4y1450

    j4y1450

    Joined:
    Mar 22, 2022
    Posts:
    3
    Okay I figured it out. Somehow, the value on the "Value" slider of the vertical scrollbar was below or above the normal 0 to 1 range. I never even touched that gameobject so I have no idea how that happened. I'm not sure why it didn't update like it normal does when the content gameobject is moved. But either way I hope this helps someone.
     
  22. fokozuynen

    fokozuynen

    Joined:
    Aug 29, 2021
    Posts:
    4
    I think on the scrollbar the Navigation need to be set to Vertical and the Value to 1. In case you need that to be set to 1 each time the Content gets enable probally need a script to get that value on reflect float and set it to 1 OnEnable but also OnEnable component Scrollbar turn off and on the bool to refresh it.
     
  23. ThavonBird

    ThavonBird

    Joined:
    Jan 24, 2023
    Posts:
    2
    Nice it works for me thanks