Merged in development (pull request #106)

Release 2.2.3
pull/413/head
Simon Jackson 2020-10-31 17:11:43 +00:00
commit a191653524
64 changed files with 1748 additions and 1029 deletions

6
.gitmodules vendored
View File

@ -1,4 +1,4 @@
[submodule "Examples"] [submodule "Examples~"]
path = Examples path = Examples~
url = https://bitbucket.org/UnityUIExtensions/unity-ui-extensions/branch/Examples url = https://SimonDarksideJ@bitbucket.org/UnityUIExtensions/unity-ui-extensions.git
branch = Examples branch = Examples

View File

@ -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

View File

@ -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/). 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 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).
straightforward as possible. Be sure to also check out the "Examples" option in the Package Manager window to import the samples to your project.
### Added ### Added
- New UPM deployment for Unity 2019, 2018 will still need to use the asset packages due to Unity compatibility issues. - Add squircle primitive
- Updated the project to the new Unity packaging guidelines, including separating out the examples to a separate package. - Adding new magnetic scroll control
- Many line drawing updates, including the ability to draw using a mouse (check the examples) - Added a static library to collate shaders on first use.
- New Unity Card UI controls thanks to @RyanslikeSoCool - 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 ### Changed
- Scroll Snaps (HSS/VSS) now have a "Hard Swipe" feature to restrict movement to a single page for each swipe - Examples now included with UPM delivery and available as a button on the UPM package manager window
- Scroll Snaps have also been updated to work better with the UIInfiniteScroll control - Updated DropDown and Autocomplete controls based on feedback in #204
- Update to the Fancy Scroll controls with even more added fanciness - Updated Accordion to support both Vertical as well as Horizontal layout
- Several updates to adopt newer Unity standards in the controls to ensure full forwards and backwards compatibility - 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 ### Deprecated
@ -29,21 +39,20 @@ None
### Fixed ### Fixed
- Mouse position use updated in - Fix to add a "RequireComponent" to Primitives as Unity 2020 does not add them by default
* RadialSlider - Remove old Examples submodule
* ColorSampler - Updated submodules to hide Examples folder Additionally, updated Package manifest to allow importing of examples direct from UPM package.
* TiltWindow - Fixed hard swipe to ensure it only ever moves one page, no matter how far you swipe.
- Check compiler warnings (#197) - Fixed a conflict when using the ScrollConflictManager in child content of a HSS or VSS
- Line Renderer click to add lines (#183) - Fix for UI Particle system looping
- ScrollSnap Swiping options - hard fast swipe (#176) - Fixed public GoToScreen call to only raise events internally (not multiple)
- Shader Loading issue / UIParticleSystem (#229) - Final roll-up and fix. Resolved race condition for associated pagination controls.
- Issue where Menu Prefabs would be disabled instead of their Clones (#210) - Fixed issue with page events not being raised when inertia was disabled (velocity was always zero)
- Check ScrollSnapBase update (#265) - 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
- UIInfiniteScroller support for VSS updated and fixes - Reorderable list items marked as transferable, remain transferable after being dropped
- Fix to allow radial slider to start from positions other than left - Patch to resolve issues without the new Input System installed
- Fix UI Particles: Texture sheet animation + Random row(#256) - Refined magnetic scroll and dependencies while documenting Updated example
- Fix for wandering ScrollSnap controls due to Local Positioning drift - Patch Tooltip
- Divide By Zero fix for Gradient (#58)
### Removed ### Removed

View File

@ -31,24 +31,64 @@ 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: 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. > 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) ## [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. #### Added
* 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) - Add squircle primitive
* Scroll Snaps (HSS/VSS) now have a "Hard Swipe" feature to restrict movement to a single page for each swipe - Adding new magnetic scroll control
* Scroll Snaps have also been updated to work better with the UIInfiniteScroll control - Added a static library to collate shaders on first use.
* New Unity Card UI controls thanks to @RyanslikeSoCool - 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.
* Update to the Fancy Scroll controls with even more added fanciness - Updated DropDown and Autocomplete controls based on feedback in #204
* Several updates to adopt newer Unity standards in the controls to ensure full forwards and backwards compatibility
#### 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 # Document revision history
@ -56,3 +96,5 @@ This version of the Unity UI Extensions is compatible with the following version
|-|-| |-|-|
|July 9th, 2020|2019.4 (v2.2) released, first UPM deployment live | |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.| |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|

View File

@ -708,33 +708,78 @@ namespace UnityEditor.UI
go.AddComponent<Image>(); go.AddComponent<Image>();
Selection.activeGameObject = go; 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<VerticalLayoutGroup>();
go.AddComponent<ContentSizeFitter>();
go.AddComponent<ToggleGroup>();
go.AddComponent<Accordion>();
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<LayoutElement>();
go.AddComponent<AccordionElement>();
Selection.activeGameObject = go;
}
#endregion #endregion
#region Drop Down controls #region Accordion
[MenuItem("GameObject/UI/Extensions/AutoComplete ComboBox", false)] [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<VerticalLayoutGroup>();
vlg.childControlHeight = true;
vlg.childControlWidth = true;
vlg.childForceExpandHeight = false;
vlg.childForceExpandHeight = true;
var csf = go.AddComponent<ContentSizeFitter>();
csf.verticalFit = ContentSizeFitter.FitMode.PreferredSize;
go.AddComponent<ToggleGroup>();
go.AddComponent<Accordion>();
}
[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<VerticalLayoutGroup>();
vlg.childControlHeight = true;
vlg.childControlWidth = true;
vlg.childForceExpandHeight = false;
vlg.childForceExpandHeight = true;
go.AddComponent<LayoutElement>();
var accordionElement = go.AddComponent<AccordionElement>();
// Header
GameObject headergo = CreateUIObject("Header", go);
var headerLayout = headergo.AddComponent<LayoutElement>();
headerLayout.minHeight = accordionElement.MinHeight;
var headerText = headergo.AddComponent<Text>();
headerText.text = "This is an Accordion header";
// Text
GameObject textgo = CreateUIObject("Text", go);
var textText = textgo.AddComponent<Text>();
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) static public void AddAutoCompleteComboBox(MenuCommand menuCommand)
{ {
GameObject autoCompleteComboBoxRoot = CreateUIElementRoot("AutoCompleteComboBox", menuCommand, s_ThickGUIElementSize); GameObject autoCompleteComboBoxRoot = CreateUIElementRoot("AutoCompleteComboBox", menuCommand, s_ThickGUIElementSize);
@ -1208,6 +1253,14 @@ namespace UnityEditor.UI
Selection.activeGameObject = go; 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<UISquircle>();
Selection.activeGameObject = go;
}
[MenuItem("GameObject/UI/Extensions/Primitives/UI Circle", false)] [MenuItem("GameObject/UI/Extensions/Primitives/UI Circle", false)]
static public void AddUICircle(MenuCommand menuCommand) static public void AddUICircle(MenuCommand menuCommand)
{ {

@ -1 +0,0 @@
Subproject commit 8f7a9de774bcf64109a5e1362650e9f37572588f

1
Examples~ Submodule

@ -0,0 +1 @@
Subproject commit 44871685f1c817afe556c761a4bf12bff7a509ef

View File

@ -1,4 +1,5 @@
Unity UI Extensions License (BSD3) # Unity UI Extensions License (BSD3)
Copyright (c) 2019 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,

143
README.md
View File

@ -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) 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: 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") [![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: 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. 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,7 +28,7 @@ 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: 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. We have expanded where you can download the UnityPackage asset and widened the options to contribute to the project.
@ -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** All funds go to support the project, no matter the amount. **Donations in code are also extremely welcome**
@ -53,18 +58,20 @@ 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: 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") [![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 > 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
> >
@ -74,66 +81,77 @@ It's been a long year since the last official release of the Unity UI Extensions
### New / updated features ### New / updated features
* New UPM deployment for Unity 2019, 2018 will still need to use the asset packages due to Unity compatibility issues. * Add squircle primitive
* Updated the project to the new Unity packaging guidelines, including separating out the examples to a separate package. * Adding new magnetic scroll control
* Many line drawing updates, including the ability to draw using a mouse (check the examples) * Added a static library to collate shaders on first use.
* Scroll Snaps (HSS/VSS) now have a "Hard Swipe" feature to restrict movement to a single page for each swipe * 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.
* Scroll Snaps have also been updated to work better with the UIInfiniteScroll control * Examples now included with UPM delivery and available as a button on the UPM package manager window
* New Unity Card UI controls thanks to @RyanslikeSoCool * Updated DropDown and Autocomplete controls based on feedback in #204
* Update to the Fancy Scroll controls with even more added fanciness * Updated Accordion to support both Vertical as well as Horizontal layout
* Several updates to adopt newer Unity standards in the controls to ensure full forwards and backwards compatibility * 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 / Examples / Examples
Examples now have their own package, this simplifies their use and deployment. Especially in 2019 with the UPM deployment. 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 UI Knob examples
* New Card UI Examples to supplement the new controls * New Magnetic Scroll Example
* New Infinite Scroll Snap example * Updated ComboBox examples for programmatic testing
* Fancy Scroll view updated with 2 new examples
* New particle system example, demonstrating programmatic control of the particle system
### Fixes ### Fixes
* Mouse position use updated in * Fix to add a "RequireComponent" to Primitives as Unity 2020 does not add them by default
- RadialSlider * Remove old Examples submodule
- ColorSampler * Updated submodules to hide Examples folder Additionally, updated Package manifest to allow importing of examples direct from UPM package.
- TiltWindow * Fixed hard swipe to ensure it only ever moves one page, no matter how far you swipe.
* Check compiler warnings (#197) * Fixed a conflict when using the ScrollConflictManager in child content of a HSS or VSS
* Line Renderer click to add lines (#183) * Fix for UI Particle system looping
* ScrollSnap Swiping options - hard fast swipe (#176) * Fixed public GoToScreen call to only raise events internally (not multiple)
* Shader Loading issue / UIParticleSystem (#229) * Final roll-up and fix. Resolved race condition for associated pagination controls.
* Issue where Menu Prefabs would be disabled instead of their Clones (#210) * Fixed issue with page events not being raised when inertia was disabled (velocity was always zero)
* Check ScrollSnapBase update (#265) * 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
* UIInfiniteScroller support for VSS updated and fixes * Reorderable list items marked as transferable, remain transferable after being dropped
* Fix to allow radial slider to start from positions other than left * Patch to resolve issues without the new Input System installed
* Fix UI Particles: Texture sheet animation + Random row(#256) * Refined magnetic scroll and dependencies while documenting Updated example
* Fix for wandering ScrollSnap controls due to Local Positioning drift * Patch Tooltip
* Divide By Zero fix for Gradient (#58)
### Known issues ### Known issues
No new issues in this release, but check the issues list for things we are currently working on: 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) * [UI Extensions Issue log](https://bitbucket.org/UnityUIExtensions/unity-ui-extensions/issues?status=new&status=open)
## Upgrade Notes ## 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 ## Release History
For the full release history, follow the below link to the full release notes page. 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) ### [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: 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) > ## [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) |
@ -168,31 +186,20 @@ NicerOutline|RaycastMask|UIFlippable|UIImageCrop|SoftAlphaMask
CylinderText|UIParticleSystem|CurlyUI|Shine Effect|Shader Effects 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)||||| [Additional Components](https://bitbucket.org/UnityUIExtensions/unity-ui-extensions/wiki/Controls#markdown-header-additional_components)|||||
------|------|------|------| ------|------|------|------|
ReturnKeyTrigger|TabNavigation|uGUITools|ScrollRectTweener|ScrollRectLinker ReturnKeyTrigger|TabNavigation|uGUITools|ScrollRectTweener|ScrollRectLinker
ScrollRectEx|UI_InfiniteScroll|UI_ScrollRectOcclusion|UIScrollToSelection|UISelectableExtension ScrollRectEx|UI_InfiniteScroll|UI_ScrollRectOcclusion|UIScrollToSelection|UISelectableExtension
switchToRectTransform|ScrollConflictManager|CLFZ2 (Encryption)|DragCorrector|PPIViewer switchToRectTransform|ScrollConflictManager|CLFZ2 (Encryption)|DragCorrector|PPIViewer
UI_TweenScale|UI_InfiniteScroll|UI_ScrollRectOcclusion|NonDrawingGraphic|UILineConnector UI_TweenScale|UI_MagneticInfiniteScroll|UI_ScrollRectOcclusion|NonDrawingGraphic|
UIHighlightable|Menu Manager|Pagination Manager|| UILineConnector|UIHighlightable|Menu Manager|Pagination Manager|
|||| ||||
*More to come* *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: 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. 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. 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) 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 * 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) * (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 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. 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. 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. 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. Please see the [full downloads list](https://bitbucket.org/UnityUIExtensions/unity-ui-extensions/wiki/Downloads) for all previous releases and their corresponding download links.

View File

@ -4,10 +4,13 @@
namespace UnityEngine.UI.Extensions namespace UnityEngine.UI.Extensions
{ {
[RequireComponent(typeof(VerticalLayoutGroup), typeof(ContentSizeFitter), typeof(ToggleGroup))] [RequireComponent(typeof(HorizontalOrVerticalLayoutGroup), typeof(ContentSizeFitter), typeof(ToggleGroup))]
[AddComponentMenu("UI/Extensions/Accordion/Accordion Group")] [AddComponentMenu("UI/Extensions/Accordion/Accordion Group")]
public class Accordion : MonoBehaviour public class Accordion : MonoBehaviour
{ {
private bool m_expandVertical = true;
[HideInInspector]
public bool ExpandVerticval => m_expandVertical;
public enum Transition public enum Transition
{ {
@ -37,5 +40,22 @@ namespace UnityEngine.UI.Extensions
get { return this.m_TransitionDuration; } get { return this.m_TransitionDuration; }
set { this.m_TransitionDuration = value; } set { this.m_TransitionDuration = value; }
} }
private void Awake()
{
m_expandVertical = GetComponent<HorizontalLayoutGroup>() ? false : true;
var group = GetComponent<ToggleGroup>();
}
#if UNITY_EDITOR
private void OnValidate()
{
if (!GetComponent<HorizontalLayoutGroup>() && !GetComponent<VerticalLayoutGroup>())
{
Debug.LogError("Accordion requires either a Horizontal or Vertical Layout group to place children");
}
}
#endif
} }
} }

View File

@ -13,6 +13,12 @@ namespace UnityEngine.UI.Extensions
[SerializeField] private float m_MinHeight = 18f; [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 Accordion m_Accordion;
private RectTransform m_RectTransform; private RectTransform m_RectTransform;
private LayoutElement m_LayoutElement; private LayoutElement m_LayoutElement;
@ -43,6 +49,7 @@ namespace UnityEngine.UI.Extensions
protected override void OnValidate() protected override void OnValidate()
{ {
base.OnValidate(); base.OnValidate();
this.m_Accordion = this.gameObject.GetComponentInParent<Accordion>();
if (this.group == null) if (this.group == null)
{ {
@ -60,11 +67,26 @@ namespace UnityEngine.UI.Extensions
{ {
if (this.isOn) if (this.isOn)
{ {
le.preferredHeight = -1f; if (m_Accordion.ExpandVerticval)
{
le.preferredHeight = -1f;
}
else
{
le.preferredWidth = -1f;
}
} }
else 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) if (state)
{ {
this.m_LayoutElement.preferredHeight = -1f; if (m_Accordion.ExpandVerticval)
{
this.m_LayoutElement.preferredHeight = -1f;
}
else
{
this.m_LayoutElement.preferredWidth = -1f;
}
} }
else 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) else if (transition == Accordion.Transition.Tween)
{ {
if (state) 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 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);
}
} }
} }
} }
@ -114,6 +164,19 @@ namespace UnityEngine.UI.Extensions
return h; 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) protected void StartTween(float startFloat, float targetFloat)
{ {
float duration = (this.m_Accordion != null) ? this.m_Accordion.transitionDuration : 0.3f; float duration = (this.m_Accordion != null) ? this.m_Accordion.transitionDuration : 0.3f;
@ -124,7 +187,14 @@ namespace UnityEngine.UI.Extensions
startFloat = startFloat, startFloat = startFloat,
targetFloat = targetFloat targetFloat = targetFloat
}; };
info.AddOnChangedCallback(SetHeight); if (m_Accordion.ExpandVerticval)
{
info.AddOnChangedCallback(SetHeight);
}
else
{
info.AddOnChangedCallback(SetWidth);
}
info.ignoreTimeScale = true; info.ignoreTimeScale = true;
this.m_FloatTweenRunner.StartTween(info); this.m_FloatTweenRunner.StartTween(info);
} }
@ -136,5 +206,13 @@ namespace UnityEngine.UI.Extensions
this.m_LayoutElement.preferredHeight = height; this.m_LayoutElement.preferredHeight = height;
} }
protected void SetWidth(float width)
{
if (this.m_LayoutElement == null)
return;
this.m_LayoutElement.preferredWidth = width;
}
} }
} }

View File

@ -95,8 +95,10 @@ namespace UnityEngine.UI.Extensions
} }
} }
//TODO design as foldout for Inspector public float DropdownOffset = 10f;
public Color ValidSelectionTextColor = Color.green;
//TODO design as foldout for Inspector
public Color ValidSelectionTextColor = Color.green;
public Color MatchingItemsRemainingTextColor = Color.black; public Color MatchingItemsRemainingTextColor = Color.black;
public Color NoItemsRemainingTextColor = Color.red; public Color NoItemsRemainingTextColor = Color.red;
@ -184,45 +186,61 @@ namespace UnityEngine.UI.Extensions
return success; return success;
} }
/* currently just using items in the list instead of being able to add to it. public void AddItem(string item)
public void AddItems(params object[] list)
{ {
List<DropDownListItem> ddItems = new List<DropDownListItem>(); AvailableOptions.Add(item);
foreach (var obj in list) RebuildPanel();
{ }
if (obj is DropDownListItem)
{ public void RemoveItem(string item)
ddItems.Add((DropDownListItem)obj); {
} AvailableOptions.Remove(item);
else if (obj is string) RebuildPanel();
{ }
ddItems.Add(new DropDownListItem(caption: (string)obj));
} public void SetAvailableOptions(List<string> newOptions)
else if (obj is Sprite) {
{ AvailableOptions.Clear();
ddItems.Add(new DropDownListItem(image: (Sprite)obj)); AvailableOptions = newOptions;
} RebuildPanel();
else }
{
throw new System.Exception("Only ComboBoxItems, Strings, and Sprite types are allowed"); public void SetAvailableOptions(string[] newOptions)
} {
} AvailableOptions.Clear();
Items.AddRange(ddItems);
Items = Items.Distinct().ToList();//remove any duplicates for (int i = 0; i < newOptions.Length; i++)
{
AvailableOptions.Add(newOptions[i]);
}
RebuildPanel();
}
public void ResetItems()
{
AvailableOptions.Clear();
RebuildPanel(); RebuildPanel();
} }
*/
/// <summary> /// <summary>
/// Rebuilds the contents of the panel in response to items being added. /// Rebuilds the contents of the panel in response to items being added.
/// </summary> /// </summary>
private void RebuildPanel() private void RebuildPanel()
{ {
if (_isPanelActive) ToggleDropdownPanel();
//panel starts with all options //panel starts with all options
_panelItems.Clear(); _panelItems.Clear();
_prunedPanelItems.Clear(); _prunedPanelItems.Clear();
panelObjects.Clear(); panelObjects.Clear();
//clear Autocomplete children in scene
foreach (Transform child in _itemsPanelRT.transform)
{
Destroy(child.gameObject);
}
foreach (string option in AvailableOptions) foreach (string option in AvailableOptions)
{ {
_panelItems.Add(option.ToLower()); _panelItems.Add(option.ToLower());
@ -326,7 +344,7 @@ namespace UnityEngine.UI.Extensions
if (_panelItems.Count < 1) return; 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.Vertical, dropdownHeight);
_scrollPanelRT.SetSizeWithCurrentAnchors(RectTransform.Axis.Horizontal, _rectTransform.sizeDelta.x); _scrollPanelRT.SetSizeWithCurrentAnchors(RectTransform.Axis.Horizontal, _rectTransform.sizeDelta.x);
@ -387,7 +405,7 @@ namespace UnityEngine.UI.Extensions
/// Toggle the drop down list /// Toggle the drop down list
/// </summary> /// </summary>
/// <param name="directClick"> whether an item was directly clicked on</param> /// <param name="directClick"> whether an item was directly clicked on</param>
public void ToggleDropdownPanel(bool directClick) public void ToggleDropdownPanel(bool directClick = false)
{ {
_isPanelActive = !_isPanelActive; _isPanelActive = !_isPanelActive;

View File

@ -21,6 +21,9 @@ namespace UnityEngine.UI.Extensions
[SerializeField] [SerializeField]
private int _itemsToDisplay; private int _itemsToDisplay;
[SerializeField]
private bool _sortItems = true;
[System.Serializable] [System.Serializable]
public class SelectionChangedEvent : UnityEngine.Events.UnityEvent<string> public class SelectionChangedEvent : UnityEngine.Events.UnityEvent<string>
{ {
@ -131,34 +134,41 @@ namespace UnityEngine.UI.Extensions
return success; return success;
} }
/* currently just using items in the list instead of being able to add to it. public void AddItem(string item)
public void AddItems(params object[] list)
{ {
List<DropDownListItem> ddItems = new List<DropDownListItem>(); AvailableOptions.Add(item);
foreach (var obj in list) RebuildPanel();
{ }
if (obj is DropDownListItem)
{ public void RemoveItem(string item)
ddItems.Add((DropDownListItem)obj); {
} AvailableOptions.Remove(item);
else if (obj is string) RebuildPanel();
{ }
ddItems.Add(new DropDownListItem(caption: (string)obj));
} public void SetAvailableOptions(List<string> newOptions)
else if (obj is Sprite) {
{ AvailableOptions.Clear();
ddItems.Add(new DropDownListItem(image: (Sprite)obj)); AvailableOptions = newOptions;
} RebuildPanel();
else }
{
throw new System.Exception("Only ComboBoxItems, Strings, and Sprite types are allowed"); public void SetAvailableOptions(string[] newOptions)
} {
} AvailableOptions.Clear();
Items.AddRange(ddItems);
Items = Items.Distinct().ToList();//remove any duplicates for (int i = 0; i < newOptions.Length; i++)
{
AvailableOptions.Add(newOptions[i]);
}
RebuildPanel();
}
public void ResetItems()
{
AvailableOptions.Clear();
RebuildPanel(); RebuildPanel();
} }
*/
/// <summary> /// <summary>
/// Rebuilds the contents of the panel in response to items being added. /// 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.Add(option.ToLower());
} }
_panelItems.Sort(); if(_sortItems) _panelItems.Sort();
List<GameObject> itemObjs = new List<GameObject>(panelObjects.Values); List<GameObject> itemObjs = new List<GameObject>(panelObjects.Values);
panelObjects.Clear(); panelObjects.Clear();

View File

@ -133,9 +133,17 @@ namespace UnityEngine.UI.Extensions
return success; return success;
} }
/* currently just using items in the list instead of being able to add to it. // currently just using items in the list instead of being able to add to it.
public void AddItems(params object[] list) /// <summary>
/// Rebuilds the list from a new collection.
/// </summary>
/// <remarks>
/// NOTE, this will clear all existing items
/// </remarks>
/// <param name="list"></param>
public void RefreshItems(params object[] list)
{ {
Items.Clear();
List<DropDownListItem> ddItems = new List<DropDownListItem>(); List<DropDownListItem> ddItems = new List<DropDownListItem>();
foreach (var obj in list) foreach (var obj in list)
{ {
@ -157,10 +165,74 @@ namespace UnityEngine.UI.Extensions
} }
} }
Items.AddRange(ddItems); Items.AddRange(ddItems);
Items = Items.Distinct().ToList();//remove any duplicates
RebuildPanel(); RebuildPanel();
} }
*/
/// <summary>
/// Adds an additional item to the drop down list (recommended)
/// </summary>
/// <param name="item">Item of type DropDownListItem</param>
public void AddItem(DropDownListItem item)
{
Items.Add(item);
RebuildPanel();
}
/// <summary>
/// Adds an additional drop down list item using a string name
/// </summary>
/// <param name="item">Item of type String</param>
public void AddItem(string item)
{
Items.Add(new DropDownListItem(caption: (string)item));
RebuildPanel();
}
/// <summary>
/// Adds an additional drop down list item using a sprite image
/// </summary>
/// <param name="item">Item of type UI Sprite</param>
public void AddItem(Sprite item)
{
Items.Add(new DropDownListItem(image: (Sprite)item));
RebuildPanel();
}
/// <summary>
/// Removes an item from the drop down list (recommended)
/// </summary>
/// <param name="item">Item of type DropDownListItem</param>
public void RemoveItem(DropDownListItem item)
{
Items.Remove(item);
RebuildPanel();
}
/// <summary>
/// Removes an item from the drop down list item using a string name
/// </summary>
/// <param name="item">Item of type String</param>
public void RemoveItem(string item)
{
Items.Remove(new DropDownListItem(caption: (string)item));
RebuildPanel();
}
/// <summary>
/// Removes an item from the drop down list item using a sprite image
/// </summary>
/// <param name="item">Item of type UI Sprite</param>
public void RemoveItem(Sprite item)
{
Items.Remove(new DropDownListItem(image: (Sprite)item));
RebuildPanel();
}
public void ResetItems()
{
Items.Clear();
RebuildPanel();
}
/// <summary> /// <summary>
/// Rebuilds the contents of the panel in response to items being added. /// Rebuilds the contents of the panel in response to items being added.

View File

@ -26,7 +26,7 @@ namespace UnityEngine.UI.Extensions
void Update() void Update()
{ {
// Check if the "Enter" key was just released with the chat input not focused // 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 we need to ignore the keypress, do nothing - otherwise activate the input field
if (_ignoreNextActivation) if (_ignoreNextActivation)
@ -60,7 +60,7 @@ namespace UnityEngine.UI.Extensions
public void OnEndEdit(string textString) public void OnEndEdit(string textString)
{ {
// If the edit ended because we clicked away, don't do anything extra // If the edit ended because we clicked away, don't do anything extra
if (!Input.GetKeyDown(KeyCode.Return)) if (!UIExtensionsInputManager.GetKeyDown(KeyCode.Return))
{ {
return; return;
} }

View File

@ -89,8 +89,7 @@ namespace UnityEngine.UI.Extensions
/// </summary> /// </summary>
public void Refresh() public void Refresh()
{ {
Destroy(_listContent); _listContent = ContentLayout.gameObject.GetOrAddComponent<ReorderableListContent>();
_listContent = ContentLayout.gameObject.AddComponent<ReorderableListContent>();
_listContent.Init(this); _listContent.Init(this);
} }

View File

@ -6,6 +6,7 @@ using System.Collections.Generic;
namespace UnityEngine.UI.Extensions namespace UnityEngine.UI.Extensions
{ {
[DisallowMultipleComponent]
public class ReorderableListContent : MonoBehaviour public class ReorderableListContent : MonoBehaviour
{ {
private List<Transform> _cachedChildren; private List<Transform> _cachedChildren;
@ -13,6 +14,7 @@ namespace UnityEngine.UI.Extensions
private ReorderableListElement _ele; private ReorderableListElement _ele;
private ReorderableList _extList; private ReorderableList _extList;
private RectTransform _rect; private RectTransform _rect;
private bool _started = false;
private void OnEnable() private void OnEnable()
{ {
@ -27,12 +29,15 @@ namespace UnityEngine.UI.Extensions
public void Init(ReorderableList extList) public void Init(ReorderableList extList)
{ {
if (_started) { StopCoroutine(RefreshChildren()); }
_extList = extList; _extList = extList;
_rect = GetComponent<RectTransform>(); _rect = GetComponent<RectTransform>();
_cachedChildren = new List<Transform>(); _cachedChildren = new List<Transform>();
_cachedListElement = new List<ReorderableListElement>(); _cachedListElement = new List<ReorderableListElement>();
StartCoroutine(RefreshChildren()); StartCoroutine(RefreshChildren());
_started = true;
} }
private IEnumerator RefreshChildren() private IEnumerator RefreshChildren()

View File

@ -23,7 +23,7 @@ namespace UnityEngine.UI.Extensions
if (droppedStruct.IsAClone) if (droppedStruct.IsAClone)
DebugLabel.text += "Source Object: " + droppedStruct.SourceObject.name + "\n"; 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("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);
} }
} }
} }

View File

@ -13,12 +13,28 @@ namespace UnityEngine.UI.Extensions
public class ReorderableListElement : MonoBehaviour, IDragHandler, IBeginDragHandler, IEndDragHandler public class ReorderableListElement : MonoBehaviour, IDragHandler, IBeginDragHandler, IEndDragHandler
{ {
[Tooltip("Can this element be dragged?")] [Tooltip("Can this element be dragged?")]
public bool IsGrabbable = true; [SerializeField]
[Tooltip("Can this element be transfered to another list")] private bool IsGrabbable = true;
public bool IsTransferable = true;
[Tooltip("Can this element be dropped in space?")]
public bool isDroppableInSpace = false;
[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>();
_canvasGroup.blocksRaycasts = value;
_isTransferable = value;
}
}
private readonly List<RaycastResult> _raycastResults = new List<RaycastResult>(); private readonly List<RaycastResult> _raycastResults = new List<RaycastResult>();
private ReorderableList _currentReorderableListRaycasted; private ReorderableList _currentReorderableListRaycasted;
@ -48,6 +64,7 @@ namespace UnityEngine.UI.Extensions
public void OnBeginDrag(PointerEventData eventData) public void OnBeginDrag(PointerEventData eventData)
{ {
if (!_canvasGroup) { _canvasGroup = gameObject.GetOrAddComponent<CanvasGroup>(); }
_canvasGroup.blocksRaycasts = false; _canvasGroup.blocksRaycasts = false;
isValid = true; isValid = true;
if (_reorderableList == null) 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 nothing found or the list is not dropable, put the fake element outside
if (_currentReorderableListRaycasted == null || _currentReorderableListRaycasted.IsDropable == false if (_currentReorderableListRaycasted == null || _currentReorderableListRaycasted.IsDropable == false
|| (_oldReorderableListRaycasted != _reorderableList && !IsTransferable) // || (_oldReorderableListRaycasted != _reorderableList && !IsTransferable)
|| ((_fakeElement.parent == _currentReorderableListRaycasted.Content || ((_fakeElement.parent == _currentReorderableListRaycasted.Content
? _currentReorderableListRaycasted.Content.childCount - 1 ? _currentReorderableListRaycasted.Content.childCount - 1
: _currentReorderableListRaycasted.Content.childCount) >= _currentReorderableListRaycasted.maxItems && !_currentReorderableListRaycasted.IsDisplacable) : _currentReorderableListRaycasted.Content.childCount) >= _currentReorderableListRaycasted.maxItems && !_currentReorderableListRaycasted.IsDisplacable)
@ -378,13 +395,19 @@ namespace UnityEngine.UI.Extensions
_draggingObject.SetParent(_currentReorderableListRaycasted.Content, false); _draggingObject.SetParent(_currentReorderableListRaycasted.Content, false);
_draggingObject.rotation = _currentReorderableListRaycasted.transform.rotation; _draggingObject.rotation = _currentReorderableListRaycasted.transform.rotation;
_draggingObject.SetSiblingIndex(_fakeElement.GetSiblingIndex()); _draggingObject.SetSiblingIndex(_fakeElement.GetSiblingIndex());
//If the item is transferable, it can be dragged out again
if (IsTransferable)
{
var cg = _draggingObject.GetComponent<CanvasGroup>();
cg.blocksRaycasts = true;
}
// Force refreshing both lists because otherwise we get inappropriate FromList in ReorderableListEventStruct // Force refreshing both lists because otherwise we get inappropriate FromList in ReorderableListEventStruct
_reorderableList.Refresh(); _reorderableList.Refresh();
_currentReorderableListRaycasted.Refresh(); _currentReorderableListRaycasted.Refresh();
_reorderableList.OnElementAdded.Invoke(args); _reorderableList.OnElementAdded.Invoke(args);
if (_displacedObject != null) if (_displacedObject != null)
{ {
finishDisplacingElement(); finishDisplacingElement();

View File

@ -147,14 +147,14 @@ namespace UnityEngine.UI.Extensions
void BeginSelection(){ void BeginSelection(){
// Click somewhere in the Game View. // Click somewhere in the Game View.
if (!Input.GetMouseButtonDown(0)) if (!UIExtensionsInputManager.GetMouseButtonDown(0))
return; return;
//The boxRect will be inactive up until the point we start selecting //The boxRect will be inactive up until the point we start selecting
boxRect.gameObject.SetActive(true); boxRect.gameObject.SetActive(true);
// Get the initial click position of the mouse. // 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 the initial click point is not inside the selection mask, we abort the selection
if (!PointIsValidAgainstSelectionMask(origin)) { if (!PointIsValidAgainstSelectionMask(origin)) {
@ -185,7 +185,7 @@ namespace UnityEngine.UI.Extensions
selectableList.Add (selectable); 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 //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; selectable.selected = false;
} }
} }
@ -211,7 +211,7 @@ namespace UnityEngine.UI.Extensions
IBoxSelectable GetSelectableAtMousePosition() { IBoxSelectable GetSelectableAtMousePosition() {
//Firstly, we cannot click on something that is not inside the selection mask (if we have one) //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; 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 //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. //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 //And if it does, we select it and send it back
return selectable; return selectable;
@ -240,7 +240,7 @@ namespace UnityEngine.UI.Extensions
var selectableScreenPoint = GetScreenPointOfSelectable(selectable); var selectableScreenPoint = GetScreenPointOfSelectable(selectable);
//Check that the click fits within the screen-radius of the 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 //And if it does, we select it and send it back
return selectable; return selectable;
@ -255,11 +255,11 @@ namespace UnityEngine.UI.Extensions
void DragSelection(){ void DragSelection(){
//Return if we're not dragging or if the selection has been aborted (BoxRect disabled) //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; return;
// Store the current mouse position in screen space. // 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? // How far have we moved the mouse?
Vector2 difference = currentMousePosition - origin; Vector2 difference = currentMousePosition - origin;
@ -414,7 +414,7 @@ namespace UnityEngine.UI.Extensions
void EndSelection(){ void EndSelection(){
//Get out if we haven't finished selecting, or if the selection has been aborted (boxRect disabled) //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; return;
clickedAfterDrag = GetSelectableAtMousePosition(); clickedAfterDrag = GetSelectableAtMousePosition();

View File

@ -1,6 +1,7 @@
/// Credit Tomasz Schelenz /// Credit Tomasz Schelenz
/// Sourced from - https://bitbucket.org/SimonDarksideJ/unity-ui-extensions/issues/46/feature-uiknob#comment-29243988 /// Sourced from - https://bitbucket.org/SimonDarksideJ/unity-ui-extensions/issues/46/feature-uiknob#comment-29243988
using System;
using UnityEngine.Events; using UnityEngine.Events;
using UnityEngine.EventSystems; using UnityEngine.EventSystems;
@ -31,17 +32,21 @@ namespace UnityEngine.UI.Extensions
[Tooltip("Direction of rotation CW - clockwise, CCW - counterClockwise")] [Tooltip("Direction of rotation CW - clockwise, CCW - counterClockwise")]
public Direction direction = Direction.CW; public Direction direction = Direction.CW;
[HideInInspector] [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")] [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")] [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")] [Tooltip("Clamp output value between 0 and 1, useful with loops > 1")]
public bool clampOutput01 = false; public bool ClampOutput01 = false;
[Tooltip("snap to position?")] [Tooltip("snap to position?")]
public bool snapToPosition = false; public bool SnapToPosition = false;
[Tooltip("Number of positions to snap")] [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)] [Space(30)]
public KnobFloatValueEvent OnValueChanged; public KnobFloatValueEvent OnValueChanged;
private float _currentLoops = 0; private float _currentLoops = 0;
@ -55,7 +60,48 @@ namespace UnityEngine.UI.Extensions
protected override void Awake() protected override void Awake()
{ {
_screenSpaceOverlay = GetComponentInParent<Canvas>().rootCanvas.renderMode == RenderMode.ScreenSpaceOverlay; _screenSpaceOverlay = GetComponentInParent<Canvas>().rootCanvas.renderMode == RenderMode.ScreenSpaceOverlay;
}
protected override void Start()
{
CheckForParentTouchMask();
}
private void CheckForParentTouchMask()
{
if (ParentTouchMask)
{
Image maskImage = ParentTouchMask.gameObject.GetOrAddComponent<Image>();
maskImage.color = MaskBackground;
EventTrigger trigger = ParentTouchMask.gameObject.GetOrAddComponent<EventTrigger>();
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) public override void OnPointerUp(PointerEventData eventData)
@ -71,7 +117,6 @@ namespace UnityEngine.UI.Extensions
_canDrag = false; _canDrag = false;
} }
public override void OnPointerDown(PointerEventData eventData) public override void OnPointerDown(PointerEventData eventData)
{ {
_canDrag = true; _canDrag = true;
@ -115,83 +160,117 @@ namespace UnityEngine.UI.Extensions
if (direction == Direction.CW) if (direction == Direction.CW)
{ {
knobValue = 1 - (finalRotation.eulerAngles.z / 360f); KnobValue = 1 - (finalRotation.eulerAngles.z / 360f);
if (snapToPosition) if (SnapToPosition)
{ {
SnapToPosition(ref knobValue); SnapToPositionValue(ref KnobValue);
finalRotation.eulerAngles = new Vector3(0, 0, 360 - 360 * knobValue); finalRotation.eulerAngles = new Vector3(0, 0, 360 - 360 * KnobValue);
} }
} }
else else
{ {
knobValue = (finalRotation.eulerAngles.z / 360f); KnobValue = (finalRotation.eulerAngles.z / 360f);
if (snapToPosition) if (SnapToPosition)
{ {
SnapToPosition(ref knobValue); SnapToPositionValue(ref KnobValue);
finalRotation.eulerAngles = new Vector3(0, 0, 360 * knobValue); finalRotation.eulerAngles = new Vector3(0, 0, 360 * KnobValue);
} }
} }
UpdateKnobValue();
transform.rotation = finalRotation;
InvokeEvents(KnobValue + _currentLoops);
_previousValue = KnobValue;
}
private void UpdateKnobValue()
{
//PREVENT OVERROTATION //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++; _currentLoops++;
} }
else if (knobValue > 0.5f && _currentLoops >= 1) else if (KnobValue > 0.5f && _currentLoops >= 1)
{ {
_currentLoops--; _currentLoops--;
} }
else else
{ {
if (knobValue > 0.5f && _currentLoops == 0) if (KnobValue > 0.5f && _currentLoops == 0)
{ {
knobValue = 0; KnobValue = 0;
transform.localEulerAngles = Vector3.zero; transform.localEulerAngles = Vector3.zero;
InvokeEvents(knobValue + _currentLoops); InvokeEvents(KnobValue + _currentLoops);
return; 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; transform.localEulerAngles = Vector3.zero;
InvokeEvents(knobValue + _currentLoops); InvokeEvents(KnobValue + _currentLoops);
return; return;
} }
} }
} }
//CHECK MAX VALUE //CHECK MAX VALUE
if (maxValue > 0) if (MaxValue > 0)
{ {
if (knobValue + _currentLoops > maxValue) if (KnobValue + _currentLoops > MaxValue)
{ {
knobValue = maxValue; KnobValue = MaxValue;
float maxAngle = direction == Direction.CW ? 360f - 360f * maxValue : 360f * maxValue; float maxAngle = direction == Direction.CW ? 360f - 360f * MaxValue : 360f * MaxValue;
transform.localEulerAngles = new Vector3(0, 0, maxAngle); transform.localEulerAngles = new Vector3(0, 0, maxAngle);
InvokeEvents(knobValue); InvokeEvents(KnobValue);
return; 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; float newValue = Mathf.Round(knobValue / snapStep) * snapStep;
knobValue = newValue; knobValue = newValue;
} }
private void InvokeEvents(float value) private void InvokeEvents(float value)
{ {
if (clampOutput01) if (ClampOutput01)
value /= loops; value /= Loops;
OnValueChanged.Invoke(value); OnValueChanged.Invoke(value);
} }

View File

@ -25,7 +25,7 @@ namespace UnityEngine.UI.Extensions
if (mGraphic.material == null || mGraphic.material.name == "Default UI Material") if (mGraphic.material == null || mGraphic.material.name == "Default UI Material")
{ {
//Applying default material with UI Image Crop shader //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 else

View File

@ -32,7 +32,7 @@ namespace UnityEngine.UI.Extensions
if (mGraphic.material == null || mGraphic.material.name == "Default UI Material") if (mGraphic.material == null || mGraphic.material.name == "Default UI Material")
{ {
//Applying default material with UI Image Crop shader //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; mat = mGraphic.material;
} }

View File

@ -25,7 +25,7 @@ namespace UnityEngine.UI.Extensions
if (mGraphic.material == null || mGraphic.material.name == "Default UI Material") if (mGraphic.material == null || mGraphic.material.name == "Default UI Material")
{ {
//Applying default material with UI Image Crop shader //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 else

View File

@ -25,7 +25,7 @@ namespace UnityEngine.UI.Extensions
if (mGraphic.material == null || mGraphic.material.name == "Default UI Material") if (mGraphic.material == null || mGraphic.material.name == "Default UI Material")
{ {
//Applying default material with UI Image Crop shader //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 else

View File

@ -25,7 +25,7 @@ namespace UnityEngine.UI.Extensions
if (mGraphic.material == null || mGraphic.material.name == "Default UI Material") if (mGraphic.material == null || mGraphic.material.name == "Default UI Material")
{ {
//Applying default material with UI Image Crop shader //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 else

View File

@ -25,7 +25,7 @@ namespace UnityEngine.UI.Extensions
if (mGraphic.material == null || mGraphic.material.name == "Default UI Material") if (mGraphic.material == null || mGraphic.material.name == "Default UI Material")
{ {
//Applying default material with UI Image Crop shader //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 else

View File

@ -48,7 +48,7 @@ namespace UnityEngine.UI.Extensions
var text = GetComponent<Text>(); var text = GetComponent<Text>();
if (text != null) if (text != null)
{ {
mat = new Material(Shader.Find("UI Extensions/SoftMaskShader")); mat = new Material(ShaderLibrary.GetShaderInstance("UI Extensions/SoftMaskShader"));
text.material = mat; text.material = mat;
cachedCanvas = text.canvas; cachedCanvas = text.canvas;
cachedCanvasTransform = cachedCanvas.transform; cachedCanvasTransform = cachedCanvas.transform;
@ -64,7 +64,7 @@ namespace UnityEngine.UI.Extensions
var graphic = GetComponent<Graphic>(); var graphic = GetComponent<Graphic>();
if (graphic != null) if (graphic != null)
{ {
mat = new Material(Shader.Find("UI Extensions/SoftMaskShader")); mat = new Material(ShaderLibrary.GetShaderInstance("UI Extensions/SoftMaskShader"));
graphic.material = mat; graphic.material = mat;
cachedCanvas = graphic.canvas; cachedCanvas = graphic.canvas;
cachedCanvasTransform = cachedCanvas.transform; cachedCanvasTransform = cachedCanvas.transform;

View File

@ -76,7 +76,7 @@ namespace UnityEngine.UI.Extensions
if (material == null) if (material == null)
{ {
var foundShader = Shader.Find("UI Extensions/Particles/Additive"); var foundShader = ShaderLibrary.GetShaderInstance("UI Extensions/Particles/Additive");
if (foundShader) if (foundShader)
{ {
material = new Material(foundShader); material = new Material(foundShader);
@ -223,9 +223,14 @@ namespace UnityEngine.UI.Extensions
frame = Mathf.FloorToInt(frameProgress * textureSheetAnimation.numTilesX); frame = Mathf.FloorToInt(frameProgress * textureSheetAnimation.numTilesX);
int row = textureSheetAnimation.rowIndex; int row = textureSheetAnimation.rowIndex;
// if (textureSheetAnimation.useRandomRow) { // FIXME - is this handled internally by rowIndex? #if UNITY_2020 || UNITY_2019
// row = Random.Range(0, textureSheetAnimation.numTilesY, using: particle.randomSeed); 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; frame += row * textureSheetAnimation.numTilesX;
break; break;
@ -234,7 +239,7 @@ namespace UnityEngine.UI.Extensions
frame %= textureSheetAnimationFrames; frame %= textureSheetAnimationFrames;
particleUV.x = (frame % textureSheetAnimation.numTilesX) * textureSheetAnimationFrameSize.x; 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.z = particleUV.x + textureSheetAnimationFrameSize.x;
particleUV.w = particleUV.y + textureSheetAnimationFrameSize.y; particleUV.w = particleUV.y + textureSheetAnimationFrameSize.y;
} }
@ -387,6 +392,7 @@ namespace UnityEngine.UI.Extensions
public void StartParticleEmission() public void StartParticleEmission()
{ {
pSystem.time = 0;
pSystem.Play(); pSystem.Play();
} }
@ -401,4 +407,4 @@ namespace UnityEngine.UI.Extensions
} }
} }
#endif #endif
} }

View File

@ -1,5 +0,0 @@
fileFormatVersion: 2
guid: a0789c2f62bad6b4c800a3dc502fa18e
folderAsset: yes
DefaultImporter:
userData:

View File

@ -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
{
/// <summary>
/// The Input axis name used to activate the object under the reticle.
/// </summary>
public string activateAxis = "Submit";
/// <summary>
/// The aimer offset position. Aimer is center screen use this offset to change that.
/// </summary>
public Vector2 aimerOffset = new Vector2(0, 0);
/// <summary>
/// The object under aimer. A static access field that lets you know what is under the aimer.
/// This field can return null.
/// </summary>
public static GameObject objectUnderAimer;
protected AimerInputModule() { }
public override void ActivateModule()
{
StandaloneInputModule StandAloneSystem = GetComponent<StandaloneInputModule>();
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<ISubmitHandler>(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<IPointerClickHandler>(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<IDragHandler>(currentOverGo);
if (pointer.pointerDrag != null)
ExecuteEvents.Execute<IBeginDragHandler>(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<IPointerClickHandler>(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();
}
}
}

View File

@ -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";
/// <summary>
/// Name of the vertical axis for movement (if axis events are used).
/// </summary>
[SerializeField]
private string m_VerticalAxis = "Vertical";
/// <summary>
/// Name of the submit button.
/// </summary>
[SerializeField]
private string m_SubmitButton = "Submit";
/// <summary>
/// Name of the submit button.
/// </summary>
[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; }
}
/// <summary>
/// Name of the horizontal axis for movement (if axis events are used).
/// </summary>
public string horizontalAxis
{
get { return m_HorizontalAxis; }
set { m_HorizontalAxis = value; }
}
/// <summary>
/// Name of the vertical axis for movement (if axis events are used).
/// </summary>
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<StandaloneInputModule>();
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();
}
}
/// <summary>
/// Process submit keys.
/// </summary>
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;
}
/// <summary>
/// Process events.
/// </summary>
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;
}
}
}

View File

@ -3,118 +3,121 @@
/// Sourced from - https://github.com/ryanslikesocool/Unity-Card-UI /// Sourced from - https://github.com/ryanslikesocool/Unity-Card-UI
/// </summary> /// </summary>
using System.Collections; using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
namespace UnityEngine.UI.Extensions namespace UnityEngine.UI.Extensions
{ {
public class CardStack2D : MonoBehaviour 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()
{ {
///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. [SerializeField]
///Unfortunately, it's only really useful if the cards are the same width. private float cardMoveSpeed = 8f;
if (useDefaultUsedXPos) [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<RectTransform>().rect.width); ///I've found that 9 is a good number for this.
usedCardXPos = (int)(Screen.width * 0.5f + cardWidth); ///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 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.
///This loop is for cards still in the stack. if (useDefaultUsedXPos)
for (int i = cards.Length; i > -1; i--)
{
if (i < cards.Length - 1)
{ {
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<RectTransform>().rect.width);
usedCardXPos = (int)(Screen.width * 0.5f + cardWidth);
} }
else
{
cardPositions[i] = Vector3.zero;
}
}
///This loop is for cards outside of the stack. cardPositions = new Vector3[cards.Length * 2 - 1];
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() ///This loop is for cards still in the stack.
{ for (int i = cards.Length; i > -1; i--)
if (canUseHorizontalAxis)
{
///Controls for the cards.
if (Input.GetAxisRaw("Horizontal") < 0 && cardArrayOffset > 0)
{ {
cardArrayOffset--; if (i < cards.Length - 1)
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)
{ {
cards[i].gameObject.GetComponent<CanvasGroup>().interactable = true; cardPositions[i] = new Vector3(-Mathf.Pow(2, i + xPowerDifference) + cardPositions[i + 1].x, 0, cardZMultiplier * Mathf.Abs(i + 1 - cards.Length));
} }
else else
{ {
cards[i].gameObject.GetComponent<CanvasGroup>().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<CanvasGroup>().interactable = true;
}
else
{
cards[i].gameObject.GetComponent<CanvasGroup>().interactable = false;
}
} }
} }
} }
}
///Stops the cards from scrolling super quickly if a button on the horizontal axis is held down. ///Stops the cards from scrolling super quickly if a button on the horizontal axis is held down.
IEnumerator ButtonCooldown() IEnumerator ButtonCooldown()
{ {
canUseHorizontalAxis = false; canUseHorizontalAxis = false;
yield return new WaitForSeconds(buttonCooldownTime); yield return new WaitForSeconds(buttonCooldownTime);
canUseHorizontalAxis = true; canUseHorizontalAxis = true;
}
} }
} }
}

View File

@ -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 System.Collections.Generic;
using UnityEngine.EventSystems; using UnityEngine.EventSystems;
using UnityEngine.Events; using UnityEngine.Events;
@ -185,11 +189,60 @@ namespace UnityEngine.UI.Extensions
if (prevButton) if (prevButton)
prevButton.GetComponent<Button>().onClick.AddListener(() => { PreviousItem(); }); prevButton.GetComponent<Button>().onClick.AddListener(() => { PreviousItem(); });
SetupDrivenTransforms(); if (IsScrollRectAvailable)
SetupSnapScroll(); {
scrollRect.horizontalNormalizedPosition = 0; SetupDrivenTransforms();
_closestItem = 0; SetupSnapScroll();
GoTo(startInfo); scrollRect.horizontalNormalizedPosition = 0;
_closestItem = 0;
GoTo(startInfo);
}
}
public void SetNewItems(ref List<Transform> newItems)
{
if (scrollRect && contentTransform)
{
for (int i = scrollRect.content.childCount - 1; i >= 0; i--)
{
Transform child = contentTransform.GetChild(i);
child.SetParent(null);
GameObject.DestroyImmediate(child.gameObject);
}
foreach (Transform item in newItems)
{
GameObject newItem = item.gameObject;
if (newItem.IsPrefab())
{
newItem = Instantiate(item.gameObject, contentTransform);
}
else
{
newItem.transform.SetParent(contentTransform);
}
}
SetupDrivenTransforms();
SetupSnapScroll();
scrollRect.horizontalNormalizedPosition = 0;
_closestItem = 0;
GoTo(startInfo);
}
}
private bool IsScrollRectAvailable
{
get
{
if (scrollRect &&
contentTransform &&
contentTransform.childCount > 0)
{
return true;
}
return false;
}
} }
private void OnDisable() private void OnDisable()
@ -470,16 +523,22 @@ namespace UnityEngine.UI.Extensions
public void OnEndDrag(PointerEventData ped) public void OnEndDrag(PointerEventData ped)
{ {
StartCoroutine("SlideAndLerp"); if (IsScrollRectAvailable)
{
StartCoroutine("SlideAndLerp");
}
} }
private void Update() private void Update()
{ {
if (_closestItem != ClosestItemIndex) if (IsScrollRectAvailable)
{ {
CurrentItemChanged.Invoke(ClosestItemIndex); if (_closestItem != ClosestItemIndex)
ChangePaginationInfo(ClosestItemIndex); {
_closestItem = ClosestItemIndex; CurrentItemChanged.Invoke(ClosestItemIndex);
ChangePaginationInfo(ClosestItemIndex);
_closestItem = ClosestItemIndex;
}
} }
} }

View File

@ -12,6 +12,8 @@ namespace UnityEngine.UI.Extensions
[AddComponentMenu("Layout/Extensions/Horizontal Scroll Snap")] [AddComponentMenu("Layout/Extensions/Horizontal Scroll Snap")]
public class HorizontalScrollSnap : ScrollSnapBase public class HorizontalScrollSnap : ScrollSnapBase
{ {
private bool updated = true;
void Start() void Start()
{ {
_isVertical = false; _isVertical = false;
@ -23,7 +25,9 @@ namespace UnityEngine.UI.Extensions
void Update() void Update()
{ {
if (!_lerp && _scroll_rect.velocity == Vector2.zero) updated = false;
if (!_lerp && (_scroll_rect.velocity == Vector2.zero && _scroll_rect.inertia))
{ {
if (!_settled && !_pointerDown) if (!_settled && !_pointerDown)
{ {
@ -37,7 +41,7 @@ namespace UnityEngine.UI.Extensions
else if (_lerp) else if (_lerp)
{ {
_screensContainer.anchoredPosition = Vector3.Lerp(_screensContainer.anchoredPosition, _lerp_target, transitionSpeed * (UseTimeScale ? Time.deltaTime : Time.unscaledDeltaTime)); _screensContainer.anchoredPosition = Vector3.Lerp(_screensContainer.anchoredPosition, _lerp_target, transitionSpeed * (UseTimeScale ? Time.deltaTime : Time.unscaledDeltaTime));
if (Vector3.Distance(_screensContainer.anchoredPosition, _lerp_target) < 0.1f) if (Vector3.Distance(_screensContainer.anchoredPosition, _lerp_target) < 0.2f)
{ {
_screensContainer.anchoredPosition = _lerp_target; _screensContainer.anchoredPosition = _lerp_target;
_lerp = false; _lerp = false;
@ -45,6 +49,8 @@ namespace UnityEngine.UI.Extensions
} }
} }
if (UseHardSwipe) return;
CurrentPage = GetPageforPosition(_screensContainer.anchoredPosition); CurrentPage = GetPageforPosition(_screensContainer.anchoredPosition);
//If the container is moving check if it needs to settle on a page //If the container is moving check if it needs to settle on a page
@ -241,6 +247,14 @@ namespace UnityEngine.UI.Extensions
/// <param name="eventData"></param> /// <param name="eventData"></param>
public override void OnEndDrag(PointerEventData eventData) public override void OnEndDrag(PointerEventData eventData)
{ {
if (updated)
{
return;
}
// to prevent double dragging, only act on EndDrag once per frame
updated = true;
_pointerDown = false; _pointerDown = false;
if (_scroll_rect.horizontal) if (_scroll_rect.horizontal)

View File

@ -30,11 +30,13 @@ namespace UnityEngine.UI.Extensions
internal int _currentPage; internal int _currentPage;
internal int _previousPage; internal int _previousPage;
internal int _halfNoVisibleItems; internal int _halfNoVisibleItems;
internal bool _moveStarted;
internal bool _isInfinite; // Is a UI Infinite scroller attached to the control internal bool _isInfinite; // Is a UI Infinite scroller attached to the control
internal int _infiniteWindow; // The infinite window the control is in internal int _infiniteWindow; // The infinite window the control is in
internal float _infiniteOffset; // How much to offset a repositioning internal float _infiniteOffset; // How much to offset a repositioning
private int _bottomItem, _topItem; private int _bottomItem, _topItem;
internal bool _startEventCalled = false;
internal bool _endEventCalled = false;
internal bool _suspendEvents = false;
[Serializable] [Serializable]
public class SelectionChangeStartEvent : UnityEvent { } public class SelectionChangeStartEvent : UnityEvent { }
@ -443,14 +445,16 @@ namespace UnityEngine.UI.Extensions
private void ChangeBulletsInfo(int targetScreen) private void ChangeBulletsInfo(int targetScreen)
{ {
if (Pagination) if (Pagination)
{
for (int i = 0; i < Pagination.transform.childCount; i++) for (int i = 0; i < Pagination.transform.childCount; i++)
{ {
Pagination.transform.GetChild(i).GetComponent<Toggle>().isOn = (targetScreen == i) Pagination.transform.GetChild(i).GetComponent<Toggle>().isOn = (targetScreen == i) ? true : false;
? true
: false;
} }
}
} }
// Make a lock function for pagination, to prevent event leaking
/// <summary> /// <summary>
/// disables the page navigation buttons when at the first or last screen /// disables the page navigation buttons when at the first or last screen
/// </summary> /// </summary>
@ -531,9 +535,12 @@ namespace UnityEngine.UI.Extensions
/// </summary> /// </summary>
public void StartScreenChange() public void StartScreenChange()
{ {
if (!_moveStarted) if (!_startEventCalled)
{ {
_moveStarted = true; _suspendEvents = true;
_startEventCalled = true;
_endEventCalled = false;
OnSelectionChangeStartEvent.Invoke(); OnSelectionChangeStartEvent.Invoke();
} }
} }
@ -551,9 +558,15 @@ namespace UnityEngine.UI.Extensions
/// </summary> /// </summary>
internal void EndScreenChange() internal void EndScreenChange()
{ {
OnSelectionChangeEndEvent.Invoke(_currentPage); if (!_endEventCalled)
_settled = true; {
_moveStarted = false; _suspendEvents = false;
_endEventCalled = true;
_startEventCalled = false;
_settled = true;
OnSelectionChangeEndEvent.Invoke(_currentPage);
}
} }
/// <summary> /// <summary>

View File

@ -200,7 +200,7 @@ namespace UnityEngine.UI.Extensions
} }
if (!Input.GetMouseButton(0)) if (!UIExtensionsInputManager.GetMouseButton(0))
{ {
// scroll slowly to nearest element when not dragged // scroll slowly to nearest element when not dragged
ScrollingElements(); ScrollingElements();

View File

@ -12,6 +12,8 @@ namespace UnityEngine.UI.Extensions
[AddComponentMenu("Layout/Extensions/Vertical Scroll Snap")] [AddComponentMenu("Layout/Extensions/Vertical Scroll Snap")]
public class VerticalScrollSnap : ScrollSnapBase public class VerticalScrollSnap : ScrollSnapBase
{ {
private bool updated = true;
void Start() void Start()
{ {
_isVertical = true; _isVertical = true;
@ -23,6 +25,8 @@ namespace UnityEngine.UI.Extensions
void Update() void Update()
{ {
updated = false;
if (!_lerp && _scroll_rect.velocity == Vector2.zero) if (!_lerp && _scroll_rect.velocity == Vector2.zero)
{ {
if (!_settled && !_pointerDown) if (!_settled && !_pointerDown)
@ -45,6 +49,8 @@ namespace UnityEngine.UI.Extensions
} }
} }
if (UseHardSwipe) return;
CurrentPage = GetPageforPosition(_screensContainer.anchoredPosition); CurrentPage = GetPageforPosition(_screensContainer.anchoredPosition);
//If the container is moving check if it needs to settle on a page //If the container is moving check if it needs to settle on a page
@ -222,10 +228,13 @@ namespace UnityEngine.UI.Extensions
{ {
InitialiseChildObjectsFromScene(); InitialiseChildObjectsFromScene();
DistributePages(); DistributePages();
if (MaskArea) UpdateVisible(); if (MaskArea)
UpdateVisible();
if (JumpOnEnable || !RestartOnEnable) SetScrollContainerPosition(); if (JumpOnEnable || !RestartOnEnable)
if(RestartOnEnable) GoToScreen(StartingScreen); SetScrollContainerPosition();
if (RestartOnEnable)
GoToScreen(StartingScreen);
} }
/// <summary> /// <summary>
@ -234,6 +243,14 @@ namespace UnityEngine.UI.Extensions
/// <param name="eventData"></param> /// <param name="eventData"></param>
public override void OnEndDrag(PointerEventData eventData) public override void OnEndDrag(PointerEventData eventData)
{ {
if (updated)
{
return;
}
// to prevent double dragging, only act on EndDrag once per frame
updated = true;
_pointerDown = false; _pointerDown = false;
if (_scroll_rect.vertical) if (_scroll_rect.vertical)

View File

@ -143,7 +143,7 @@ namespace UnityEngine.UI.Extensions
private void Update() private void Update()
{ {
// On Android the back button is sent as Esc // On Android the back button is sent as Esc
if (Input.GetKeyDown(KeyCode.Escape) && menuStack.Count > 0) if (UIExtensionsInputManager.GetKeyDown(KeyCode.Escape) && menuStack.Count > 0)
{ {
menuStack.Peek().OnBackPressed(); menuStack.Peek().OnBackPressed();
} }

View File

@ -10,6 +10,7 @@ namespace UnityEngine.UI.Extensions
PerLine PerLine
} }
[RequireComponent(typeof(CanvasRenderer))]
public class UIPrimitiveBase : MaskableGraphic, ILayoutElement, ICanvasRaycastFilter public class UIPrimitiveBase : MaskableGraphic, ILayoutElement, ICanvasRaycastFilter
{ {
static protected Material s_ETC1DefaultUI = null; static protected Material s_ETC1DefaultUI = null;

View File

@ -0,0 +1,141 @@
/// Credit Soprachev Andrei
using System.Collections.Generic;
using System.Linq;
using UnityEditor;
namespace UnityEngine.UI.Extensions
{
[AddComponentMenu("UI/Extensions/Primitives/Squircle")]
public class UISquircle : UIPrimitiveBase
{
const float C = 1.0f;
public enum Type
{
Classic,
Scaled
}
[Space]
public Type squircleType = Type.Scaled;
[Range(1, 40)]
public float n = 4;
[Min(0.1f)]
public float delta = 5f;
public float quality = 0.1f;
[Min(0)]
public float radius = 1000;
private float a, b;
private List<Vector2> vert = new List<Vector2>();
private float SquircleFunc(float t, bool xByY)
{
if (xByY)
return (float)System.Math.Pow(C - System.Math.Pow(t / a, n), 1f / n) * b;
return (float)System.Math.Pow(C - System.Math.Pow(t / b, n), 1f / n) * a;
}
protected override void OnPopulateMesh(VertexHelper vh)
{
float dx = 0;
float dy = 0;
float width = rectTransform.rect.width / 2;
float height = rectTransform.rect.height / 2;
if (squircleType == Type.Classic)
{
a = width;
b = height;
}
else
{
a = Mathf.Min(width, height, radius);
b = a;
dx = width - a;
dy = height - a;
}
float x = 0;
float y = 1;
vert.Clear();
vert.Add(new Vector2(0, height));
while (x < y)
{
y = SquircleFunc(x, true);
vert.Add(new Vector2(dx + x, dy + y));
x += delta;
}
if (float.IsNaN(vert.Last().y))
{
vert.RemoveAt(vert.Count - 1);
}
while (y > 0)
{
x = SquircleFunc(y, false);
vert.Add(new Vector2(dx + x, dy + y));
y -= delta;
}
vert.Add(new Vector2(width, 0));
for (int i = 1; i < vert.Count - 1; i++)
{
if (vert[i].x < vert[i].y)
{
if (vert[i - 1].y - vert[i].y < quality)
{
vert.RemoveAt(i);
i -= 1;
}
}
else
{
if (vert[i].x - vert[i - 1].x < quality)
{
vert.RemoveAt(i);
i -= 1;
}
}
}
vert.AddRange(vert.AsEnumerable().Reverse().Select(t => new Vector2(t.x, -t.y)));
vert.AddRange(vert.AsEnumerable().Reverse().Select(t => new Vector2(-t.x, t.y)));
vh.Clear();
for (int i = 0; i < vert.Count - 1; i++)
{
vh.AddVert(vert[i], color, Vector2.zero);
vh.AddVert(vert[i + 1], color, Vector2.zero);
vh.AddVert(Vector2.zero, color, Vector2.zero);
vh.AddTriangle(i * 3, i * 3 + 1, i * 3 + 2);
}
}
#if UNITY_EDITOR
[CustomEditor(typeof(UISquircle))]
public class UISquircleEditor : Editor
{
public override void OnInspectorGUI()
{
DrawDefaultInspector();
UISquircle script = (UISquircle)target;
GUILayout.Label("Vertex count: " + script.vert.Count().ToString());
}
}
#endif
}
}

View File

@ -1,8 +1,11 @@
fileFormatVersion: 2 fileFormatVersion: 2
guid: 08b9f423b73fdfb47b59e7de89863600 guid: d7948ca2f24604c4aa5340622512a976
MonoImporter: MonoImporter:
externalObjects: {}
serializedVersion: 2 serializedVersion: 2
defaultReferences: [] defaultReferences: []
executionOrder: 0 executionOrder: 0
icon: {instanceID: 0} icon: {instanceID: 0}
userData: userData:
assetBundleName:
assetBundleVariant:

View File

@ -56,7 +56,7 @@ namespace UnityEngine.UI.Extensions
} }
} }
if (Input.GetKeyDown(KeyCode.Tab) && Input.GetKey(KeyCode.LeftShift)) if (UIExtensionsInputManager.GetKeyDown(KeyCode.Tab) && UIExtensionsInputManager.GetKey(KeyCode.LeftShift))
{ {
if (NavigationMode == NavigationMode.Manual && NavigationPath.Length > 0) if (NavigationMode == NavigationMode.Manual && NavigationPath.Length > 0)
{ {
@ -85,7 +85,7 @@ namespace UnityEngine.UI.Extensions
} }
} }
} }
else if (Input.GetKeyDown(KeyCode.Tab)) else if (UIExtensionsInputManager.GetKeyDown(KeyCode.Tab))
{ {
if (NavigationMode == NavigationMode.Manual && NavigationPath.Length > 0) if (NavigationMode == NavigationMode.Manual && NavigationPath.Length > 0)
{ {

View File

@ -135,7 +135,7 @@ namespace UnityEngine.UI.Extensions
public void OnScreenSpaceCamera() public void OnScreenSpaceCamera()
{ {
//get the dynamic position of the pos in viewport coordinates //get the dynamic position of the pos in viewport coordinates
Vector3 newPos = GUICamera.ScreenToViewportPoint(Input.mousePosition); Vector3 newPos = GUICamera.ScreenToViewportPoint(UIExtensionsInputManager.MousePosition);
// store in val the updated position (x or y) of the tooltip edge of interest // store in val the updated position (x or y) of the tooltip edge of interest
float val; float val;

View File

@ -121,6 +121,11 @@ namespace UnityEngine.UI.Extensions
this.gameObject.SetActive(false); this.gameObject.SetActive(false);
} }
public void SetTooltip(string ttext)
{
SetTooltip(ttext, transform.position);
}
//Call this function externally to set the text of the template and activate the tooltip //Call this function externally to set the text of the template and activate the tooltip
public void SetTooltip(string ttext, Vector3 basePos, bool refreshCanvasesBeforeGetSize = false) public void SetTooltip(string ttext, Vector3 basePos, bool refreshCanvasesBeforeGetSize = false)
{ {

View File

@ -55,10 +55,10 @@ namespace UnityEngine.UI.Extensions
{ {
switch (tooltipPositioningType) { switch (tooltipPositioningType) {
case TooltipPositioningType.mousePosition: case TooltipPositioningType.mousePosition:
StartHover(Input.mousePosition + offset, true); StartHover(UIExtensionsInputManager.MousePosition + offset, true);
break; break;
case TooltipPositioningType.mousePositionAndFollow: case TooltipPositioningType.mousePositionAndFollow:
StartHover(Input.mousePosition + offset, true); StartHover(UIExtensionsInputManager.MousePosition + offset, true);
hovered = true; hovered = true;
StartCoroutine(HoveredMouseFollowingLoop()); StartCoroutine(HoveredMouseFollowingLoop());
break; break;
@ -72,7 +72,7 @@ namespace UnityEngine.UI.Extensions
IEnumerator HoveredMouseFollowingLoop() { IEnumerator HoveredMouseFollowingLoop() {
while (hovered) { while (hovered) {
StartHover(Input.mousePosition + offset); StartHover(UIExtensionsInputManager.MousePosition + offset);
yield return null; yield return null;
} }
} }

View File

@ -1,4 +1,6 @@
namespace UnityEngine.UI.Extensions using System;
namespace UnityEngine.UI.Extensions
{ {
public static class ExtentionMethods public static class ExtentionMethods
{ {
@ -11,5 +13,21 @@
} }
return result; return result;
} }
public static bool IsPrefab(this GameObject gameObject)
{
if (gameObject == null)
{
throw new ArgumentNullException(nameof(gameObject));
}
return
!gameObject.scene.IsValid() &&
!gameObject.scene.isLoaded &&
gameObject.GetInstanceID() >= 0 &&
// I noticed that ones with IDs under 0 were objects I didn't recognize
!gameObject.hideFlags.HasFlag(HideFlags.HideInHierarchy);
// I don't care about GameObjects *inside* prefabs, just the overall prefab.
}
} }
} }

View File

@ -30,7 +30,7 @@ namespace UnityEngine.UI.Extensions
public void OnEndEdit(string txt) public void OnEndEdit(string txt)
{ {
if (!Input.GetKeyDown(KeyCode.Return) && !Input.GetKeyDown(KeyCode.KeypadEnter)) if (!UIExtensionsInputManager.GetKeyDown(KeyCode.Return) && !UIExtensionsInputManager.GetKeyDown(KeyCode.KeypadEnter))
return; return;
EnterSubmit.Invoke(txt); EnterSubmit.Invoke(txt);
if (defocusInput) if (defocusInput)

View File

@ -100,7 +100,7 @@ namespace UnityEngine.UI.Extensions
{ {
for (int i = 0; i < m_PaginationChildren.Count; i++) for (int i = 0; i < m_PaginationChildren.Count; i++)
{ {
if (m_PaginationChildren[i].isOn) if (m_PaginationChildren[i].isOn && !scrollSnap._suspendEvents)
{ {
GoToScreen(i); GoToScreen(i);
break; break;

View File

@ -18,7 +18,7 @@ namespace UnityEngine.UI.Extensions
public ScrollRect ParentScrollRect; public ScrollRect ParentScrollRect;
[Tooltip("The parent ScrollSnap control hosting this Scroll Snap.\nIf left empty, it will use the ScrollSnap of the ParentScrollRect")] [Tooltip("The parent ScrollSnap control hosting this Scroll Snap.\nIf left empty, it will use the ScrollSnap of the ParentScrollRect")]
public ScrollSnapBase ParentScrollSnap; private ScrollSnapBase ParentScrollSnap;
private ScrollRect _myScrollRect; private ScrollRect _myScrollRect;
private IBeginDragHandler[] _beginDragHandlers; private IBeginDragHandler[] _beginDragHandlers;
@ -30,6 +30,14 @@ namespace UnityEngine.UI.Extensions
private bool scrollOtherHorizontally; private bool scrollOtherHorizontally;
void Awake() void Awake()
{
if (ParentScrollRect)
{
InitialiseConflictManager();
}
}
private void InitialiseConflictManager()
{ {
//Get the current scroll rect so we can disable it if the other one is scrolling //Get the current scroll rect so we can disable it if the other one is scrolling
_myScrollRect = this.GetComponent<ScrollRect>(); _myScrollRect = this.GetComponent<ScrollRect>();
@ -55,12 +63,27 @@ namespace UnityEngine.UI.Extensions
} }
void Start() void Start()
{
if (ParentScrollRect)
{
AssignScrollRectHandlers();
}
}
private void AssignScrollRectHandlers()
{ {
_beginDragHandlers = ParentScrollRect.GetComponents<IBeginDragHandler>(); _beginDragHandlers = ParentScrollRect.GetComponents<IBeginDragHandler>();
_dragHandlers = ParentScrollRect.GetComponents<IDragHandler>(); _dragHandlers = ParentScrollRect.GetComponents<IDragHandler>();
_endDragHandlers = ParentScrollRect.GetComponents<IEndDragHandler>(); _endDragHandlers = ParentScrollRect.GetComponents<IEndDragHandler>();
} }
public void SetParentScrollRect(ScrollRect parentScrollRect)
{
ParentScrollRect = parentScrollRect;
InitialiseConflictManager();
AssignScrollRectHandlers();
}
#region DragHandler #region DragHandler
public void OnBeginDrag(PointerEventData eventData) public void OnBeginDrag(PointerEventData eventData)

View File

@ -0,0 +1,27 @@
/// Credit SimonDarksideJ
using System.Collections.Generic;
namespace UnityEngine.UI.Extensions
{
public static class ShaderLibrary
{
public static Dictionary<string, Shader> shaderInstances = new Dictionary<string, Shader>();
public static Shader[] preLoadedShaders;
public static Shader GetShaderInstance(string shaderName)
{
if (shaderInstances.ContainsKey(shaderName))
{
return shaderInstances[shaderName];
}
var newInstance = Shader.Find(shaderName);
if (newInstance != null)
{
shaderInstances.Add(shaderName, newInstance);
}
return newInstance;
}
}
}

View File

@ -1,8 +1,11 @@
fileFormatVersion: 2 fileFormatVersion: 2
guid: 26158f38115d49a4a915f46c7eced4ab guid: 3d4dc4c08600582419712a4f2370c81b
MonoImporter: MonoImporter:
externalObjects: {}
serializedVersion: 2 serializedVersion: 2
defaultReferences: [] defaultReferences: []
executionOrder: 0 executionOrder: 0
icon: {instanceID: 0} icon: {instanceID: 0}
userData: userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,292 @@
/// Credit SimonDarksideJ
/// Sourced from: https://bitbucket.org/UnityUIExtensions/unity-ui-extensions/issues/348/menu-manager-does-not-work-with-the-new
using System;
using System.Collections.Generic;
#if (UNITY_2019 || UNITY_2020) && !ENABLE_LEGACY_INPUT_MANAGER
using UnityEngine.InputSystem;
using UnityEngine.InputSystem.Controls;
#endif
namespace UnityEngine.UI.Extensions
{
public static class UIExtensionsInputManager
{
#if (UNITY_2019 || UNITY_2020) && !ENABLE_LEGACY_INPUT_MANAGER
private static bool[] mouseButtons = new bool[3] { false, false, false };
private static Dictionary<KeyCode, bool> keys = new Dictionary<KeyCode, bool>();
private static Dictionary<String, bool> buttons = new Dictionary<String, bool>();
#endif
public static bool GetMouseButton(int button)
{
#if (UNITY_2019 || UNITY_2020) && !ENABLE_LEGACY_INPUT_MANAGER
if (Mouse.current == null)
{
return false;
}
return Mouse.current.leftButton.isPressed;
#else
return Input.GetMouseButton(button);
#endif
}
public static bool GetMouseButtonDown(int button)
{
#if (UNITY_2019 || UNITY_2020) && !ENABLE_LEGACY_INPUT_MANAGER
if (Mouse.current == null)
{
return false;
}
if (Mouse.current.leftButton.isPressed)
{
if (!mouseButtons[button])
{
mouseButtons[button] = true;
return true;
}
}
return false;
#else
return Input.GetMouseButtonDown(button);
#endif
}
public static bool GetMouseButtonUp(int button)
{
#if (UNITY_2019 || UNITY_2020) && !ENABLE_LEGACY_INPUT_MANAGER
if (Mouse.current == null)
{
return false;
}
if (mouseButtons[button] && !Mouse.current.leftButton.isPressed)
{
mouseButtons[button] = false;
return true;
}
return false;
#else
return Input.GetMouseButtonUp(button);
#endif
}
public static bool GetButton(string input)
{
#if (UNITY_2019 || UNITY_2020) && !ENABLE_LEGACY_INPUT_MANAGER
ButtonControl buttonPressed = GetButtonControlFromString(input);
if (!buttons.ContainsKey(input))
{
buttons.Add(input, false);
}
return buttonPressed != null ? buttonPressed.isPressed : false;
#else
return Input.GetButton(input);
#endif
}
#if (UNITY_2019 || UNITY_2020) && !ENABLE_LEGACY_INPUT_MANAGER
private static ButtonControl GetButtonControlFromString(string input)
{
if (Gamepad.current == null)
{
return null;
}
switch (input)
{
case "Submit":
return Gamepad.current.aButton;
case "Cancel":
return Gamepad.current.bButton;
default:
return null;
}
}
#endif
public static bool GetButtonDown(string input)
{
#if (UNITY_2019 || UNITY_2020) && !ENABLE_LEGACY_INPUT_MANAGER
ButtonControl buttonPressed = GetButtonControlFromString(input);
if (buttonPressed.isPressed)
{
if (!buttons.ContainsKey(input))
{
buttons.Add(input, false);
}
if (!buttons[input])
{
buttons[input] = true;
return true;
}
}
else
{
buttons[input] = false;
}
return false;
#else
return Input.GetButtonDown(input);
#endif
}
public static bool GetButtonUp(string input)
{
#if (UNITY_2019 || UNITY_2020) && !ENABLE_LEGACY_INPUT_MANAGER
ButtonControl buttonPressed = GetButtonControlFromString(input);
if (buttons[input] && !buttonPressed.isPressed)
{
buttons[input] = false;
return true;
}
return false;
#else
return Input.GetButtonUp(input);
#endif
}
public static bool GetKey(KeyCode key)
{
#if (UNITY_2019 || UNITY_2020) && !ENABLE_LEGACY_INPUT_MANAGER
KeyControl keyPressed = GetKeyControlFromKeyCode(key);
if (!keys.ContainsKey(key))
{
keys.Add(key, false);
}
return keyPressed != null ? keyPressed.isPressed : false;
#else
return Input.GetKey(key);
#endif
}
#if (UNITY_2019 || UNITY_2020) && !ENABLE_LEGACY_INPUT_MANAGER
private static KeyControl GetKeyControlFromKeyCode(KeyCode key)
{
if (Keyboard.current == null)
{
return null;
}
switch (key)
{
case KeyCode.Escape:
return Keyboard.current.escapeKey;
case KeyCode.KeypadEnter:
return Keyboard.current.numpadEnterKey;
case KeyCode.UpArrow:
return Keyboard.current.upArrowKey;
case KeyCode.DownArrow:
return Keyboard.current.downArrowKey;
case KeyCode.RightArrow:
return Keyboard.current.rightArrowKey;
case KeyCode.LeftArrow:
return Keyboard.current.leftArrowKey;
case KeyCode.LeftShift:
return Keyboard.current.leftShiftKey;
case KeyCode.Tab:
return Keyboard.current.tabKey;
default:
return null;
}
}
#endif
public static bool GetKeyDown(KeyCode key)
{
#if (UNITY_2019 || UNITY_2020) && !ENABLE_LEGACY_INPUT_MANAGER
KeyControl keyPressed = GetKeyControlFromKeyCode(key);
if (keyPressed.isPressed)
{
if (!keys.ContainsKey(key))
{
keys.Add(key, false);
}
if (!keys[key])
{
keys[key] = true;
return true;
}
}
else
{
keys[key] = false;
}
return false;
#else
return Input.GetKeyDown(key);
#endif
}
public static bool GetKeyUp(KeyCode key)
{
#if (UNITY_2019 || UNITY_2020) && !ENABLE_LEGACY_INPUT_MANAGER
KeyControl keyPressed = GetKeyControlFromKeyCode(key);
if (keys[key] && !keyPressed.isPressed)
{
keys[key] = false;
return true;
}
return false;
#else
return Input.GetKeyUp(key);
#endif
}
public static float GetAxisRaw(string axis)
{
#if (UNITY_2019 || UNITY_2020) && !ENABLE_LEGACY_INPUT_MANAGER
if (Gamepad.current == null)
{
return 0f;
}
switch (axis)
{
case "Horizontal":
return Gamepad.current.leftStick.x.ReadValue();
case "Vertical":
return Gamepad.current.leftStick.y.ReadValue();
}
return 0f;
#else
return Input.GetAxisRaw(axis);
#endif
}
public static Vector3 MousePosition
{
get
{
#if (UNITY_2019 || UNITY_2020) && !ENABLE_LEGACY_INPUT_MANAGER
return Mouse.current.position.ReadValue();
#else
return Input.mousePosition;
#endif
}
}
public static Vector3 MouseScrollDelta
{
get
{
#if (UNITY_2019 || UNITY_2020) && !ENABLE_LEGACY_INPUT_MANAGER
return Mouse.current.position.ReadValue();
#else
return Input.mouseScrollDelta;
#endif
}
}
}
}

View File

@ -1,8 +1,11 @@
fileFormatVersion: 2 fileFormatVersion: 2
guid: 3d7a94ee2faf9f04696882b3a2cbf035 guid: de7e73fc10fb95143a19dbc76c2595a7
MonoImporter: MonoImporter:
externalObjects: {}
serializedVersion: 2 serializedVersion: 2
defaultReferences: [] defaultReferences: []
executionOrder: 0 executionOrder: 0
icon: {instanceID: 0} icon: {instanceID: 0}
userData: userData:
assetBundleName:
assetBundleVariant:

View File

@ -124,7 +124,7 @@ namespace UnityEngine.UI.Extensions
for (int i = 0; i < CancelScrollKeycodes.Count; i++) for (int i = 0; i < CancelScrollKeycodes.Count; i++)
{ {
if (Input.GetKeyDown(CancelScrollKeycodes[i]) == true) if (UIExtensionsInputManager.GetKeyDown(CancelScrollKeycodes[i]) == true)
{ {
IsManualScrollingAvailable = true; IsManualScrollingAvailable = true;

View File

@ -1,6 +1,7 @@
/// Credit Tomasz Schelenz /// Credit Tomasz Schelenz
/// Sourced from - https://bitbucket.org/SimonDarksideJ/unity-ui-extensions/issues/81/infinite-scrollrect /// Sourced from - https://bitbucket.org/SimonDarksideJ/unity-ui-extensions/issues/81/infinite-scrollrect
/// Demo - https://www.youtube.com/watch?v=uVTV7Udx78k - configures automatically. - works in both vertical and horizontal (but not both at the same time) - drag and drop - can be initialized by code (in case you populate your scrollview content from code) /// Demo - https://www.youtube.com/watch?v=uVTV7Udx78k - configures automatically. - works in both vertical and horizontal (but not both at the same time) - drag and drop - can be initialized by code (in case you populate your scrollview content from code)
/// Updated by Febo Zodiaco - https://bitbucket.org/UnityUIExtensions/unity-ui-extensions/issues/349/magnticinfinitescroll
using System.Collections.Generic; using System.Collections.Generic;
@ -11,10 +12,10 @@ namespace UnityEngine.UI.Extensions
/// ///
/// Fields /// Fields
/// - InitByUSer - in case your scrollrect is populated from code, you can explicitly Initialize the infinite scroll after your scroll is ready /// - InitByUSer - in case your scrollrect is populated from code, you can explicitly Initialize the infinite scroll after your scroll is ready
/// by callin Init() method /// by calling Init() method
/// ///
/// Notes /// Notes
/// - doesn't work in both vertical and horizontal orientation at the same time. /// - does not work in both vertical and horizontal orientation at the same time.
/// - in order to work it disables layout components and size fitter if present(automatically) /// - in order to work it disables layout components and size fitter if present(automatically)
/// ///
/// </summary> /// </summary>
@ -24,30 +25,70 @@ namespace UnityEngine.UI.Extensions
//if true user will need to call Init() method manually (in case the contend of the scrollview is generated from code or requires special initialization) //if true user will need to call Init() method manually (in case the contend of the scrollview is generated from code or requires special initialization)
[Tooltip("If false, will Init automatically, otherwise you need to call Init() method")] [Tooltip("If false, will Init automatically, otherwise you need to call Init() method")]
public bool InitByUser = false; public bool InitByUser = false;
private ScrollRect _scrollRect; protected ScrollRect _scrollRect;
private ContentSizeFitter _contentSizeFitter; private ContentSizeFitter _contentSizeFitter;
private VerticalLayoutGroup _verticalLayoutGroup; private VerticalLayoutGroup _verticalLayoutGroup;
private HorizontalLayoutGroup _horizontalLayoutGroup; private HorizontalLayoutGroup _horizontalLayoutGroup;
private GridLayoutGroup _gridLayoutGroup; private GridLayoutGroup _gridLayoutGroup;
private bool _isVertical = false; protected bool _isVertical = false;
private bool _isHorizontal = false; protected bool _isHorizontal = false;
private float _disableMarginX = 0; private float _disableMarginX = 0;
private float _disableMarginY = 0; private float _disableMarginY = 0;
private bool _hasDisabledGridComponents = false; private bool _hasDisabledGridComponents = false;
private List<RectTransform> items = new List<RectTransform>(); protected List<RectTransform> items = new List<RectTransform>();
private Vector2 _newAnchoredPosition = Vector2.zero; private Vector2 _newAnchoredPosition = Vector2.zero;
//TO DISABLE FLICKERING OBJECT WHEN SCROLL VIEW IS IDLE IN BETWEEN OBJECTS //TO DISABLE FLICKERING OBJECT WHEN SCROLL VIEW IS IDLE IN BETWEEN OBJECTS
private float _treshold = 100f; private float _threshold = 100f;
private int _itemCount = 0; private int _itemCount = 0;
private float _recordOffsetX = 0; private float _recordOffsetX = 0;
private float _recordOffsetY = 0; private float _recordOffsetY = 0;
void Awake() protected virtual void Awake()
{ {
if (!InitByUser) if (!InitByUser)
Init(); Init();
} }
public virtual void SetNewItems(ref List<Transform> newItems)
{
if (_scrollRect != null)
{
if (_scrollRect.content == null && newItems == null)
{
return;
}
if (items != null)
{
items.Clear();
}
for (int i = _scrollRect.content.childCount - 1; i >= 0; i--)
{
Transform child = _scrollRect.content.GetChild(i);
child.SetParent(null);
GameObject.DestroyImmediate(child.gameObject);
}
foreach (Transform newItem in newItems)
{
newItem.SetParent(_scrollRect.content);
}
SetItems();
}
}
private void SetItems()
{
for (int i = 0; i < _scrollRect.content.childCount; i++)
{
items.Add(_scrollRect.content.GetChild(i).GetComponent<RectTransform>());
}
_itemCount = _scrollRect.content.childCount;
}
public void Init() public void Init()
{ {
if (GetComponent<ScrollRect>() != null) if (GetComponent<ScrollRect>() != null)
@ -56,10 +97,6 @@ namespace UnityEngine.UI.Extensions
_scrollRect.onValueChanged.AddListener(OnScroll); _scrollRect.onValueChanged.AddListener(OnScroll);
_scrollRect.movementType = ScrollRect.MovementType.Unrestricted; _scrollRect.movementType = ScrollRect.MovementType.Unrestricted;
for (int i = 0; i < _scrollRect.content.childCount; i++)
{
items.Add(_scrollRect.content.GetChild(i).GetComponent<RectTransform>());
}
if (_scrollRect.content.GetComponent<VerticalLayoutGroup>() != null) if (_scrollRect.content.GetComponent<VerticalLayoutGroup>() != null)
{ {
_verticalLayoutGroup = _scrollRect.content.GetComponent<VerticalLayoutGroup>(); _verticalLayoutGroup = _scrollRect.content.GetComponent<VerticalLayoutGroup>();
@ -85,7 +122,7 @@ namespace UnityEngine.UI.Extensions
Debug.LogError("UI_InfiniteScroll doesn't support scrolling in both directions, please choose one direction (horizontal or vertical)"); Debug.LogError("UI_InfiniteScroll doesn't support scrolling in both directions, please choose one direction (horizontal or vertical)");
} }
_itemCount = _scrollRect.content.childCount; SetItems();
} }
else else
{ {
@ -102,7 +139,7 @@ namespace UnityEngine.UI.Extensions
{ {
_recordOffsetY *= -1; _recordOffsetY *= -1;
} }
_disableMarginY = _recordOffsetY * _itemCount / 2;// _scrollRect.GetComponent<RectTransform>().rect.height/2 + items[0].sizeDelta.y; _disableMarginY = _recordOffsetY * _itemCount / 2;
} }
if (_isHorizontal) if (_isHorizontal)
{ {
@ -111,7 +148,7 @@ namespace UnityEngine.UI.Extensions
{ {
_recordOffsetX *= -1; _recordOffsetX *= -1;
} }
_disableMarginX = _recordOffsetX * _itemCount / 2;//_scrollRect.GetComponent<RectTransform>().rect.width/2 + items[0].sizeDelta.x; _disableMarginX = _recordOffsetX * _itemCount / 2;
} }
if (_verticalLayoutGroup) if (_verticalLayoutGroup)
@ -142,7 +179,7 @@ namespace UnityEngine.UI.Extensions
{ {
if (_isHorizontal) if (_isHorizontal)
{ {
if (_scrollRect.transform.InverseTransformPoint(items[i].gameObject.transform.position).x > _disableMarginX + _treshold) if (_scrollRect.transform.InverseTransformPoint(items[i].gameObject.transform.position).x > _disableMarginX + _threshold)
{ {
_newAnchoredPosition = items[i].anchoredPosition; _newAnchoredPosition = items[i].anchoredPosition;
_newAnchoredPosition.x -= _itemCount * _recordOffsetX; _newAnchoredPosition.x -= _itemCount * _recordOffsetX;
@ -160,7 +197,7 @@ namespace UnityEngine.UI.Extensions
if (_isVertical) if (_isVertical)
{ {
if (_scrollRect.transform.InverseTransformPoint(items[i].gameObject.transform.position).y > _disableMarginY + _treshold) if (_scrollRect.transform.InverseTransformPoint(items[i].gameObject.transform.position).y > _disableMarginY + _threshold)
{ {
_newAnchoredPosition = items[i].anchoredPosition; _newAnchoredPosition = items[i].anchoredPosition;
_newAnchoredPosition.y -= _itemCount * _recordOffsetY; _newAnchoredPosition.y -= _itemCount * _recordOffsetY;

View File

@ -0,0 +1,200 @@
/// Credit Febo Zodiaco
/// Sourced from - https://bitbucket.org/UnityUIExtensions/unity-ui-extensions/issues/349/magnticinfinitescroll
///
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine.EventSystems;
namespace UnityEngine.UI.Extensions
{
[AddComponentMenu("UI/Extensions/UI Magnetic Infinite Scroll")]
[RequireComponent(typeof(ScrollRect))]
public class UI_MagneticInfiniteScroll : UI_InfiniteScroll, IDragHandler, IEndDragHandler, IScrollHandler
{
public event Action<GameObject> OnNewSelect;
[Tooltip("The pointer to the pivot, the visual element for centering objects.")]
[SerializeField]
private RectTransform pivot = null;
[Tooltip("The maximum speed that allows you to activate the magnet to center on the pivot")]
[SerializeField]
private float maxSpeedForMagnetic = 10f;
[SerializeField]
[Tooltip("The index of the object which must be initially centered")]
private int indexStart = 0;
[SerializeField]
[Tooltip("The time to decelerate and aim to the pivot")]
private float timeForDeceleration = 0.05f;
private float _pastPositionMouseSpeed;
private float _initMovementDirection = 0;
private float _pastPosition = 0;
private float _currentSpeed = 0.0f;
private float _stopValue = 0.0f;
private readonly float _waitForContentSet = 0.1f;
private float _currentTime = 0;
private int _nearestIndex = 0;
private bool _useMagnetic = true;
private bool _isStopping = false;
private bool _isMovement = false;
public List<RectTransform> Items { get; }
protected override void Awake()
{
base.Awake();
StartCoroutine(SetInitContent());
}
private void Update()
{
if (_scrollRect == null || !_scrollRect.content || !pivot || !_useMagnetic || !_isMovement || items == null)
{
return;
}
float currentPosition = GetRightAxis(_scrollRect.content.anchoredPosition);
_currentSpeed = Mathf.Abs(currentPosition - _pastPosition);
_pastPosition = currentPosition;
if (Mathf.Abs(_currentSpeed) > maxSpeedForMagnetic)
{
return;
}
if (_isStopping)
{
Vector2 anchoredPosition = _scrollRect.content.anchoredPosition;
_currentTime += Time.deltaTime;
float valueLerp = _currentTime / timeForDeceleration;
float newPosition = Mathf.Lerp(GetRightAxis(anchoredPosition), _stopValue, valueLerp);
_scrollRect.content.anchoredPosition = _isVertical ? new Vector2(anchoredPosition.x, newPosition) :
new Vector2(newPosition, anchoredPosition.y);
if (newPosition == GetRightAxis(anchoredPosition) && _nearestIndex > 0 && _nearestIndex < items.Count)
{
_isStopping = false;
_isMovement = false;
var item = items[_nearestIndex];
if (item != null && OnNewSelect != null)
{
OnNewSelect.Invoke(item.gameObject);
}
}
}
else
{
float distance = Mathf.Infinity * (-_initMovementDirection);
for (int i = 0; i < items.Count; i++)
{
var item = items[i];
if (item == null)
{
continue;
}
var aux = GetRightAxis(item.position) - GetRightAxis(pivot.position);
if ((_initMovementDirection <= 0 && aux < distance && aux > 0) ||
(_initMovementDirection > 0 && aux > distance && aux < 0))
{
distance = aux;
_nearestIndex = i;
}
}
_isStopping = true;
_stopValue = GetAnchoredPositionForPivot(_nearestIndex);
_scrollRect.StopMovement();
}
}
public override void SetNewItems(ref List<Transform> newItems)
{
foreach (var element in newItems)
{
RectTransform rectTransform = element.GetComponent<RectTransform>();
if (rectTransform && pivot)
{
rectTransform.sizeDelta = pivot.sizeDelta;
}
}
base.SetNewItems(ref newItems);
}
public void SetContentInPivot(int index)
{
float newPos = GetAnchoredPositionForPivot(index);
Vector2 anchoredPosition = _scrollRect.content.anchoredPosition;
if (_scrollRect.content)
{
_scrollRect.content.anchoredPosition = _isVertical ? new Vector2(anchoredPosition.x, newPos) :
new Vector2(newPos, anchoredPosition.y);
_pastPosition = GetRightAxis(_scrollRect.content.anchoredPosition);
}
}
private IEnumerator SetInitContent()
{
yield return new WaitForSeconds(_waitForContentSet);
SetContentInPivot(indexStart);
}
private float GetAnchoredPositionForPivot(int index)
{
if (!pivot || items == null || items.Count < 0)
{
return 0f;
}
index = Mathf.Clamp(index, 0, items.Count - 1);
float posItem = GetRightAxis(items[index].anchoredPosition);
float posPivot = GetRightAxis(pivot.anchoredPosition);
return posPivot - posItem;
}
private void FinishPrepareMovement()
{
_isMovement = true;
_useMagnetic = true;
_isStopping = false;
_currentTime = 0;
}
private float GetRightAxis(Vector2 vector)
{
return _isVertical ? vector.y : vector.x;
}
public void OnDrag(PointerEventData eventData)
{
float currentPosition = GetRightAxis(UIExtensionsInputManager.MousePosition);
_initMovementDirection = Mathf.Sign(currentPosition - _pastPositionMouseSpeed);
_pastPositionMouseSpeed = currentPosition;
_useMagnetic = false;
_isStopping = false;
}
public void OnEndDrag(PointerEventData eventData)
{
FinishPrepareMovement();
}
public void OnScroll(PointerEventData eventData)
{
_initMovementDirection = -UIExtensionsInputManager.MouseScrollDelta.y;
FinishPrepareMovement();
}
}
}

View File

@ -1,8 +1,11 @@
fileFormatVersion: 2 fileFormatVersion: 2
guid: 303ab8dad3437bf46814373cfb86cc5d guid: 8a2ddc0989b894a499a02fb975aa0322
MonoImporter: MonoImporter:
externalObjects: {}
serializedVersion: 2 serializedVersion: 2
defaultReferences: [] defaultReferences: []
executionOrder: 0 executionOrder: 0
icon: {instanceID: 0} icon: {instanceID: 0}
userData: userData:
assetBundleName:
assetBundleVariant:

View File

@ -1,5 +0,0 @@
fileFormatVersion: 2
guid: c84a253080bc0ec4995041aa5a6656ae
folderAsset: yes
DefaultImporter:
userData:

View File

@ -1,48 +0,0 @@
/// Credit Ralph Barbagallo (www.flarb.com /www.ralphbarbagallo.com / @flarb)
/// Sourced from - http://forum.unity3d.com/threads/vr-cursor-possible-unity-4-6-gui-bug-or-is-it-me
namespace UnityEngine.UI.Extensions
{
[AddComponentMenu("UI/Extensions/VR Cursor")]
public class VRCursor : MonoBehaviour
{
public float xSens;
public float ySens;
private Collider currentCollider;
// Update is called once per frame
void Update()
{
Vector3 thisPosition;
thisPosition.x = Input.mousePosition.x * xSens;
thisPosition.y = Input.mousePosition.y * ySens - 1;
thisPosition.z = transform.position.z;
transform.position = thisPosition;
VRInputModule.cursorPosition = transform.position;
if (Input.GetMouseButtonDown(0) && currentCollider)
{
VRInputModule.PointerSubmit(currentCollider.gameObject);
}
}
void OnTriggerEnter(Collider other)
{
//print("OnTriggerEnter other " + other.gameObject);
VRInputModule.PointerEnter(other.gameObject);
currentCollider = other;
}
void OnTriggerExit(Collider other)
{
//print("OnTriggerExit other " + other.gameObject);
VRInputModule.PointerExit(other.gameObject);
currentCollider = null;
}
}
}

View File

@ -1,69 +0,0 @@
/// Credit Ralph Barbagallo (www.flarb.com /www.ralphbarbagallo.com / @flarb)
/// Sourced from - http://forum.unity3d.com/threads/vr-cursor-possible-unity-4-6-gui-bug-or-is-it-me
/// Fix supplied by - http://forum.unity3d.com/threads/vr-cursor-possible-unity-4-6-gui-bug-or-is-it-me.296934/
using UnityEngine.EventSystems;
namespace UnityEngine.UI.Extensions
{
[AddComponentMenu("Event/VR Input Module")]
public class VRInputModule : BaseInputModule
{
public static GameObject targetObject;
static VRInputModule _singleton;
private static bool mouseClicked;
public static Vector3 cursorPosition;
protected override void Awake()
{
_singleton = this;
}
public override void Process()
{
if (targetObject == null)
{
mouseClicked = false;
return;
}
}
public static void PointerSubmit(GameObject obj)
{
targetObject = obj;
mouseClicked = true;
if (mouseClicked)
{
//BaseEventData data = GetBaseEventData(); //Original from Process(). Can't be called here so is replaced by the next line:
BaseEventData data = new BaseEventData(_singleton.eventSystem)
{
selectedObject = targetObject
};
ExecuteEvents.Execute(targetObject, data, ExecuteEvents.submitHandler);
print("clicked " + targetObject.name);
mouseClicked = false;
}
}
public static void PointerExit(GameObject obj)
{
print("PointerExit " + obj.name);
PointerEventData pEvent = new PointerEventData(_singleton.eventSystem);
ExecuteEvents.Execute(obj, pEvent, ExecuteEvents.pointerExitHandler);
ExecuteEvents.Execute(obj, pEvent, ExecuteEvents.deselectHandler); //This fixes the problem
}
public static void PointerEnter(GameObject obj)
{
print("PointerEnter " + obj.name);
PointerEventData pEvent = new PointerEventData(_singleton.eventSystem)
{
pointerEnter = obj
};
RaycastResult rcr = new RaycastResult() { worldPosition = cursorPosition };
pEvent.pointerCurrentRaycast = rcr;
ExecuteEvents.Execute(obj, pEvent, ExecuteEvents.pointerEnterHandler);
}
}
}

View File

@ -1,7 +1,8 @@
{ {
"name": "UnityUIExtensions", "name": "UnityUIExtensions",
"references": [ "references": [
"GUID:2bafac87e7f4b9b418d9448d219b01ab" "GUID:2bafac87e7f4b9b418d9448d219b01ab",
"GUID:75469ad4d38634e559750d17036d5f7c"
], ],
"includePlatforms": [], "includePlatforms": [],
"excludePlatforms": [], "excludePlatforms": [],
@ -10,5 +11,6 @@
"precompiledReferences": [], "precompiledReferences": [],
"autoReferenced": true, "autoReferenced": true,
"defineConstraints": [], "defineConstraints": [],
"versionDefines": [] "versionDefines": [],
"noEngineReferences": false
} }

View File

@ -1,16 +0,0 @@
# This is a sample build configuration for Other.
# Check our guides at https://confluence.atlassian.com/x/5Q4SMw for more examples.
# Only use spaces to indent your .yml configuration.
# -----
# You can specify a custom docker image from Docker Hub as your build environment.
image: atlassian/default-image:2
pipelines:
custom:
npmpublish:
- step:
script:
- echo "Publishing Unity UI Extensions to NPM"
- pipe: atlassian/npm-publish:0.3.1
variables:
NPM_TOKEN: $NPM_TOKEN

View File

@ -1,7 +1,7 @@
{ {
"name": "com.unity.uiextensions", "name": "com.unity.uiextensions",
"displayName": "Unity UI Extensions", "displayName": "Unity UI Extensions",
"version": "2.2.2", "version": "2.2.3",
"description": "An extension project for the Unity3D UI system, all crafted and contributed by the awesome Unity community", "description": "An extension project for the Unity3D UI system, all crafted and contributed by the awesome Unity community",
"author": "Simon darkside Jackson <@SimonDarksideJ>", "author": "Simon darkside Jackson <@SimonDarksideJ>",
"contributors": [{ "contributors": [{
@ -21,6 +21,13 @@
"Unity", "Unity",
"Unity UI", "Unity UI",
"UI Extensions" "UI Extensions"
],
"samples": [
{
"displayName": "UI Extensions Samples",
"description": "Examples and demonstrations of the Unity UI Extensions controls",
"path": "Examples~"
}
], ],
"license": "BSD3" "license": "BSD3"
} }