Search Unity

Unity UI Open Source Scroll Snap Project - Unity UI Scroll Snaps

Discussion in 'UGUI & TextMesh Pro' started by Beks_Omega, Feb 27, 2018.

  1. Beks_Omega

    Beks_Omega

    Joined:
    Jun 7, 2017
    Posts:
    72
    Unity UI Scroll Snaps

    Unity UI Scroll Snaps is a new open source project focused on creating robust components for all of your scrolling and snapping needs.

    This was originally inspired by an idea I had for a menu system where you could scroll and select item options, but even though I saw some amazing extensions of the Unity Scroll Rect I couldn't find any solutions that had adaptable spacing for different sized items, so I decided to create one myself! After much tinkering and many additions I decided the script I'd written was ready to take it's first steps into the broader world, and maybe even meet some other friendly Scroll Snap scripts out there!

    New Version!

    This project now has a new Version 1, completely rewritten from scratch! You can go here to check it out, and learn why this change has happened. Version 0 is still (for now) the official version because it is the most fully featured, but in the future cool stuff will be happening over there.

    Creative Tenets

    1. Components should be as self-contained as possible, ease of installment for the user takes priority over minimizing duplicate code.
    2. Components should not rely on vanilla Unity Components like Scroll Rects, they should handle whatever they need to do themselves, to make it easier for the user.
    3. What you see is what you get, when the user is setting up the component in the editor it should look the same as how it will look when they run it.

    All of these things help ensure a good experience for the user. No more making sure you have the 5 scripts this component needs to function, no more redundant components cluttering up your gameobjects, and especially no more uncertainty about how something will look after you hit play.

    Contributing

    This project is specifically for Scroll Snaps, things that scroll and then snap to items. If you have a lovely UI component that you're just dying to put somewhere, but it doesn't have to do with scroll snaps, consider contributing it to the Unity UI Extensions project.

    If you do indeed have a Scroll Snap component that you want to show the world we would love to take it! You can find out more about contributing here and here. Just be prepared PRs will probably get commented on :p

    Downloading

    Download instructions can be found here, or if you just want the latest asset package right now here it is for your enjoyment.

    List of All the Things

    Examples of "all the things" in action are part of the asset package or can be downloaded individually here. You can also check out the List of All the Things for Version 1 here.

    Directional Scroll Snap

    The Directional Scroll Snap is based on the idea of the scrollable item menu. Items are "snapped to" (aligned with the center of the Directional Scroll Snap) along one axis so that it either scrolls vertically or horizontally. The Directional Scroll Snap also snaps to items pivots not their centers (although you can set it to their center) to give you more options in how you animate & organize your items.

    Options Include:
    • Moving Horizontally or Vertically
    • Locking or Unlocking the non-moving direction. (so it can be loosey goosey if you want)
    • Looping functionality
    • Use velocity when snapping, or don't.
    • Different snap types: snap to nearest, snap to last passed, and snap to next.
    • Different Interpolators for scrolling animations, it can overshoot, anticipate, do a little dance, ect.
    • The ability to override Interpolators (among other things) for different input types.
    • Button control for going back (up/left) and forward (down/right)
    • Scrollbar control (which can use velocity or not, whatever suites your fancy)
    • Scroll wheel & touch pad control (ditto above)
    • Mouse pointer & touch control (you get the drill)
    • Filtering of items, you can tell the Scroll Snap what it is and is not allowed to snap to, and what it is and is not allowed to calculate its size with. So you can have unsnap-to-able descriptive text & decorative edging that stretches to the size of the content. So pretty!
    • Supports placing items "by hand" (whatever that means) as well as Horizontal Layout Group, Vertical Layout Group, and Grid Layout Group.
    • Supports populating and editting the Scroll Snap at runtime through functions like: InsertChild, RemoveChild, SetChildSnappability and more.
    • Plus lots of Unity events to hook into including, but not limited to: Start Movement, Snapped to Item, and Closest Item Changed.

    Omni Directional Scroll Snap


    The Omni Directional Scroll Snap is based on the idea of the item/skill tree. The intention being that you could move the Scroll Snap vertically, horizontally, diagonally... or even a bit of each, and when you stopped moving it it would snap to the nearest item. When the Omni Directional Scroll Snap snaps to an item it aligns the item both horizontally and vertically, so the pivot of the item is at the dead center of the Scroll Snap.

    Options Include:
    • Using velocity when snapping, or not.
    • Different Interpolators for scrolling animations, including crowd favorites like: Viscous Fluid, Overshoot, Accelerate Decelerate, and many more.
    • The ability to override interpolators (among other things) for different input types.
    • Any control method you can think of! We've got scrollbar control, scroll wheel control, touch pads, mouse drags, and touch control.
    • Filtering of Items, letting you tell the Scroll Snap what it is allowed to snap to, and what it is allowed to calculate its size with. So you can add some some lovely unsnap-to-able lines between the items in your skill tree, and decorative edging that stretches to the size of the content. All the options you could only dream of!
    • Supports placing items with individual love and care, or throwing them in a Layout Group (Horizontal Layout Group, Vertical Layout Group, or Grid Layout Group) and letting the computer do the work.
    • Supports populating and editting the Scroll Snap at runtime through functions like: InsertChild, RemoveChild, SetChildSnappability and more.
    • Plus 5 different Unity Events you can hook into including (but not limited to) your old friend On Value Changed, your new friend Start Movement Event, and your new new friend On Closest Item Changed.

    Scroller

    The Scroller is based on the Android Open Source Project's Scroller. It makes it easy to move something from point A to point B in way that's cleaner and more robust than simple lerping.

    Options Include:
    • Interpolators for scrolling animations. It comes with a smattering of built in interpolators that allow you to change up your scrolling animations, such as Viscous Fluid, Overshoot, and Anticipate, or you can create your own interpolator for it to use.
    • Animations based on velocity (Flings) and animations based on duration (Scrolls).
    • Functions for calculating where a Fling will land before it has been flung.
     
    Last edited: Jan 24, 2019
    WessamMahjoob and mchts like this.
  2. Beks_Omega

    Beks_Omega

    Joined:
    Jun 7, 2017
    Posts:
    72
    Updates to Directional Scroll Snap:
    • Added support for Grid Layout Groups.
    • Fixed Horizontal & Vertical Layout group support in the Directional Scroll Snap.
    • Now the Directional Scroll Snap never changes position of items when it starts driving their RectTransforms.
    • Fixed some other minor bugs in the Directional Scroll Snap.
     
  3. sp-sergio-gil

    sp-sergio-gil

    Joined:
    Mar 5, 2014
    Posts:
    45
    good job!
     
    Beks_Omega likes this.
  4. Beks_Omega

    Beks_Omega

    Joined:
    Jun 7, 2017
    Posts:
    72
    Added New Component Omni Directional Scroll Snap:

    The Omni Directional Scroll Snap is based on the idea of the item/skill tree. The intention being that you could move the Scroll Snap vertically, horizontally, diagonally... or even a bit of each, and when you stopped moving it it would snap to the nearest item. When the Omni Directional Scroll Snap snaps to an item it aligns the item both horizontally and vertically, so the pivot of the item is at the dead center of the Scroll Snap.

    Options Include:
    • Using velocity when snapping, or not.
    • Different Interpolators for scrolling animations, including crowd favorites like: Viscous Fluid, Overshoot, Accelerate Decelerate, and many more.
    • Any control method you can think of! We've got scrollbar control, scroll wheel control, touch pads, mouse drags, and touch control.
    • Filtering of Items, letting you tell the Scroll Snap what it is allowed to snap to, and what it is allowed to calculate its size with. So you can add some some lovely unsnap-to-able lines between the items in your skill tree, and decorative edging that stretches to the size of the content. All the options you could only dream of!
    • Supports placing items with individual love and care, or throwing them in a Layout Group (Horizontal Layout Group, Vertical Layout Group, or Grid Layout Group) and letting the computer do the work.
    • Plus 5 different Unity Events you can hook into including (but not limited to) your old friend On Value Changed, your new friend Start Movement Event, and your new new friend On Closest Item Changed.

    The repository and download links all include examples of this new Component so you can get started playing with it right away. If you have any questions about it or questions about anything else feel free to ask!
     
  5. Beks_Omega

    Beks_Omega

    Joined:
    Jun 7, 2017
    Posts:
    72
    Updates to Directional Scroll Snap:
    • Added a new Snap Type: Snap To Next. The Directional Scroll Snap previously only had the options: Snap to Nearest and Snap To Last Passed.
    • Removed code for keeping item position consistent because it was causing problems.
    • Moved the Directional Scroll Snap Editor into the UnityEngine.UI.ScrollSnaps namespace.
    • Fixed a couple other little bugs and typos.
     
  6. sp-sergio-gil

    sp-sergio-gil

    Joined:
    Mar 5, 2014
    Posts:
    45
    wow!

    Have you plans to move on to create a infinite scroll and reusign cells to do this?
     
  7. Beks_Omega

    Beks_Omega

    Joined:
    Jun 7, 2017
    Posts:
    72
    An infinite scrolling/circular scrolling component is next on my list! Right now I'm working on deciding if it would work better as an addition to the Directional Scroll Snap, or as a separate component with it's own capabilities. If you have any opinions feel free to leave a comment or shoot me a message.
     
  8. sp-sergio-gil

    sp-sergio-gil

    Joined:
    Mar 5, 2014
    Posts:
    45
    If I can I will check your code to be sure how is splitted, but perhaps the good point could be having a component that enables having a reusable or a normal scroll with the infinite scroll option and then have another component that would be the snap + pagination behaviour?

    Aside that, it could be usefull to have an option to define a desired starting cell to snap at the beginning?
     
    Last edited: Mar 8, 2018
  9. Beks_Omega

    Beks_Omega

    Joined:
    Jun 7, 2017
    Posts:
    72
    If I'm reading this right it looks like you're looking for a Component that just does the infinite/circular scrolling without any snapping behavior?

    While I definitively want to do some stuff with infinite/circular scrolling I also want all of the Components to have some sort of snapping and some sort of scrolling mechanic - hence the name Unity UI Scroll Snaps hehe. I know that makes the project pretty limited in its scope but I think that helps maintain the focus on making the Components it does contain the best they can be.

    If you are indeed looking for a simple infinite/circular scrolling solution I believe the Unity UI Extensions project has one here.

    Otherwise I'm sorry I read your comment wrong and I do still want to add infinite/circular capabilities! Just along with snapping.

    Good idea! There probably won't be scrolling to the start cell, because if I remember correctly from past work starting up a scrolling animation on frame 1 gives a pretty terrible choppy effect, but I can definitely make it so that when you start it up it's already snapped to a cell. I'll add it to my list!
     
  10. sp-sergio-gil

    sp-sergio-gil

    Joined:
    Mar 5, 2014
    Posts:
    45
    Hey! I like the idea of having a component that does all the things (infinite, reusable, snap,...) the think is that I trying only to give my opinion on how I would like to proceed... like having all in the same component, having different components related,...

    As you said, I was trying to help and giving my opinion
     
  11. BeeBop1

    BeeBop1

    Joined:
    Oct 5, 2013
    Posts:
    19
    Hey this is cool!!!
    Any idea how I could magnify the selected one as theyre moving, like a smooth magnification of the centred item?
    Thanks heaps for this project.
     
    Beks_Omega likes this.
  12. dohaiha930

    dohaiha930

    Joined:
    Mar 27, 2018
    Posts:
    55
    Very useful for us when create scroll snap view, thank you very much! :D
     
    Beks_Omega likes this.
  13. Beks_Omega

    Beks_Omega

    Joined:
    Jun 7, 2017
    Posts:
    72
    Ok I have two pretty simple solutions for you! I based all of this on the Directional Scroll Snap, but the idea behind both solutions should work for either the Direction or OmniDirectional components, you may just have to switch around a few lines of code.

    And just for reference my Directional Scroll Snap's snap mode is set to SnapToNext.

    This creates a sort of "gradient" of scale based on an Animation Curve. The items closest to the center of the scroll snap are larger than the items further away, and whenever the scroll snap moves it updates.

    You're going to need access to the Calculate Children of the scroll snap (unless you only want to scale the Snap Children, in that case grab those) so you're going to need to add two simple lines of code to the Directional Scroll Snap (this will be added in an up-comming update [EDIT: Added]).



    That done you're going to need to create a class like this:

    Code (CSharp):
    1. using System.Collections;
    2. using UnityEngine;
    3. using UnityEngine.UI.ScrollSnaps;
    4.  
    5. public class ScaleBasedOnDistance : MonoBehaviour {
    6.  
    7.     public DirectionalScrollSnap scrollSnap;
    8.     public RectTransform scrollSnapRectTransform;
    9.     public AnimationCurve scaleCurve;
    10.  
    11.     public void Start()
    12.     {
    13.         scrollSnap.UpdateLayout();
    14.         UpdateScale();
    15.     }
    16.  
    17.     public void OnValueChanged(Vector2 normalizedPos)
    18.     {
    19.         UpdateScale();
    20.     }
    21.  
    22.     private void UpdateScale()
    23.     {
    24.         foreach (RectTransform child in scrollSnap.calculateChildren)
    25.         {
    26.             float scale = scaleCurve.Evaluate(Vector3.Distance(scrollSnapRectTransform.position, child.position));
    27.             child.localScale = new Vector3(scale, scale, scale);
    28.         }
    29.     }
    30. }
    31.  
    Attach that to a GameObject in your Scene (I attached mine to my Directional Scroll Snap), fill in the variables, and add the OnValueChanged function to the Direction Scroll Snap's OnValueChanged event.

    The Animation Curve really determines the look and feel of this solution. In this first example I set it up so that anything further away than 500 had a scale of 1, and because the farthest away an item can be is 500 it creates a scale "gradient" across all of the items.


    Video Link

    In the second example I set the "max distance" to be 200, this makes it so the closest 1 or 2 items are the only ones affected.


    Video Link

    The solution you use for your specific senario may be different (e.g. you may want to manipulate the item's size delta's directly, or change their color instead of their scale) but hopefully this gives you one idea of how you could acheive this!

    This is a solution for only manipulating the target item and the previous target item, so it doesn't create the "gradient" of scale that was in the previous solution. Everything here is based on animation times.

    First you're going to need to fix a bug I discovered while creating this (I'll put up a fix for this soon [EDIT: Fixed]) all you need to do is change the > sign in this function to a >= sign. (The picture has it fixed)



    And then you're going to need to create a class like this:

    Code (CSharp):
    1. using System.Collections;
    2. using UnityEngine;
    3. using UnityEngine.UI.ScrollSnaps;
    4.  
    5. public class ScaleBasedTarget : MonoBehaviour {
    6.  
    7.     public DirectionalScrollSnap scrollSnap;
    8.     public RectTransform scrollSnapRectTransform;
    9.     public AnimationCurve scaleCurve;
    10.  
    11.     private RectTransform targetItem;
    12.     private RectTransform previousTargetItem;
    13.  
    14.     public void Start()
    15.     {
    16.         scrollSnap.UpdateLayout();
    17.  
    18.         scrollSnap.GetChildAtIndex(scrollSnap.closestSnapPositionIndex, out selectedItem);
    19.         selectedItem.localScale = new Vector3(1.5f, 1.5f, 1.5f);
    20.     }
    21.  
    22.     public void TargetItemSelected(int snapIndex)
    23.     {
    24.         previousTargetItem = targetItem;
    25.         scrollSnap.GetChildAtIndex(snapIndex, out targetItem);
    26.         StartCoroutine(ScaleSelectedItems());
    27.     }
    28.  
    29.     private IEnumerator ScaleSelectedItems()
    30.     {
    31.         while (scrollSnap.scroller.timePassedSinceStartOfAnimation < scrollSnap.scroller.durationOfLatestAnimation)
    32.         {
    33.             if (previousTargetItem != null)
    34.             {
    35.                 float scale = Mathf.Lerp(1.5f, 1f, scrollSnap.scroller.timePassedSinceStartOfAnimation / (float)scrollSnap.scroller.durationOfLatestAnimation);
    36.                 previousTargetItem.localScale = new Vector3(scale, scale, scale);
    37.             }
    38.  
    39.             if (targetItem != null)
    40.             {
    41.                 float scale = Mathf.Lerp(1f, 1.5f, scrollSnap.scroller.timePassedSinceStartOfAnimation / (float)scrollSnap.scroller.durationOfLatestAnimation);
    42.                 targetItem.localScale = new Vector3(scale, scale, scale);
    43.             }
    44.  
    45.             yield return null;
    46.         }
    47.     }
    48. }
    49.  
    Attach that to a GameObject in your Scene (I attached mine to my Directional Scroll Snap), fill in the variables, and add the TargetItemSelected function to the Direction Scroll Snap's TargetItemChanged event.

    Video Link

    This achieves an effect that only manipulates objects once the TargetItem has been selected. It is not a robust solution (in this form at least) because it doesn't handle things like people moving the Scroll Snap in the middle of an animation, but hopefully it gives you an idea of a different way you could handle the same problem!

    Sorry it took me so long to get back to you! And sorry that I wrote such a wall of text for your 1 line question hehe. (I may have gotten a bit carried away.) Tell me if you have any feedback about the examples above or about the Scroll Snap project in general!
     
    Last edited: Mar 27, 2018
  14. Beks_Omega

    Beks_Omega

    Joined:
    Jun 7, 2017
    Posts:
    72
    Update: More Accessors and some Bug Fixes
    [Edit: Update 0.5.0]

    Directional Scroll Snap:
    • Added calculateChildren property and snapChildren property, which gives you a list of the children used for calculating and snapping (respectively) - from Start to End.
    • Added a closestItem property so you don't have to go through the bother of
      scrollSnap.GetChildAtIndex(scrollSnap.closestSnapPositionIndex, out child); 
    • Fixed bug with all of the Get<Thing>AtIndex functions, so now they will let you get things at index 0
    • Added #if statements around all of the UnityEditor pieces, so it should work with builds better now (yay!)
    • And fixed some other minor bugs.
    OmniDirectional Scroll Snap:
    • Added calculateChildrenTopToBottom, calculateChildrenLeftToRight, snapChildrenTopToBottom, and snapChildrenLeftToRight properties, so now you have access to the OmniDirectional Scroll Snap's children in whatever order you so choose.
    • Added #if statements around all of the UnityEditor pieces.
    • And fixed some other minor bugs.
    Scroller:
    • Added public properties so you can read the Scroller's friction, minDuration, and maxDuration after it has been created.
     
    Last edited: Apr 16, 2018
  15. BeeBop1

    BeeBop1

    Joined:
    Oct 5, 2013
    Posts:
    19
    This is amazing, thank you! I really like option one, curve two. I've got it setup and all working perfectly :D
     
    Beks_Omega likes this.
  16. ali-but

    ali-but

    Joined:
    Apr 3, 2018
    Posts:
    19
    Hi ,i am using DirectionalScrollSnap . i have noticed that it only starts from far left side of scroll . what if i want to start from right and move towards left ? is it possible ?
     
  17. Beks_Omega

    Beks_Omega

    Joined:
    Jun 7, 2017
    Posts:
    72
    Currently the Directional Scroll Snap starts wherever it is in edit mode. So if you have the Content positioned so that it's towards the left it will start on the left, and if you have the Content positioned on the right it will start on the right.

    Try moving your Content so that whatever item you would like the Scroll Snap to start on is centered.


    Video Link

    In the future I'm hoping to add a public variable so you can specify a starting item (as sp-sergio-gil suggested), but alas this is not available yet.

    Tell me if this helps with your problem or if you were talking about something different! Ty for the feedback!
     
    Last edited: Apr 4, 2018
  18. ali-but

    ali-but

    Joined:
    Apr 3, 2018
    Posts:
    19
    Hi, Actually i was adding data on runtime not in editor mode . So what i did it i scalled content with Vector(-1,1,1) and all the childs under content with (-1,1,1) also . now it is moving from right towards left
     
  19. ali-but

    ali-but

    Joined:
    Apr 3, 2018
    Posts:
    19
    there is another issue . sometimes it doesn't snap to next child and give this error "
    Child: AVPro Video(Clone) is outside the valid bounds of the content. If this was unintentional move it inside region indicated by the green arrow gizmos. If you see no green arrows turn on Draw Gizmos.
    UnityEngine.Canvas:SendWillRenderCanvases()
    "

    i can confirm it does not happen because of my (-1,1,1) scalling .
     
  20. Beks_Omega

    Beks_Omega

    Joined:
    Jun 7, 2017
    Posts:
    72
    That sounds like a very interesting solution, but sadly that's not how the Directional Scroll Snap is setup to work. Let me see if some pictures can help.

    So I've turned on the Draw Gizmos bool to hopefully show what I'm talking about better. This Scroll Snap's content's scale is set to 1,1,1 and as you can see three of the items have cyan lines going through their pivots (meaning they're snappable), while the one to the left is outlined in red. This is because it is outside the bounds of the placeable region, meaning if the Directional Scroll Snap tried to calculate its content's size right now it would throw the warning you're describing.


    All of the child items, that you want used in size calculation and snapping, must be inside the region indicated by the green arrows.

    Now if we look at the Scroll Snap where the content has a scale of -1,1,1 you can see that three of the items are outlined in red, while the one to the right has a cyan line through it (meaning it's snappable). This is because the scale flip is confusing the Directional Scroll Snap.


    All of this is to say that you generally want to keep the content's scale set to 1,1,1 and when populating your scroll snap keep the top left corner in mind.

    Here is a solution for populating your scroll snap programmatically (either from start -> end or from end -> start) while keeping the scale at 1,1,1. This also aligns the content on the right after it finishes (or at the bottom in the case of vertical scroll snaps) but this can be changed as well.

    Just be sure to fill in all public variables through the inspector, and change line 27 to your prefered fill method before testing it out.

    Code (CSharp):
    1. using UnityEngine;
    2. using UnityEngine.UI.ScrollSnaps;
    3.  
    4. public class PopulateScrollSnap : MonoBehaviour {
    5.  
    6.    
    7.     public DirectionalScrollSnap scrollSnap;
    8.  
    9.     //if you're moving horizontally this will be how far below the top
    10.     //of the content you want your items to be. (-100, -200, ect)
    11.     //if you're moving vertically this is how far right of the left
    12.     //of the content you want your items to be. (100, 200, ect)
    13.     public float nonMovementAxisPos;
    14.  
    15.     //this is the distance between the pivots of the items (for simplicity)
    16.     //if you want to set the distances between the edges of the items
    17.     //(because, for example, you have different sized items) you can do that
    18.     //it just takes some fancier coding.
    19.     public float distance;
    20.  
    21.     public GameObject prefab;
    22.  
    23.     public int amount;
    24.  
    25.     public void Start()
    26.     {
    27.         //Either of the Fill Functions here
    28.  
    29.         scrollSnap.UpdateLayout();
    30.         scrollSnap.horizontalNormalizedPosition = 1;
    31.         //or scrollSnap.verticalNormalizedPosition = 1; if you're moving vertically
    32.     }
    33.  
    34.     public void FillFromStartToEnd()
    35.     {
    36.         for (int i = 0; i < amount; i++)
    37.         {
    38.             GameObject GO = Instantiate(prefab, scrollSnap.content);
    39.             //do any other setup on the GO around here
    40.  
    41.             RectTransform goRect = GO.GetComponent<RectTransform>();
    42.             goRect.anchorMin = new Vector2(0, 1);
    43.             goRect.anchorMax = new Vector2(0, 1);
    44.  
    45.             //if we're moving horizontally we want to modify the X axis (0) otherwise
    46.             //we want to modify the Y axis (1)
    47.             int movementAxis = (scrollSnap.movementDirection == DirectionalScrollSnap.MovementDirection.Horizontal) ? 0 : 1;
    48.             int nonMovementAxis = 1 - movementAxis;
    49.  
    50.             //if we're moving horizontally the end is towards the right (positive)
    51.             //but if we're moving vertically the end is towards the bottom (negative)
    52.             //hence the multiplier
    53.             int directionMultiplier = (scrollSnap.movementDirection == DirectionalScrollSnap.MovementDirection.Horizontal) ? 1 : -1;
    54.  
    55.             Vector2 newGOAnchorPos = Vector2.zero;
    56.             newGOAnchorPos[movementAxis] = distance * i * directionMultiplier;
    57.             newGOAnchorPos[nonMovementAxis] = nonMovementAxisPos;
    58.  
    59.             goRect.anchoredPosition = newGOAnchorPos;
    60.         }
    61.     }
    62.  
    63.     public void FillFromEndToStart()
    64.     {
    65.         for (int i = 0; i < amount; i++)
    66.         {
    67.             GameObject GO = Instantiate(prefab, scrollSnap.content);
    68.             //do any other setup on the GO around here
    69.  
    70.             RectTransform goRect = GO.GetComponent<RectTransform>();
    71.             goRect.anchorMin = new Vector2(0, 1);
    72.             goRect.anchorMax = new Vector2(0, 1);
    73.  
    74.             //if we're moving horizontally we want to modify the X axis (0) otherwise
    75.             //we want to modify the Y axis (1)
    76.             int movementAxis = (scrollSnap.movementDirection == DirectionalScrollSnap.MovementDirection.Horizontal) ? 0 : 1;
    77.             int nonMovementAxis = 1 - movementAxis;
    78.  
    79.             //if we're moving horizontally the end is towards the right (positive)
    80.             //but if we're moving vertically the end is towards the bottom (negative)
    81.             //hence the multiplier
    82.             int directionMultiplier = (scrollSnap.movementDirection == DirectionalScrollSnap.MovementDirection.Horizontal) ? 1 : -1;
    83.  
    84.             Vector2 newGOAnchorPos = Vector2.zero;
    85.             newGOAnchorPos[movementAxis] = ((distance * amount) - (distance * i)) * directionMultiplier;
    86.             newGOAnchorPos[nonMovementAxis] = nonMovementAxisPos;
    87.  
    88.             goRect.anchoredPosition = newGOAnchorPos;
    89.         }
    90.     }
    91. }
    Now I know that class probably won't solve all of your problems (and I mean really what would be the fun in it if it did), but hopefully it gives you a starting place to work from!

    ***

    PS: In the next update public functions for adding items programmatically will be added*, so you don't have to go through this hassle yourself, along with looping functionally.*

    *This will only be added to the Directional Scroll Snap for now though.
     
  21. ali-but

    ali-but

    Joined:
    Apr 3, 2018
    Posts:
    19
    Hi Beks_Omega , You were right about red lines Outlined becasue of -1,1,1 scalling. I have used your above code and modified it according to my need and content is showing according to my need with out red outlines, thank you for that .

    how ever the issue where when you're scrolling through and sometimes it doenst scroll snap to next item is still there .
    i have uploaded a video for your reference

    https://drive.google.com/file/d/1CFk-_0HEVBUFs-YEnhSmPbdzkQkVEIiB/view?usp=drivesdk



    in this videio you will notice next items get stuck. i am using scroll snap to next item

    Edit: I have noticed it only happens when you are moving from first child to 2nd child and from 2nd last child to last child and vice versa

    these are my settings in unity editor



    There is one another thing which is not relevent to the video , In order to diabled or animate forward and back button of scroll i was checking m_SnapPositions.IndexOf(snapPos) if its 0 i disable back if it is m_SnapPositions.IndexOf(snapPos) == m_SnapPositions.Count-1 i disable forward . i am doing this check at the end of DoEndManualMovement

    is there any other better way to do this ?
     
    Last edited: Apr 5, 2018
  22. Beks_Omega

    Beks_Omega

    Joined:
    Jun 7, 2017
    Posts:
    72
    I'm having trouble replicating this particular behavior. Would you mind sending me some more images of your settings?

    It would be awesome if you could send me images of:
    • The RectTransform component of your Directional Scroll Snap (whatever the DirectionalScrollSnap component is attached to).
    • The RectTransform of your Content.
    • The (Horizontal)LayoutGroup on your Content (if you have one).
    • The RectTransform component of your prefab (the one that you're replicating programmatically).
    Most likely the Scroll Snap is handling one of these three things incorrectly.

    Sounds like a reasonable way of handling that, but if you send me the code I could give you a more informed response.

    Ty for the videos and info!
     
    Last edited: Apr 5, 2018
  23. ali-but

    ali-but

    Joined:
    Apr 3, 2018
    Posts:
    19
  24. ali-but

    ali-but

    Joined:
    Apr 3, 2018
    Posts:
    19
    Hi Beks_Omega
    Snapping issue was on my side ,i eddited your code a bit which caused that . its fine now and working as expected .
     
  25. Beks_Omega

    Beks_Omega

    Joined:
    Jun 7, 2017
    Posts:
    72
    I'm glad you it's working ali-but! I hope it works well for your problem! If you have any other feedback, requests, or questions be sure to ask!
     
  26. ali-but

    ali-but

    Joined:
    Apr 3, 2018
    Posts:
    19
    I would be nice if it doesn't throw an error when content has no child because i am adding content child dynamically it keeps throwing error all the times. except for that awesome job for Unity Community
     
  27. Beks_Omega

    Beks_Omega

    Joined:
    Jun 7, 2017
    Posts:
    72
    In the next update I've changed it so that it doesn't update automatically in edit mode, it only updates when you push the "Update" button, so as long as that doesn't have any negative repercussions when I go into testing that should fix the annoying error-ness.

    Otherwise I'll come up with a different solution to mitigate that problem. You're doing something supported so it shouldn't throw errors. :D

    Ty for the feedback!
     
  28. Beks_Omega

    Beks_Omega

    Joined:
    Jun 7, 2017
    Posts:
    72
    Update 0.6.0 Looping!

    Directional Scroll Snap:
    • Added Looping functionality.
    • Added new Examples of looping to the Directional Scroll Snap example so you can see how it works.
    • Added new Functions so you can populate and edit the Scroll Snap at runtime including InsertChild, RemoveChild, SetChildStartSpacing, SetChildEndSpacing and more. @ali-but tell me if you would like an updated example of populating the Scroll Snap using these methods!
    • Added the new concept of SnapIndex vs CalculateIndex.
    • Changed the GetChildAtIndex method to GetChildAtSnapIndex.
    • Added the GetChildAtCalculateIndex method.
    • Now Only calls UpdateLayout in edit mode when the Update button is pressed to allow for easier editting of layout groups.
    • Removed the MissingReference exception when the content has no children.
    Scroller:
    • Added the ShiftAnimation method.
    You can view the full update log here.

    I've done quite a bit of testing on this and I /think/ it's all solid but I am the only tester, and there are a lot of edge cases with looping, so there will probably be bugs. If you do find a but please tell me! I really want to fix it :D

    ***

    Next I'm going to be working on putting more documentation on the project wiki, and I'll probably put out some bug fix and optimization releases.

    After that I'm going to be adding new features like the start item suggested by sp-sergio-gil so if you have any requests/suggestions/ect be sure to contact me!
     
  29. Beks_Omega

    Beks_Omega

    Joined:
    Jun 7, 2017
    Posts:
    72
    Non-Code Update:

    Added Wiki Documentation on the bitbucket, if you find anything missing feel free to add it or shoot me a msg!
     
  30. Beks_Omega

    Beks_Omega

    Joined:
    Jun 7, 2017
    Posts:
    72
    Update 0.6.1 Optimization and Bug Fixes

    Directional Scroll Snap:
    • Optimized looping and all of the public "layout" functions (InsertChild, RemoveChild, SetItemEndSpacing, ect) I'm not promising it's perfect, but it's definitely better!
    • Another Optimization: Now uses List.Clear instead of new List<>(); whenever a list needs to be overwritten.
    • Fixed a particularly nasty bug where verticalNormalizedPosition would return the incorrect value. This would cause issues where the Scroll Snap would appear to jump or vibrate under certain circumstances.
    • Fixed a smattering of other bugs.
    OmniDirectional Scroll Snap:
    • Like the Directional Scroll Snap: Now uses List.Clear instead of new List<>(); whenever a list needs to be overwritten.
    • Now only calls UpdateLayout in edit mode when the Update button is pressed to allow for easier editting of layout groups.
    • Added public get properties for things like friction and interpolator type.
    • Fixed the same verticalNormalizedPosition bug.
    • Squashed some other bug families.
    You can view the full update log here.

    ***
    Next up (as long as no bugs are found), are going to be some new features added to both the Directional Scroll Snap and OmniDirectional Scroll Snap including the start item suggested by sp-sergio-gil and (hopefully) a more more customizable velocity/animation system that will probably come to you in the form of dropdowns and toggles hehe.

    After that the OmniDirectional Scroll Snap is probably gonna get some TLC in the form of some public layout functions like the Directional Scroll Snap got in update 0.6.0

    I'll state once again, if you have any feature requests or find any bugs, shout at me :D
     
    ali-but likes this.
  31. VodouSidi

    VodouSidi

    Joined:
    Feb 8, 2018
    Posts:
    5
    Hello guys! I hope this topic isn't closed yet, because I have a question. I have a horizontal scroll snap in my project, and it works nice (thanks a lot for this amazing feature by the way @Beks_Omega). What I am trying to do is simple: I want to set back the current page of the scroll snap to be the first page once the player (rigid body FPS) exits a certain area (collider). So I tried this:

    Code (CSharp):
    1.     private void OnTriggerExit(Collider col)
    2.     {
    3.         if (col.gameObject.name == "RigidBodyFPSController") {
    4.     // Other instructions here, then:      
    5.             GameObject.Find("Horizontal Scroll Snap").GetComponent<ScrollRect>().horizontalNormalizedPosition = 0;
    6.         }
    7.     }
    But this doesn't work at all. The other instructions in the "if" all work perfectly fine, but this one doesn't. I must say I am pretty new to Unity and its C#, so maybe I am missing something?
    I really need your help, guys!
     
  32. Beks_Omega

    Beks_Omega

    Joined:
    Jun 7, 2017
    Posts:
    72
    Looks like a pretty easy fix! Instead of getting the ScrollRect component you just need to get the DirectionalScrollSnap component (assuming you're using a Directional Scroll Snap and not an OmniDirectional one).

    You may also need to add the statement:
    using UnityEngine.UI.ScrollSnaps
    to the top of your script if you haven't already. Observe lines 1 & 7.

    Code (CSharp):
    1. using UnityEngine.UI.ScrollSnaps;
    2.  
    3. private void OnTriggerExit(Collider col)
    4.     {
    5.         if (col.gameObject.name == "RigidBodyFPSController") {
    6.     // Other instructions here, then:    
    7.             GameObject.Find("Horizontal Scroll Snap").GetComponent<DirectionalScrollSnap().horizontalNormalizedPosition = 0;
    8.         }
    9.     }
    If that doesn't work for you shoot me back a msg! I hope you enjoy the project and if you have an requests, recommendations, comments, or other questions be sure to shout. :D
     
  33. VodouSidi

    VodouSidi

    Joined:
    Feb 8, 2018
    Posts:
    5
    Thanks a lot! :)
     
  34. Beks_Omega

    Beks_Omega

    Joined:
    Jun 7, 2017
    Posts:
    72
    I'm working on the next release and I wanted to get some feedback about this animation system idea I've had rolling around in my head.

    My question is:
    And here's where you can go answer. Please do not reply to this forum with an answer.

    And please note that the vote does not control what goes into a release. There could be technical limitations to what can be done, or UX limitations to how this information can be displayed. This vote does not guarantee what does or does not go into a future release.

    If you do have any requests for features, especially (but not necessarily) ones related to improving the animation system, I would love to hear them! As well as any other comments or questions.

    Thank you for taking the time to fill out the survey if you choose to do so! I really apreciate the feedback and input!
     
  35. nikescar

    nikescar

    Joined:
    Nov 16, 2011
    Posts:
    165
    Hello Beks,

    I've noticed that using spacing on a Vertical or Horizontal Layout Group does not work as expected. If the spacing value is anything other than 0 or the height/width of a Child Item, the snap positions are off.

    I've made a temporary fix for this:

    Code (CSharp):
    1. private void GetSnapPositions()
    2.         {
    3.             m_SnapPositions.Clear();
    4.  
    5.             foreach(RectTransform child in m_ChildrenForSnappingFromStartToEnd)
    6.             {
    7.                 float normalizedPosition;
    8.                 GetNormalizedPositionOfChild(child, out normalizedPosition);
    9.                 SetNormalizedPosition(normalizedPosition, axis);
    10.                 Vector2 spacingFix = Vector2.zero;
    11.                 if (contentIsHorizonalLayoutGroup)
    12.                 {
    13.                     spacingFix = Vector2.right * m_EndSpacing * 2;
    14.                 }
    15.                 else if (contentIsVerticalLayoutGroup)
    16.                 {
    17.                     spacingFix = Vector2.up * m_EndSpacing * 2;
    18.                 }
    19.                 m_SnapPositions.Add(RoundVector2ToInts(m_Content.anchoredPosition) + spacingFix);
    20.             }
    21.         }
    and

    Code (CSharp):
    1. private bool contentIsHorizonalLayoutGroup
    2.         {
    3.             get
    4.             {
    5.                 if (m_Content == null)
    6.                 {
    7.                     return false;
    8.                 }
    9.                 HorizontalLayoutGroup horizLayoutGroup = m_Content.GetComponent<HorizontalLayoutGroup>();
    10.                 return horizLayoutGroup;
    11.             }
    12.         }
    13.      
    14.         private bool contentIsVerticalLayoutGroup
    15.         {
    16.             get
    17.             {
    18.                 if (m_Content == null)
    19.                 {
    20.                     return false;
    21.                 }
    22.                 VerticalLayoutGroup vertLayoutGroup = content.GetComponent<VerticalLayoutGroup>();
    23.                 return vertLayoutGroup;
    24.             }
    25.         }
    ...but this is very hack-y because it uses the m_endSpacing value only so end spacing and the spacing value on the LayoutGroup have to be the same but, it works for me.

    Thanks for the great asset!
     
  36. Beks_Omega

    Beks_Omega

    Joined:
    Jun 7, 2017
    Posts:
    72
    Thank you for sending this in! That sounds like an absolutely terrible bug so I'm really sorry it's happening! For some reason I can't seem to replicate it though. Would you mind sending me some more info about how you had your Scroll Snap set up before you added your fix?

    (Sorry if this list is a bit long but I want to include any info I might need)
    What version of Scroll Snaps are you using (0.6.0, 0.6.1, or earlier)?
    Are you using a Directional Scroll Snap or an OmniDirectionalScrollSnap?
    Could you send me a pic of the Scroll Snap's Inspector settings (fully expanded if possible)?
    Could you send me a pic of the Vertical/Horizontal Layout Group's settings (fully expanded if possible)?
    Could you send me a short video or picture of what the Scroll Snap looks like when it is misaligned?

    Thank you again for sending in that solution! And thank you for using the project! If you have any other feedback, questions, comments, requests, or solutions be sure to post!
     
  37. nikescar

    nikescar

    Joined:
    Nov 16, 2011
    Posts:
    165
    Hi Beks,

    Turns out my solution only works in very specific instances.

    I did notice that, in looping scrollviews, if you watch the Inspector in Debug mode while dragging the scrollview, 0 seems to be the position at which the Content object should be snapping. If that is the case, then m_SnapPositions and the like might not be necessary.

    Here is a project to show you what is happening: https://1drv.ms/u/s!Av-LCZ77XIdujo00dhMPwmoVrsBxSw

    This project is with a fresh, untouched UnityUIScrollSnaps 0.6.1

    Thanks for taking a look!
     
  38. Beks_Omega

    Beks_Omega

    Joined:
    Jun 7, 2017
    Posts:
    72
    Thank you for sending this too me, it perfectly demonstrated what you were talking about!

    I figured out that I couldn't replicate it because I was doing my testing on a Directional Scroll Snap set to Horizontal, where this bug does not occur.

    It turns out that this was actually a bug in the GetNormalizedPositionOfChild function, where it would return incorrect values if the Scroll Snap was Vertical. The bug fix will be released with version 0.7.0 (the animation update) which will be coming out soon. Here is the fix if you would like to correct it for your personal use before then:

    Change this:
    Code (CSharp):
    1. public bool GetNormalizedPositionOfChild(RectTransform child, out float normalizedPosition)
    2.         {
    3.             Vector2 startPos = m_ViewBounds.Extents
    4.             normalizedPosition = DistanceOnAxis(child.anchoredPosition, startPos, axis) / (m_ContentBounds.size[axis] - m_ViewBounds.size[axis]);
    5.             return child.parent == m_Content;
    6.         }
    To this:

    Code (CSharp):
    1. public bool GetNormalizedPositionOfChild(RectTransform child, out float normalizedPosition)
    2.         {
    3.             UpdateBounds(); //this just makes sure m_ViewBounds isn't null or anything
    4.             Vector2 startPos = new Vector2(m_ViewBounds.extents.x, -m_ViewBounds.extents.y); //this actually fixes the bug
    5.             normalizedPosition = DistanceOnAxis(child.anchoredPosition, startPos, axis) / (m_ContentBounds.size[axis] - m_ViewBounds.size[axis]);
    6.             return child.parent == m_Content;
    7.         }
    Curse me for deciding to make forward down! lol

    Message me back if that doesn't work for ya, but I tested it in my project as well as yours and it seems to be working!

    I'm not sure if you're refering to Scroll Rects (made by Unity) or Scroll Snaps, but so far I have not seen this to be true with the latter (it could be true and I just haven't seen it though ¯\_(ツ)_/¯). SnapPositions would still have to be maintained for non-looping Scroll Snaps but maybe for looping ones there're some optimizations to be done, who knows. If you wanna play around with it and find you can make it work be sure to put up a PR I'd love to see it!

    So again tell me if the fix works, doesn't work, sorta works, ect and tell me if you find any other bugs as well! If you have any other feedback be sure to post :D and ty again for sending this in!
     
  39. Beks_Omega

    Beks_Omega

    Joined:
    Jun 7, 2017
    Posts:
    72
    Update 0.7.0 New Animation System

    Directional & OmniDirectional Scroll Snaps:
    • Added a public Start Item (requested by sp-sergio-gil )
    • Added functions for jumping to items & snap indexes.
    • All animations are now in essence scroll animations, taking in an interpolator and a duration (it looks wicked when you use an overshoot interpolator on flings) but it still allows you to simulate flings while doing so.
    • Added the ability to override settings like interpolator and friction for different input types.
    • Added an option to disable touch input.
    • Added an option to change how many items the Scroll Snap moves by when a button is pressed.
    • Added a virtual ImplimentCustomInterpolator function that makes it easier to impliment custom interpolators.
    • Removed public fling functions (since everything is based on scrolls now).
    • Fixed some buggies.
    Scroller:
    • Added flywheel functionality to flings (even if flings are not supported by Scroll Snaps any longer they are still supported by the Scroller) which allows you to add the velocity of a new Fling animation to the velocity of any already running fling animations.
    • Added CalculateMovementDelta, CalculateDecelerationRate, and CalculateDuration public functions. These public functions allow you to get the estimated movement delta, deceleration rate, or duration, for a Fling based on the given input.
    • Added new DecelerateAccelerate interpolator.
    • Removed min duration, max duration, friction, and interpolator vars. All of these things are now passed (or there equivalents are passed) when you start each individual animation.
    For the full list of changes see the Update Log.

    ***

    Tell me if you like the new animation system or if you don't like it. It is definitely different than the old one but hopefully also better! If you guys have any questions about how to do certain things with it or if you have suggestions for other things to add be sure to post! And if you have any other feedback including bugs, comments, or cool things you've made be sure to post that as well! :D
     
  40. nikescar

    nikescar

    Joined:
    Nov 16, 2011
    Posts:
    165
    I can't wait to try out this update!

    Something I did notice on the previous version was some Editor errors when building for Android (and probably any other platform). At the very least it needs to have #if UNITY_EDITOR tags around OnValidate and the like but I think there may be a few more issues there too.

    Thanks for the continued work on this useful tool :)
     
  41. Beks_Omega

    Beks_Omega

    Joined:
    Jun 7, 2017
    Posts:
    72
    Ty for informing me! Next thing I look into will be that :D
     
  42. Claes

    Claes

    Joined:
    Jul 4, 2011
    Posts:
    4
    I'm having some trouble implementing the example you provided to ali-but. Whenever I populate stuff, it's all misplaced, and the interaction doesn't work as intended.

    Could you possibly provide an example? I'm mainly trying to populate vertical scroll snap. I can't seem to get the list to grow dynamically in the direction I want (top -> down). Objects always populate either upwards or from the middle and out. Am I doing something wrong?

    Thanks.

    EDIT: I went with another solution and edited the anchor. Maybe that's the same solution for this bundle, but I'm happy with how this works for now.
     
    Last edited: May 20, 2018
  43. Beks_Omega

    Beks_Omega

    Joined:
    Jun 7, 2017
    Posts:
    72
    I'm glad you found something that works for you! (Sorry I couldn't respond sooner)

    There are also some built-in layouting functions you can use (in particular InsertChild) that might be helpful. If you still want an example I can post some code &r post an example project. Or if the solution you have currently works great that's rad too!

    Ty for posting and again I'm sorry I couldn't respond more quickly! If you have any more questions, suggestions, or other feedback be sure to post!
     
  44. Beks_Omega

    Beks_Omega

    Joined:
    Jun 7, 2017
    Posts:
    72
    Update 0.8.0 OmniDirectional Layouting

    Directional Scroll Snap & OmniDirectional Scroll Snap:
    • Placing items inside of the green arrow gizmos (below & to the right of the top left) is no longer necessary! The green arrows have been completely removed and you can now place items wherever you want!
    OmniDirectional Scroll Snap:
    • Runtime Layouting functions have made their way to the OmniDirectional Scroll Snap! Including functions such as InsertChild, RemoveChild, and SetChildSnappability. As well as functions exclusive to the OmniDirectional Scroll Snap such as MoveChildren(RectTransform referenceChild, RelativeDirection direction, Vector2 offset) which moves all of the children relative to the referenceChild by the offset. i.e. move all children below the reference child by (0, -100).
    Those are the major updates! For a full list of updates see the Updates Log.

    ***

    So this is as far as I planned for the Scroll Snaps project, which means that I don't have any more ideas of my own that I want to add, but I will still be accepting suggestions! But until I get any the project will be staying at update 0.8.0.

    I will still be accepting suggestions, PRs, and bug reports, so be sure to send those in!

    And if you have any questions about the project, or general comments I will still be watching this forum so be sure to post!

    Thank you guys so much for using the project! :D
     
    nikescar likes this.
  45. nikescar

    nikescar

    Joined:
    Nov 16, 2011
    Posts:
    165
    This is great Beks. I'll be putting this project through its paces and I'll be sure to let you know if I find anything. Thanks again for your work on this.
     
    Beks_Omega likes this.
  46. bbbenni

    bbbenni

    Joined:
    Jun 8, 2018
    Posts:
    2
    Hey.
    I first worked with the "Horizontal Scroll Snap" from Unity UI Extensions Project. Unfortunately I cannot get buttons within the pages to work.

    Is it possible to use Buttons within pages with this scroll snap asset?

    My goal is to build an UI like the homescreen of Smartphones and start new scenes on button (app) click.

    Thanks in advance.

    Benni
     
  47. Beks_Omega

    Beks_Omega

    Joined:
    Jun 7, 2017
    Posts:
    72
    Indeed it is!

    I believe the simplest solution would be to include the buttons as children of the different "screens", and the "screens" would be children of the content.

    Here's an example hierarchy:



    And then you can include as many buttons and screens as you see fit. :D

    If you have any other questions be sure to ask! I could also probably send you an example package if you think that would be helpful! I also tried to get a video of buttons working for you, but Win 10 was just not workin with me today.

    Good luck with your project! It sounds like an interesting UI challenge!
     
  48. Beks_Omega

    Beks_Omega

    Joined:
    Jun 7, 2017
    Posts:
    72
    Update 0.8.1 Help URLs
    • Add Help URL links to the Directional Scroll Snap, OmniDirectional Scroll Snap, and Scroller*, so that they now send you to their wiki pages, instead of the default Monobehavior documentation.
    Here's a picture of the button you can click to go to the documentation:


    *I added the HelpURLAttribute to the Scroller class, but I'm not actually sure where (if anywhere) this shows up in the editor, since it is not a Monobehavior.
     
  49. Beks_Omega

    Beks_Omega

    Joined:
    Jun 7, 2017
    Posts:
    72
  50. IMAGINE360

    IMAGINE360

    Joined:
    Apr 15, 2016
    Posts:
    3
    Hello Beks_Omega.

    This is a really nice asset. Good Job !

    I only have a question :

    I'd like to have my item being at full screen size ( Scale With canvas size which already scale with screen size) For an IOS and Android App (So it can be used on different screen size).

    The only issue is that the "content" GameObject and "Item" Gameobject Rect transform are driven by the DirectionalScrollSnap. Means each time i try to set them manually in the editor , they get resized at launch.

    Is there any option to do this with your asset ?

    Thank you.