diff --git a/.gitmodules b/.gitmodules index aad4ee6..fd7acb8 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,4 +1,4 @@ -[submodule "Examples"] - path = Examples - url = https://bitbucket.org/UnityUIExtensions/unity-ui-extensions/branch/Examples +[submodule "Examples~"] + path = Examples~ + url = https://SimonDarksideJ@bitbucket.org/UnityUIExtensions/unity-ui-extensions.git branch = Examples diff --git a/.npmignore b/.npmignore deleted file mode 100644 index 823c4a9..0000000 --- a/.npmignore +++ /dev/null @@ -1,42 +0,0 @@ -/[Ll]ibrary/ -/[Tt]emp/ -/[Oo]bj/ -/[Bb]uild/ -/[Bb]uilds/ -/[Ee]xport -/Assets/AssetStoreTools* - -# Autogenerated VS/MD/Consulo solution and project files -ExportedObj/ -.consulo/ -*.csproj -*.unityproj -*.sln -*.suo -*.tmp -*.user -*.userprefs -*.pidb -*.booproj -*.svd - -# Unity3D generated meta files -*.pidb.meta - -# Mac files -*.DS_Store - -# Unity3D Generated File On Crash Reports -sysinfo.txt - -# Builds -*.apk -*.unitypackage -/.vs - -# UPM Build updates -[Ee]xamples -[Ee]xamples.meta - -# NPM publish exclusions -bitbucket-pipelines.yml diff --git a/CHANGELOG.md b/CHANGELOG.md index e32c76e..2138a11 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,24 +4,34 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](http://keepachangelog.com/). -## 2019.4 (v2.2) - 2020-07-09 +## 2019.5 (v2.3) - 2020-10-31 -Here we write upgrading notes for brands. It's a team effort to make them as -straightforward as possible. +Since the move to UPM, the team have been able to react quicker and push out fixes a lot easier, without affecting previous installation (whilst still adhering to Unity's backwards compatibility pattern). So it is with great news we announce this new release, faster that ever :D (and thanks to UPM, easier to upgrade than ever). +Be sure to also check out the "Examples" option in the Package Manager window to import the samples to your project. ### Added -- New UPM deployment for Unity 2019, 2018 will still need to use the asset packages due to Unity compatibility issues. -- Updated the project to the new Unity packaging guidelines, including separating out the examples to a separate package. -- Many line drawing updates, including the ability to draw using a mouse (check the examples) -- New Unity Card UI controls thanks to @RyanslikeSoCool +- Add squircle primitive +- Adding new magnetic scroll control +- Added a static library to collate shaders on first use. +- Finalized new InputManagerHelper, which translates input based on the operating input system, new or old Updated CardStack2D to have defined keyboard input or specific gamepad input over the older axisname for new input system. +- Updated DropDown and Autocomplete controls based on feedback in #204 ### Changed -- Scroll Snaps (HSS/VSS) now have a "Hard Swipe" feature to restrict movement to a single page for each swipe -- Scroll Snaps have also been updated to work better with the UIInfiniteScroll control -- Update to the Fancy Scroll controls with even more added fanciness -- Several updates to adopt newer Unity standards in the controls to ensure full forwards and backwards compatibility +- Examples now included with UPM delivery and available as a button on the UPM package manager window +- Updated DropDown and Autocomplete controls based on feedback in #204 +- Updated Accordion to support both Vertical as well as Horizontal layout +- Updated ComboBox controls to improve better programmatic controls +- Updates to the Infinite scroll to support content of various sizes +- Updated UI Knob control - enabled dragging outside the target area, added example scene +- Minor update to MagneticInfinite Scroll +- Refactored and extended the ContentScrollSnap control +- Added protection against errors and empty scrollrect content +- Added new SetNewItems function to add children programmatically to the control and reset accordingly +- Patch supplied by a contributor to improve the texture sheet use with the UIParticlesystem +- Added "SetKnobValue" function which allows the setting of Value and loops +- Added the programmatic capability to change the parent scroll rect on the ScrollConflictManager at runtime. ### Deprecated @@ -29,21 +39,20 @@ None ### Fixed -- Mouse position use updated in - * RadialSlider - * ColorSampler - * TiltWindow -- Check compiler warnings (#197) -- Line Renderer click to add lines (#183) -- ScrollSnap Swiping options - hard fast swipe (#176) -- Shader Loading issue / UIParticleSystem (#229) -- Issue where Menu Prefabs would be disabled instead of their Clones (#210) -- Check ScrollSnapBase update (#265) -- UIInfiniteScroller support for VSS updated and fixes -- Fix to allow radial slider to start from positions other than left -- Fix UI Particles: Texture sheet animation + Random row(#256) -- Fix for wandering ScrollSnap controls due to Local Positioning drift -- Divide By Zero fix for Gradient (#58) +- Fix to add a "RequireComponent" to Primitives as Unity 2020 does not add them by default +- Remove old Examples submodule +- Updated submodules to hide Examples folder Additionally, updated Package manifest to allow importing of examples direct from UPM package. +- Fixed hard swipe to ensure it only ever moves one page, no matter how far you swipe. +- Fixed a conflict when using the ScrollConflictManager in child content of a HSS or VSS +- Fix for UI Particle system looping +- Fixed public GoToScreen call to only raise events internally (not multiple) +- Final roll-up and fix. Resolved race condition for associated pagination controls. +- Fixed issue with page events not being raised when inertia was disabled (velocity was always zero) +- When cloned, reorderable list was creating a second List Content component that was not initialized. Refactored to ensure only one list content was present and is initialized correctly +- Reorderable list items marked as transferable, remain transferable after being dropped +- Patch to resolve issues without the new Input System installed +- Refined magnetic scroll and dependencies while documenting Updated example +- Patch Tooltip ### Removed diff --git a/Documentation~/com.unity.uiextensions.md b/Documentation~/com.unity.uiextensions.md index 778ef82..93ed189 100644 --- a/Documentation~/com.unity.uiextensions.md +++ b/Documentation~/com.unity.uiextensions.md @@ -8,7 +8,7 @@ The Unity UI Extensions project is a collection of extension scripts/effects and > Contact the UI Extensions Team > Be sure to logon to the new [Gitter Chat site](https://gitter.im/Unity-UI-Extensions/Lobby) for the UI Extensions project, if you have any questions, queries or suggestions > Much easier than posting a question / issue on [YouTube](http://www.youtube.com/c/UnityUIExtensions), [Twitter](https://twitter.com/hashtag/UnityUIExtensions) or [Facebook](https://www.facebook.com/UnityUIExtensions) :D -> +> > [**UIExtensions Gitter Chanel**](https://gitter.im/Unity-UI-Extensions/Lobby) # Installing Unity UI Extensions @@ -31,28 +31,70 @@ For a full list of the controls and how they are used, please see the [online do This version of the Unity UI Extensions is compatible with the following versions of the Unity Editor: -* 2019 and above - the recommended path for 2019+ is to use the Unity Package Manager to get access to the package. Full details for installing via UPM can be [found here](https://bitbucket.org/UnityUIExtensions/unity-ui-extensions/wiki/UPMInstallation). +- 2019 and above - the recommended path for 2019+ is to use the Unity Package Manager to get access to the package. Full details for installing via UPM can be [found here](https://bitbucket.org/UnityUIExtensions/unity-ui-extensions/wiki/UPMInstallation). > Alternatively, the Asset packages have been tested to work with 2019 as well if you prefer to install that way. -* 2018 and below - for 2018 and use this package, you will have to import the asset package(s), either from the Asset Store or from the alternate download locations [listed here](https://bitbucket.org/UnityUIExtensions/unity-ui-extensions/wiki/Downloads). +- 2018 and below - for 2018 and use this package, you will have to import the asset package(s), either from the Asset Store or from the alternate download locations [listed here](https://bitbucket.org/UnityUIExtensions/unity-ui-extensions/wiki/Downloads). ## [Release Notes](https://bitbucket.org/UnityUIExtensions/unity-ui-extensions/wiki/ReleaseNotes/RELEASENOTES) -### 2019.4 - 2.2 - Back from the future +### 2019.5 - 2.3 - Accelerated Deployment -* New UPM deployment for Unity 2019, 2018 will still need to use the asset packages due to Unity compatibility issues. -* Updated the project to the new Unity packaging guidelines, including separating out the examples to a separate package. -* Many line drawing updates, including the ability to draw using a mouse (check the examples) -* Scroll Snaps (HSS/VSS) now have a "Hard Swipe" feature to restrict movement to a single page for each swipe -* Scroll Snaps have also been updated to work better with the UIInfiniteScroll control -* New Unity Card UI controls thanks to @RyanslikeSoCool -* Update to the Fancy Scroll controls with even more added fanciness -* Several updates to adopt newer Unity standards in the controls to ensure full forwards and backwards compatibility +#### Added + +- Add squircle primitive +- Adding new magnetic scroll control +- Added a static library to collate shaders on first use. +- Finalized new InputManagerHelper, which translates input based on the operating input system, new or old Updated CardStack2D to have defined keyboard input or specific gamepad input over the older axisname for new input system. +- Updated DropDown and Autocomplete controls based on feedback in #204 + +#### Changed + +- Examples now included with UPM delivery and available as a button on the UPM package manager window +- Updated DropDown and Autocomplete controls based on feedback in #204 +- Updated Accordion to support both Vertical as well as Horizontal layout +- Updated ComboBox controls to improve better programmatic controls +- Updates to the Infinite scroll to support content of various sizes +- Updated UI Knob control - enabled dragging outside the target area, added example scene +- Minor update to MagneticInfinite Scroll +- Refactored and extended the ContentScrollSnap control +- Added protection against errors and empty scrollrect content +- Added new SetNewItems function to add children programmatically to the control and reset accordingly +- Patch supplied by a contributor to improve the texture sheet use with the UIParticlesystem +- Added "SetKnobValue" function which allows the setting of Value and loops +- Added the programmatic capability to change the parent scroll rect on the ScrollConflictManager at runtime. + +#### Deprecated + +None + +#### Fixed + +- Fix to add a "RequireComponent" to Primitives as Unity 2020 does not add them by default +- Remove old Examples submodule +- Updated submodules to hide Examples folder Additionally, updated Package manifest to allow importing of examples direct from UPM package. +- Fixed hard swipe to ensure it only ever moves one page, no matter how far you swipe. +- Fixed a conflict when using the ScrollConflictManager in child content of a HSS or VSS +- Fix for UI Particle system looping +- Fixed public GoToScreen call to only raise events internally (not multiple) +- Final roll-up and fix. Resolved race condition for associated pagination controls. +- Fixed issue with page events not being raised when inertia was disabled (velocity was always zero) +- When cloned, reorderable list was creating a second List Content component that was not initialized. Refactored to ensure only one list content was present and is initialized correctly +- Reorderable list items marked as transferable, remain transferable after being dropped +- Patch to resolve issues without the new Input System installed +- Refined magnetic scroll and dependencies while documenting Updated example +- Patch Tooltip + +#### Removed + +None # Document revision history |Date|Details| |-|-| |July 9th, 2020|2019.4 (v2.2) released, first UPM deployment live | -|September 3rd, 2019|2019.1 (v2.1) released, First major update for the 2.0 series.| \ No newline at end of file +|September 3rd, 2019|2019.1 (v2.1) released, First major update for the 2.0 series.| +|August 8th, 2020|2019.4 (v2.2) released, New UPM Delivery.| +|October 10th, 2020|2019.5 (v2.2) released, New UPM fast delivery| diff --git a/Editor/UIExtensionsMenuOptions.cs b/Editor/UIExtensionsMenuOptions.cs index 2915619..cfce769 100644 --- a/Editor/UIExtensionsMenuOptions.cs +++ b/Editor/UIExtensionsMenuOptions.cs @@ -708,33 +708,78 @@ namespace UnityEditor.UI go.AddComponent(); Selection.activeGameObject = go; } - #endregion - - #region Accordion - [MenuItem("GameObject/UI/Extensions/Accordion/Accordion Group", false)] - static public void AddAccordionGroup(MenuCommand menuCommand) - { - GameObject go = CreateUIElementRoot("Accordion Group", menuCommand, s_ThickGUIElementSize); - go.AddComponent(); - go.AddComponent(); - go.AddComponent(); - go.AddComponent(); - Selection.activeGameObject = go; - } - - [MenuItem("GameObject/UI/Extensions/Accordion/Accordion Element", false)] - static public void AddAccordionElement(MenuCommand menuCommand) - { - GameObject go = CreateUIElementRoot("Accordion Element", menuCommand, s_ThickGUIElementSize); - go.AddComponent(); - go.AddComponent(); - Selection.activeGameObject = go; - - } #endregion - #region Drop Down controls - [MenuItem("GameObject/UI/Extensions/AutoComplete ComboBox", false)] + #region Accordion + [MenuItem("GameObject/UI/Extensions/Accordion/Accordion", false)] + static public void AddAccordionVertical(MenuCommand menuCommand) + { + GameObject go = CreateUIElementRoot("Accordion Group", menuCommand, s_ThickGUIElementSize); + CreateAccordionGroup(go); + for (int i = 0; i < 3; i++) + { + GameObject child = CreateUIObject($"Accordion Element {i}", go); + CreateAccordionElement(child); + } + Selection.activeGameObject = go; + } + + [MenuItem("GameObject/UI/Extensions/Accordion/Accordion Group", false)] + static public void AddAccordionGroup(MenuCommand menuCommand) + { + GameObject go = CreateUIElementRoot("Accordion Group", menuCommand, s_ThickGUIElementSize); + CreateAccordionGroup(go); + Selection.activeGameObject = go; + } + + private static void CreateAccordionGroup(GameObject go) + { + var vlg = go.AddComponent(); + vlg.childControlHeight = true; + vlg.childControlWidth = true; + vlg.childForceExpandHeight = false; + vlg.childForceExpandHeight = true; + var csf = go.AddComponent(); + csf.verticalFit = ContentSizeFitter.FitMode.PreferredSize; + go.AddComponent(); + go.AddComponent(); + } + + [MenuItem("GameObject/UI/Extensions/Accordion/Accordion Element", false)] + static public void AddAccordionElement(MenuCommand menuCommand) + { + GameObject go = CreateUIElementRoot("Accordion Element", menuCommand, s_ThickGUIElementSize); + CreateAccordionElement(go); + + Selection.activeGameObject = go; + } + + private static void CreateAccordionElement(GameObject go) + { + var vlg = go.AddComponent(); + vlg.childControlHeight = true; + vlg.childControlWidth = true; + vlg.childForceExpandHeight = false; + vlg.childForceExpandHeight = true; + go.AddComponent(); + var accordionElement = go.AddComponent(); + + // Header + GameObject headergo = CreateUIObject("Header", go); + var headerLayout = headergo.AddComponent(); + headerLayout.minHeight = accordionElement.MinHeight; + var headerText = headergo.AddComponent(); + headerText.text = "This is an Accordion header"; + + // Text + GameObject textgo = CreateUIObject("Text", go); + var textText = textgo.AddComponent(); + textText.text = "This is an example of text in an accordion element\nLots of information can be put here for selection\nIf you like"; + } + #endregion + + #region Drop Down controls + [MenuItem("GameObject/UI/Extensions/AutoComplete ComboBox", false)] static public void AddAutoCompleteComboBox(MenuCommand menuCommand) { GameObject autoCompleteComboBoxRoot = CreateUIElementRoot("AutoCompleteComboBox", menuCommand, s_ThickGUIElementSize); @@ -1208,6 +1253,14 @@ namespace UnityEditor.UI Selection.activeGameObject = go; } + [MenuItem("GameObject/UI/Extensions/Primitives/UI Squircle", false)] + static public void AddUISquircle(MenuCommand menuCommand) + { + GameObject go = CreateUIElementRoot("UI Squircle", menuCommand, s_ImageGUIElementSize); + go.AddComponent(); + Selection.activeGameObject = go; + } + [MenuItem("GameObject/UI/Extensions/Primitives/UI Circle", false)] static public void AddUICircle(MenuCommand menuCommand) { diff --git a/Examples b/Examples deleted file mode 160000 index 8f7a9de..0000000 --- a/Examples +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 8f7a9de774bcf64109a5e1362650e9f37572588f diff --git a/Examples~ b/Examples~ new file mode 160000 index 0000000..4487168 --- /dev/null +++ b/Examples~ @@ -0,0 +1 @@ +Subproject commit 44871685f1c817afe556c761a4bf12bff7a509ef diff --git a/LICENSE.md b/LICENSE.md index 6b19b96..f95287c 100644 --- a/LICENSE.md +++ b/LICENSE.md @@ -1,21 +1,22 @@ -Unity UI Extensions License (BSD3) +# Unity UI Extensions License (BSD3) + Copyright (c) 2019 -Redistribution and use in source and binary forms, with or without modification, +Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. -2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer +2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. -3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived +3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, -INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, -OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, -OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, -EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. \ No newline at end of file +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, +INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, +OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, +OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, +EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/README.md b/README.md index 7b3cd35..faed0e1 100644 --- a/README.md +++ b/README.md @@ -1,21 +1,26 @@ -# README +# Unity UI Extensions README This is an extension project for the new Unity UI system which can be found at: [Unity UI Source](https://bitbucket.org/Unity-Technologies/ui) -## [ Check out the control demos on our Tumblr page](https://unityuiextensions.tumblr.com/) -# [Intro](https://bitbucket.org/UnityUIExtensions/unity-ui-extensions/wiki/GettingStarted) +> [Check out the control demos on our Tumblr page](https://unityuiextensions.tumblr.com/) + +## [Intro](https://bitbucket.org/UnityUIExtensions/unity-ui-extensions/wiki/GettingStarted) + For more info, here's a little introduction video for the project: [![View Intro Video](http://img.youtube.com/vi/njoIeE4akq0/0.jpg)](http://www.youtube.com/watch?v=njoIeE4akq0 "Unity UI Extensions intro video") You can follow the UI Extensions team for updates and news on: -## [Twitter](https://twitter.com/hashtag/UnityUIExtensions?src=hash) / [Facebook](https://www.facebook.com/UnityUIExtensions/) / [YouTube](https://www.youtube.com/channel/UCG3gZOkmL-2rmZat4ufv28Q) -> ## Chat live with the Unity UI Extensions community on Gitter here: [UI Extensions Live Chat](https://gitter.im/Unity-UI-Extensions/Lobby) +### [Twitter](https://twitter.com/hashtag/UnityUIExtensions?src=hash) / [Facebook](https://www.facebook.com/UnityUIExtensions/) / [YouTube](https://www.youtube.com/channel/UCG3gZOkmL-2rmZat4ufv28Q) + +> ## Chat live with the Unity UI Extensions community on Gitter here: +> +> ## [UI Extensions Live Chat](https://gitter.im/Unity-UI-Extensions/Lobby) ----- -# [What is this repository for? ](https://bitbucket.org/UnityUIExtensions/unity-ui-extensions/wiki/About) +## [What is this repository for?](https://bitbucket.org/UnityUIExtensions/unity-ui-extensions/wiki/About) In this repository is a collection of extension scripts / effects and controls to enhance your Unity UI experience. These scripts have been gathered from many sources, combined and improved over time. @@ -23,15 +28,15 @@ In this repository is a collection of extension scripts / effects and controls t You can either download / fork this project to access the scripts, or you can also download these pre-compiled Unity Assets, chock full of goodness for each release: -# [Download - 2019.4 (aka 2.2)](https://bitbucket.org/UnityUIExtensions/unity-ui-extensions/wiki/Downloads) +## [Download - 2019.5 (aka 2.3)](https://bitbucket.org/UnityUIExtensions/unity-ui-extensions/wiki/Downloads) We have expanded where you can download the UnityPackage asset and widened the options to contribute to the project. > I will still stress however, ***contribution is optional***. **The assets / code will always remain FREE** -| [![Download from Itch.IO](https://bytebucket.org/UnityUIExtensions/unity-ui-extensions/wiki/SiteImages/itchio.png)](https://unityuiextensions.itch.io/uiextensions2-0 "Download from Itch.IO") | [![Download from Itch.IO](https://bitbucket.org/UnityUIExtensions/unity-ui-extensions/wiki/SiteImages/unionassets.png)](https://unionassets.com/unity-ui-extensions "Download from Union Assets") | [![Download from Itch.IO](https://bitbucket.org/UnityUIExtensions/unity-ui-extensions/wiki/SiteImages/patreon.jpg)](https://www.patreon.com/UnityUIExtensions "Support Unity UI Extensions on Patreon & download")| +| [![Download from Itch.IO](https://bytebucket.org/UnityUIExtensions/unity-ui-extensions/wiki/SiteImages/itchio.png)](https://unityuiextensions.itch.io/uiextensions2-0 "Download from Itch.IO") | [![Download from Itch.IO](https://bitbucket.org/UnityUIExtensions/unity-ui-extensions/wiki/SiteImages/unionassets.png)](https://unionassets.com/unity-ui-extensions "Download from Union Assets") | [![Download from Itch.IO](https://bitbucket.org/UnityUIExtensions/unity-ui-extensions/wiki/SiteImages/patreon.jpg)](https://www.patreon.com/UnityUIExtensions "Support Unity UI Extensions on Patreon & download")| | :--- | :--- | :--- | -| [Grab from Itchio](https://unityuiextensions.itch.io/uiextensions2-0) | [Obtain via Union Assets](https://unionassets.com/unity-ui-extensions) |[Support through Patreon](https://www.patreon.com/UnityUIExtensions) | +| [Grab from Itchio](https://unityuiextensions.itch.io/uiextensions2-0) | [Obtain via Union Assets](https://unionassets.com/unity-ui-extensions) |[Support through Patreon](https://www.patreon.com/UnityUIExtensions) | > Still available to download on the [BitBucket site](https://bitbucket.org/UnityUIExtensions/unity-ui-extensions/downloads) if you prefer @@ -39,9 +44,9 @@ To view previous releases, visit the [release archive](https://bitbucket.org/Uni ----- -# [Supporting the UI Extensions project](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=89L8T9N6BR7LJ) +## [Supporting the UI Extensions project](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=89L8T9N6BR7LJ) -If you wish to further support the Unity UI Extensions project itself, then you can either subsidise your downloads above, or using the links below. +If you wish to further support the Unity UI Extensions project itself, then you can either subsidize your downloads above, or using the links below. All funds go to support the project, no matter the amount. **Donations in code are also extremely welcome** @@ -53,90 +58,103 @@ All funds go to support the project, no matter the amount. **Donations in code a ----- -# [Getting Started](https://bitbucket.org/UnityUIExtensions/unity-ui-extensions/wiki/GettingStarted) +## [Getting Started](https://bitbucket.org/UnityUIExtensions/unity-ui-extensions/wiki/GettingStarted) + To get started with the project, here's a little guide: [![View Getting Started Video](http://img.youtube.com/vi/sVLeYmsNQAI/0.jpg)](http://www.youtube.com/watch?v=sVLeYmsNQAI "Unity UI getting started video") ----- -# [Updates:](https://bitbucket.org/UnityUIExtensions/unity-ui-extensions/wiki/ReleaseNotes/RELEASENOTES) +## [Updates:](https://bitbucket.org/UnityUIExtensions/unity-ui-extensions/wiki/ReleaseNotes/RELEASENOTES) -## Release 2019.4 - (v2.2) - Back from the future +## Update 2019.5 - 2.3 - Accelerated Deployment -It's been a long year since the last official release of the Unity UI Extensions project and WOW, have there been a lot of ups and downs. Big thanks to the community for their support of the project whether that was funds, code or even just testing and helping to iron out some pesky bugs. +Since the move to UPM, the team have been able to react quicker and push out fixes a lot easier, without affecting previous installation (whilst still adhering to Unity's backwards compatibility pattern). So it is with great news we announce this new release, faster that ever :D (and thanks to UPM, easier to upgrade than ever). +Be sure to also check out the "Examples" option in the Package Manager window to import the samples to your project. > Be sure to logon to the new [Gitter Chat](https://gitter.im/Unity-UI-Extensions/Lobby) site for the UI Extensions project, if you have any questions, queries or suggestions -> +> > Much easier that posting a question / issue on YouTube, Twitter or Facebook :D -> +> > ## [UIExtensions Gitter Chanel](https://gitter.im/Unity-UI-Extensions/Lobby) ### New / updated features -* New UPM deployment for Unity 2019, 2018 will still need to use the asset packages due to Unity compatibility issues. -* Updated the project to the new Unity packaging guidelines, including separating out the examples to a separate package. -* Many line drawing updates, including the ability to draw using a mouse (check the examples) -* Scroll Snaps (HSS/VSS) now have a "Hard Swipe" feature to restrict movement to a single page for each swipe -* Scroll Snaps have also been updated to work better with the UIInfiniteScroll control -* New Unity Card UI controls thanks to @RyanslikeSoCool -* Update to the Fancy Scroll controls with even more added fanciness -* Several updates to adopt newer Unity standards in the controls to ensure full forwards and backwards compatibility +* Add squircle primitive +* Adding new magnetic scroll control +* Added a static library to collate shaders on first use. +* Finalized new InputManagerHelper, which translates input based on the operating input system, new or old Updated CardStack2D to have defined keyboard input or specific gamepad input over the older axisname for new input system. +* Examples now included with UPM delivery and available as a button on the UPM package manager window +* Updated DropDown and Autocomplete controls based on feedback in #204 +* Updated Accordion to support both Vertical as well as Horizontal layout +* Updated ComboBox controls to improve better programmatic controls +* Updates to the Infinite scroll to support content of various sizes +* Updated UI Knob control - enabled dragging outside the target area, added example scene +* Minor update to MagneticInfinite Scroll +* Refactored and extended the ContentScrollSnap control +* Added protection against errors and empty scrollrect content +* Added new SetNewItems function to add children programmatically to the control and reset accordingly +* Patch supplied by a contributor to improve the texture sheet use with the UIParticlesystem +* Added "SetKnobValue" function which allows the setting of Value and loops +* Added the programmatic capability to change the parent scroll rect on the ScrollConflictManager at runtime. ### Examples / Examples / Examples + Examples now have their own package, this simplifies their use and deployment. Especially in 2019 with the UPM deployment. -* Refreshed all examples for Unity 2019 -* New Card UI Examples to supplement the new controls -* New Infinite Scroll Snap example -* Fancy Scroll view updated with 2 new examples -* New particle system example, demonstrating programmatic control of the particle system +* New UI Knob examples +* New Magnetic Scroll Example +* Updated ComboBox examples for programmatic testing ### Fixes -* Mouse position use updated in - - RadialSlider - - ColorSampler - - TiltWindow -* Check compiler warnings (#197) -* Line Renderer click to add lines (#183) -* ScrollSnap Swiping options - hard fast swipe (#176) -* Shader Loading issue / UIParticleSystem (#229) -* Issue where Menu Prefabs would be disabled instead of their Clones (#210) -* Check ScrollSnapBase update (#265) -* UIInfiniteScroller support for VSS updated and fixes -* Fix to allow radial slider to start from positions other than left -* Fix UI Particles: Texture sheet animation + Random row(#256) -* Fix for wandering ScrollSnap controls due to Local Positioning drift -* Divide By Zero fix for Gradient (#58) - +* Fix to add a "RequireComponent" to Primitives as Unity 2020 does not add them by default +* Remove old Examples submodule +* Updated submodules to hide Examples folder Additionally, updated Package manifest to allow importing of examples direct from UPM package. +* Fixed hard swipe to ensure it only ever moves one page, no matter how far you swipe. +* Fixed a conflict when using the ScrollConflictManager in child content of a HSS or VSS +* Fix for UI Particle system looping +* Fixed public GoToScreen call to only raise events internally (not multiple) +* Final roll-up and fix. Resolved race condition for associated pagination controls. +* Fixed issue with page events not being raised when inertia was disabled (velocity was always zero) +* When cloned, reorderable list was creating a second List Content component that was not initialized. Refactored to ensure only one list content was present and is initialized correctly +* Reorderable list items marked as transferable, remain transferable after being dropped +* Patch to resolve issues without the new Input System installed +* Refined magnetic scroll and dependencies while documenting Updated example +* Patch Tooltip ### Known issues + No new issues in this release, but check the issues list for things we are currently working on: * [UI Extensions Issue log](https://bitbucket.org/UnityUIExtensions/unity-ui-extensions/issues?status=new&status=open) ## Upgrade Notes -Due to the restructure of the package to meet Unity's new package guidelines, we recomment **Deleting the current Unity UI Extensions** folder prior to importing the new package -For Unity 2019 users using the new UPM deployment, be sure to delete the existing folder in your assets folder before adding the new package to avoid conflict +Due to the restructure of the package to meet Unity's new package guidelines, we recommend **Deleting the current Unity UI Extensions** folder prior to importing the new package. + +For Unity 2019 users using the new UPM deployment, be sure to delete the existing folder in your assets folder before adding the new package to avoid conflict. + +----- ----------------- ## Release History For the full release history, follow the below link to the full release notes page. ### [Release Notes](https://bitbucket.org/UnityUIExtensions/unity-ui-extensions/wiki/ReleaseNotes/RELEASENOTES) ---- -# [Controls and extensions listed in this project](https://bitbucket.org/UnityUIExtensions/unity-ui-extensions/wiki/Controls): +----- + +## [Controls and extensions listed in this project](https://bitbucket.org/UnityUIExtensions/unity-ui-extensions/wiki/Controls) There are almost 70+ extension controls / effect and other utilities in the project which are listed on the following page: > ## [Check out the control demos on our Tumblr page](https://www.tumblr.com/blog/unityuiextensions) -> | [![UI Line Renderer](https://bytebucket.org/UnityUIExtensions/unity-ui-extensions/wiki/SiteImages/LineRenderer.gif)](https://www.tumblr.com/blog/unityuiextensions "UI Line Renderer") | [![UI Knob](https://bitbucket.org/UnityUIExtensions/unity-ui-extensions/wiki/SiteImages/UIKnob.gif)](https://www.tumblr.com/blog/unityuiextensions "UI Knob") | [![ScrollSnap](https://bitbucket.org/UnityUIExtensions/unity-ui-extensions/wiki/SiteImages/ScrollSnap.gif)](https://www.tumblr.com/blog/unityuiextensions "Scroll Snap")| +> +> | [![UI Line Renderer](https://bytebucket.org/UnityUIExtensions/unity-ui-extensions/wiki/SiteImages/LineRenderer.gif)](https://www.tumblr.com/blog/unityuiextensions "UI Line Renderer") | [![UI Knob](https://bitbucket.org/UnityUIExtensions/unity-ui-extensions/wiki/SiteImages/UIKnob.gif)](https://www.tumblr.com/blog/unityuiextensions "UI Knob") | [![ScrollSnap](https://bitbucket.org/UnityUIExtensions/unity-ui-extensions/wiki/SiteImages/ScrollSnap.gif)](https://www.tumblr.com/blog/unityuiextensions "Scroll Snap")| > | :--- | :--- | :--- | -> | [UI Line Renderer](https://www.tumblr.com/blog/unityuiextensions) | [UI Knob](https://www.tumblr.com/blog/unityuiextensions) |[Scroll Snap](https://www.tumblr.com/blog/unityuiextensions) | +> | [UI Line Renderer](https://www.tumblr.com/blog/unityuiextensions) | [UI Knob](https://www.tumblr.com/blog/unityuiextensions) |[Scroll Snap](https://www.tumblr.com/blog/unityuiextensions) | ## [UI Extensions controls list](https://bitbucket.org/UnityUIExtensions/unity-ui-extensions/wiki/Controls) @@ -168,31 +186,20 @@ NicerOutline|RaycastMask|UIFlippable|UIImageCrop|SoftAlphaMask CylinderText|UIParticleSystem|CurlyUI|Shine Effect|Shader Effects |||| -[VR Components](https://bitbucket.org/UnityUIExtensions/unity-ui-extensions/wiki/Controls#markdown-header-vr_components)||||| -------|------|------|------| -VRCursor|VRInputModule||| -|||| - -[Input Modules](https://bitbucket.org/UnityUIExtensions/unity-ui-extensions/wiki/Controls#markdown-header-input_modules)||||| -------|------|------|------| -AimerInputModule|GamePadInputModule||| -|||| - [Additional Components](https://bitbucket.org/UnityUIExtensions/unity-ui-extensions/wiki/Controls#markdown-header-additional_components)||||| ------|------|------|------| ReturnKeyTrigger|TabNavigation|uGUITools|ScrollRectTweener|ScrollRectLinker ScrollRectEx|UI_InfiniteScroll|UI_ScrollRectOcclusion|UIScrollToSelection|UISelectableExtension switchToRectTransform|ScrollConflictManager|CLFZ2 (Encryption)|DragCorrector|PPIViewer -UI_TweenScale|UI_InfiniteScroll|UI_ScrollRectOcclusion|NonDrawingGraphic|UILineConnector -UIHighlightable|Menu Manager|Pagination Manager|| +UI_TweenScale|UI_MagneticInfiniteScroll|UI_ScrollRectOcclusion|NonDrawingGraphic| +UILineConnector|UIHighlightable|Menu Manager|Pagination Manager| |||| *More to come* ---- +----- - -# [How do I get set up?](https://bitbucket.org/UnityUIExtensions/unity-ui-extensions/wiki/GettingStarted) +## [How do I get set up?](https://bitbucket.org/UnityUIExtensions/unity-ui-extensions/wiki/GettingStarted) As of Unity 2019, there are now two paths for getting access to the Unity UI Extensions project: @@ -205,7 +212,7 @@ Alternatively, you can also use the pre-compiled Unity packages if you wish, how The pre-compiled Unity assets are the only solution for Unity 2018 or earlier due to the changes in the Unity UI framework in Unity made for 2019. Either clone / download this repository to your machine and then copy the scripts in, or use the pre-packaged .UnityPackage for your version of Unity and import it as a custom package in to your project. -# [Contribution guidelines ](https://bitbucket.org/UnityUIExtensions/unity-ui-extensions/wiki/ContributionGuidelines) +## [Contribution guidelines](https://bitbucket.org/UnityUIExtensions/unity-ui-extensions/wiki/ContributionGuidelines) Got a script you want added? Then just fork the bitbucket repository and submit a PR. All contributions accepted (including fixes) @@ -215,21 +222,21 @@ Just ensure: * The script uses the **Unity.UI.Extensions** namespace so they do not affect any other developments * (optional) Add Component and Editor options where possible (editor options are in the Editor\UIExtensionsMenuOptions.cs file) -# [License ](https://bitbucket.org/UnityUIExtensions/unity-ui-extensions/wiki/License) +## [License](https://bitbucket.org/UnityUIExtensions/unity-ui-extensions/wiki/License) -All scripts conform to the BSD3 license and are free to use / distribute. See the [LICENSE](https://bitbucket.org/UnityUIExtensions/unity-ui-extensions/wiki/License) file for more information +All scripts conform to the BSD3 license and are free to use / distribute. See the [LICENSE](https://bitbucket.org/UnityUIExtensions/unity-ui-extensions/wiki/License) file for more information = -# [Like what you see? ](https://bitbucket.org/UnityUIExtensions/unity-ui-extensions/wiki/FurtherInfo) +## [Like what you see?](https://bitbucket.org/UnityUIExtensions/unity-ui-extensions/wiki/FurtherInfo) All these scripts were put together for my latest book Unity3D UI Essentials Check out the [page on my blog](http://bit.ly/Unity3DUIEssentials) for more details and learn all about the inner workings of the new Unity UI System. -# [The downloads ](https://bitbucket.org/UnityUIExtensions/unity-ui-extensions/wiki/Downloads) +## [The downloads](https://bitbucket.org/UnityUIExtensions/unity-ui-extensions/wiki/Downloads) As this repo was created to support my new Unity UI Title ["Unity 3D UI Essentials"](http://bit.ly/Unity3DUIEssentials), in the downloads section you will find two custom assets (SpaceShip-DemoScene-Start.unitypackage and RollABallSample-Start.unitypackage). These are just here as starter scenes for doing UI tasks in the book. I will add more sample scenes for the UI examples in this repository and detail them above over time. -# [Previous Releases](https://bitbucket.org/UnityUIExtensions/unity-ui-extensions/wiki/Downloads) +## [Previous Releases](https://bitbucket.org/UnityUIExtensions/unity-ui-extensions/wiki/Downloads) -Please see the [full downloads list](https://bitbucket.org/UnityUIExtensions/unity-ui-extensions/wiki/Downloads) for all previous releases and their corresponding download links. \ No newline at end of file +Please see the [full downloads list](https://bitbucket.org/UnityUIExtensions/unity-ui-extensions/wiki/Downloads) for all previous releases and their corresponding download links. diff --git a/Runtime/Scripts/Controls/Accordion/Accordion.cs b/Runtime/Scripts/Controls/Accordion/Accordion.cs index 88b43f7..88e7074 100644 --- a/Runtime/Scripts/Controls/Accordion/Accordion.cs +++ b/Runtime/Scripts/Controls/Accordion/Accordion.cs @@ -4,11 +4,14 @@ namespace UnityEngine.UI.Extensions { - [RequireComponent(typeof(VerticalLayoutGroup), typeof(ContentSizeFitter), typeof(ToggleGroup))] + [RequireComponent(typeof(HorizontalOrVerticalLayoutGroup), typeof(ContentSizeFitter), typeof(ToggleGroup))] [AddComponentMenu("UI/Extensions/Accordion/Accordion Group")] public class Accordion : MonoBehaviour { - + private bool m_expandVertical = true; + [HideInInspector] + public bool ExpandVerticval => m_expandVertical; + public enum Transition { Instant, @@ -37,5 +40,22 @@ namespace UnityEngine.UI.Extensions get { return this.m_TransitionDuration; } set { this.m_TransitionDuration = value; } } + + private void Awake() + { + m_expandVertical = GetComponent() ? false : true; + var group = GetComponent(); + } + +#if UNITY_EDITOR + + private void OnValidate() + { + if (!GetComponent() && !GetComponent()) + { + Debug.LogError("Accordion requires either a Horizontal or Vertical Layout group to place children"); + } + } +#endif } } \ No newline at end of file diff --git a/Runtime/Scripts/Controls/Accordion/AccordionElement.cs b/Runtime/Scripts/Controls/Accordion/AccordionElement.cs index 64f20e2..1ed11db 100644 --- a/Runtime/Scripts/Controls/Accordion/AccordionElement.cs +++ b/Runtime/Scripts/Controls/Accordion/AccordionElement.cs @@ -12,7 +12,13 @@ namespace UnityEngine.UI.Extensions { [SerializeField] private float m_MinHeight = 18f; - + + public float MinHeight => m_MinHeight; + + [SerializeField] private float m_MinWidth = 40f; + + public float MinWidth => m_MinWidth; + private Accordion m_Accordion; private RectTransform m_RectTransform; private LayoutElement m_LayoutElement; @@ -43,7 +49,8 @@ namespace UnityEngine.UI.Extensions protected override void OnValidate() { base.OnValidate(); - + this.m_Accordion = this.gameObject.GetComponentInParent(); + if (this.group == null) { ToggleGroup tg = this.GetComponentInParent(); @@ -60,11 +67,26 @@ namespace UnityEngine.UI.Extensions { if (this.isOn) { - le.preferredHeight = -1f; + if (m_Accordion.ExpandVerticval) + { + le.preferredHeight = -1f; + } + else + { + le.preferredWidth = -1f; + } } else { - le.preferredHeight = this.m_MinHeight; + if (m_Accordion.ExpandVerticval) + { + le.preferredHeight = this.m_MinHeight; + } + else + { + le.preferredWidth = this.m_MinWidth; + + } } } } @@ -81,22 +103,50 @@ namespace UnityEngine.UI.Extensions { if (state) { - this.m_LayoutElement.preferredHeight = -1f; + if (m_Accordion.ExpandVerticval) + { + this.m_LayoutElement.preferredHeight = -1f; + } + else + { + this.m_LayoutElement.preferredWidth = -1f; + } } else { - this.m_LayoutElement.preferredHeight = this.m_MinHeight; + if (m_Accordion.ExpandVerticval) + { + this.m_LayoutElement.preferredHeight = this.m_MinHeight; + } + else + { + this.m_LayoutElement.preferredWidth = this.m_MinWidth; + } } } else if (transition == Accordion.Transition.Tween) { if (state) { - this.StartTween(this.m_MinHeight, this.GetExpandedHeight()); + if (m_Accordion.ExpandVerticval) + { + this.StartTween(this.m_MinHeight, this.GetExpandedHeight()); + } + else + { + this.StartTween(this.m_MinWidth, this.GetExpandedWidth()); + } } else { - this.StartTween(this.m_RectTransform.rect.height, this.m_MinHeight); + if (m_Accordion.ExpandVerticval) + { + this.StartTween(this.m_RectTransform.rect.height, this.m_MinHeight); + } + else + { + this.StartTween(this.m_RectTransform.rect.width, this.m_MinWidth); + } } } } @@ -113,7 +163,20 @@ namespace UnityEngine.UI.Extensions return h; } - + + protected float GetExpandedWidth() + { + if (this.m_LayoutElement == null) + return this.m_MinWidth; + + float originalPrefW = this.m_LayoutElement.preferredWidth; + this.m_LayoutElement.preferredWidth = -1f; + float w = LayoutUtility.GetPreferredWidth(this.m_RectTransform); + this.m_LayoutElement.preferredWidth = originalPrefW; + + return w; + } + protected void StartTween(float startFloat, float targetFloat) { float duration = (this.m_Accordion != null) ? this.m_Accordion.transitionDuration : 0.3f; @@ -124,7 +187,14 @@ namespace UnityEngine.UI.Extensions startFloat = startFloat, targetFloat = targetFloat }; - info.AddOnChangedCallback(SetHeight); + if (m_Accordion.ExpandVerticval) + { + info.AddOnChangedCallback(SetHeight); + } + else + { + info.AddOnChangedCallback(SetWidth); + } info.ignoreTimeScale = true; this.m_FloatTweenRunner.StartTween(info); } @@ -136,5 +206,13 @@ namespace UnityEngine.UI.Extensions this.m_LayoutElement.preferredHeight = height; } + + protected void SetWidth(float width) + { + if (this.m_LayoutElement == null) + return; + + this.m_LayoutElement.preferredWidth = width; + } } } \ No newline at end of file diff --git a/Runtime/Scripts/Controls/ComboBox/AutoCompleteComboBox.cs b/Runtime/Scripts/Controls/ComboBox/AutoCompleteComboBox.cs index 04274c1..1350f87 100644 --- a/Runtime/Scripts/Controls/ComboBox/AutoCompleteComboBox.cs +++ b/Runtime/Scripts/Controls/ComboBox/AutoCompleteComboBox.cs @@ -95,8 +95,10 @@ namespace UnityEngine.UI.Extensions } } - //TODO design as foldout for Inspector - public Color ValidSelectionTextColor = Color.green; + public float DropdownOffset = 10f; + + //TODO design as foldout for Inspector + public Color ValidSelectionTextColor = Color.green; public Color MatchingItemsRemainingTextColor = Color.black; public Color NoItemsRemainingTextColor = Color.red; @@ -184,45 +186,61 @@ namespace UnityEngine.UI.Extensions return success; } - /* currently just using items in the list instead of being able to add to it. - public void AddItems(params object[] list) + public void AddItem(string item) { - List ddItems = new List(); - foreach (var obj in list) - { - if (obj is DropDownListItem) - { - ddItems.Add((DropDownListItem)obj); - } - else if (obj is string) - { - ddItems.Add(new DropDownListItem(caption: (string)obj)); - } - else if (obj is Sprite) - { - ddItems.Add(new DropDownListItem(image: (Sprite)obj)); - } - else - { - throw new System.Exception("Only ComboBoxItems, Strings, and Sprite types are allowed"); - } - } - Items.AddRange(ddItems); - Items = Items.Distinct().ToList();//remove any duplicates + AvailableOptions.Add(item); + RebuildPanel(); + } + + public void RemoveItem(string item) + { + AvailableOptions.Remove(item); + RebuildPanel(); + } + + public void SetAvailableOptions(List newOptions) + { + AvailableOptions.Clear(); + AvailableOptions = newOptions; + RebuildPanel(); + } + + public void SetAvailableOptions(string[] newOptions) + { + AvailableOptions.Clear(); + + for (int i = 0; i < newOptions.Length; i++) + { + AvailableOptions.Add(newOptions[i]); + } + + RebuildPanel(); + } + + public void ResetItems() + { + AvailableOptions.Clear(); RebuildPanel(); } - */ /// /// Rebuilds the contents of the panel in response to items being added. /// private void RebuildPanel() { + if (_isPanelActive) ToggleDropdownPanel(); + //panel starts with all options _panelItems.Clear(); _prunedPanelItems.Clear(); panelObjects.Clear(); + //clear Autocomplete children in scene + foreach (Transform child in _itemsPanelRT.transform) + { + Destroy(child.gameObject); + } + foreach (string option in AvailableOptions) { _panelItems.Add(option.ToLower()); @@ -326,7 +344,7 @@ namespace UnityEngine.UI.Extensions if (_panelItems.Count < 1) return; - float dropdownHeight = _rectTransform.sizeDelta.y * Mathf.Min(_itemsToDisplay, _panelItems.Count); + float dropdownHeight = _rectTransform.sizeDelta.y * Mathf.Min(_itemsToDisplay, _panelItems.Count) + DropdownOffset; _scrollPanelRT.SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical, dropdownHeight); _scrollPanelRT.SetSizeWithCurrentAnchors(RectTransform.Axis.Horizontal, _rectTransform.sizeDelta.x); @@ -387,7 +405,7 @@ namespace UnityEngine.UI.Extensions /// Toggle the drop down list /// /// whether an item was directly clicked on - public void ToggleDropdownPanel(bool directClick) + public void ToggleDropdownPanel(bool directClick = false) { _isPanelActive = !_isPanelActive; diff --git a/Runtime/Scripts/Controls/ComboBox/ComboBox.cs b/Runtime/Scripts/Controls/ComboBox/ComboBox.cs index 156cd1a..f0b7bbe 100644 --- a/Runtime/Scripts/Controls/ComboBox/ComboBox.cs +++ b/Runtime/Scripts/Controls/ComboBox/ComboBox.cs @@ -21,6 +21,9 @@ namespace UnityEngine.UI.Extensions [SerializeField] private int _itemsToDisplay; + [SerializeField] + private bool _sortItems = true; + [System.Serializable] public class SelectionChangedEvent : UnityEngine.Events.UnityEvent { @@ -131,34 +134,41 @@ namespace UnityEngine.UI.Extensions return success; } - /* currently just using items in the list instead of being able to add to it. - public void AddItems(params object[] list) + public void AddItem(string item) { - List ddItems = new List(); - foreach (var obj in list) - { - if (obj is DropDownListItem) - { - ddItems.Add((DropDownListItem)obj); - } - else if (obj is string) - { - ddItems.Add(new DropDownListItem(caption: (string)obj)); - } - else if (obj is Sprite) - { - ddItems.Add(new DropDownListItem(image: (Sprite)obj)); - } - else - { - throw new System.Exception("Only ComboBoxItems, Strings, and Sprite types are allowed"); - } - } - Items.AddRange(ddItems); - Items = Items.Distinct().ToList();//remove any duplicates + AvailableOptions.Add(item); + RebuildPanel(); + } + + public void RemoveItem(string item) + { + AvailableOptions.Remove(item); + RebuildPanel(); + } + + public void SetAvailableOptions(List newOptions) + { + AvailableOptions.Clear(); + AvailableOptions = newOptions; + RebuildPanel(); + } + + public void SetAvailableOptions(string[] newOptions) + { + AvailableOptions.Clear(); + + for (int i = 0; i < newOptions.Length; i++) + { + AvailableOptions.Add(newOptions[i]); + } + RebuildPanel(); + } + + public void ResetItems() + { + AvailableOptions.Clear(); RebuildPanel(); } - */ /// /// Rebuilds the contents of the panel in response to items being added. @@ -171,7 +181,7 @@ namespace UnityEngine.UI.Extensions { _panelItems.Add(option.ToLower()); } - _panelItems.Sort(); + if(_sortItems) _panelItems.Sort(); List itemObjs = new List(panelObjects.Values); panelObjects.Clear(); diff --git a/Runtime/Scripts/Controls/ComboBox/DropDownList.cs b/Runtime/Scripts/Controls/ComboBox/DropDownList.cs index b702d46..959c8fe 100644 --- a/Runtime/Scripts/Controls/ComboBox/DropDownList.cs +++ b/Runtime/Scripts/Controls/ComboBox/DropDownList.cs @@ -133,9 +133,17 @@ namespace UnityEngine.UI.Extensions return success; } - /* currently just using items in the list instead of being able to add to it. - public void AddItems(params object[] list) + // currently just using items in the list instead of being able to add to it. + /// + /// Rebuilds the list from a new collection. + /// + /// + /// NOTE, this will clear all existing items + /// + /// + public void RefreshItems(params object[] list) { + Items.Clear(); List ddItems = new List(); foreach (var obj in list) { @@ -157,10 +165,74 @@ namespace UnityEngine.UI.Extensions } } Items.AddRange(ddItems); - Items = Items.Distinct().ToList();//remove any duplicates RebuildPanel(); } - */ + + /// + /// Adds an additional item to the drop down list (recommended) + /// + /// Item of type DropDownListItem + public void AddItem(DropDownListItem item) + { + Items.Add(item); + RebuildPanel(); + } + + /// + /// Adds an additional drop down list item using a string name + /// + /// Item of type String + public void AddItem(string item) + { + Items.Add(new DropDownListItem(caption: (string)item)); + RebuildPanel(); + } + + /// + /// Adds an additional drop down list item using a sprite image + /// + /// Item of type UI Sprite + public void AddItem(Sprite item) + { + Items.Add(new DropDownListItem(image: (Sprite)item)); + RebuildPanel(); + } + + /// + /// Removes an item from the drop down list (recommended) + /// + /// Item of type DropDownListItem + public void RemoveItem(DropDownListItem item) + { + Items.Remove(item); + RebuildPanel(); + } + + /// + /// Removes an item from the drop down list item using a string name + /// + /// Item of type String + public void RemoveItem(string item) + { + Items.Remove(new DropDownListItem(caption: (string)item)); + RebuildPanel(); + } + + /// + /// Removes an item from the drop down list item using a sprite image + /// + /// Item of type UI Sprite + public void RemoveItem(Sprite item) + { + Items.Remove(new DropDownListItem(image: (Sprite)item)); + RebuildPanel(); + } + + public void ResetItems() + { + Items.Clear(); + RebuildPanel(); + } /// /// Rebuilds the contents of the panel in response to items being added. diff --git a/Runtime/Scripts/Controls/InputFocus.cs b/Runtime/Scripts/Controls/InputFocus.cs index e900806..9802314 100644 --- a/Runtime/Scripts/Controls/InputFocus.cs +++ b/Runtime/Scripts/Controls/InputFocus.cs @@ -26,7 +26,7 @@ namespace UnityEngine.UI.Extensions void Update() { // Check if the "Enter" key was just released with the chat input not focused - if (Input.GetKeyUp(KeyCode.Return) && !_inputField.isFocused) + if (UIExtensionsInputManager.GetKeyUp(KeyCode.Return) && !_inputField.isFocused) { // If we need to ignore the keypress, do nothing - otherwise activate the input field if (_ignoreNextActivation) @@ -60,7 +60,7 @@ namespace UnityEngine.UI.Extensions public void OnEndEdit(string textString) { // If the edit ended because we clicked away, don't do anything extra - if (!Input.GetKeyDown(KeyCode.Return)) + if (!UIExtensionsInputManager.GetKeyDown(KeyCode.Return)) { return; } diff --git a/Runtime/Scripts/Controls/ReorderableList/ReorderableList.cs b/Runtime/Scripts/Controls/ReorderableList/ReorderableList.cs index c010421..a710886 100644 --- a/Runtime/Scripts/Controls/ReorderableList/ReorderableList.cs +++ b/Runtime/Scripts/Controls/ReorderableList/ReorderableList.cs @@ -89,8 +89,7 @@ namespace UnityEngine.UI.Extensions /// public void Refresh() { - Destroy(_listContent); - _listContent = ContentLayout.gameObject.AddComponent(); + _listContent = ContentLayout.gameObject.GetOrAddComponent(); _listContent.Init(this); } diff --git a/Runtime/Scripts/Controls/ReorderableList/ReorderableListContent.cs b/Runtime/Scripts/Controls/ReorderableList/ReorderableListContent.cs index 9ef2e7a..8908aed 100644 --- a/Runtime/Scripts/Controls/ReorderableList/ReorderableListContent.cs +++ b/Runtime/Scripts/Controls/ReorderableList/ReorderableListContent.cs @@ -6,6 +6,7 @@ using System.Collections.Generic; namespace UnityEngine.UI.Extensions { + [DisallowMultipleComponent] public class ReorderableListContent : MonoBehaviour { private List _cachedChildren; @@ -13,6 +14,7 @@ namespace UnityEngine.UI.Extensions private ReorderableListElement _ele; private ReorderableList _extList; private RectTransform _rect; + private bool _started = false; private void OnEnable() { @@ -27,12 +29,15 @@ namespace UnityEngine.UI.Extensions public void Init(ReorderableList extList) { + if (_started) { StopCoroutine(RefreshChildren()); } + _extList = extList; _rect = GetComponent(); _cachedChildren = new List(); _cachedListElement = new List(); StartCoroutine(RefreshChildren()); + _started = true; } private IEnumerator RefreshChildren() diff --git a/Runtime/Scripts/Controls/ReorderableList/ReorderableListDebug.cs b/Runtime/Scripts/Controls/ReorderableList/ReorderableListDebug.cs index b051c88..5cc5ecf 100644 --- a/Runtime/Scripts/Controls/ReorderableList/ReorderableListDebug.cs +++ b/Runtime/Scripts/Controls/ReorderableList/ReorderableListDebug.cs @@ -23,7 +23,7 @@ namespace UnityEngine.UI.Extensions if (droppedStruct.IsAClone) DebugLabel.text += "Source Object: " + droppedStruct.SourceObject.name + "\n"; DebugLabel.text += string.Format("From {0} at Index {1} \n", droppedStruct.FromList.name, droppedStruct.FromIndex); - DebugLabel.text += string.Format("To {0} at Index {1} \n", droppedStruct.ToList.name, droppedStruct.ToIndex); + DebugLabel.text += string.Format("To {0} at Index {1} \n", droppedStruct.ToList == null ? "Empty space" : droppedStruct.ToList.name, droppedStruct.ToIndex); } } } \ No newline at end of file diff --git a/Runtime/Scripts/Controls/ReorderableList/ReorderableListElement.cs b/Runtime/Scripts/Controls/ReorderableList/ReorderableListElement.cs index 47750e9..b8768dc 100644 --- a/Runtime/Scripts/Controls/ReorderableList/ReorderableListElement.cs +++ b/Runtime/Scripts/Controls/ReorderableList/ReorderableListElement.cs @@ -13,12 +13,28 @@ namespace UnityEngine.UI.Extensions public class ReorderableListElement : MonoBehaviour, IDragHandler, IBeginDragHandler, IEndDragHandler { [Tooltip("Can this element be dragged?")] - public bool IsGrabbable = true; - [Tooltip("Can this element be transfered to another list")] - public bool IsTransferable = true; - [Tooltip("Can this element be dropped in space?")] - public bool isDroppableInSpace = false; + [SerializeField] + private bool IsGrabbable = true; + [Tooltip("Can this element be transfered to another list")] + [SerializeField] + private bool _isTransferable = true; + + [Tooltip("Can this element be dropped in space?")] + [SerializeField] + private bool isDroppableInSpace = false; + + + public bool IsTransferable + { + get { return _isTransferable; } + set + { + _canvasGroup = gameObject.GetOrAddComponent(); + _canvasGroup.blocksRaycasts = value; + _isTransferable = value; + } + } private readonly List _raycastResults = new List(); private ReorderableList _currentReorderableListRaycasted; @@ -48,6 +64,7 @@ namespace UnityEngine.UI.Extensions public void OnBeginDrag(PointerEventData eventData) { + if (!_canvasGroup) { _canvasGroup = gameObject.GetOrAddComponent(); } _canvasGroup.blocksRaycasts = false; isValid = true; if (_reorderableList == null) @@ -162,7 +179,7 @@ namespace UnityEngine.UI.Extensions //If nothing found or the list is not dropable, put the fake element outside if (_currentReorderableListRaycasted == null || _currentReorderableListRaycasted.IsDropable == false - || (_oldReorderableListRaycasted != _reorderableList && !IsTransferable) +// || (_oldReorderableListRaycasted != _reorderableList && !IsTransferable) || ((_fakeElement.parent == _currentReorderableListRaycasted.Content ? _currentReorderableListRaycasted.Content.childCount - 1 : _currentReorderableListRaycasted.Content.childCount) >= _currentReorderableListRaycasted.maxItems && !_currentReorderableListRaycasted.IsDisplacable) @@ -378,13 +395,19 @@ namespace UnityEngine.UI.Extensions _draggingObject.SetParent(_currentReorderableListRaycasted.Content, false); _draggingObject.rotation = _currentReorderableListRaycasted.transform.rotation; _draggingObject.SetSiblingIndex(_fakeElement.GetSiblingIndex()); + + //If the item is transferable, it can be dragged out again + if (IsTransferable) + { + var cg = _draggingObject.GetComponent(); + cg.blocksRaycasts = true; + } // Force refreshing both lists because otherwise we get inappropriate FromList in ReorderableListEventStruct _reorderableList.Refresh(); _currentReorderableListRaycasted.Refresh(); _reorderableList.OnElementAdded.Invoke(args); - - + if (_displacedObject != null) { finishDisplacingElement(); diff --git a/Runtime/Scripts/Controls/SelectionBox/SelectionBox.cs b/Runtime/Scripts/Controls/SelectionBox/SelectionBox.cs index ca99161..cb8a632 100644 --- a/Runtime/Scripts/Controls/SelectionBox/SelectionBox.cs +++ b/Runtime/Scripts/Controls/SelectionBox/SelectionBox.cs @@ -147,14 +147,14 @@ namespace UnityEngine.UI.Extensions void BeginSelection(){ // Click somewhere in the Game View. - if (!Input.GetMouseButtonDown(0)) + if (!UIExtensionsInputManager.GetMouseButtonDown(0)) return; //The boxRect will be inactive up until the point we start selecting boxRect.gameObject.SetActive(true); // Get the initial click position of the mouse. - origin = new Vector2(Input.mousePosition.x, Input.mousePosition.y); + origin = new Vector2(UIExtensionsInputManager.MousePosition.x, UIExtensionsInputManager.MousePosition.y); //If the initial click point is not inside the selection mask, we abort the selection if (!PointIsValidAgainstSelectionMask(origin)) { @@ -185,7 +185,7 @@ namespace UnityEngine.UI.Extensions selectableList.Add (selectable); //We're using left shift to act as the "Add To Selection" command. So if left shift isn't pressed, we want everything to begin deselected - if (!Input.GetKey (KeyCode.LeftShift)) { + if (!UIExtensionsInputManager.GetKey (KeyCode.LeftShift)) { selectable.selected = false; } } @@ -211,7 +211,7 @@ namespace UnityEngine.UI.Extensions IBoxSelectable GetSelectableAtMousePosition() { //Firstly, we cannot click on something that is not inside the selection mask (if we have one) - if (!PointIsValidAgainstSelectionMask(Input.mousePosition)) { + if (!PointIsValidAgainstSelectionMask(UIExtensionsInputManager.MousePosition)) { return null; } @@ -227,7 +227,7 @@ namespace UnityEngine.UI.Extensions //Once we've found the rendering camera, we check if the selectables rectTransform contains the click. That way we //Can click anywhere on a rectTransform to select it. - if (RectTransformUtility.RectangleContainsScreenPoint(rectTransform, Input.mousePosition, screenCamera)) { + if (RectTransformUtility.RectangleContainsScreenPoint(rectTransform, UIExtensionsInputManager.MousePosition, screenCamera)) { //And if it does, we select it and send it back return selectable; @@ -240,7 +240,7 @@ namespace UnityEngine.UI.Extensions var selectableScreenPoint = GetScreenPointOfSelectable(selectable); //Check that the click fits within the screen-radius of the selectable - if (Vector2.Distance(selectableScreenPoint, Input.mousePosition) <= radius) { + if (Vector2.Distance(selectableScreenPoint, UIExtensionsInputManager.MousePosition) <= radius) { //And if it does, we select it and send it back return selectable; @@ -255,11 +255,11 @@ namespace UnityEngine.UI.Extensions void DragSelection(){ //Return if we're not dragging or if the selection has been aborted (BoxRect disabled) - if (!Input.GetMouseButton(0) || !boxRect.gameObject.activeSelf) + if (!UIExtensionsInputManager.GetMouseButton(0) || !boxRect.gameObject.activeSelf) return; // Store the current mouse position in screen space. - Vector2 currentMousePosition = new Vector2(Input.mousePosition.x, Input.mousePosition.y); + Vector2 currentMousePosition = new Vector2(UIExtensionsInputManager.MousePosition.x, UIExtensionsInputManager.MousePosition.y); // How far have we moved the mouse? Vector2 difference = currentMousePosition - origin; @@ -414,7 +414,7 @@ namespace UnityEngine.UI.Extensions void EndSelection(){ //Get out if we haven't finished selecting, or if the selection has been aborted (boxRect disabled) - if (!Input.GetMouseButtonUp(0) || !boxRect.gameObject.activeSelf) + if (!UIExtensionsInputManager.GetMouseButtonUp(0) || !boxRect.gameObject.activeSelf) return; clickedAfterDrag = GetSelectableAtMousePosition(); diff --git a/Runtime/Scripts/Controls/UI_Knob.cs b/Runtime/Scripts/Controls/UI_Knob.cs index f3e4396..9ca6119 100644 --- a/Runtime/Scripts/Controls/UI_Knob.cs +++ b/Runtime/Scripts/Controls/UI_Knob.cs @@ -1,6 +1,7 @@ /// Credit Tomasz Schelenz /// Sourced from - https://bitbucket.org/SimonDarksideJ/unity-ui-extensions/issues/46/feature-uiknob#comment-29243988 +using System; using UnityEngine.Events; using UnityEngine.EventSystems; @@ -31,17 +32,21 @@ namespace UnityEngine.UI.Extensions [Tooltip("Direction of rotation CW - clockwise, CCW - counterClockwise")] public Direction direction = Direction.CW; [HideInInspector] - public float knobValue; + public float KnobValue; [Tooltip("Max value of the knob, maximum RAW output value knob can reach, overrides snap step, IF set to 0 or higher than loops, max value will be set by loops")] - public float maxValue = 0; + public float MaxValue = 0; [Tooltip("How many rotations knob can do, if higher than max value, the latter will limit max value")] - public int loops = 1; + public int Loops = 0; [Tooltip("Clamp output value between 0 and 1, useful with loops > 1")] - public bool clampOutput01 = false; + public bool ClampOutput01 = false; [Tooltip("snap to position?")] - public bool snapToPosition = false; + public bool SnapToPosition = false; [Tooltip("Number of positions to snap")] - public int snapStepsPerLoop = 10; + public int SnapStepsPerLoop = 10; + [Tooltip("Parent touch area to extend the touch radius")] + public RectTransform ParentTouchMask; + [Tooltip("Default background color of the touch mask. Defaults as transparent")] + public Color MaskBackground = new Color(0, 0, 0, 0); [Space(30)] public KnobFloatValueEvent OnValueChanged; private float _currentLoops = 0; @@ -55,7 +60,48 @@ namespace UnityEngine.UI.Extensions protected override void Awake() { - _screenSpaceOverlay = GetComponentInParent().rootCanvas.renderMode == RenderMode.ScreenSpaceOverlay; + _screenSpaceOverlay = GetComponentInParent().rootCanvas.renderMode == RenderMode.ScreenSpaceOverlay; + } + + protected override void Start() + { + CheckForParentTouchMask(); + } + + private void CheckForParentTouchMask() + { + if (ParentTouchMask) + { + Image maskImage = ParentTouchMask.gameObject.GetOrAddComponent(); + maskImage.color = MaskBackground; + EventTrigger trigger = ParentTouchMask.gameObject.GetOrAddComponent(); + trigger.triggers.Clear(); + //PointerDownEvent + EventTrigger.Entry pointerDownEntry = new EventTrigger.Entry(); + pointerDownEntry.eventID = EventTriggerType.PointerDown; + pointerDownEntry.callback.AddListener((data) => { OnPointerDown((PointerEventData)data); }); + trigger.triggers.Add(pointerDownEntry); + //PointerUpEvent + EventTrigger.Entry pointerUpEntry = new EventTrigger.Entry(); + pointerUpEntry.eventID = EventTriggerType.PointerUp; + pointerUpEntry.callback.AddListener((data) => { OnPointerUp((PointerEventData)data); }); + trigger.triggers.Add(pointerUpEntry); + //PointerEnterEvent + EventTrigger.Entry pointerEnterEntry = new EventTrigger.Entry(); + pointerEnterEntry.eventID = EventTriggerType.PointerEnter; + pointerEnterEntry.callback.AddListener((data) => { OnPointerEnter((PointerEventData)data); }); + trigger.triggers.Add(pointerEnterEntry); + //PointerExitEvent + EventTrigger.Entry pointerExitEntry = new EventTrigger.Entry(); + pointerExitEntry.eventID = EventTriggerType.PointerExit; + pointerExitEntry.callback.AddListener((data) => { OnPointerExit((PointerEventData)data); }); + trigger.triggers.Add(pointerExitEntry); + //DragEvent + EventTrigger.Entry dragEntry = new EventTrigger.Entry(); + dragEntry.eventID = EventTriggerType.Drag; + dragEntry.callback.AddListener((data) => { OnDrag((PointerEventData)data); }); + trigger.triggers.Add(dragEntry); + } } public override void OnPointerUp(PointerEventData eventData) @@ -71,7 +117,6 @@ namespace UnityEngine.UI.Extensions _canDrag = false; } - public override void OnPointerDown(PointerEventData eventData) { _canDrag = true; @@ -115,83 +160,117 @@ namespace UnityEngine.UI.Extensions if (direction == Direction.CW) { - knobValue = 1 - (finalRotation.eulerAngles.z / 360f); + KnobValue = 1 - (finalRotation.eulerAngles.z / 360f); - if (snapToPosition) + if (SnapToPosition) { - SnapToPosition(ref knobValue); - finalRotation.eulerAngles = new Vector3(0, 0, 360 - 360 * knobValue); + SnapToPositionValue(ref KnobValue); + finalRotation.eulerAngles = new Vector3(0, 0, 360 - 360 * KnobValue); } } else { - knobValue = (finalRotation.eulerAngles.z / 360f); + KnobValue = (finalRotation.eulerAngles.z / 360f); - if (snapToPosition) + if (SnapToPosition) { - SnapToPosition(ref knobValue); - finalRotation.eulerAngles = new Vector3(0, 0, 360 * knobValue); + SnapToPositionValue(ref KnobValue); + finalRotation.eulerAngles = new Vector3(0, 0, 360 * KnobValue); } } + UpdateKnobValue(); + + transform.rotation = finalRotation; + InvokeEvents(KnobValue + _currentLoops); + + _previousValue = KnobValue; + } + + private void UpdateKnobValue() + { //PREVENT OVERROTATION - if (Mathf.Abs(knobValue - _previousValue) > 0.5f) + if (Mathf.Abs(KnobValue - _previousValue) > 0.5f) { - if (knobValue < 0.5f && loops > 1 && _currentLoops < loops - 1) + if (KnobValue < 0.5f && Loops > 1 && _currentLoops < Loops - 1) { _currentLoops++; } - else if (knobValue > 0.5f && _currentLoops >= 1) + else if (KnobValue > 0.5f && _currentLoops >= 1) { _currentLoops--; } else { - if (knobValue > 0.5f && _currentLoops == 0) + if (KnobValue > 0.5f && _currentLoops == 0) { - knobValue = 0; + KnobValue = 0; transform.localEulerAngles = Vector3.zero; - InvokeEvents(knobValue + _currentLoops); + InvokeEvents(KnobValue + _currentLoops); return; } - else if (knobValue < 0.5f && _currentLoops == loops - 1) + else if (KnobValue < 0.5f && _currentLoops == Loops - 1) { - knobValue = 1; + KnobValue = 1; transform.localEulerAngles = Vector3.zero; - InvokeEvents(knobValue + _currentLoops); + InvokeEvents(KnobValue + _currentLoops); return; } } } //CHECK MAX VALUE - if (maxValue > 0) + if (MaxValue > 0) { - if (knobValue + _currentLoops > maxValue) + if (KnobValue + _currentLoops > MaxValue) { - knobValue = maxValue; - float maxAngle = direction == Direction.CW ? 360f - 360f * maxValue : 360f * maxValue; + KnobValue = MaxValue; + float maxAngle = direction == Direction.CW ? 360f - 360f * MaxValue : 360f * MaxValue; transform.localEulerAngles = new Vector3(0, 0, maxAngle); - InvokeEvents(knobValue); + InvokeEvents(KnobValue); return; } } - - transform.rotation = finalRotation; - InvokeEvents(knobValue + _currentLoops); - - _previousValue = knobValue; } - private void SnapToPosition(ref float knobValue) + + public void SetKnobValue(float value, int loops = 0) { - float snapStep = 1 / (float)snapStepsPerLoop; + Quaternion newRoation = Quaternion.identity; + KnobValue = value; + _currentLoops = loops; + + if (SnapToPosition) + { + SnapToPositionValue(ref KnobValue); + + } + if (direction == Direction.CW) + { + newRoation.eulerAngles = new Vector3(0, 0, 360 - 360 * KnobValue); + } + else + { + newRoation.eulerAngles = new Vector3(0, 0, 360 * KnobValue); + } + + UpdateKnobValue(); + + transform.rotation = newRoation; + InvokeEvents(KnobValue + _currentLoops); + + _previousValue = KnobValue; + } + + private void SnapToPositionValue(ref float knobValue) + { + float snapStep = 1 / (float)SnapStepsPerLoop; float newValue = Mathf.Round(knobValue / snapStep) * snapStep; knobValue = newValue; } private void InvokeEvents(float value) { - if (clampOutput01) - value /= loops; + if (ClampOutput01) + value /= Loops; OnValueChanged.Invoke(value); } diff --git a/Runtime/Scripts/Effects/ShaderEffects/UIAdditiveEffect.cs b/Runtime/Scripts/Effects/ShaderEffects/UIAdditiveEffect.cs index 6b90e47..f8bf812 100644 --- a/Runtime/Scripts/Effects/ShaderEffects/UIAdditiveEffect.cs +++ b/Runtime/Scripts/Effects/ShaderEffects/UIAdditiveEffect.cs @@ -25,7 +25,7 @@ namespace UnityEngine.UI.Extensions if (mGraphic.material == null || mGraphic.material.name == "Default UI Material") { //Applying default material with UI Image Crop shader - mGraphic.material = new Material(Shader.Find("UI Extensions/UIAdditive")); + mGraphic.material = new Material(ShaderLibrary.GetShaderInstance("UI Extensions/UIAdditive")); } } else diff --git a/Runtime/Scripts/Effects/ShaderEffects/UIImageCrop.cs b/Runtime/Scripts/Effects/ShaderEffects/UIImageCrop.cs index 46c4065..aca20c8 100644 --- a/Runtime/Scripts/Effects/ShaderEffects/UIImageCrop.cs +++ b/Runtime/Scripts/Effects/ShaderEffects/UIImageCrop.cs @@ -32,7 +32,7 @@ namespace UnityEngine.UI.Extensions if (mGraphic.material == null || mGraphic.material.name == "Default UI Material") { //Applying default material with UI Image Crop shader - mGraphic.material = new Material(Shader.Find("UI Extensions/UI Image Crop")); + mGraphic.material = new Material(ShaderLibrary.GetShaderInstance("UI Extensions/UI Image Crop")); } mat = mGraphic.material; } diff --git a/Runtime/Scripts/Effects/ShaderEffects/UILinearDodgeEffect.cs b/Runtime/Scripts/Effects/ShaderEffects/UILinearDodgeEffect.cs index f09934d..4d883b4 100644 --- a/Runtime/Scripts/Effects/ShaderEffects/UILinearDodgeEffect.cs +++ b/Runtime/Scripts/Effects/ShaderEffects/UILinearDodgeEffect.cs @@ -25,7 +25,7 @@ namespace UnityEngine.UI.Extensions if (mGraphic.material == null || mGraphic.material.name == "Default UI Material") { //Applying default material with UI Image Crop shader - mGraphic.material = new Material(Shader.Find("UI Extensions/UILinearDodge")); + mGraphic.material = new Material(ShaderLibrary.GetShaderInstance("UI Extensions/UILinearDodge")); } } else diff --git a/Runtime/Scripts/Effects/ShaderEffects/UIMultiplyEffect.cs b/Runtime/Scripts/Effects/ShaderEffects/UIMultiplyEffect.cs index e3fa701..00206a2 100644 --- a/Runtime/Scripts/Effects/ShaderEffects/UIMultiplyEffect.cs +++ b/Runtime/Scripts/Effects/ShaderEffects/UIMultiplyEffect.cs @@ -25,7 +25,7 @@ namespace UnityEngine.UI.Extensions if (mGraphic.material == null || mGraphic.material.name == "Default UI Material") { //Applying default material with UI Image Crop shader - mGraphic.material = new Material(Shader.Find("UI Extensions/UIMultiply")); + mGraphic.material = new Material(ShaderLibrary.GetShaderInstance("UI Extensions/UIMultiply")); } } else diff --git a/Runtime/Scripts/Effects/ShaderEffects/UIScreenEffect.cs b/Runtime/Scripts/Effects/ShaderEffects/UIScreenEffect.cs index ba5e2bc..386a3fb 100644 --- a/Runtime/Scripts/Effects/ShaderEffects/UIScreenEffect.cs +++ b/Runtime/Scripts/Effects/ShaderEffects/UIScreenEffect.cs @@ -25,7 +25,7 @@ namespace UnityEngine.UI.Extensions if (mGraphic.material == null || mGraphic.material.name == "Default UI Material") { //Applying default material with UI Image Crop shader - mGraphic.material = new Material(Shader.Find("UI Extensions/UIScreen")); + mGraphic.material = new Material(ShaderLibrary.GetShaderInstance("UI Extensions/UIScreen")); } } else diff --git a/Runtime/Scripts/Effects/ShaderEffects/UISoftAdditiveEffect.cs b/Runtime/Scripts/Effects/ShaderEffects/UISoftAdditiveEffect.cs index 6d80b95..764d0b9 100644 --- a/Runtime/Scripts/Effects/ShaderEffects/UISoftAdditiveEffect.cs +++ b/Runtime/Scripts/Effects/ShaderEffects/UISoftAdditiveEffect.cs @@ -25,7 +25,7 @@ namespace UnityEngine.UI.Extensions if (mGraphic.material == null || mGraphic.material.name == "Default UI Material") { //Applying default material with UI Image Crop shader - mGraphic.material = new Material(Shader.Find("UI Extensions/UISoftAdditive")); + mGraphic.material = new Material(ShaderLibrary.GetShaderInstance("UI Extensions/UISoftAdditive")); } } else diff --git a/Runtime/Scripts/Effects/SoftMaskScript.cs b/Runtime/Scripts/Effects/SoftMaskScript.cs index 999c35c..b5edda9 100644 --- a/Runtime/Scripts/Effects/SoftMaskScript.cs +++ b/Runtime/Scripts/Effects/SoftMaskScript.cs @@ -48,7 +48,7 @@ namespace UnityEngine.UI.Extensions var text = GetComponent(); if (text != null) { - mat = new Material(Shader.Find("UI Extensions/SoftMaskShader")); + mat = new Material(ShaderLibrary.GetShaderInstance("UI Extensions/SoftMaskShader")); text.material = mat; cachedCanvas = text.canvas; cachedCanvasTransform = cachedCanvas.transform; @@ -64,7 +64,7 @@ namespace UnityEngine.UI.Extensions var graphic = GetComponent(); if (graphic != null) { - mat = new Material(Shader.Find("UI Extensions/SoftMaskShader")); + mat = new Material(ShaderLibrary.GetShaderInstance("UI Extensions/SoftMaskShader")); graphic.material = mat; cachedCanvas = graphic.canvas; cachedCanvasTransform = cachedCanvas.transform; diff --git a/Runtime/Scripts/Effects/UIParticleSystem.cs b/Runtime/Scripts/Effects/UIParticleSystem.cs index 95c3a0e..b9c4981 100644 --- a/Runtime/Scripts/Effects/UIParticleSystem.cs +++ b/Runtime/Scripts/Effects/UIParticleSystem.cs @@ -76,7 +76,7 @@ namespace UnityEngine.UI.Extensions if (material == null) { - var foundShader = Shader.Find("UI Extensions/Particles/Additive"); + var foundShader = ShaderLibrary.GetShaderInstance("UI Extensions/Particles/Additive"); if (foundShader) { material = new Material(foundShader); @@ -223,9 +223,14 @@ namespace UnityEngine.UI.Extensions frame = Mathf.FloorToInt(frameProgress * textureSheetAnimation.numTilesX); int row = textureSheetAnimation.rowIndex; - // if (textureSheetAnimation.useRandomRow) { // FIXME - is this handled internally by rowIndex? - // row = Random.Range(0, textureSheetAnimation.numTilesY, using: particle.randomSeed); - // } +#if UNITY_2020 || UNITY_2019 + if (textureSheetAnimation.rowMode == ParticleSystemAnimationRowMode.Random) +#else + if (textureSheetAnimation.useRandomRow) +#endif + { // FIXME - is this handled internally by rowIndex? + row = Mathf.Abs((int)particle.randomSeed % textureSheetAnimation.numTilesY); + } frame += row * textureSheetAnimation.numTilesX; break; @@ -234,7 +239,7 @@ namespace UnityEngine.UI.Extensions frame %= textureSheetAnimationFrames; particleUV.x = (frame % textureSheetAnimation.numTilesX) * textureSheetAnimationFrameSize.x; - particleUV.y = 1.0f - Mathf.FloorToInt(frame / textureSheetAnimation.numTilesX) * textureSheetAnimationFrameSize.y; + particleUV.y = 1.0f - ((frame / textureSheetAnimation.numTilesX) + 1) * textureSheetAnimationFrameSize.y; particleUV.z = particleUV.x + textureSheetAnimationFrameSize.x; particleUV.w = particleUV.y + textureSheetAnimationFrameSize.y; } @@ -387,6 +392,7 @@ namespace UnityEngine.UI.Extensions public void StartParticleEmission() { + pSystem.time = 0; pSystem.Play(); } @@ -401,4 +407,4 @@ namespace UnityEngine.UI.Extensions } } #endif -} \ No newline at end of file + } \ No newline at end of file diff --git a/Runtime/Scripts/InputModules.meta b/Runtime/Scripts/InputModules.meta deleted file mode 100644 index 2969fc2..0000000 --- a/Runtime/Scripts/InputModules.meta +++ /dev/null @@ -1,5 +0,0 @@ -fileFormatVersion: 2 -guid: a0789c2f62bad6b4c800a3dc502fa18e -folderAsset: yes -DefaultImporter: - userData: diff --git a/Runtime/Scripts/InputModules/AimerInputModule.cs b/Runtime/Scripts/InputModules/AimerInputModule.cs deleted file mode 100644 index d4ce670..0000000 --- a/Runtime/Scripts/InputModules/AimerInputModule.cs +++ /dev/null @@ -1,163 +0,0 @@ -/// Credit Chris Trueman -/// Sourced from - http://forum.unity3d.com/threads/use-reticle-like-mouse-for-worldspace-uis.295271/ - -namespace UnityEngine.EventSystems.Extensions -{ - [RequireComponent(typeof(EventSystem))] - [AddComponentMenu("Event/Extensions/Aimer Input Module")] - public class AimerInputModule : PointerInputModule - { - /// - /// The Input axis name used to activate the object under the reticle. - /// - public string activateAxis = "Submit"; - - /// - /// The aimer offset position. Aimer is center screen use this offset to change that. - /// - public Vector2 aimerOffset = new Vector2(0, 0); - - /// - /// The object under aimer. A static access field that lets you know what is under the aimer. - /// This field can return null. - /// - public static GameObject objectUnderAimer; - - protected AimerInputModule() { } - - public override void ActivateModule() - { - StandaloneInputModule StandAloneSystem = GetComponent(); - - if (StandAloneSystem != null && StandAloneSystem.enabled) - { - Debug.LogError("Aimer Input Module is incompatible with the StandAloneInputSystem, " + - "please remove it from the Event System in this scene or disable it when this module is in use"); - } - } - - public override void Process() - { - bool pressed = Input.GetButtonDown(activateAxis); - bool released = Input.GetButtonUp(activateAxis); - - PointerEventData pointer = GetAimerPointerEventData(); - - ProcessInteraction(pointer, pressed, released); - - if (!released) - ProcessMove(pointer); - else - RemovePointerData(pointer); - } - - protected virtual PointerEventData GetAimerPointerEventData() - { - PointerEventData pointerData; - - //Not certain on the use of this. - //I know that -1 is the mouse and anything positive would be a finger/touch, 0 being the first finger, 1 being the second and so one till the system limit is reached. - //So that is the reason I choose -2. - GetPointerData(-2, out pointerData, true); - - pointerData.Reset(); - - pointerData.position = new Vector2(Screen.width * 0.5f, Screen.height * 0.5f) + aimerOffset; - - eventSystem.RaycastAll(pointerData, m_RaycastResultCache); - var raycast = FindFirstRaycast(m_RaycastResultCache); - pointerData.pointerCurrentRaycast = raycast; - m_RaycastResultCache.Clear(); - return pointerData; - } - - private void ProcessInteraction(PointerEventData pointer, bool pressed, bool released) - { - var currentOverGo = pointer.pointerCurrentRaycast.gameObject; - - objectUnderAimer = ExecuteEvents.GetEventHandler(currentOverGo);//we only want objects that we can submit on. - - if (pressed) - { - pointer.eligibleForClick = true; - pointer.delta = Vector2.zero; - pointer.pressPosition = pointer.position; - pointer.pointerPressRaycast = pointer.pointerCurrentRaycast; - - // search for the control that will receive the press - // if we can't find a press handler set the press - // handler to be what would receive a click. - var newPressed = ExecuteEvents.ExecuteHierarchy(currentOverGo, pointer, ExecuteEvents.submitHandler); - - // didn't find a press handler... search for a click handler - if (newPressed == null) - { - newPressed = ExecuteEvents.ExecuteHierarchy(currentOverGo, pointer, ExecuteEvents.pointerDownHandler); - if (newPressed == null) - newPressed = ExecuteEvents.GetEventHandler(currentOverGo); - } - else - { - pointer.eligibleForClick = false; - } - - if (newPressed != pointer.pointerPress) - { - pointer.pointerPress = newPressed; - pointer.rawPointerPress = currentOverGo; - pointer.clickCount = 0; - } - - // Save the drag handler as well - pointer.pointerDrag = ExecuteEvents.GetEventHandler(currentOverGo); - - if (pointer.pointerDrag != null) - ExecuteEvents.Execute(pointer.pointerDrag, pointer, ExecuteEvents.beginDragHandler); - } - - if (released) - { - //Debug.Log("Executing pressup on: " + pointer.pointerPress); - ExecuteEvents.Execute(pointer.pointerPress, pointer, ExecuteEvents.pointerUpHandler); - - //Debug.Log("KeyCode: " + pointer.eventData.keyCode); - - // see if we mouse up on the same element that we clicked on... - var pointerUpHandler = ExecuteEvents.GetEventHandler(currentOverGo); - - // PointerClick - if (pointer.pointerPress == pointerUpHandler && pointer.eligibleForClick) - { - float time = Time.unscaledTime; - - if (time - pointer.clickTime < 0.3f) - ++pointer.clickCount; - else - pointer.clickCount = 1; - pointer.clickTime = time; - - ExecuteEvents.Execute(pointer.pointerPress, pointer, ExecuteEvents.pointerClickHandler); - } - else if (pointer.pointerDrag != null) - { - ExecuteEvents.ExecuteHierarchy(currentOverGo, pointer, ExecuteEvents.dropHandler); - } - - pointer.eligibleForClick = false; - pointer.pointerPress = null; - pointer.rawPointerPress = null; - - if (pointer.pointerDrag != null) - ExecuteEvents.Execute(pointer.pointerDrag, pointer, ExecuteEvents.endDragHandler); - - pointer.pointerDrag = null; - } - } - - public override void DeactivateModule() - { - base.DeactivateModule(); - ClearSelection(); - } - } -} \ No newline at end of file diff --git a/Runtime/Scripts/InputModules/GamePadInputModule.cs b/Runtime/Scripts/InputModules/GamePadInputModule.cs deleted file mode 100644 index d1d0d9b..0000000 --- a/Runtime/Scripts/InputModules/GamePadInputModule.cs +++ /dev/null @@ -1,226 +0,0 @@ -/// Credit Simon (simonDarksideJ) Jackson -/// Sourced from - UI SIM source and My Brain - -namespace UnityEngine.EventSystems -{ - [AddComponentMenu("Event/Extensions/GamePad Input Module")] - public class GamePadInputModule : BaseInputModule - { - private float m_PrevActionTime; - Vector2 m_LastMoveVector; - int m_ConsecutiveMoveCount = 0; - - protected GamePadInputModule() - {} - - [SerializeField] - private string m_HorizontalAxis = "Horizontal"; - - /// - /// Name of the vertical axis for movement (if axis events are used). - /// - [SerializeField] - private string m_VerticalAxis = "Vertical"; - - /// - /// Name of the submit button. - /// - [SerializeField] - private string m_SubmitButton = "Submit"; - - /// - /// Name of the submit button. - /// - [SerializeField] - private string m_CancelButton = "Cancel"; - - [SerializeField] - private float m_InputActionsPerSecond = 10; - - [SerializeField] - private float m_RepeatDelay = 0.1f; - - public float inputActionsPerSecond - { - get { return m_InputActionsPerSecond; } - set { m_InputActionsPerSecond = value; } - } - - public float repeatDelay - { - get { return m_RepeatDelay; } - set { m_RepeatDelay = value; } - } - - /// - /// Name of the horizontal axis for movement (if axis events are used). - /// - public string horizontalAxis - { - get { return m_HorizontalAxis; } - set { m_HorizontalAxis = value; } - } - - /// - /// Name of the vertical axis for movement (if axis events are used). - /// - public string verticalAxis - { - get { return m_VerticalAxis; } - set { m_VerticalAxis = value; } - } - - public string submitButton - { - get { return m_SubmitButton; } - set { m_SubmitButton = value; } - } - - public string cancelButton - { - get { return m_CancelButton; } - set { m_CancelButton = value; } - } - - public override bool ShouldActivateModule() - { - if (!base.ShouldActivateModule()) - return false; - - var shouldActivate = true; - shouldActivate |= Input.GetButtonDown(m_SubmitButton); - shouldActivate |= Input.GetButtonDown(m_CancelButton); - shouldActivate |= !Mathf.Approximately(Input.GetAxisRaw(m_HorizontalAxis), 0.0f); - shouldActivate |= !Mathf.Approximately(Input.GetAxisRaw(m_VerticalAxis), 0.0f); - return shouldActivate; - } - - public override void ActivateModule() - { - StandaloneInputModule StandAloneSystem = GetComponent(); - - if (StandAloneSystem && StandAloneSystem.enabled) - { - Debug.LogError("StandAloneInputSystem should not be used with the GamePadInputModule, " + - "please remove it from the Event System in this scene or disable it when this module is in use"); - } - - base.ActivateModule(); - - var toSelect = eventSystem.currentSelectedGameObject; - if (toSelect == null) - toSelect = eventSystem.firstSelectedGameObject; - - eventSystem.SetSelectedGameObject(toSelect, GetBaseEventData()); - } - - public override void DeactivateModule() - { - base.DeactivateModule(); - } - - public override void Process() - { - bool usedEvent = SendUpdateEventToSelectedObject(); - - if (eventSystem.sendNavigationEvents) - { - if (!usedEvent) - usedEvent |= SendMoveEventToSelectedObject(); - - if (!usedEvent) - SendSubmitEventToSelectedObject(); - } - } - - /// - /// Process submit keys. - /// - protected bool SendSubmitEventToSelectedObject() - { - if (eventSystem.currentSelectedGameObject == null) - return false; - - var data = GetBaseEventData(); - if (Input.GetButtonDown(m_SubmitButton)) - ExecuteEvents.Execute(eventSystem.currentSelectedGameObject, data, ExecuteEvents.submitHandler); - - if (Input.GetButtonDown(m_CancelButton)) - ExecuteEvents.Execute(eventSystem.currentSelectedGameObject, data, ExecuteEvents.cancelHandler); - return data.used; - } - - private Vector2 GetRawMoveVector() - { - Vector2 move = Vector2.zero; - move.x = Input.GetAxisRaw(m_HorizontalAxis); - move.y = Input.GetAxisRaw(m_VerticalAxis); - - if (Input.GetButtonDown(m_HorizontalAxis)) - { - if (move.x < 0) - move.x = -1f; - if (move.x > 0) - move.x = 1f; - } - if (Input.GetButtonDown(m_VerticalAxis)) - { - if (move.y < 0) - move.y = -1f; - if (move.y > 0) - move.y = 1f; - } - return move; - } - - /// - /// Process events. - /// - protected bool SendMoveEventToSelectedObject() - { - float time = Time.unscaledTime; - - Vector2 movement = GetRawMoveVector(); - if (Mathf.Approximately(movement.x, 0f) && Mathf.Approximately(movement.y, 0f)) - { - m_ConsecutiveMoveCount = 0; - return false; - } - - // If user pressed key again, always allow event - bool allow = Input.GetButtonDown(m_HorizontalAxis) || Input.GetButtonDown(m_VerticalAxis); - bool similarDir = (Vector2.Dot(movement, m_LastMoveVector) > 0); - if (!allow) - { - // Otherwise, user held down key or axis. - // If direction didn't change at least 90 degrees, wait for delay before allowing consecutive event. - if (similarDir && m_ConsecutiveMoveCount == 1) - allow = (time > m_PrevActionTime + m_RepeatDelay); - // If direction changed at least 90 degree, or we already had the delay, repeat at repeat rate. - else - allow = (time > m_PrevActionTime + 1f / m_InputActionsPerSecond); - } - if (!allow) - return false; - - var axisEventData = GetAxisEventData(movement.x, movement.y, 0.6f); - ExecuteEvents.Execute(eventSystem.currentSelectedGameObject, axisEventData, ExecuteEvents.moveHandler); - if (!similarDir) - m_ConsecutiveMoveCount = 0; - m_ConsecutiveMoveCount++; - m_PrevActionTime = time; - m_LastMoveVector = movement; - return axisEventData.used; - } - - protected bool SendUpdateEventToSelectedObject() - { - if (eventSystem.currentSelectedGameObject == null) - return false; - - var data = GetBaseEventData(); - ExecuteEvents.Execute(eventSystem.currentSelectedGameObject, data, ExecuteEvents.updateSelectedHandler); - return data.used; - } - } -} diff --git a/Runtime/Scripts/Layout/CardUI/2D Cards/CardStack2D.cs b/Runtime/Scripts/Layout/CardUI/2D Cards/CardStack2D.cs index d099b6b..61487c1 100644 --- a/Runtime/Scripts/Layout/CardUI/2D Cards/CardStack2D.cs +++ b/Runtime/Scripts/Layout/CardUI/2D Cards/CardStack2D.cs @@ -3,118 +3,121 @@ /// Sourced from - https://github.com/ryanslikesocool/Unity-Card-UI /// - using System.Collections; -using System.Collections.Generic; -using UnityEngine; -using UnityEngine.UI; +using System.Collections; namespace UnityEngine.UI.Extensions { -public class CardStack2D : MonoBehaviour -{ - - [SerializeField] - private float cardMoveSpeed = 8f; - [SerializeField] - private float buttonCooldownTime = 0.125f; - [SerializeField] - private int cardZMultiplier = 32; - [SerializeField] - private bool useDefaultUsedXPos = true; - [SerializeField] - private int usedCardXPos = 1280; - [SerializeField] - private Transform[] cards = null; - - private int cardArrayOffset; - private Vector3[] cardPositions; - private int xPowerDifference; - - ///Static variables can be used across the scene if this script is in it. - ///Thankfully it doesn't matter if another script attempts to use the variable and this script isn't in the scene. - public static bool canUseHorizontalAxis = true; - - void Start() + public class CardStack2D : MonoBehaviour { - ///I've found that 9 is a good number for this. - ///I wouldn't really recommend changing it, but go ahead if you want to. - xPowerDifference = 9 - cards.Length; - ///This is optional, but makes it super easy to figure out the off screen position for cards. - ///Unfortunately, it's only really useful if the cards are the same width. - if (useDefaultUsedXPos) + [SerializeField] + private float cardMoveSpeed = 8f; + [SerializeField] + private float buttonCooldownTime = 0.125f; + [SerializeField] + private int cardZMultiplier = 32; + [SerializeField] + private bool useDefaultUsedXPos = true; + [SerializeField] + private int usedCardXPos = 1280; + [SerializeField] + private KeyCode leftButton = KeyCode.LeftArrow; + [SerializeField] + private KeyCode rightButton = KeyCode.RightArrow; + [SerializeField] + private Transform[] cards = null; + + + + private int cardArrayOffset; + private Vector3[] cardPositions; + private int xPowerDifference; + + ///Static variables can be used across the scene if this script is in it. + ///Thankfully it doesn't matter if another script attempts to use the variable and this script isn't in the scene. + public static bool canUseHorizontalAxis = true; + + void Start() { - int cardWidth = (int)(cards[0].GetComponent().rect.width); - usedCardXPos = (int)(Screen.width * 0.5f + cardWidth); - } + ///I've found that 9 is a good number for this. + ///I wouldn't really recommend changing it, but go ahead if you want to. + xPowerDifference = 9 - cards.Length; - cardPositions = new Vector3[cards.Length * 2 - 1]; - - ///This loop is for cards still in the stack. - for (int i = cards.Length; i > -1; i--) - { - if (i < cards.Length - 1) + ///This is optional, but makes it super easy to figure out the off screen position for cards. + ///Unfortunately, it's only really useful if the cards are the same width. + if (useDefaultUsedXPos) { - cardPositions[i] = new Vector3(-Mathf.Pow(2, i + xPowerDifference) + cardPositions[i + 1].x, 0, cardZMultiplier * Mathf.Abs(i + 1 - cards.Length)); + int cardWidth = (int)(cards[0].GetComponent().rect.width); + usedCardXPos = (int)(Screen.width * 0.5f + cardWidth); } - else - { - cardPositions[i] = Vector3.zero; - } - } - ///This loop is for cards outside of the stack. - for (int i = cards.Length; i < cardPositions.Length; i++) - { - cardPositions[i] = new Vector3(usedCardXPos + 4 * (i - cards.Length), 0, -2 + -2 * (i - cards.Length)); - } - } + cardPositions = new Vector3[cards.Length * 2 - 1]; - void Update() - { - if (canUseHorizontalAxis) - { - ///Controls for the cards. - if (Input.GetAxisRaw("Horizontal") < 0 && cardArrayOffset > 0) + ///This loop is for cards still in the stack. + for (int i = cards.Length; i > -1; i--) { - cardArrayOffset--; - StartCoroutine(ButtonCooldown()); - } - else if (Input.GetAxisRaw("Horizontal") > 0 && cardArrayOffset < cards.Length - 1) - { - cardArrayOffset++; - StartCoroutine(ButtonCooldown()); - } - } - - ///This loop moves the cards. I know that none of my lerps are the "right way," but it looks much nicer. - for (int i = 0; i < cards.Length; i++) - { - cards[i].localPosition = Vector3.Lerp(cards[i].localPosition, cardPositions[i + cardArrayOffset], Time.deltaTime * cardMoveSpeed); - if (Mathf.Abs(cards[i].localPosition.x - cardPositions[i + cardArrayOffset].x) < 0.01f) - { - cards[i].localPosition = cardPositions[i + cardArrayOffset]; - - ///This disables interaction with cards that are not on top of the stack. - if (cards[i].localPosition.x == 0) + if (i < cards.Length - 1) { - cards[i].gameObject.GetComponent().interactable = true; + cardPositions[i] = new Vector3(-Mathf.Pow(2, i + xPowerDifference) + cardPositions[i + 1].x, 0, cardZMultiplier * Mathf.Abs(i + 1 - cards.Length)); } else { - cards[i].gameObject.GetComponent().interactable = false; + cardPositions[i] = Vector3.zero; + } + } + + ///This loop is for cards outside of the stack. + for (int i = cards.Length; i < cardPositions.Length; i++) + { + cardPositions[i] = new Vector3(usedCardXPos + 4 * (i - cards.Length), 0, -2 + -2 * (i - cards.Length)); + } + } + + void Update() + { + if (canUseHorizontalAxis) + { + ///Controls for the cards. + if ((UIExtensionsInputManager.GetAxisRaw("Horizontal") < 0 || UIExtensionsInputManager.GetKey(leftButton)) && cardArrayOffset > 0) + { + cardArrayOffset--; + StartCoroutine(ButtonCooldown()); + } + else if ((UIExtensionsInputManager.GetAxisRaw("Horizontal") > 0 || UIExtensionsInputManager.GetKey(rightButton)) && cardArrayOffset < cards.Length - 1) + { + cardArrayOffset++; + StartCoroutine(ButtonCooldown()); + } + } + + ///This loop moves the cards. I know that none of my lerps are the "right way," but it looks much nicer. + for (int i = 0; i < cards.Length; i++) + { + cards[i].localPosition = Vector3.Lerp(cards[i].localPosition, cardPositions[i + cardArrayOffset], Time.deltaTime * cardMoveSpeed); + if (Mathf.Abs(cards[i].localPosition.x - cardPositions[i + cardArrayOffset].x) < 0.01f) + { + cards[i].localPosition = cardPositions[i + cardArrayOffset]; + + ///This disables interaction with cards that are not on top of the stack. + if (cards[i].localPosition.x == 0) + { + cards[i].gameObject.GetComponent().interactable = true; + } + else + { + cards[i].gameObject.GetComponent().interactable = false; + } } } } - } - ///Stops the cards from scrolling super quickly if a button on the horizontal axis is held down. - IEnumerator ButtonCooldown() - { - canUseHorizontalAxis = false; - yield return new WaitForSeconds(buttonCooldownTime); - canUseHorizontalAxis = true; + ///Stops the cards from scrolling super quickly if a button on the horizontal axis is held down. + IEnumerator ButtonCooldown() + { + canUseHorizontalAxis = false; + yield return new WaitForSeconds(buttonCooldownTime); + canUseHorizontalAxis = true; + } } -} } \ No newline at end of file diff --git a/Runtime/Scripts/Layout/ContentScrollSnapHorizontal.cs b/Runtime/Scripts/Layout/ContentScrollSnapHorizontal.cs index 7a65c69..9b242c4 100644 --- a/Runtime/Scripts/Layout/ContentScrollSnapHorizontal.cs +++ b/Runtime/Scripts/Layout/ContentScrollSnapHorizontal.cs @@ -1,4 +1,8 @@ -using System.Collections; +/// Credit Beka Westberg +/// Sourced from - https://bitbucket.org/UnityUIExtensions/unity-ui-extensions/pull-requests/28 +/// Updated by SimonDarksideJ - Added some exception management and a SetNewItems to replace the content programmatically + +using System.Collections; using System.Collections.Generic; using UnityEngine.EventSystems; using UnityEngine.Events; @@ -185,11 +189,60 @@ namespace UnityEngine.UI.Extensions if (prevButton) prevButton.GetComponent