Skip to content

A simple and flexible Unity library for managing and navigating screens with high performance and reusability.

License

Notifications You must be signed in to change notification settings

AnhPham/Simple-Screen-Manager-for-Unity-aka-SS

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Simple Screen Manager for Unity (aka SS)

Who is this for?

  • Developers looking for a very simple Screen Manager / Navigator for Unity with enough features to build any type of game, even mid-core or more complex projects.
  • Those who want to learn the basics in 10 minutes.
  • Those who want to master advanced features in 30 minutes.

Concept

  • Regardless of fullscreen page or modal/modeless window, they are all considered Screen.
  • At any given time, only one Screen is visible to optimize performance. If a Screen is shown on top of another, the underlying Screen will be temporarily hidden, and it will reappear when the top Screen is closed.
  • A Screen is a freeform prefab that does not require any specific scripts, allowing it to be used as a child object anywhere.
  • A Scene is freeform and contains any object, including its own UI canvas. The Scene’s canvas will not be hidden when a Screen is displayed on top.
  • The package size is only 38 KB and does not depend on any external libraries.

Demo

In this demo, even though they share the same prefab, the Store can be displayed as a modal window or as the content of the Store Tab.

Basic Usage

1. Screen Settings

Set this to change the main canvas scaler and the game window size
From Menu: SS / Screen Settings / Input Screen Width & Height / Save

Demo

2. Create a screen

From Menu: SS / Screen Generator / Input Screen Name / Generate

Demo

3. Drag screen prefab to Resources/Screens folder

In case of not using Addressables

Demo

4. Add a screen on top with default animation

ScreenManager.Add<Screen1Controller>(screenName: "Screen1");

Demo

5. Close a screen

ScreenManager.Close();

Demo

6. Load a scene with automatic fade

ScreenManager.Load<Scene1Controller>(sceneName: "Scene1");

Demo

Basic Usage Tutorial Video

https://youtu.be/mzCAjf7hye4


Advance Usage

1. Addressables

If you want to use Addressables, you do not need to drag screen prefabs to Resources/Screens

1.1. Install Addressables package:

From Menu: Window / Package Manager / Unity Registry / Addressables / Install

1.2. Add this Scripting Define Symbol: ADDRESSABLE

From Menu: Edit / Project Settings / Player / Other Settings / Scripting Define Symbols / + / ADDRESSABLE / Apply

Demo

1.3. Add screen prefab to addressables groups

Make sure the addressable name is the same as the screen name, not a path to the prefab.

Demo

2. Screen Animations

2.1. Default Screen Animations:

public enum ScreenAnimation
{
    BottomHide, // The screen slides from the center to the bottom when hiding.
    BottomShow, // The screen slides from the bottom to the center when showing.
    FadeHide,   // The screen fades out when hiding.
    FadeShow,   // The screen fades in when showing.
    LeftHide,   // The screen slides from the center to the left when hiding.
    LeftShow,   // The screen slides from the left to the center when showing.
    RightHide,  // The screen slides from the center to the right when hiding.
    RightShow,  // The screen slides from the right to the center when showing.
    RotateHide, // The screen rotates clockwise when hiding.
    RotateShow, // The screen rotates counterclockwise when showing.
    ScaleHide,  // The screen scales down to 0 when hiding.
    ScaleShow,  // The screen scales up to 1 when showing.
    TopHide,    // The screen slides from the center to the top when hiding.
    TopShow     // The screen slides from the top to the center when showing.
}

2.2. Set Animations when adding screen:

The screen slides from the left to the center when showing.

ScreenManager.Add<Screen1Controller>(screenName: "Screen1", showAnimation: ScreenAnimation.LeftShow, hideAnimation: ScreenAnimation.LeftHide);

The screen slides from the center to the left when hiding. The 'hideAnimation' which is declared in the Add function will be used

ScreenManager.Close();

The screen fades out when hiding.

ScreenManager.Close(hideAnimation: ScreenAnimation.FadeHide);

2.3. Custom Screen Animations:

Put your custom animations (Unity legacy animations) in Resources/Animations

Demo

Add screen with custom animations

ScreenManager.Add<Screen1Controller>(screenName: "Screen1", showAnimation: "Custom1Show", hideAnimation: "Custom1Hide");

2.4. Custom Animation Object:

In default, animations will be added to the root object of screen

ScreenManager.Add<Screen1Controller>(screenName: "Screen1");

Demo

