Tasharen Entertainment Forum

Support => NGUI 3 Support => Topic started by: dmitry on October 06, 2012, 04:34:26 AM

Title: Reordering items in UIGrid or UITable by dragging
Post by: dmitry on October 06, 2012, 04:34:26 AM
I'm very very new to NGUI and need to create a list of items that could be reordered by dragging a handle on a side of the items.

I think I can make it draggable by the handle, and when I start dragging, the item should be removed from the list and then when I move it a placeholder should be inserted in the list to display where the item would go. But how can I insert something in the middle of the UIGrid or UITable?

Has anybody done this before?
Title: Re: Reordering items in UIGrid or UITable by dragging
Post by: ArenMook on October 06, 2012, 09:27:28 AM
If you don't call UIGrid's reposition function, you can safely remove and add items to it wherever you wish. The position only gets recalculated when you call that function. If you want a specific order, just set the "sorted" property to "true" and name entries sequentially, such as: "001", "002", etc.
Title: Re: Reordering items in UIGrid or UITable by dragging
Post by: broken on October 31, 2013, 08:52:31 AM
UP!

I create chat where each message is a separate UILabel in UITable (Clipped Panel) (needed in order for me to hang up the collider to special areas of the text, eg. nickname).
I have a limit on the number of messages in chat (number of labels).

The maximum limit for example 30-50 messages.
Messages may contain emoticons, colors, colliders, and can be a few lines of text.
Сhat messages can come fast enough, so what is a better (effective and faster):
1. Rename all existing items, sorting by name and update item content (reuse items).
2. Removal of the first element and the creation of (adding) new item in the end.

Thanks!
Title: Re: Reordering items in UIGrid or UITable by dragging
Post by: ArenMook on November 01, 2013, 08:24:22 AM
Test it and find out. I'd lean toward 1.
Title: Re: Reordering items in UIGrid or UITable by dragging
Post by: broken on November 02, 2013, 01:30:00 AM
Test it and find out. I'd lean toward 1.

I tried a test (in Editor! with Stopwatch for 100 items and max limit 30), and the options to remove the first item, and adding new item faster.
Code for recreate item (without sorting), ElapsedMilliseconds ~145 :
  1.         public void AddMessage(ChatListMessageData message)
  2.         {
  3.                 List<Transform> items = itemsRoot.children;
  4.                
  5.                 if (items.Count == maxMessages)
  6.                 {
  7.                         NGUITools.Destroy(items[0].gameObject);
  8.                 }
  9.                
  10.                 GameObject item = NGUITools.AddChild(itemsRoot.gameObject, itemPrefab);
  11.                 ChatListMessageItem chatItem = item.GetComponent<ChatListMessageItem>();
  12.                 chatItem.message = message;
  13.                
  14.                 itemsRoot.Reposition();
  15.                
  16.                 RefreshScrollBar();
  17.         }
  18.  

Code for reuse item (with all items renaming and table sorting), ElapsedMilliseconds ~186 :
  1.         public void AddMessage(ChatListMessageData message)
  2.         {              
  3.                 GameObject item = null;
  4.                 List<Transform> items = itemsRoot.children;
  5.                 string itemName = "Item";
  6.                
  7.                 if (items.Count < maxMessages)
  8.                 {
  9.                         item = NGUITools.AddChild(itemsRoot.gameObject, itemPrefab);
  10.                         item.name = itemName + items.Count.ToString("000");
  11.                 }
  12.                 else
  13.                 {
  14.                         item = items[0].gameObject;
  15.                         for (int i = 1; i < items.Count; ++i)
  16.                         {
  17.                                 items[i].gameObject.name = itemName + (i - 1).ToString("000");
  18.                         }
  19.                         item.name = itemName + (items.Count - 1).ToString("000");
  20.                 }
  21.                
  22.                 ChatListMessageItem chatItem = item.GetComponent<ChatListMessageItem>();
  23.                 chatItem.message = message;
  24.                
  25.                 itemsRoot.Reposition();
  26.                
  27.                 RefreshScrollBar();
  28.         }
  29.  

Code for reuse item (with last item renaming and table sorting), ElapsedMilliseconds ~171:
  1.         public void AddMessage(ChatListMessageData message)
  2.         {              
  3.                 GameObject item = null;
  4.                 List<Transform> items = itemsRoot.children;
  5.                 string itemName = "Item";
  6.                
  7.                 if (items.Count < maxMessages)
  8.                 {
  9.                         item = NGUITools.AddChild(itemsRoot.gameObject, itemPrefab);
  10.                         item.name = itemName + items.Count.ToString("000");
  11.                 }
  12.                 else
  13.                 {
  14.                         item = items[0].gameObject;
  15.                         item.name = itemName + _lastIndex.ToString("000");
  16.                 }
  17.                
  18.                 ChatListMessageItem chatItem = item.GetComponent<ChatListMessageItem>();
  19.                 chatItem.message = message;
  20.                 _lastIndex++;
  21.                
  22.                 itemsRoot.Reposition();
  23.                
  24.                 RefreshScrollBar();
  25.         }
  26.  

If the first option (for a new item creation ) also include sorting, then time almost equally (~178)
Maybe I'm doing something wrong to be reused?
Title: Re: Reordering items in UIGrid or UITable by dragging
Post by: ArenMook on November 02, 2013, 08:03:24 AM
Creation means GC allocation, meaning spikes in performance that are best avoided.
Title: Re: Reordering items in UIGrid or UITable by dragging
Post by: broken on November 03, 2013, 07:02:42 AM
Well, then try to use the renaming of all the elements and sorting. Thanks! :)
Title: Re: Reordering items in UIGrid or UITable by dragging
Post by: broken on November 04, 2013, 12:12:00 AM
Decided to look into the profiler, that's what it shows (attach).
Here I am adding 100 items (in for loop test) with a limit of 30 items. If beyond the limit, all the elements are renamed and sorted in the above code.
As in your opinion, is this normal?
Title: Re: Reordering items in UIGrid or UITable by dragging
Post by: ArenMook on November 04, 2013, 12:20:52 PM
Drop a kinematic rigidbody on your UIRoot.
Title: Re: Reordering items in UIGrid or UITable by dragging
Post by: broken on November 04, 2013, 01:22:56 PM
Drop a kinematic rigidbody on your UIRoot.

It is normal to have to throw kinematic Rigidbody on UIRoot? Not seen this in your examples. Why is that? Is because of the sorting of elements and their colliders? Why no one else was interested about it on this forum :)

UPD1: Yes, I added Rigidbody, operations with static collider disappeared from the profiler, now the Dynamic Collider, but now there is not much colliders calls.
What are the disadvantages to expect from the addition of Rigidbody on UIRoot?

And yet, limit on the number of messages is known in advance, I think it might be worth in advance in the editor to create dummy elements of the chat list (pool), and make them inactive (+ Table - Hide Inactive). And as a new message in the chat, instead of the original creation, to make them active?
Title: Re: Reordering items in UIGrid or UITable by dragging
Post by: ArenMook on November 05, 2013, 05:33:49 AM
Rigidbody trick supposedly helps due to how Unity works. It's generally good to have rigidbodies on panels, but UIRoot works as well. In the tests I've done, it always usually decreased performance rather than increase it (albeit slightly), so it's more for physics-intensive scenes. I guess none of mine fell under that category.

Anyway, we're deviating from the original topic. As I mentioned, lean towards what makes more sense / performs better in your case and don't worry about it.