Please try this instead last line: Code (CSharp): ScrollRect.content.anchoredPosition = new_position; ScrollRect.Rebuild(UnityEngine.UI.CanvasUpdate.PostLayout); ScrollRect.content.anchoredPosition = new_position; It is not mistake - you should set same value two times and call Rebuild in between.
Also try disable ListView.LimitScrollValue and change ScrollRect Movement Type to Unrestricted or Elastic.
Hi all, I just purchased "New UI Widgets" and I have an error with ListView : Code (CSharp): Trying to remove Text (UnityEngine.UI.Text) from rebuild list while we are already inside a rebuild loop. This is not supported. UnityEngine.GameObject:SetActive(Boolean) UIWidgets.ScrollRectPaginator:<UpdatePageButtons>m__0(ScrollRectPage) (at Assets/UIWidgets/Standart Assets/ScrollRectUtilites/ScrollRectPaginator.cs:428) System.Collections.Generic.List`1:ForEach(Action`1) UIWidgets.ScrollRectPaginator:UpdatePageButtons() (at Assets/UIWidgets/Standart Assets/ScrollRectUtilites/ScrollRectPaginator.cs:428) UIWidgets.ScrollRectPaginator:set_Pages(Int32) (at Assets/UIWidgets/Standart Assets/ScrollRectUtilites/ScrollRectPaginator.cs:206) UIWidgets.ScrollRectPaginator:RecalculatePages() (at Assets/UIWidgets/Standart Assets/ScrollRectUtilites/ScrollRectPaginator.cs:721) UnityEngine.Events.UnityEvent:Invoke() UIWidgets.ResizeListener:OnRectTransformDimensionsChange() (at Assets/UIWidgets/Standart Assets/Utilites/ResizeListener.cs:45) UnityEngine.UI.ScrollRect:LateUpdate() It has something to do with the way the ScrollRectPaginator caches pages : Code (CSharp): var to_cache = DefaultPages.GetRange(Pages, DefaultPages.Count - Pages); to_cache.ForEach(x => x.gameObject.SetActive(false)); DefaultPagesCache.AddRange(to_cache); DefaultPages.RemoveRange(Pages, DefaultPages.Count - Pages); if (SRNextPage!=null) { SRNextPage.SetPage(Pages - 1); } I tried to fix it by myself but it's harded than expected, does someone have a solution ? I really need to use ListView Thank you for your answer(s)
What Unity version you use? It's not reproduced on the versions I tested. As temporary fix you can add following code to UIWidgets/Standart Assets/ScrollRectUtilites/ScrollRectPaginator.cs Code (CSharp): protected bool NeedUpdatePageButtons; protected virtual void Update() { if (NeedUpdatePageButtons) { UpdatePageButtons(); NeedUpdatePageButtons = false; } } and replace Pages property with this code: Code (CSharp): public virtual int Pages { get { return pages; } protected set { pages = value; NeedUpdatePageButtons = true;// instead UpdatePageButtons(); } } This way page buttons will be update in next frame, not in current during rebuild loop.
Hi, I recently got a new error (I'm using Unity 5.6.3p2) once my application is built (it does not occur if running with the editor) : The VisibilityTreeView is a simple class inherited from TreeViewCustom It seems to prevent my application UI from working. Do you have any fix about this ? I tried last version of the asset but the error still occurs.
Please check VisibilityTreeView code, this problem can be caused "#if UNITY_EDITOR" for serialized field using constructor for class derived from MonoBehaviour two or more different classes with same name VisibilityTreeView Code (CSharp): using UnityEngine; using System; namespace UIWidgetsSamples { public class TestError : MonoBehaviour { public string ValidString; // this can cause error, remove #if UNITY_EDITOR or add [NonSerialized] attribute and remove [SerializeField] attribute #if UNITY_EDITOR [SerializeField] string someString; public int SomeInt; #endif public A SomeClass; // this also can cause error, don't use constructors for class derived from MonoBehaviour and ScriptableObject // instead use Start() for MonoBehaviour or override Init() for TreeView public TestError() { SomeClass = new B(); } } [Serializable] public class A { } [Serializable] public class B : A { public string AnotherString; } } namespace AnotherNamespace { // another class with same name also can cause error public class TestError : MonoBehaviour { } }
Thanks, I had no "#if UNITY_EDITOR" with serialized field, no duplicate class names, and only 2 EMPTY constructors in Monobehaviour classes but it did not fix my problem. However, I managed to fix it. It was linked to code obfuscation. I skipped obfuscation of UIWidgets classes , and of personal classes that inherited from UIWidgets classes, and the error disappeared. Thanks for your help !
Hello Ilya! I think in this code (AutocompleteCustom.cs): Code (CSharp): /// <summary> /// Handle input deselected event. /// </summary> /// <param name="eventData">Event data.</param> protected virtual void InputDeselected(BaseEventData eventData) { var ev = eventData as PointerEventData; if ((ev!=null) && (ev.pointerCurrentRaycast.gameObject!=null) && (ev.pointerCurrentRaycast.gameObject.transform.IsChildOf(DisplayListView.Container))) { AllowItemSelectionEvent = true; } else { HideOptions(); } } must be: Code (CSharp): if ((ev!=null) && (ev.pointerCurrentRaycast.gameObject!=null) && (ev.pointerCurrentRaycast.gameObject.transform.IsChildOf(DisplayListView.transform))) else click on DisplayListView scrollbar invoke HideOptions(); Thanks for UI Widgets!
@ilih - Unless you intended for the chat example audio to be 3D, best to set audio source spatial blend to 2D. I was wondering, why do I never hear this audio ...?
I tried the "UIWidgets-1.9.2.exe" but it seems that moving the focus via keyboard (i.e. TAB key) between widgets is not implemented. So, is it possible to have this behaviour in UI Widgets? Regards, Gianni
Keyboard navigation is works, but it's uses arrow keys, not TAB key. It's standard Unity UI behaviour.
OK, but arrow keys does not seem to work in the demo either, right? Anyway, is the keyboard navigation customizable in UI Widgets?
Works, but hightlight effect on buttons very weak so it's hard to notice, you can try it with ListView or RangeSlider. Yes.
Hi ilih, I'm sorry to insist but the arrow keys seems working to move from value to value inside a single widget. My question was different: I mean moving from widget to widget. Please give a look at "spinners.png" attached. The focus is on "Spinner" and I want to push a key (Tab, or left-arrow) to move the focus to the following widget (i.e."Tooltip"). Looking at "UIWidgets-1.9.2.exe" I also noticed an incorrect visualization on "Spinner and Slider" page. You can see the vertical sliders overlapping the label in "sliders.png" image. Regards, Gianni
Yes, you can move from widget to widget. I changed highlighted color and made video how it's looks https://ilih.ru/unity-assets/video/UIWidgets/ArrowsNavigation.mp4 And here is navigation graph in editor: Thanks, I'll fix it.
Does this support xbox (etc) controllers? (I searched the topic but wasn't clear about the answer. thx
I'm considering New UI Widgets but all the screenshots show the same theme. What is the difficulty in changing colors/textures/fonts? Do you have a gallery of other themes?
Yes, you can navigate between widgets and click on them. Only exception are widgets with default Unity InputField which does not have any virtual keyboard, so you cannot type anything in InputFields.
Same as default Unity UI widgets. Problem can be with amount of widgets you want to change, it's take a lot of time to change all of them. No.
Hi, I've been looking at this tutorial on combobox: https://ilih.ru/unity-assets/UIWidgets/docs/Manual.Combobox/ When you select an item from the list of a combobox it seems that you can only select the text, a string, would it be possible to select something else? For example, the object to which this text is associated. I ask to save information in each element of a list of a combobox that I can then obtain by selecting an item from the list. For example: You have a selection of eye types in the combobox: Blues Green Blacks When you select one, the only way to know what you have chosen is to make a comparison of strings, but if for example the player does not play in English but in another language, for example Spanish, it would be: Azules Verdes Negros And the comparison between strings would not work. But if the object in the canvas containing the text Blues or "Azules" has a class associated with information, I can add there any type of information to access it if the player selects Blues in the combobox. I do not know if I explained well. I am also interested in knowing if it is possible in the Tree View.
For localization support you can use ComboboxIcons with LocalizedName property (ListViewIcons items and TreeView nodes also have LocalizedName property) and compare by Name with original value. Or you can create own Combobox or TreeView with own types. Basic ListView and Combobox with string value are outdated widgets, they leaved by compatibility reasons. Now better use ListViewIcons and ComboboxIcons or create your own using ListViewCustom/ComboboxCustom/TreeViewCustom etc.
Hey! I'm considering purchasing your asset however can you please clarify whether it would be possible to change the font to an alternative font easily across all items? Thanks
Relatively easy. Drag&drop all prefabs from UIWidgets/Prefabs to empty scene Hierarchy window, search by type, find "Text" Select all finded gameobjects with Ctrl+A Change font in Inspector window Reset search Click "Apply" for each prefab in Inspector window, this is take time - it's near 50 prefabs
used tiny fraction of everything so far, but e.g. draggable and resizable work without much hassle with practically anything thrown at it - good job !
Sorry, forgot to mark event class as serializable. Fix: UIWidgets/Standart Assets/Switch/Switch.cs, add "[System.Serializable]" before SwitchEvent definition. Code (CSharp): [System.Serializable] public class SwitchEvent : UnityEvent<bool> After this OnValueChanged event will be available in Inpector window.
Greetings, in a ListViewIcons, what is the best way to: temporarily hide an element temporarily disable it (make it not interactable) Many thanks
Create new ListView based on ListViewIcons 1. Create item class with Visible and Interactable properties and derived from ListViewIconsItemDescription (you need to change ListViewIconsItemDescription.Changed access to protected) Code (CSharp): using UIWidgets; using System; namespace UIWidgetsSamples { [Serializable] public class ListViewIconsItemDescriptionExt : ListViewIconsItemDescription { bool visible = true; public bool Visible { get { return visible; } set { visible = value; Changed("Visible"); } } bool interactable = true; public bool Interactable { get { return interactable; } set { interactable = value; Changed("Interactable"); } } } } 2. Create component class which will check is item interactable and derived from ListViewIconsItemComponent Code (CSharp): using UnityEngine; using UnityEngine.EventSystems; using UIWidgets; namespace UIWidgetsSamples { public class ListViewIconsItemComponentExt : ListViewIconsItemComponent, IViewData<ListViewIconsItemDescriptionExt> { /// <summary> /// Gets the current item. /// </summary> public ListViewIconsItemDescriptionExt ItemExt { get; protected set; } public virtual void SetData(ListViewIconsItemDescriptionExt item) { ItemExt = item; SetData(item as ListViewIconsItemDescription); } public override void OnPointerClick(PointerEventData eventData) { if (ItemExt.Interactable) { base.OnPointerClick(eventData); } } public override void OnSubmit(BaseEventData eventData) { if (ItemExt.Interactable) { base.OnSubmit(eventData); } } public override void OnSelect(BaseEventData eventData) { if (ItemExt.Interactable) { base.OnSelect(eventData); } } public override void OnDeselect(BaseEventData eventData) { if (ItemExt.Interactable) { base.OnDeselect(eventData); } } } } 3. Create ListViewIconsExt with DataSourceExt property to use it instead DataSource. Code (CSharp): using UIWidgets; using System.Linq; namespace UIWidgetsSamples { public class ListViewIconsExt : ListViewCustom<ListViewIconsItemComponentExt,ListViewIconsItemDescriptionExt> { protected ObservableList<ListViewIconsItemDescriptionExt> dataSourceExt; /// <summary> /// Gets or sets the data source. /// </summary> /// <value>The data source.</value> public virtual ObservableList<ListViewIconsItemDescriptionExt> DataSourceExt { get { if (dataSourceExt==null) { #pragma warning disable 0618 dataSourceExt = new ObservableList<ListViewIconsItemDescriptionExt>(DataSource); dataSourceExt.OnChange += UpdateDataSource; DataSource = new ObservableList<ListViewIconsItemDescriptionExt>(dataSourceExt, false); UpdateDataSource(); #pragma warning restore 0618 } return dataSourceExt; } set { if (dataSourceExt!=null) { dataSourceExt.OnChange -= UpdateDataSource; } dataSourceExt = value; dataSourceExt.OnChange += UpdateDataSource; DataSource = new ObservableList<ListViewIconsItemDescriptionExt>(false); UpdateDataSource(); } } protected void UpdateDataSource() { DataSource.BeginUpdate(); DataSource.Clear(); DataSource.AddRange(DataSourceExt.Where(x => x.Visible)); DataSource.EndUpdate(); } } } 4. Replace ListViewIcons and ListViewIconsItemComponent to new components in ListViewIcons gameobject.
Thanks, the code works like a charm! I also need to add a passive color property in the ListViewIconsExt for not interactable elements?
Add at start of ListViewIconsExt.cs "using UnityEngine;". And add inside class colors definition and overrided coloring functions: Code (CSharp): [SerializeField] public Color DisabledColor = Color.gray; [SerializeField] public Color DisabledBackgroundColor = Color.gray; protected override void HighlightColoring(ListViewIconsItemComponentExt component) { if (component==null) { return ; } if (DataSourceExt[component.Index].Interactable) { base.HighlightColoring(component); } else { component.GraphicsColoring(DisabledColor, DisabledBackgroundColor, FadeDuration); } } protected override void SelectColoring(ListViewIconsItemComponentExt component) { if (component==null) { return ; } if (DataSourceExt[component.Index].Interactable) { base.SelectColoring(component); } else { component.GraphicsColoring(DisabledColor, DisabledBackgroundColor, FadeDuration); } } protected override void DefaultColoring(ListViewIconsItemComponentExt component) { if (component==null) { return ; } if (DataSourceExt[component.Index].Interactable) { base.DefaultColoring(component); } else { component.GraphicsColoring(DisabledColor, DisabledBackgroundColor, FadeDuration); } }
Hi! looking for control like this Please. see items are start from zero index if there is no item in left. same from right. with out UI effect
I'm trying to download the TextMeshPro version from your site, but it won't accept my invoice number. I tried with and without the letter prefix, and with and without the leading 0, with no luck.
Hi, is there a way to add and clear tabs from code at runtime? I noticed that I got an exception on start, if the list of tabs is empty Many thanks
To remove exception you need made some changes in UpdateButtons() in UIWidgets/Standart Assets/Tabs/Tabs.cs and TabsCustom.cs (this changes will added in next release, so not will be lost with update) Remove code at start of the method: Code (CSharp): if (tabObjects.Length==0) { throw new ArgumentException("TabObjects array is empty. Fill it."); } After "AddCallbacks();" insert code: Code (CSharp): if (tabObjects.Length==0) { return ; } Here is sample code how to add and clear tabs: Code (CSharp): using UnityEngine; using UnityEngine.UI; using System; using UIWidgets; namespace UIWidgetsSamples { /// <summary> /// Test Tabs creation. /// </summary> public class TestTabsCreate : MonoBehaviour { /// <summary> /// The tabs. /// </summary> [SerializeField] protected Tabs Tabs; /// <summary> /// The template. /// </summary> [SerializeField] public GameObject Template; /// <summary> /// Show tabs. /// </summary> public void SetTabs(int count) { ClearTabs(); Tabs.TabObjects = CreateTabs(count); } /// <summary> /// Clears the tabs. /// </summary> public void ClearTabs() { Tabs.TabObjects.ForEach(x => Destroy(x.TabObject)); Tabs.TabObjects = new Tab[]{}; } Tab[] CreateTabs(int count) { var tabs = new Tab[count]; for (int i = 0; i < count; i++) { var tab_name = "Tab " + (i + 1); tabs[i] = new Tab(){ Name = tab_name, TabObject = CreateTabObject(tab_name), }; } return tabs; } GameObject CreateTabObject(string tabName) { var result = Instantiate(Template) as GameObject; result.name = tabName; result.transform.SetParent(Template.transform.parent, false); result.SetActive(true); result.GetComponentInChildren<Text>().text = tabName; return result.gameObject; } } }
It seems that is not possible to deselect an element from a ListView if you have multiselection disable. How can I disable a single selection element? Thanks
You can use following script to deselect the element by click. Add this component to ListView gameobject. It enables multiselection and when element selected all previously selected elements will be deselected, so it works same as multiselection disable, but the element can be deselected. Code (CSharp): using UnityEngine; using UIWidgets; namespace UIWidgetsSamples { [RequireComponent(typeof(ListViewBase))] public class ListViewDeselect : MonoBehaviour { ListViewBase listView; void Start() { listView = GetComponent<ListViewBase>(); listView.MultipleSelect = true; listView.OnSelect.AddListener(SelectListener); DeselectAllExceptLast(); } void SelectListener(int index, ListViewItem component) { DeselectAllExceptLast(); } void DeselectAllExceptLast() { var indices = listView.SelectedIndices; for (int i=0; i < (indices.Count - 1); i++) { listView.Deselect(indices[i]); } } void OnDestroy() { if (listView!=null) { listView.OnSelect.RemoveListener(SelectListener); } } } } Also you can deselect element from code with such line "listView.Deselect(listView.SelectedIndex);"
I'm having problems with garbage being created by EasyLayout (several KB per frame per active instance of the EasyLayout component). Do you have any idea what it might be, @ilih? I'm not using any of the other components from the pack. It doesn't seem to be caused by the UpdateLayout method, because that's not continually being called.
Please show EasyLayout settings, I'll try to reproduce it and check what can cause this problem. And what version you use? EasyLayoutResizer.cs should be exists in EasyLayout folder.
Hey, thanks for the quick reply! I'm using UIWidgets 1.8.4, and there's no EasyLayoutResizer.cs in the folder. Here's the settings of one of my EasyLayout components. Inside this is just a bunch of buttons (which aren't changing) but it's generating 9.8KB of garbage per frame.