Author Topic: "Infinite" UIDraggablePanel - Should I be using UICenterOnChild.onFinished?  (Read 4423 times)

electrodruid

  • Newbie
  • *
  • Thank You
  • -Given: 0
  • -Receive: 1
  • Posts: 48
    • View Profile
Hi,

I've got a UIDraggablePanel containing a grid full of full-screen elements. I want the panel to be draggable infinitely in either direction, scrolling through a large array of information and wrapping at both ends. I have a version that works pretty well, using only 3 of these elements. We start centered on m_itemInfoDisplays[1], and every time the user scrolls up to m_itemInfoDisplays[0] or down to m_itemInfoDisplays[1] my script re-centers the grid and resets all of the display elements to reflect the fact that we've just scrolled one element through the array. I do this by hooking into UICenterOnChild.onFinished. When you're scrolling through slowly it works great, but if you try to scroll quickly or continuously then UICenterOnChild doesn't always finish, so you end up scrolling to the bottom/top of the 3 ItemInfoDisplays and the UIDraggablePanel won't let you scroll any further. You have to stop, and wait for onFinished for it to reset stuff before you can carry on scrolling.

This isn't ideal. What am I doing wrong? Is there some other way I should be hooking this code up that doesn't require UICenterOnChild to have completed?

Code (stripped down and generalised a bit, but hopefully representative of what I'm doing)
  1. public class MyInfinitePanel : MonoBehaviour
  2. {
  3.         class ItemInfo
  4.         {
  5.                 public int m_index;
  6.                
  7.                 public string m_someInfoText;
  8.                 public float m_someMoreInfo;
  9.                 // You get the idea :) 
  10.         }
  11.        
  12.         // These components references are set via drag & drop in Editor.
  13.         // Our grid contains 3 ItemInfoDisplays because each ItemInfoDisplay fills the panel's clip region, but it
  14.         // should work in case where we display N items simultaneously and there are N+2 ItemInfoDisplays in the array
  15.         public ItemInfoDisplay[]                        m_itemInfoDisplays;            
  16.         public UIDraggablePanel                         m_draggablePanel;
  17.         public UICenterOnChild                          m_centerOnChild;
  18.        
  19.         // A large array of ItemInfo (which contains "info" about an "item", which can be fed
  20.         // to a ItemInfoDisplay which will update to display this info).
  21.         // Not shown: how we populate this array, but it's not important really.
  22.         ItemInfo[]                                      m_items;
  23.         int                                                     m_currentItemIndex = 0;
  24.  
  25.         void Start()
  26.         {
  27.                 // Hook up to onFinished, so we can rearrange the display to keep the scrolling infinite
  28.                 if(m_centerOnChild)
  29.                 {
  30.                         m_centerOnChild.onFinished += OnCenterOnChildFinished;
  31.                 }
  32.         }
  33.  
  34.         void OnCenterOnChildFinished()
  35.         {
  36.                 if(m_centerOnChild != null)
  37.                 {
  38.                         GameObject go = m_centerOnChild.centeredObject;
  39.                        
  40.                         if(go != null)
  41.                         {
  42.                                 ItemInfoDisplay centeredDisplay = go.GetComponent<ItemInfoDisplay>();
  43.  
  44.                                 if(centeredDisplay != null)
  45.                                 {
  46.                                         // Get the index from the currently-selected ItemInfoDisplay, and set that
  47.                                         // as the currently selected item index
  48.                                         int selectedIndex = centeredDisplay.m_index;
  49.                                        
  50.                                         if(selectedIndex != m_currentItemIndex)
  51.                                         {
  52.                                                 m_currentItemIndex = centeredDisplay.m_index;
  53.                                        
  54.                                                 // Re-center panel if necessary
  55.                                                 if(m_draggablePanel)
  56.                                                 {
  57.                                                         int lastIndex = m_itemInfoDisplays.Length - 1;
  58.  
  59.                                                         if(centeredDisplay == m_itemInfoDisplays[0])
  60.                                                         {
  61.                                                                 BumpEntries(centeredDisplay.entryPanelHeight, -1);
  62.                                                         }
  63.                                                         else if (centeredDisplay == m_itemInfoDisplays[lastIndex])
  64.                                                         {
  65.                                                                 BumpEntries(centeredDisplay.entryPanelHeight, 1);
  66.                                                         }
  67.                                                 }
  68.                                         }
  69.                                 }
  70.                         }
  71.                 }
  72.         }
  73.        
  74.         // Bump all the display entries along 1 (either up or down), so we
  75.         // can maintain an infinitely-scrolling carousel
  76.         void BumpEntries(float panelHeight, int bumpDir)
  77.         {
  78.                 // This is for a vertically-scrolling panel
  79.                 m_draggablePanel.MoveRelative(new Vector3(0, -panelHeight * bumpDir, 0));
  80.                                                                
  81.                 for(int i = 0; i < m_itemInfoDisplays.Length; ++i)
  82.                 {
  83.                         ItemInfoDisplay itemInfoDisplay = m_itemInfoDisplays[i];
  84.                        
  85.                         if(itemInfoDisplay != null)
  86.                         {
  87.                                 int nextIndex = (int)Mathf.Repeat(itemInfoDisplay.m_index + bumpDir, m_items.Length);
  88.                                
  89.                                 // ItemInfoDisplay has this SetDisplay method which takes the information from an ItemInfo
  90.                                 // and applies it to the relevant widgets so that the display reflects the information. Also
  91.                                 // tells the itemInfoDisplay the index of the item its displaying.
  92.                                 itemInfoDisplay.SetDisplay(m_items[nextIndex], nextIndex);
  93.                         }
  94.                 }
  95.         }
  96. }
  97.  

ArenMook

  • Administrator
  • Hero Member
  • *****
  • Thank You
  • -Given: 337
  • -Receive: 1171
  • Posts: 22,128
  • Toronto, Canada
    • View Profile
I don't advise relying on onFinished callback, as that's not what it's designed for. I suggest just checking the position in Update() and adjusting positions as necessary.