-
Notifications
You must be signed in to change notification settings - Fork 11
Commit
Initial working version
- Loading branch information
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
# Changelog | ||
All notable changes to this project will be documented in this file. | ||
|
||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), | ||
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). | ||
|
||
## [0.0.1] | ||
### Added | ||
- First initial working version | ||
|
||
### [Unreleased] | ||
- Windows Manager Custom Editor; | ||
- Spawn / Despan window in editor time for quick editing; | ||
- Proper History Display; | ||
- Add Collection Display GUI (Collectable to DisplayGUI); | ||
- Add more transition; | ||
- Add ability to allow window to implement custom transition; | ||
- Implement support for Addressables Based Window | ||
- Support for hierachy instance spawning | ||
|
||
|
||
|
||
[0.0.1]: https://github.com/brunomikoski/UIManager/releases/tag/v1.0.0 | ||
|
||
|
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,72 @@ | ||
# UIManager | ||
# UI Manager | ||
|
||
|
||
[![openupm](https://img.shields.io/npm/v/com.brunomikoski.uimanager?label=openupm®istry_uri=https://package.openupm.com)](https://openupm.com/packages/com.brunomikoski.uimanager/) [![Codacy Badge](https://app.codacy.com/project/badge/Grade/177397001d74494a9ec54031a428c8dc)](https://www.codacy.com/manual/badawe/ScriptableObjectCollection?utm_source=github.com&utm_medium=referral&utm_content=badawe/ScriptableObjectCollection&utm_campaign=Badge_Grade) | ||
|
||
[![](https://img.shields.io/github/followers/brunomikoski?label=Follow&style=social)](https://github.com/brunomikoski) [![](https://img.shields.io/twitter/follow/brunomikoski?style=social)](https://twitter.com/brunomikoski) | ||
|
||
|
||
*UI Manager* it's a UI/GUI/Windows solution for Unity with layers approach, It's built to support the most variety of games with complex demands and expensive UI. | ||
|
||
|
||
## Features | ||
- Automatically Instantiation and manage of windows based on Layers | ||
- Built on [ScriptableObject Collection](https://github.com/brunomikoski/ScriptableObjectCollection/), so you have quick access by code/inspector of your Windows and features. | ||
- Transitions support, you can quickly define a series of transition per window, and quickly create and reuse new ones. | ||
- Quickly access window events | ||
- Fully events system for interacting with window. | ||
- Full Window Interfaces for quickly develop windows components. | ||
- 2 Layers Behaviours, `Exclusive`: will close the current open window before opening a new one, `Additive`: will open the new window on top | ||
- Groups Support, setup your windows based on groups (Gameplay / Meta / Shop) and quickly load / unload specific groups to free memory | ||
- Script Based, not messying around trying to see where a window reference is. | ||
|
||
## How to use? | ||
- UI Manager needs 4 different Scriptable Object Collections to work WindowIDs, LayerIDs, GroupIDs and Transitions, you should be able to create it by the `Tools / UI Manager / Initial Setup` | ||
- Every GUI that you want to display on the system, needs his own unique identifier (WindowIDs) right now the system comes with the following options: | ||
`PrefabBasedWindowID` and `AddressablesBasedWindowID` if you have the AddressableSystem package on your project. | ||
|
||
|
||
## FAQ | ||
- How do I create a new Window? | ||
- To create a new Window you need both a new `WindowID` and a Prefab, after creating a new one on the `WindowIDs` and define the target settings, you just need to assign the `Prefab` reference into the WindowID to work. | ||
- How do I access the Windows Manager? | ||
- The windows manager its a pure solution for working with UI, so I doesn't come with a Singleton/Service Locator/DI System, feel free to use whatever your project needs. | ||
- After the initial setup is done, you can use the static generated file generated out of `WindowIDs` to interact with windows, ex.: `AllWindows.MainMenu.Open();` | ||
- How can I access the events? | ||
- You can subscribe to any window event by: `windowManager.SubscribeToWindowEvent(WindowEvent targetEvent, WindowID windowID, Action callback)` and `windowManager.SubscribeToAnyWindowEvent(WindowEvent targetEvent, Action<Window> callback) | ||
- Available Window Events: `OnWillOpen, OnOpened, OnWillClose, OnClosed, OnLostFocus, OnGainFocus` | ||
- You can also subscribe to specific transitions `windowsManager.SubscribeToTransitionEvent(AllWindows.MainMenu, AllWindows.Shopping, OnEnterShopFromMainMenu);` | ||
- I want some component of a Window to do something when the window is open | ||
- You just need your child component of the window to implement one of the WindowInterfaces: `IOnAfterWindowOpen` | ||
- I want to create a new transition | ||
- Just select the Transitions Collection and create a new type by using the Add Menu, you can do the transition that you want. | ||
|
||
## System Requirements | ||
Unity 2018.4.0 or later versions | ||
|
||
|
||
## Installation | ||
|
||
### OpenUPM | ||
The package is available on the [openupm registry](https://openupm.com). It's recommended to install it via [openupm-cli](https://github.com/openupm/openupm-cli). | ||
|
||
``` | ||
openupm add com.brunomikoski.uimanager | ||
``` | ||
|
||
### Manifest | ||
You can also install via git URL by adding this entry in your **manifest.json** | ||
``` | ||
"com.brunomikoski.uimanager": "https://github.com/brunomikoski/UIManager.git" | ||
``` | ||
|
||
### Unity Package Manager | ||
``` | ||
from Window->Package Manager, click on the + sign and Add from git: https://github.com/badawe/ScriptableObjectCollection.git | ||
``` | ||
|
||
## License TL:DR | ||
- You can freely use Scriptable Object Collection in both commercial and non-commercial projects | ||
- You can redistribute verbatim copies of the code, along with any readme files and attributions | ||
- You can modify the code only for your own (company/studio) use and you cannot redistribute modified versions outside your own company/studio (but you can send pull requests to me) | ||
|
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
{ | ||
"name": "BrunoMikoski.UIManager.Editor", | ||
"references": [ | ||
"BrunoMikoski.UIManager", | ||
"BrunoMikoski.ScriptableObjectCollection", | ||
"BrunoMikoski.ScriptableObjectCollection.Editor" | ||
], | ||
"includePlatforms": [ | ||
"Editor" | ||
], | ||
"excludePlatforms": [], | ||
"allowUnsafeCode": false, | ||
"overrideReferences": false, | ||
"precompiledReferences": [], | ||
"autoReferenced": true, | ||
"defineConstraints": [], | ||
"versionDefines": [], | ||
"noEngineReferences": false | ||
} |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
using UnityEditor; | ||
using UnityEngine; | ||
|
||
namespace BrunoMikoski.UIManager.CustomEditors | ||
{ | ||
[CustomEditor(typeof(WindowsManager))] | ||
public class WindowsManagerCustomEditor : Editor | ||
{ | ||
public override void OnInspectorGUI() | ||
{ | ||
base.OnInspectorGUI(); | ||
|
||
DrawEditorSpawning(); | ||
} | ||
|
||
private void DrawEditorSpawning() | ||
{ | ||
using (new EditorGUI.DisabledGroupScope(DisableEditorSpawningOptions())) | ||
{ | ||
using (new EditorGUILayout.VerticalScope("Box")) | ||
{ | ||
EditorGUILayout.LabelField("Windows", EditorStyles.foldoutHeader); | ||
EditorGUILayout.Space(); | ||
|
||
using (new EditorGUILayout.HorizontalScope()) | ||
{ | ||
if (GUILayout.Button("Instantiate All Windows", EditorStyles.miniButton)) | ||
InstantiateAllWindows(); | ||
if (GUILayout.Button("Remove All Windows", EditorStyles.miniButton)) | ||
InstantiateAllWindows(); | ||
} | ||
} | ||
} | ||
} | ||
|
||
private void InstantiateAllWindows() | ||
{ | ||
WindowsManager windowsManager = target as WindowsManager; | ||
windowsManager.InitializeLayers(); | ||
} | ||
|
||
private bool DisableEditorSpawningOptions() | ||
{ | ||
return Application.isPlaying; | ||
} | ||
} | ||
} |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,140 @@ | ||
using BrunoMikoski.ScriptableObjectCollections; | ||
using DG.Tweening; | ||
using UnityEditor; | ||
using UnityEngine; | ||
|
||
namespace BrunoMikoski.UIManager | ||
{ | ||
public class InitialSetupEditorWindow : EditorWindow | ||
{ | ||
private DefaultAsset ScriptableObjectFolder; | ||
private DefaultAsset GeneratedCodeFolder; | ||
|
||
public static InitialSetupEditorWindow GetWindowInstance() | ||
{ | ||
return GetWindow<InitialSetupEditorWindow>("Setup UI Manager"); | ||
} | ||
|
||
public static void Open() | ||
{ | ||
InitialSetupEditorWindow window = GetWindowInstance(); | ||
window.ShowPopup(); | ||
} | ||
|
||
private void OnGUI() | ||
{ | ||
using (new EditorGUILayout.VerticalScope("Box")) | ||
{ | ||
EditorGUILayout.LabelField("Settings", EditorStyles.foldoutHeader); | ||
EditorGUILayout.Space(); | ||
ScriptableObjectFolder = (DefaultAsset) EditorGUILayout.ObjectField("Scriptable Objects Folder", | ||
ScriptableObjectFolder, typeof(DefaultAsset), false); | ||
|
||
GeneratedCodeFolder = (DefaultAsset) EditorGUILayout.ObjectField("Generated Code Folder", | ||
GeneratedCodeFolder, typeof(DefaultAsset), false); | ||
|
||
|
||
using (new EditorGUI.DisabledScope(!AreSettingsValid())) | ||
{ | ||
Color color = GUI.color; | ||
GUI.color = Color.green; | ||
if (GUILayout.Button("Create")) | ||
PerformInitialSetup(); | ||
|
||
GUI.color = color; | ||
} | ||
} | ||
} | ||
|
||
private void PerformInitialSetup() | ||
{ | ||
if (!CollectionsRegistry.Instance.TryGetCollectionForType(out ScriptableObjectCollection<WindowID> windowIDs)) | ||
{ | ||
windowIDs = ScriptableObjectCollectionUtils.CreateScriptableObjectOfType<WindowIDs>(ScriptableObjectFolder, true, | ||
"WindowIDs"); | ||
} | ||
|
||
if (!CollectionsRegistry.Instance.TryGetCollectionForType(out ScriptableObjectCollection<LayerID> layerIDs)) | ||
{ | ||
layerIDs = ScriptableObjectCollectionUtils.CreateScriptableObjectOfType<LayerIDs>(ScriptableObjectFolder, true, | ||
"LayerIDs"); | ||
} | ||
|
||
|
||
layerIDs.GetOrAddNew("Main"); | ||
layerIDs.GetOrAddNew("Popup"); | ||
layerIDs.GetOrAddNew("Overlay"); | ||
|
||
|
||
if (!CollectionsRegistry.Instance.TryGetCollectionForType(out ScriptableObjectCollection<GroupID> groupIDs)) | ||
{ | ||
groupIDs = ScriptableObjectCollectionUtils.CreateScriptableObjectOfType<GroupIDs>(ScriptableObjectFolder, true, | ||
"GroupIDs"); | ||
} | ||
groupIDs.GetOrAddNew("Main"); | ||
|
||
|
||
if (!CollectionsRegistry.Instance.TryGetCollectionForType( | ||
out ScriptableObjectCollection<TransitionBase> transitions)) | ||
{ | ||
transitions = ScriptableObjectCollectionUtils.CreateScriptableObjectOfType<Transitions>(ScriptableObjectFolder, true, | ||
"Transitions"); | ||
} | ||
transitions.GetOrAddNew(typeof(ReverseTransition), "ReverseInTransition"); | ||
transitions.GetOrAddNew<FadeTransition>("FadeInTransition") | ||
.SetAnimationValues(0, 1, 0.3f, Ease.Linear); | ||
|
||
transitions.GetOrAddNew<ScaleTransition>("ScaleInTransition") | ||
.SetAnimationValues(Vector3.zero, Vector3.one, 0.6f, Ease.OutBack); | ||
|
||
|
||
ScriptableObjectCollectionSettings.Instance.SetGenerateCustomStaticFile(windowIDs, true); | ||
ScriptableObjectCollectionSettings.Instance.SetGenerateCustomStaticFile(layerIDs, true); | ||
ScriptableObjectCollectionSettings.Instance.SetGenerateCustomStaticFile(groupIDs, true); | ||
ScriptableObjectCollectionSettings.Instance.SetGenerateCustomStaticFile(transitions, true); | ||
|
||
ScriptableObjectCollectionSettings.Instance.SetGenerateCustomStaticFileName(windowIDs, "WindowIDsStatic"); | ||
ScriptableObjectCollectionSettings.Instance.SetGenerateCustomStaticFileName(layerIDs, "LayerIDsStatic"); | ||
ScriptableObjectCollectionSettings.Instance.SetGenerateCustomStaticFileName(groupIDs, "GroupIDsStatic"); | ||
ScriptableObjectCollectionSettings.Instance.SetGenerateCustomStaticFileName(transitions, "TransitionsStatic"); | ||
|
||
string generatedCodeFolderPath = AssetDatabase.GetAssetPath(GeneratedCodeFolder); | ||
|
||
ScriptableObjectCollectionSettings.Instance.SetOverridingStaticFileLocation(windowIDs, true); | ||
ScriptableObjectCollectionSettings.Instance.SetOverridingStaticFileLocation(layerIDs, true); | ||
ScriptableObjectCollectionSettings.Instance.SetOverridingStaticFileLocation(groupIDs, true); | ||
ScriptableObjectCollectionSettings.Instance.SetOverridingStaticFileLocation(transitions, true); | ||
|
||
ScriptableObjectCollectionSettings.Instance.SetStaticFileFolderForCollection(windowIDs, generatedCodeFolderPath); | ||
ScriptableObjectCollectionSettings.Instance.SetStaticFileFolderForCollection(layerIDs, generatedCodeFolderPath); | ||
ScriptableObjectCollectionSettings.Instance.SetStaticFileFolderForCollection(groupIDs, generatedCodeFolderPath); | ||
ScriptableObjectCollectionSettings.Instance.SetStaticFileFolderForCollection(transitions, generatedCodeFolderPath); | ||
|
||
AssetDatabase.SaveAssets(); | ||
AssetDatabase.Refresh(); | ||
Close(); | ||
} | ||
|
||
private bool AreSettingsValid() | ||
{ | ||
return ScriptableObjectFolder != null; | ||
} | ||
|
||
public static bool NeedSetup() | ||
{ | ||
if (!CollectionsRegistry.Instance.TryGetCollectionForType(out ScriptableObjectCollection<WindowID> _)) | ||
return true; | ||
|
||
if (!CollectionsRegistry.Instance.TryGetCollectionForType(out ScriptableObjectCollection<LayerID> _)) | ||
return true; | ||
|
||
if (!CollectionsRegistry.Instance.TryGetCollectionForType(out ScriptableObjectCollection<GroupID> _)) | ||
return true; | ||
|
||
if (!CollectionsRegistry.Instance.TryGetCollectionForType(out ScriptableObjectCollection<TransitionBase> _)) | ||
return true; | ||
|
||
return false; | ||
} | ||
} | ||
} |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
using BrunoMikoski.ScriptableObjectCollections; | ||
using UnityEditor; | ||
|
||
namespace BrunoMikoski.UIManager | ||
{ | ||
public static class UIManagerEditorTools | ||
{ | ||
|
||
[MenuItem("Tools/UI Manager/Initial Setup")] | ||
public static void InitialSetup() | ||
{ | ||
InitialSetupEditorWindow.Open(); | ||
} | ||
|
||
[MenuItem("Tools/UI Manager/Initial Setup", true)] | ||
public static bool InitialSetup_Validator() | ||
{ | ||
return !InitialSetupEditorWindow.NeedSetup(); | ||
} | ||
} | ||
|
||
} |