In case you only want to animate a few objects on the screen, the rest are static and not animated

ScreenManager.Add<Screen1Controller>(screenName: "Screen1", animationObjectName: "Animation");

Demo

2.5. Screen Animation Speed

In default, Screen Animation Speed is 1. You can change it.

ScreenManager.Set(screenAnimationSpeed: 1.5f);

3. Events

3.1. On Screen Loaded

Note: onScreenLoaded is called after Awake & OnEnable, before Start of scripts in screen

ScreenManager.Add<Screen1Controller>(screenName: "Screen1", onScreenLoad: (screen) => {
    // screen.Init();
});

3.2. On Scene Loaded

Note: onSceneLoaded is called after Awake & OnEnable, before Start of scripts in scene

ScreenManager.Load<Scene1Controller>(sceneName: "Scene1", onSceneLoaded: (scene1) =>
{
    // scene1.Init();
});

3.3. On Screen Closed

Note: onScreenClosed is called after the hideAnimation is ended (right after the screen is destroyed)

ScreenManager.Close(() =>
{
    // Code after closing this screen
});

3.4. On Key Back

If you create a screen by the Screen Generator, the screen controller will implement OnKeyBack of the IKeyBack interface by default. It means when players press the physics back button on Android (or ESC key on PC), the screen will be closed. If you don't want that, just remove IKeyBack in the script.

public class Screen1Controller : MonoBehaviour, IKeyBack
{
    public void OnKeyBack()
    {
        ScreenManager.Close();
    }
}

3.5. On Screen Added

Some projects require sending logs for analytics, indicating which screen is added, from which screen, and whether it was added manually (user click) or automatically.

// On Start of Main
ScreenManager.AddListener(onScreenAdded: (toScreen, fromScreen, manually) => {
    Debug.Log(string.Format("Add screen {0} from screen {1} ") + (manually ? "manually" : "automatically"));
});
ScreenManager.Load<Scene1Controller>(sceneName: "Scene1");
// On Screen1 Button Tap
ScreenManager.Add<Screen1Controller>(screenName: "Screen1", manually:true);
// On Start of Screen1Controller
ScreenManager.Add<Screen2Controller>(screenName: "Screen2", manually:false);

Output:

Added Screen1 from Scene1 manually
Added Screen2 from Screen1 automatically

3.6. On Screen Changed

Some projects require displaying an ads banner only when no screens are being shown.

void OnEnable()
{
    ScreenManager.AddListener(OnScreenChanged);
}
void OnDisable()
{
    ScreenManager.RemoveListener(OnScreenChanged);
}
void OnScreenChanged(int screenCount)
{
    if (screenCount > 0)
    {
        // Banner.Hide();
    }
    else
    {
        // Banner.Show();
    }
}

4. Set conditions to display screen

4.1. Wait Until No Screen

In this example, Screen2 will be shown when user closes Screen1, then Screen3 will be shown when user closes Screen2.

ScreenManager.Add<Screen1Controller>(screenName: "Screen1");
ScreenManager.Add<Screen2Controller>(screenName: "Screen2",  waitUntilNoScreen: true);
ScreenManager.Add<Screen3Controller>(screenName: "Screen3",  waitUntilNoScreen: true);

Demo

This example does not use waitUntilNoScreen, 3 Screens will appear consecutively.

ScreenManager.Add<Screen1Controller>(screenName: "Screen1");
ScreenManager.Add<Screen2Controller>(screenName: "Screen2");
ScreenManager.Add<Screen3Controller>(screenName: "Screen3");

Demo

4.2. Custom Add-Condition

In this example, Screen1 will be shown when the bool something variable becomes true

bool something = false;
ScreenManager.Add<Screen1Controller>(screenName: "Screen1", addCondition: WaitSomething);
bool WaitSomething()
{
    return something;
}

4.3. Wait until no screen to do other things

In some cases, you have to wait until there is no more Screen displayed before doing something to avoid being covered by a Screen.

IEnumerator WaitUntilNoScreenToDoSomething()
{
    while (!ScreenManager.IsNoMoreScreen())
    {
        yield return 0;
    }

    // Do somethings
}

5. Screen Shield

The Screen shield is an image with customizable color and transparency, located between the current Scene (with its UI canvas) and the top Screen. By default, the Screen shield will be shown when a Screen is displayed.

5.1. Set Screen Shield Color

ScreenManager.Set(screenShieldColor: new Color(0, 0, 0, 0.8f));

