com.unity.uiextensions icon indicating copy to clipboard operation
com.unity.uiextensions copied to clipboard

UI HSS with UI_InfiniteScroll instancing dynamic content issue / workAround

Open SimonDarksideJ opened this issue 2 years ago • 2 comments

Issue created by <unknown> as Bitbucket Issue #​237 on 2018.05.09 00:33. Hello, for understanding sake i will approach this issue on two steps. the first one being an Empty HSS without UI_InfiniteScroll and the second step including the UI_InfiniteScroll functionality

Context/Setup:

Experimental ScrollSnapBase https://bitbucket.org/UnityUIExtensions/unity-ui-extensions/raw/4e6f14118ffe5f66ecc9bae3eb8c823922af1442/Scripts/Layout/ScrollSnapBase.cs

Empty Horizontal Scroll Snap

https://imgur.com/Ocpgbkr

2 buttons:

button#1- Instances prefab and adds it through Addchild


public void AddnewImage () {

		GameObject go = Instantiate (leprefab);
		snapper.AddChild (go);
		GameObject go2 = Instantiate (leprefab);
		snapper.AddChild (go2);
		GameObject go3 = Instantiate (leprefab);
		snapper.AddChild (go3);

	}

button#2-Deletes all Children

public void RemoveChildrens(){
	   snapper.RemoveAllChildren(out s);
		   for(int i = 0; i<s.Length; i++){
                      Destroy (s[i].gameObject); 
		   }
}

Issue reproduction

Click Button#1 as many times as you want, all instances will be correctly added and you can scroll through them

Click Button#2 to clear all the children.

Click Button#1 to add a new set of children and they will not be correctly positioned and/or will behave incorrectly

Issue workaround

i believe that the issue is that _currentPage and _screensContaioner.offsetMin are not being reset

added following code to HorizontalSrollSnap RemoveAllChildren(); line 175


_scroll_rect.horizontalNormalizedPosition = 0;
            CurrentPage = 0;

		///thisCode
               _currentPage = StartingScreen;
		_screensContainer.offsetMin = new Vector2 (0,0);
		UpdateLayout();
               ///end code workaround

            InitialiseChildObjectsFromScene();
            DistributePages();

Now you should be able to instance / delete and it will scroll as intended

Issue#2 including the UI_InfiniteScroll Script

Context/Setup:

Same as Issue#1, except that the HSS now has UI_InfiniteScroll with Init by user set to true

Button#3- toggles the Init() method of UI_IS


	public void Runinit(){
		infiScroll.Init ();
	}

Button#2- added a new line


public void RemoveChildrens(){
		snapper.RemoveAllChildren(out s);
		for(int i = 0; i<s.Length; i++){

			Destroy (s[i].gameObject); 
		}

		infiScroll.DeleteParameters ();
	}

Issue reproduction

Click Button#1 as many times as you want, all instances will be correctly added and you can scroll through them

Click Button#3 to init the infinity script, and they will scroll correctly

Click Button#2 to clear all the children.

Click Button#1 to add a new set of children and click button#3 they will not be correctly positioned and/or will behave incorrectly, sometimes they dissapear, sometimes you cannot scroll through them past first and last child.

Issue Workaround

well this was a tricky one and thanks to issue #132 and @Bastiaan Hofsteenge workaround i archieved it to work.

https://bitbucket.org/UnityUIExtensions/unity-ui-extensions/issues/132/infinitescroll-snap-script

i added a function to ui_infiniteScroll as the content object is not being reset (same as issue#1)


public void DeleteParameters(){
                        if(items.Count > 0)
			items.Clear ();
			_scrollRect.content.offsetMin = new Vector2 (0,0);
			
		}

Now to fix the issue we need to validate when screen is 0, so it doesnt return an error

line 142 UI_InfiniteScroll

public void OnScroll(Vector2 pos) { if (!_hasDisabledGridComponents) DisableGridComponents();

		if (items.Count == 0)
			return;

        (...)

Now in ScrollSnapBase line 94 we add the following


if (_isInfinate)
{
	float infWindow = (float)value /(float)_screensContainer.childCount;          
		if (infWindow < 0)
			{
			   _infiniteWindow = (int)(Math.Floor(infWindow));                        
			}else{	
				if (_screensContainer.childCount > 0)
					_infiniteWindow = value / _screensContainer.childCount;
				else 
				      _infiniteWindow = 0;

				}
				
					_infiniteWindow = value < 0 ? (-_infiniteWindow) : _infiniteWindow;
					//Multiplying values by zero doesn't help, so start at Window 1
					//_infiniteWindow += 1;
					//Calculate the page within the child count range

					if (_screensContainer.childCount > 0)
					value = value % _screensContainer.childCount;
					else 
						value = 0;
					
					if (value < 0)
					{
						value = _screensContainer.childCount + value;
					}
					else if (value > _screensContainer.childCount - 1)
					{
						value = value - _screensContainer.childCount;
					}
				}

Now you can add and delete children as you like just call Init() after Removing previous Children

it may not be the best approach but hey, its something!

Scripts: https://pastebin.com/xMqua0N4 - ScrollSnapBase https://pastebin.com/hZ5cK6Ee - UI_InfiniteScroll https://pastebin.com/pLpFPcT5 - HorizontalScrollSnap https://pastebin.com/Tp3ghWxf - myCustom method used for this issue, in case its useful

Regards!

SimonDarksideJ avatar Apr 25 '22 18:04 SimonDarksideJ