Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

[Scripts] Useful 4.6 Scripts Collection

Discussion in 'UGUI & TextMesh Pro' started by Melang, Aug 24, 2014.

  1. Gangsta-Geek

    Gangsta-Geek

    Joined:
    Aug 11, 2012
    Posts:
    32
    Hello everyone! Thanks for these wonderful script. I've ran into an error that I dont know how to fix in the raycastMask script. Has anyone else ran into this error? My game still build and runs but I would like to clear this error if possible.

    UnityPro 4.6.4p1 Mac OSX 10.9.5


    NullReferenceException: Object reference not set to an instance of an object
    UnityEngine.UI.Extensions.RaycastMask.IsRaycastLocationValid (Vector2 sp, UnityEngine.Camera eventCamera) (at Assets/unity-ui-extensions/Scripts/RaycastMask.cs:48)
    UnityEngine.UI.Graphic.Raycast (Vector2 sp, UnityEngine.Camera eventCamera) (at /Users/builduser/buildslave/unity/build/Extensions/guisystem/UnityEngine.UI/UI/Core/Graphic.cs:435)
    UnityEngine.UI.GraphicRaycaster.Raycast (UnityEngine.Canvas canvas, UnityEngine.Camera eventCamera, Vector2 pointerPosition, System.Collections.Generic.List`1 results) (at /Users/builduser/buildslave/unity/build/Extensions/guisystem/UnityEngine.UI/UI/Core/GraphicRaycaster.cs:218)
    UnityEngine.UI.GraphicRaycaster.Raycast (UnityEngine.EventSystems.PointerEventData eventData, System.Collections.Generic.List`1 resultAppendList) (at /Users/builduser/buildslave/unity/build/Extensions/guisystem/UnityEngine.UI/UI/Core/GraphicRaycaster.cs:125)
    UnityEngine.EventSystems.EventSystem.RaycastAll (UnityEngine.EventSystems.PointerEventData eventData, System.Collections.Generic.List`1 raycastResults) (at /Users/builduser/buildslave/unity/build/Extensions/guisystem/UnityEngine.UI/EventSystem/EventSystem.cs:174)
    UnityEngine.EventSystems.PointerInputModule.GetMousePointerEventData () (at /Users/builduser/buildslave/unity/build/Extensions/guisystem/UnityEngine.UI/EventSystem/InputModules/PointerInputModule.cs:192)
    UnityEngine.EventSystems.StandaloneInputModule.ProcessMouseEvent () (at /Users/builduser/buildslave/unity/build/Extensions/guisystem/UnityEngine.UI/EventSystem/InputModules/StandaloneInputModule.cs:236)
    UnityEngine.EventSystems.StandaloneInputModule.Process () (at /Users/builduser/buildslave/unity/build/Extensions/guisystem/UnityEngine.UI/EventSystem/InputModules/StandaloneInputModule.cs:158)
    UnityEngine.EventSystems.EventSystem.Update () (at /Users/builduser/buildslave/unity/build/Extensions/guisystem/UnityEngine.UI/EventSystem/EventSystem.cs:271)
     
  2. SimonDarksideJ

    SimonDarksideJ

    Joined:
    Jul 3, 2012
    Posts:
    1,688
    Looks like there is a change in the camera logic that the raycast mask is dependant on, will try and find some time to investigate the version we have in the UI Extensions repo
     
  3. khanstruct

    khanstruct

    Joined:
    Feb 11, 2011
    Posts:
    2,869
    Is there a tutorial for the Accordion/Collapsible script? I can't seem to get mine working. I can't even figure out which components each UI element is supposed to have. :(
     
  4. SimonDarksideJ

    SimonDarksideJ

    Joined:
    Jul 3, 2012
    Posts:
    1,688
    on the front page, it includes a link to the original video / instructions, including the prefab's for the control.

    Not had time yet to go back and document it further. (always willing to accept help if anyone else has time :D)
     
  5. NibbleByteMHS

    NibbleByteMHS

    Joined:
    Jun 11, 2013
    Posts:
    1
    There is a bug in the script that happens ONLY in release with this method:
    Code (CSharp):
    1.  
    2. protected override void OnRectTransformDimensionsChange ()
    3.         {
    4.                 var tmpRect = curveForText [curveForText.length - 1];
    5.                 tmpRect.time = rectTrans.rect.width;
    6.                 curveForText.MoveKey (curveForText.length - 1, tmpRect);
    7.         }
    8.  
    If object is initially deactivated, this method can still be called (due to uGUI inner-workings) and since OnEnable() and Awake() have never been called, it throws NullReferenceException on rectTrans.rect.width because rectTrans is never fetched.
    Just try to anchor the object to stretch to the sides, so it changes dimensions and deactivate it.
    Note: In editor this works fine because OnValidate() gets called regularly and caches the rectTrans.
     
  6. Breyer

    Breyer

    Joined:
    Nov 10, 2012
    Posts:
    412
    what version u use? my package from this thread or collection from Simon? as im aware Simon have lastes ver of my scripts. This issue was solved long ago. You can see link in my signature as well if you want latest version
     
  7. pioj

    pioj

    Joined:
    Nov 5, 2012
    Posts:
    34
    Yes, please. Do it. I currently depend of Grid Layouts for almost everything.
     
  8. tequyla

    tequyla

    Joined:
    Jul 22, 2012
    Posts:
    335
    Hi,

    do u know whay we have this error with unity free 4.6.5f1 for Gradient script?

    Code (CSharp):
    1. NullReferenceException: Object reference not set to an instance of an object
    2. Gradient.ModifyVertices (System.Collections.Generic.List`1 vertexList) (at Assets/Standard Assets/Scripts/Gradient.cs:50)
    3. UnityEngine.UI.Graphic.UpdateGeometry () (at C:/buildslave/unity/build/Extensions/guisystem/UnityEngine.UI/UI/Core/Graphic.cs:344)
    4. UnityEngine.UI.Text.UpdateGeometry () (at C:/buildslave/unity/build/Extensions/guisystem/UnityEngine.UI/UI/Core/Text.cs:363)
    5. UnityEngine.UI.Graphic.Rebuild (CanvasUpdate update) (at C:/buildslave/unity/build/Extensions/guisystem/UnityEngine.UI/UI/Core/Graphic.cs:317)
    6. UnityEngine.UI.CanvasUpdateRegistry.PerformUpdate () (at C:/buildslave/unity/build/Extensions/guisystem/UnityEngine.UI/UI/Core/CanvasUpdateRegistry.cs:104)
    7. UnityEngine.Canvas:SendWillRenderCanvases()
    8.  


    Regards.
     
  9. Ippokratis

    Ippokratis

    Joined:
    Oct 13, 2008
    Posts:
    1,521
    Could you give a link to the gradient script ?
     
  10. tequyla

    tequyla

    Joined:
    Jul 22, 2012
    Posts:
    335
  11. pioj

    pioj

    Joined:
    Nov 5, 2012
    Posts:
    34
    Sorry to bump this but, Is there a solution for ScrollRect + Grid Layout Group, on gamepad?
     
  12. Freezy

    Freezy

    Joined:
    Jul 15, 2012
    Posts:
    234
    find a way to switch control focus (probably already uses arrow keys by default)
    you could then wait for focus on the grid controller, then add input to that control when certain axis or buttons are triggered.

    Explain the problem more extensively if you need more help, the best way is to just make your own thread.
    Posting unrelated questions makes a forum messy.
     
  13. Kaz_Yamof

    Kaz_Yamof

    Joined:
    Jan 17, 2013
    Posts:
    28
    Switcher for Unity
    Hi guys, I've made a Switcher On/Off asset for Unity. Check it out!

    upload_2015-6-20_13-4-30.png

    How to use:
    The Switcher prefab has a scrpt called Switcher.cs. The properties are:
    • onColor = color to assume when switcher is on;
    • offColor = color to assume when switcher is off;
    • disbledColor = color to assume when switcher is transitioning between the states;
    • IsOn = property to get the current value of switcher, or to set a new value and trigger the transition of the button;
    Repo link: here.

    Comments and suggestions are wellcome.
     
  14. silentassassin47

    silentassassin47

    Joined:
    May 10, 2015
    Posts:
    1
    Great Job!!You saved my Mouse!!
     
    Senshi likes this.
  15. fermmmm

    fermmmm

    Joined:
    Oct 18, 2013
    Posts:
    129
    I've made uGUI Anchor Tools:

    - Convert screen space coordinates (pixels) to "anchor coordinates" (values from 0 to 1 used by anchors). And the opposite as well. Usefull for mouse/touch interaction.

    - Move and resize anchors using position and size concept instead of the complicated anchorMin and anchorMax concept. Usefull for tween libraries and cleaner code without math operations.

    - Convert anchor coordinates from the object to global (canvas level). And the opposite as well. Usefull for coordinate convertion between anchors located in different containers.

    Asset link:
    https://www.assetstore.unity3d.com/#!/content/41927

    More info:
    http://forum.unity3d.com/threads/released-ugui-anchor-tools.344407/
     
    Last edited: Aug 4, 2015
  16. Mikea15

    Mikea15

    Joined:
    Sep 20, 2012
    Posts:
    93
    @SimonDarksideJ I'm using a mix of the horizontalsnapscroll, with some modifications of mine, and I cannot make the items align in the center of the screen. Is there a way I can snap the items, so they are centered on screen? Also, In order to make the first and last item center on screen, I add padding left and right of the size of each item element.

    Any ideas? Tips?
     
  17. Freezy

    Freezy

    Joined:
    Jul 15, 2012
    Posts:
    234
    I redid the horizontal scroll snap thing as the one previously shared gave me all kinds of problems.
    It allows for horizontal and vertical snapping, handles keyboard input, mouse drag & select and scrolling wheel.
    You can define the anchor point, this will make the selected item align with that point.

    There are looping Next and Previous functions you can use, keyboard currently does not loop out of the box. Though you can alter Unity's navigation to set it up like that if you need to.

    Code (CSharp):
    1.  
    2. using UnityEngine;
    3. using UnityEngine.UI;
    4. using UnityEngine.EventSystems;
    5. using System;
    6.  
    7. /// <summary>
    8. /// Created by Freezy from Elicit Ice
    9. /// You are free to use and alter this code in any way you see fit, provided you leave this notice here
    10. /// </summary>
    11. public class ScrollToSelected : ScrollRect {
    12.     public float scrollSpeed = 100f;
    13.     public float scrollTime = 0.3f;
    14.  
    15.     [Range(0, 1)]
    16.     public float scrollingAnchorHorizontal = 0.5f;
    17.     [Range(0, 1)]
    18.     public float scrollingAnchorVertical = 0.5f;
    19.  
    20.     public enum ReleaseMode {
    21.         None,
    22.         //ScrollOnly, does not work
    23.         FullSelection,
    24.     }
    25.  
    26.     public int itemCount {
    27.         get { return content.childCount; }
    28.     }
    29.  
    30.     private bool IsMyChild(RectTransform selection) {
    31.         if (selection == null)
    32.             return false;
    33.         return selection.transform.parent == content.transform;
    34.     }
    35.  
    36.     public ReleaseMode releaseMode = ReleaseMode.FullSelection;
    37.     [ReadOnly]
    38.     public RectTransform targetScrollObject;
    39.  
    40.     // references
    41.     private RectTransform currentCanvas;
    42.  
    43.     protected override void Start() {
    44.         base.Start();
    45.         currentCanvas = GetComponentInParent<Canvas>().GetComponent<RectTransform>();
    46.         movementType = MovementType.Unrestricted;
    47.     }
    48.  
    49.     public override void OnBeginDrag(PointerEventData data) {
    50.         base.OnBeginDrag(data);
    51.         HandleReleaseMode(data);
    52.     }
    53.  
    54.     private void HandleReleaseMode(PointerEventData data) {
    55.         switch (releaseMode) {
    56.         default:
    57.         case ReleaseMode.None:
    58.             break;
    59.         //case ReleaseMode.ScrollOnly:
    60.         //    targetScrollObject = null;
    61.         //    break;
    62.         case ReleaseMode.FullSelection:
    63.             targetScrollObject = null;
    64.             data.selectedObject = null;
    65.             break;
    66.         }
    67.     }
    68.  
    69.     public override void OnScroll(PointerEventData data) {
    70.         base.OnScroll(data);
    71.         HandleReleaseMode(data);
    72.     }
    73.  
    74.     private void Update() {
    75.         ScrollRectToLevelSelection();
    76.     }
    77.  
    78.     private void ScrollRectToLevelSelection() {
    79.         if (content == null || viewRect == null || EventSystem.current == null)
    80.             return;
    81.  
    82.         // get calculation references
    83.         var currentObject = EventSystem.current.currentSelectedGameObject;
    84.         RectTransform selection = currentObject == null ? null : currentObject.GetComponent<RectTransform>();
    85.         RectTransform lastSelection = targetScrollObject == null ? selection : targetScrollObject;
    86.  
    87.         // check if selection is in the layout rect
    88.         if (!IsMyChild(selection)) {
    89.             //check clamp values
    90.             ClampPosition();
    91.             return;
    92.         }
    93.  
    94.         //keep a backreference for next update
    95.         targetScrollObject = selection;
    96.  
    97.         //somewhere within the viewRect
    98.         var contentAnchor = GetCenterPoint();
    99.         //there is an item we want to see
    100.         var itemPosition = selection.anchoredPosition;
    101.         //and keep in full view.
    102.         var itemOffset = GetItemOffset(selection);
    103.  
    104.         // so we calculate the position where we should look
    105.         var desiredPosition = (contentAnchor - itemPosition) - itemOffset;
    106.         ScrollTo(desiredPosition);
    107.     }
    108.  
    109.     public bool hasTarget { get { return targetScrollObject != null; } }
    110.  
    111.     public Vector2 scrollingAnchor {
    112.         get {
    113.             return new Vector2(
    114.                 horizontal ? scrollingAnchorHorizontal : 0f,
    115.                 vertical ? scrollingAnchorVertical : 0f);
    116.         }
    117.         set { scrollingAnchorHorizontal = value.x; scrollingAnchorVertical = value.y; }
    118.     }
    119.  
    120.     Vector2 GetSize(Rect rect) {
    121.         return new Vector2(
    122.             horizontal ? rect.width : 0,
    123.             vertical ? rect.height : 0
    124.         );
    125.     }
    126.  
    127.     private Vector2 GetViewSize() {
    128.         return GetSize(viewRect.rect);
    129.     }
    130.  
    131.     private Vector2 GetItemSize(RectTransform selection) {
    132.         return GetSize(selection.rect);
    133.     }
    134.  
    135.     private Vector2 GetItemOffset(RectTransform selection) {
    136.         return Vector2.Scale(GetItemSize(selection), scrollingAnchor);
    137.     }
    138.  
    139.     /// <summary>
    140.     /// Return viewRect size, scaled by anchor position
    141.     /// </summary>
    142.     /// <returns></returns>
    143.     private Vector2 GetCenterPoint() {
    144.         return Vector2.Scale(GetViewSize(), scrollingAnchor);
    145.     }
    146.  
    147.     private void ScrollTo(Vector2 set) {
    148.         var pos = content.anchoredPosition;
    149.         var vel = velocity;
    150.         pos.x = Mathf.SmoothDamp(pos.x, set.x, ref vel.x, scrollTime, scrollSpeed);
    151.         pos.y = Mathf.SmoothDamp(pos.y, set.y, ref vel.y, scrollTime, scrollSpeed);
    152.         velocity = vel;
    153.         SetContentAnchoredPosition(pos);
    154.     }
    155.  
    156.     private void ClampPosition() {
    157.         int last = content.childCount - 1;
    158.         if (last < 0)
    159.             return; //no kids, no scrolling
    160.  
    161.         RectTransform firstChild = content.GetChild(0).GetComponent<RectTransform>();
    162.         RectTransform lastChild = content.GetChild(last).GetComponent<RectTransform>();
    163.  
    164.         //var contentSize = GetSize(content.rect);
    165.         var pos = content.anchoredPosition;
    166.  
    167.         //somewhere within the viewRect
    168.         var contentAnchor = GetCenterPoint();
    169.  
    170.         //there is an item we want to see and keep in full view.
    171.         // so we calculate the position where we should look
    172.         Vector2 min = contentAnchor - lastChild.anchoredPosition - GetItemOffset(firstChild);
    173.         Vector2 max = contentAnchor - firstChild.anchoredPosition - GetItemOffset(firstChild);
    174.  
    175.         if (horizontal) {
    176.             pos.x = Mathf.Clamp(pos.x, min.x, max.x);
    177.         }
    178.         if (vertical) {
    179.             pos.y = Mathf.Clamp(pos.y, min.y, max.y);
    180.         }
    181.  
    182.         if (Vector2.SqrMagnitude(content.anchoredPosition - pos) > 0.01f) {
    183.             SetContentAnchoredPosition(pos);
    184.             content.hasChanged = true;
    185.         } else
    186.             velocity = Vector2.zero;
    187.     }
    188.  
    189.     public void Next() {
    190.         if (!IsMyChild(targetScrollObject))
    191.             return;
    192.  
    193.         int id = targetScrollObject.GetSiblingIndex() + 1;
    194.         Transform t;
    195.         if (id < itemCount)
    196.             t = content.GetChild(id);
    197.         else
    198.             t = content.GetChild(0);
    199.         Select(t);
    200.     }
    201.  
    202.     public void Previous() {
    203.         if (!IsMyChild(targetScrollObject))
    204.             return;
    205.  
    206.         int id = targetScrollObject.GetSiblingIndex();
    207.         Transform t;
    208.         if (id > 0)
    209.             id -= 1;
    210.         else
    211.             id = itemCount - 1;
    212.  
    213.         t = content.GetChild(id);
    214.         Select(t);
    215.     }
    216.  
    217.     public void Select(Transform t) {
    218.         if (t != null)
    219.             Select(t.GetComponent<Selectable>());
    220.     }
    221.  
    222.     public void Select(Selectable select) {
    223.         if (select != null)
    224.             select.Select();
    225.     }
    226. }
    227.  
    and in case you need the editor
    Code (CSharp):
    1.  
    2. using UnityEngine;
    3. using System.Collections;
    4. using UnityEditor;
    5.  
    6. [CustomEditor(typeof(ScrollToSelected), true)]
    7. public class ScrollToSelectedEditor : Editor {
    8.     public override void OnInspectorGUI() {
    9.         ScrollToSelected scroll = (ScrollToSelected)target;
    10.         base.OnInspectorGUI();
    11.     }
    12. }
    13.  

    If you make any improvements please share them with all of us.
    I was trying to get a 'soft' scrollonly release, where an item would remain selected.
    But it was not that simple to just add this behaviour, so I removed that option from the enum for now.
     
    Senshi and Mikea15 like this.
  18. Mikea15

    Mikea15

    Joined:
    Sep 20, 2012
    Posts:
    93
    Hey thanks mate, I've been messing around this today, and I've successfully made it work. The thing is that since my layouts are generated by horizontal layout groups, I don't have the size information in start or awake, so I have to delay the construction of the scroll view padding and other stuff I need.

    Here's the script. If you need a Horizontal Scroll Rect, that snaps in the center of the scroll view, with left and right padding. All commented and I guess ready to be built upon. ;)

    Code (CSharp):
    1.  
    2. using UnityEngine;
    3. using UnityEngine.UI;
    4. using UnityEngine.EventSystems;
    5.  
    6. using System.Collections;
    7.  
    8. [RequireComponent (typeof(ScrollRect))]
    9. public class ScrollSnap : MonoBehaviour, IBeginDragHandler, IEndDragHandler, IDragHandler
    10. {
    11.     [SerializeField] private Vector3[] _childCenterPositions;
    12.  
    13.     [SerializeField] private Vector3 _lerpTo;
    14.     [SerializeField] private bool _isLerping;
    15.  
    16.     [Range(1f, 25f)]
    17.     [SerializeField] private float _snapSpeed = 10f;
    18.  
    19.     private ScrollRect _scrollRect;
    20.     private RectTransform _scrollContent;
    21.     private Vector3 _scrollContentCenter;
    22.  
    23.     private HorizontalLayoutGroup _horizontalLayoutGroup;
    24.  
    25.     private bool _isReady;
    26.  
    27.     private int _currentIndex;
    28.     private int _previousIndex;
    29.  
    30.     void Awake( )
    31.     {
    32.         _isReady = false;
    33.         _scrollRect = this.GetComponent<ScrollRect>();
    34.         _scrollRect.enabled = _isReady;
    35.         _scrollContent = _scrollRect.content;
    36.         _horizontalLayoutGroup = this.GetComponentInChildren<HorizontalLayoutGroup>();
    37.     }
    38.  
    39.     void Start ()
    40.     {
    41.         StartCoroutine( ConfigScrollSnap() );
    42.     }
    43.  
    44.     IEnumerator ConfigScrollSnap( )
    45.     {
    46.         yield return new WaitForSeconds(1.0f);
    47.  
    48.         // get child count.
    49.         // get content width
    50.         // get spacing between items
    51.         var childCount = _scrollContent.childCount;
    52.         var contentWidth = _scrollContent.rect.width;
    53.         var spacingBetweenChild = _horizontalLayoutGroup.spacing;
    54.  
    55.         // get scroll rect transform
    56.         var scrollRectTransform = _scrollRect.transform as RectTransform;
    57.         var scrollRectWidth = scrollRectTransform.rect.width;
    58.         // get scroll content position + half the scrollrect width
    59.         _scrollContentCenter = _scrollContent.localPosition + new Vector3(scrollRectWidth * 0.5f, 0f, 0f);
    60.  
    61.         // set side padding if center on middle screen
    62.         // padding is calculated automatically based on scroll rect width.
    63.         // and spacing.
    64.         _horizontalLayoutGroup.padding.left = Mathf.FloorToInt(scrollRectWidth * 0.5f + spacingBetweenChild);
    65.         _horizontalLayoutGroup.padding.right = Mathf.FloorToInt(scrollRectWidth * 0.5f + spacingBetweenChild);
    66.  
    67.         Debug.Log("Updated padding left and right.");
    68.  
    69.         // quick and dirty hack.
    70.         // this makes the horizontal layout to recalculate its size..
    71.         // or at least fires the content size fitter so it adjusts.
    72.         _horizontalLayoutGroup.childForceExpandWidth = true;
    73.         _horizontalLayoutGroup.childForceExpandWidth = false;
    74.  
    75.         yield return new WaitForSeconds(1.0f);
    76.  
    77.         // assume all same size.
    78.         // child size = ( 4000 - ( 50 * 11 ) ) / 12.
    79.         var childWidth = ( contentWidth - ( spacingBetweenChild * childCount - 1 ) ) / childCount;
    80.         var childCenter = new Vector3(childWidth * 0.5f, 0.0f, 0.0f);
    81.  
    82.         // get all child.
    83.  
    84.         _childCenterPositions = new Vector3[_scrollContent.childCount];
    85.         // i starts at 1, because zero will be _scrollRect.content.transform. and I only want the children
    86.         for( int i = 0; i < _childCenterPositions.Length; i++ )
    87.         {
    88.             _childCenterPositions[i] = childCenter + _scrollContent.GetChild(i).localPosition;
    89.         }
    90.  
    91.         _isReady = true;
    92.         _scrollRect.enabled = _isReady;
    93.  
    94.         if( _childCenterPositions.Length > 0 )
    95.         {
    96.             _currentIndex = 0;
    97.             SnapToIndex(_currentIndex);
    98.         }
    99.     }
    100.  
    101.     void Update( )
    102.     {
    103.         if( Input.GetKeyDown(KeyCode.LeftArrow) )
    104.         {
    105.             _currentIndex--;
    106.             if( _currentIndex < 0 )
    107.                 _currentIndex = 0;
    108.             SnapToIndex(_currentIndex);
    109.         }
    110.         if( Input.GetKeyDown(KeyCode.RightArrow) )
    111.         {
    112.             _currentIndex++;
    113.             if( _currentIndex > _childCenterPositions.Length - 1 )
    114.                 _currentIndex = _childCenterPositions.Length - 1;
    115.             SnapToIndex(_currentIndex);
    116.         }
    117.  
    118.     }
    119.  
    120.     void LateUpdate( )
    121.     {
    122.         if( _isReady && _isLerping )
    123.         {
    124.             _scrollContent.localPosition = Vector3.Lerp( _scrollContent.localPosition, _lerpTo, _snapSpeed * Time.deltaTime);
    125.             if( Vector3.Distance(_scrollContent.localPosition, _lerpTo) < 0.01f )
    126.             {
    127.                 _isLerping = false;
    128.             }
    129.         }
    130.     }
    131.  
    132.     /// <summary>
    133.     /// Finds the index of the closest item to the center of the screen.
    134.     /// </summary>
    135.     /// <returns>The closest index.</returns>
    136.     public int FindClosestIndex( Vector3 toPosition )
    137.     {
    138.         float distance = float.MaxValue;
    139.         int id = -1;
    140.         for( int i = 0; i < _childCenterPositions.Length; i++ )
    141.         {
    142.             var child = _childCenterPositions[i];
    143.             var dist = Vector3.Distance( toPosition, child );
    144.             if( dist < distance )
    145.             {
    146.                 distance = dist;
    147.                 id = i;
    148.             }
    149.         }
    150.         return id;
    151.     }
    152.  
    153.     public void SnapToIndex( int index )
    154.     {
    155.         var childPos = _childCenterPositions[index];
    156.    
    157.         _lerpTo = new Vector3( _scrollContentCenter.x - childPos.x, 0f, 0f );
    158.         _isLerping = true;
    159.     }
    160.  
    161.     #region Drag Interfaces
    162.  
    163.     public void OnBeginDrag( PointerEventData data )
    164.     {
    165.         _isLerping = false;
    166.     }
    167.  
    168.     public void OnDrag( PointerEventData data )
    169.     {
    170.  
    171.     }
    172.  
    173.     public void OnEndDrag( PointerEventData data )
    174.     {
    175.         if( _isReady )
    176.         {
    177.             var inverseContentRectLocalPosition = -_scrollContent.localPosition;
    178.             var itemIndex = FindClosestIndex(inverseContentRectLocalPosition);
    179.  
    180.             _currentIndex = itemIndex;
    181.             SnapToIndex( _currentIndex );
    182.         }
    183.     }
    184.  
    185.     #endregion
    186. }
    187.  
    188.  
    Enjoy. :)
    I'll try yours nonetheless @Freezy

    PS: I've edited the code to fix some issues, and adapt to more generic situations. ;)
    PPS: I've also uploaded a Unity package with a demo ;)
     

    Attached Files:

    Last edited: Aug 14, 2015
    Senshi likes this.
  19. SimonDarksideJ

    SimonDarksideJ

    Joined:
    Jul 3, 2012
    Posts:
    1,688
    Sorry I've been remiss. Only just got back off hols.
    Did notice some updated being posted to the UI Extensions repo, will check them out with the above. Thanks @Mikea15 & @Freezy for stepping in to the breech :D
     
  20. Mikea15

    Mikea15

    Joined:
    Sep 20, 2012
    Posts:
    93
    Thanks! There are still some issues with the above script ( padding. I'll fix it soon ). And it will only work for horizontal scrolling, but hey, its a start. :)

    I've been having issues, because my layouts are calculated with Layout groups, so I have to delay the creation of the child containers. After that, I enable and disable a boolean value ( childForceExpandWidth ), to force the scrollrect to recalculate bounds ( which I haven't found a way to make it better, yet ), but it works pretty well so far. :D
     
  21. Freezy

    Freezy

    Joined:
    Jul 15, 2012
    Posts:
    234
    Having the scrollrect source might help ;-)
     
  22. Mikea15

    Mikea15

    Joined:
    Sep 20, 2012
    Posts:
    93
    Yep, I saw that. They seem to use
    Code (CSharp):
    1. EnsureLayoutHasRebuilt();
    2. UpdateBounds();
    I'll dig deeper on this when I get time :)
    Thanks ;)
     
  23. SimonDarksideJ

    SimonDarksideJ

    Joined:
    Jul 3, 2012
    Posts:
    1,688
    Managed to find some time this weekend @Mikea15 to update the repo, anything to add before I wrap up the next package?
     
  24. SimonDarksideJ

    SimonDarksideJ

    Joined:
    Jul 3, 2012
    Posts:
    1,688
    @zero3growlithe as the EventSystem.lastSelectedGameObject has now been deprecated, do you have an update for the ScrollTo script to work without it?
     
  25. SimonDarksideJ

    SimonDarksideJ

    Joined:
    Jul 3, 2012
    Posts:
    1,688
    @Ges Added in upcoming update :D - great work
     
  26. Mikea15

    Mikea15

    Joined:
    Sep 20, 2012
    Posts:
    93
    hey @SimonDarksideJ I continue to have issues with calculating the width of the content, inside the scrollrect, due to all container sizes being calculated through LayoutGroups. I'm trying a different approach, maybe a smarter one, which is to subclass ScrollRect directly and then apply the necessary calculations to make it snap to the items.. I'm going this way because ScrollRect calls UpdateBounds and EnsureLayoutIsrebuilt, and those are private methods, so we can't access them by referencing the script from another one. We can't even from subclassing it, but the idea is to add more, and not substitute the OnDragEnd for example, so I think I should have less layout issues this way.

    I'll try to make this as generic as possible, so anyone else can use it. I'll post an update once I get it to work properly.
     
  27. SimonDarksideJ

    SimonDarksideJ

    Joined:
    Jul 3, 2012
    Posts:
    1,688
    Interesting, although I think ScrollRectEx might already do some of what you mention @Mikea15 or even the SnapScrollRect controls (now have 2 :D)
    If these don't do it for you, then would welcome another addition to the Extensions project. (just updating this weekend)
     
  28. Mikea15

    Mikea15

    Joined:
    Sep 20, 2012
    Posts:
    93
    hmm.. I've only seen HorizontalScrollSnap ;) I'll check those out, thanks :D

    PS: I wasn't able to work it out yet.

    I've compiled screenshots of my hierarchy, maybe someone will be able to understand better, or spot an issue ;)

    So basically:
    1. I have a full screen panel (1), with vertical layout group.
    2. Scrollview (2), with layout element, and horizontal layout group.
    3. ScrollRect (3), with Custom script to snap custom items in the center of the screen. This adds padding to the left side and right side of the Horizontal Layout Group from (2). This will expand by the left side and right side, half the size of the ScrollView (2), this is so the items can be aligned in the center, otherwise the content (4) hasn't enough space, and the first/last item will be aligned to the left/right instead of center.
    4. Content (4), with again, Horizontal Layout group for the items, and content size fitter, so it expands Horizontally. Items are created at runtime.

    Now, if I remove the Horizontal Layout group from (1), and (2), I don't get what I want, because my layout will be ruined, but I will have the width value of the scrollView (2) from the start and will be able to add the correct left/right padding, and my items will align to the center.

    Now If I wait, some* time, before I create the content's child items, and then add the padding, it will work. But curiously not every time, and not on every screen resolution.. I must have something wrong.

    *some being 1 or 2 seconds? :/

    Here's a demo video (vine) with a 2 second delay.
    https://vine.co/v/eIXIdD7nwXu

    It works fine, but it bugs me that I have to wait 2 seconds for the layout to calculate correctly. I'm trying to improve this. Maybe I can make this in the background, once, and then forget about it. Don't know. Maybe it won't be a problem, but I wanted a "nicer" way to make this.

    Thanks again ;)
     

    Attached Files:

    Last edited: Aug 30, 2015
  29. Freezy

    Freezy

    Joined:
    Jul 15, 2012
    Posts:
    234
    I'm currently facing the same, I decided to rewrite the entire class using the source as a base and just skip the inheritance altogether. Juggling multiple projects at the moment, progress is slow as this is not a showstopping feature.
     
  30. Mikea15

    Mikea15

    Joined:
    Sep 20, 2012
    Posts:
    93
    @Freezy, I've just updated my post above. ;) Check if this is what you're looking for, I can give you the code.
     
  31. Freezy

    Freezy

    Joined:
    Jul 15, 2012
    Posts:
    234
    Actually I am solving the issue of padding by using non-selectable rects, then calculate the bounds of the first and last selectable items (more sample points are needed when using a grid), joining the bounds into a single bounds, now we have the selectable view size.

    Selectable is anything you can click on, which the padding items will not respond to, so that is a perfect match.
    Finding the first and last child would only be needed when the set changes, which is easy enough to monitor.
    As we mostly deal with dynamic sets in these situations anyways, this should not be a big issue.

    Then I take the viewrect, pick an arbitrary anchor point, then align the selected item on that anchor point (either using the same anchor point for the selectable, or use the pivot point).
    This works ok-enough for non-standard sized items, as the view only really cares about the first and the last selectable items.

    Trickier is hooking up the scrollbar so that it also ignores the padding items.
    As for forcing a recalculation of the layout, Canvas probably has a function for that.
    Also have you tried delaying start by using a coroutine? it would allow you to pick a few frames later (yield return null, yield return null), which should be enough for the layout.
     
  32. Mikea15

    Mikea15

    Joined:
    Sep 20, 2012
    Posts:
    93
    Actually I've never tried yield return null., but I'm waiting for 2 or 3 seconds, which sometimes is not enough.
     
  33. David-Rosser

    David-Rosser

    Joined:
    Apr 28, 2015
    Posts:
    1
    Has anyone had any luck getting grid layout groups to work with the accordion scripts? The accordion scripts work by changing the height of their children, but grid layout groups seem to not work with this functionality. Sorry if this is the wrong place to ask this.
     
  34. Ges

    Ges

    Joined:
    Apr 23, 2014
    Posts:
    31
    MaxEden, Kellyrayj, JohnTube and 2 others like this.
  35. SimonDarksideJ

    SimonDarksideJ

    Joined:
    Jul 3, 2012
    Posts:
    1,688
    Interesting @Ges , fancy adding it to the UI Extensions project? (link in sig)
     
  36. Ges

    Ges

    Joined:
    Apr 23, 2014
    Posts:
    31
    Sure.
     
  37. Freezy

    Freezy

    Joined:
    Jul 15, 2012
    Posts:
    234
    Not sure where this is best posted, so I thought I would start here

    To alter the BaseVertexEffect to BaseMeshEffect Unity 5.2

    Step 1: change the class from BaseVertexEffect to BaseMeshEffect or the interface from IVertexModifier to IMeshModifier
    Step 2: add:
    Code (CSharp):
    1.  
    2.  
    3.     public enum MeshMode {
    4.         Triangles,
    5.         Quads
    6.     }
    7.  
    8.     public MeshMode mode = MeshMode.Quads;
    9.  
    10.     public override void ModifyMesh(Mesh mesh) {
    11.         if (!this.IsActive())
    12.             return;
    13.  
    14.         List<UIVertex> vertexList = new List<UIVertex>();
    15.         using (VertexHelper vertexHelper = new VertexHelper(mesh)) {
    16.             vertexHelper.GetUIVertexStream(vertexList);
    17.         }
    18.  
    19.         ModifyVertices(vertexList);
    20.  
    21.         if (vertexList.Count == 0) {
    22.             mesh.Clear();
    23.             return;
    24.         }
    25.  
    26.         try {
    27.             using (VertexHelper vertexHelper2 = new VertexHelper()) {
    28.                 switch (mode) {
    29.                 case MeshMode.Triangles:
    30.                     vertexHelper2.AddUIVertexTriangleStream(vertexList);
    31.                     break;
    32.                 case MeshMode.Quads:
    33.                     {
    34.                         int quads = vertexList.Count / 4;
    35.                         for (int q = 0; q < quads; q++) {
    36.                             int i = q * 4;
    37.                             vertexHelper2.AddUIVertexQuad(new UIVertex[] { vertexList[i + 3], vertexList[i + 2], vertexList[i + 1], vertexList[i] });
    38.                         }
    39.                     }
    40.                     break;
    41.                 }
    42.                 vertexHelper2.FillMesh(mesh);
    43.             }
    44.         } catch (ArgumentOutOfRangeException ex) {
    45.             Debug.LogWarning("Out of range???");
    46.         }
    47.     }
    48.  
    Step 3:
    remove the override keywords where the compiler tells you to ;-)

    Step 4:
    wrap the changes in a nice #if #else
    using UNITY_5_2

    Step 5: ???

    Step 6: Profit



    OR
    Write an abstract class CustomVertexEffect that implements from IMeshModifier and implements the IVertexModifier (but that still throws a deprecation) so implement it abstractly and remove it again ;-)

    It's not an interface, but we need there to be some code (the ModifyMesh posted above), so yeah limits...

    Ah somebody beat me to the punch http://forum.unity3d.com/threads/basevertexeffect-change-to-basemesheffect.338455/
    but after editing the code a couple of times, I think I 'improved' the flexibility of the code a bit.
     
    Last edited: Sep 9, 2015
    Senshi likes this.
  38. SimonDarksideJ

    SimonDarksideJ

    Joined:
    Jul 3, 2012
    Posts:
    1,688
    For the UI Extensions project, I've simply been updating them to use the new style (mesh over custom UI Vertexes).
    Almost done updating. Doubt I'll bother with #IF's, will just maintain two separate branches for now and two separate Assets. Pain for me sure, but at the current rate of Unity version rollout, the old will be very old very soon, so I don't see a point trying to mess with #IF's for the UI system.
     
  39. SimonDarksideJ

    SimonDarksideJ

    Joined:
    Jul 3, 2012
    Posts:
    1,688
    in the final cut (just checking in now), I've gone for a mix, where effects only work at the vertex level, it's updated to extract and return the modified vertices to the mesh.

    For others, I've done as above and just used:
    Code (CSharp):
    1.             List < UIVertex > verts = new List<UIVertex>();
    2.             using (var helper = new VertexHelper(mesh))
    3.             {
    4.                 helper.GetUIVertexStream(verts);
    5.             }
    Then saved it back with:
    Code (CSharp):
    1.             using (var helper = new VertexHelper())
    2.             {
    3.                 helper.AddUIVertexTriangleStream(verts);
    4.                 helper.FillMesh(mesh);
    5.             }
    Lots of changes, hopefully for the better.
     
    Senshi likes this.
  40. Freezy

    Freezy

    Joined:
    Jul 15, 2012
    Posts:
    234
    inherting from a sinlgle class could make those #if 's a lot less messy


    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3. using UnityEngine.UI;
    4. using System.Collections.Generic;
    5.  
    6. public abstract class MeshEffect : BaseMeshEffect {
    7.  
    8.     public enum MeshMode {
    9.         Triangles,
    10.         Quads
    11.     }
    12.  
    13.     public abstract MeshMode GetMode();
    14.     public abstract void ModifyVertices(List<UIVertex> verts);
    15.  
    16.  
    17.     // Unity Image graphic cycles through triangle indices
    18.     //  0, 1, 2, 3, 4, 5
    19.     //  they equal positions
    20.     //  0, 2, 3, 1, 0, 3
    21.     //
    22.     // on the following
    23.     //
    24.     //    2 ----- 3
    25.     //    |       |
    26.     //    |       |
    27.     //    0 ----- 1
    28.     //
    29.     // or
    30.     // 0, 1, 2, 3, 4, 5
    31.     // equals
    32.     // 0, 1, 2, 3, 0, 2
    33.     //
    34.     // on the following
    35.     //
    36.     //    1 ----- 2
    37.     //    |       |
    38.     //    |       |
    39.     //    0 ----- 3
    40.  
    41.     public override void ModifyMesh(Mesh mesh) {
    42.         if (!this.IsActive())
    43.             return;
    44.  
    45.         List<UIVertex> vertexList = new List<UIVertex>();
    46.         using (VertexHelper vertexHelper = new VertexHelper(mesh)) {
    47.             vertexHelper.GetUIVertexStream(vertexList);
    48.         }
    49.  
    50.         ModifyVertices(vertexList);
    51.  
    52.         if (vertexList.Count == 0) {
    53.             mesh.Clear();
    54.             return;
    55.         }
    56.  
    57.         try {
    58.             using (VertexHelper vertexHelper2 = new VertexHelper()) {
    59.                 switch (GetMode()) {
    60.                 case MeshMode.Triangles:
    61.                     vertexHelper2.AddUIVertexTriangleStream(vertexList);
    62.                     break;
    63.                 case MeshMode.Quads:
    64.                     {
    65.                         int quads = vertexList.Count / 4;
    66.                         for (int q = 0; q < quads; q++) {
    67.                             int i = q * 4;
    68.                             vertexHelper2.AddUIVertexQuad(new UIVertex[] { vertexList[i + 3], vertexList[i + 2], vertexList[i + 1], vertexList[i] });
    69.                         }
    70.                     }
    71.                     break;
    72.                 }
    73.                 vertexHelper2.FillMesh(mesh);
    74.             }
    75.         } catch (System.ArgumentOutOfRangeException ex) {
    76.             Debug.LogWarning("Out of range??? " + ex.ToString());
    77.         }
    78.     }
    79.  
    80. }
    81.  
    The child script would just implement the two abstract functions
    public abstract MeshMode GetMode();
    public abstract void ModifyVertices(List<UIVertex> verts);

    So that the ModifyMesh does the heavy lifting
    on pre 5.2, it would simply go directly to ModifyVertices using a few preprocessors
     
  41. davidb1

    davidb1

    Joined:
    Sep 20, 2015
    Posts:
    3
    Is there any way to make the HorizontalSnap Script work with "virtua" pages made by GridLayout?
    (Say 6 items would make one page)
     
  42. SimonDarksideJ

    SimonDarksideJ

    Joined:
    Jul 3, 2012
    Posts:
    1,688
    If you want multiple items to make up one page, then just lay them out as children of the page.
    The version in the UI Extensions project seems to work well for that (also has a vertical version as well)
     
  43. SimonDarksideJ

    SimonDarksideJ

    Joined:
    Jul 3, 2012
    Posts:
    1,688
    The next version of the UI Extensions is now up, adding the Radial layout and a couple of other controls and some fixes.
    Thanks for all the communities hard work to help grow and expand the project.

    It was late when I pushed up the new release, so no more videos just yet, will follow up when I get another free hour.
     
  44. AwDogsGo2Heaven

    AwDogsGo2Heaven

    Joined:
    Jan 17, 2014
    Posts:
    102
    The new version of Gradient unfortunately doesn't work for me in 5.2. The colors are really light and look inverted. Anyone else have better luck?
     
  45. AwDogsGo2Heaven

    AwDogsGo2Heaven

    Joined:
    Jan 17, 2014
    Posts:
    102
    Using color32 instead of 'color' in the Gradient script fixed everything for me and made it behave as it did before 5.1
     
  46. SimonDarksideJ

    SimonDarksideJ

    Joined:
    Jul 3, 2012
    Posts:
    1,688
    Interesting fix @AwDogsGo2Heaven Can you raise that as issue on the UIExtensions project or (if you have the time) fix it and submit a PR for it.

    Thanks for pointing out the fix
     
  47. pertsa

    pertsa

    Joined:
    Jul 3, 2013
    Posts:
    15
    Hi,

    Curved text was nice! It would be really cool if those meshes could be modified at runtime, but it seems that OnValidate is needed for that and it only works in editor. Is there a way to do this?
     
  48. SimonDarksideJ

    SimonDarksideJ

    Joined:
    Jul 3, 2012
    Posts:
    1,688
    UI meshes are rebuilt when the canvas or objects are "SetDirty", so you can rebuild them how you like in OnPopulateMesh(VertextHelper)
     
  49. Tripwire

    Tripwire

    Joined:
    Oct 12, 2010
    Posts:
    442
    Hi,

    I'm really looking forward to use this scripts package for my projects! Thanks for all the work you guys put into it to get it this far!!

    Though i'm having a bit of an import problem, I keep getting this error after import:

    Error `UnityEngine.UI.Extensions.CurvedText' does not implement inherited abstract member `UnityEngine.UI.BaseMeshEffect.ModifyMesh(UnityEngine.UI.VertexHelper)' Solution 'Draw Together' ‎(2 projects) Assets/unity-ui-extensions/Scripts/CurvedText.cs 8
     
  50. SimonDarksideJ

    SimonDarksideJ

    Joined:
    Jul 3, 2012
    Posts:
    1,688
    You need to ensure you use the correct version for the version of Unity you are using because of the different versions of the UI API.

    If you are on 5.2.1P1 or above, you need to download the 5.3 package as stated on the front page as there were 2 API versions in 5.2 :S