5.2. Display a Screen with/without a Shield

ScreenManager.Add<Screen1Controller>(screenName:"Screen1");

Demo

ScreenManager.Add<Screen1Controller>(screenName:"Screen1", hasShield: false);

Demo

5.3. Show/Hide the Screen shield manually (with fade animation)

ScreenManager.ShowShield();
ScreenManager.HideShield();

Demo

6. Other parameters of adding a screen

6.1. Use Existing Screen

If this parameter is true, check if the screen is existing, bring it to the top. If not found, instantiate a new one

ScreenManager.Add<Screen2Controller>(screenName: "Screen2", useExistingScreen: true);
ScreenManager.Add<Screen1Controller>(screenName: "Screen1", useExistingScreen: true);

Demo

By default, this parameter is false, instantiate a new screen whenever Add is called

ScreenManager.Add<Screen2Controller>(screenName: "Screen2");
ScreenManager.Add<Screen1Controller>(screenName: "Screen1");

Demo

6.2. Destroy Top Screen

If this parameter is true, destroy the top screen before adding a screen

ScreenManager.Add<Screen2Controller>(screenName: "Screen2", destroyTopScreen: true);

Demo

By default, this parameter is false, temporary hide the top screen when add the Screen2, and show it again after closing the Screen2

ScreenManager.Add<Screen2Controller>(screenName: "Screen2");

Demo

7. Loading

7.1. Scene Loading

Show a loading UI while loading a Scene.

From Menu, SS / Screen Generator, create a Screen named SceneLoading. Use ScreenManager.asyncOperation.progress to get progress of scene loading, like below example

public class SceneLoadingController : MonoBehaviour
{
    const float PROGRESS_WIDTH = 500;
    const float PROGRESS_HEIGHT = 50;

    [SerializeField] RectTransform m_Progress;

    private void Update()
    {
        m_Progress.sizeDelta = new Vector2(ScreenManager.asyncOperation.progress * PROGRESS_WIDTH, PROGRESS_HEIGHT);
    }
}

Do not forget to set the Scene Loading name on App Launch

ScreenManager.Set(sceneLoadingName: "SceneLoading");

Demo

7.2. Loading on Top

Show a loading UI on top of all screens

From Menu, SS / Screen Generator, create a Screen named Loading. You should add a loop loading animation to it.

Do not forget to set the Loading name on App Launch

ScreenManager.Set(loadingName: "Loading");

Show Loading

ScreenManager.Loading(true);

Hide Loading

ScreenManager.Loading(false);

Demo

8. Tooltip

Show a tooltip with automatic screen padding.

Demo

From Menu, SS / Tooltip Generator, input Tooltip name, select Text type (Default or TextMeshPro), click Generate

Demo

Edit the Tooltip prefab as you want, drag it to Resources/Screens folder (or drag to Addressable Group in case of using Addressables). You can also edit the Tooltip showing animation

Do not forget to set the Tooltip name on App Launch

ScreenManager.Set(tooltipName: "Tooltip");

Show the tooltip

public Transform button;
// targetY is the distance from the start position along the Y axis
ScreenManager.ShowTooltip(text: "Tooltip Text", worldPosition: button.position, targetY: 100f);

Hide the tooltip

ScreenManager.HideTooltip();

9. Other useful methods of ScreenManager

9.1. Top

In some cases, you want to add somethings to the top of all Screens (like some flying coins)

// Coin.cs
transform.SetParent(ScreenManager.Top);

9.2. Destroy

Destroy immediately the screen which is at the top of all screens, without playing animation.

ScreenManager.Destroy();

9.3. DestroyAll

Destroy immediately all screens, without playing animation.

ScreenManager.DestroyAll();

9.4. Destroy or Close a specific screen

var screen1 = FindObjectOfType<Screen1Controller>(true);
ScreenManager.Destroy(screen: screen1);
ScreenManager.Close(screen: screen1);

Render pipeline compatibility

✅ Built-in
✅ URP
✅ HDRP

Unity Version

2022.3.30 or higher. In fact this package can work on most versions of Unity because it is very compact.

License

This software is released under the MIT License.
You are free to use it within the scope of the license.
However, the following copyright and license notices are required for use.

https://github.com/AnhPham/Simple-Screen-Manager-for-Unity-aka-SS?tab=MIT-1-ov-file

About

A simple and flexible Unity library for managing and navigating screens with high performance and reusability.

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages