- 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.
- 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.
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.
Set this to change the main canvas scaler and the game window sizeFrom Menu: SS / Screen Settings / Input Screen Width & Height / Save
From Menu: SS / Screen Generator / Input Screen Name / Generate
ScreenManager.Add<Screen1Controller>(screenName: "Screen1");
ScreenManager.Close();
ScreenManager.Load<Scene1Controller>(sceneName: "Scene1");
If you want to use Addressables, you do not need to drag screen prefabs to Resources/Screens
From Menu: Window / Package Manager / Unity Registry / Addressables / Install
From Menu: Edit / Project Settings / Player / Other Settings / Scripting Define Symbols / + / ADDRESSABLE / Apply
Make sure the addressable name is the same as the screen name, not a path to the prefab.
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.
}
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);
Put your custom animations (Unity legacy animations) in Resources/Animations
Add screen with custom animations
ScreenManager.Add<Screen1Controller>(screenName: "Screen1", showAnimation: "Custom1Show", hideAnimation: "Custom1Hide");
In default, animations will be added to the root object of screen
ScreenManager.Add<Screen1Controller>(screenName: "Screen1");
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");
In default, Screen Animation Speed is 1. You can change it.
ScreenManager.Set(screenAnimationSpeed: 1.5f);
Note: onScreenLoaded is called after Awake & OnEnable, before Start of scripts in screen
ScreenManager.Add<Screen1Controller>(screenName: "Screen1", onScreenLoad: (screen) => {
// screen.Init();
});
Note: onSceneLoaded is called after Awake & OnEnable, before Start of scripts in scene
ScreenManager.Load<Scene1Controller>(sceneName: "Scene1", onSceneLoaded: (scene1) =>
{
// scene1.Init();
});
Note: onScreenClosed is called after the hideAnimation is ended (right after the screen is destroyed)
ScreenManager.Close(() =>
{
// Code after closing this screen
});
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();
}
}
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
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();
}
}
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);
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");
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;
}
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
}
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.
ScreenManager.Set(screenShieldColor: new Color(0, 0, 0, 0.8f));
ScreenManager.Add<Screen1Controller>(screenName:"Screen1");
ScreenManager.Add<Screen1Controller>(screenName:"Screen1", hasShield: false);
ScreenManager.ShowShield();
ScreenManager.HideShield();
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);
By default, this parameter is false, instantiate a new screen whenever Add is called
ScreenManager.Add<Screen2Controller>(screenName: "Screen2");
ScreenManager.Add<Screen1Controller>(screenName: "Screen1");
If this parameter is true, destroy the top screen before adding a screen
ScreenManager.Add<Screen2Controller>(screenName: "Screen2", destroyTopScreen: true);
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");
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");
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);
Show a tooltip with automatic screen padding.
From Menu, SS / Tooltip Generator, input Tooltip name, select Text type (Default or TextMeshPro), click Generate
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();
In some cases, you want to add somethings to the top of all Screens (like some flying coins)
// Coin.cs
transform.SetParent(ScreenManager.Top);
Destroy immediately the screen which is at the top of all screens, without playing animation.
ScreenManager.Destroy();
Destroy immediately all screens, without playing animation.
ScreenManager.DestroyAll();
var screen1 = FindObjectOfType<Screen1Controller>(true);
ScreenManager.Destroy(screen: screen1);
ScreenManager.Close(screen: screen1);
✅ Built-in
✅ URP
✅ HDRP
2022.3.30 or higher. In fact this package can work on most versions of Unity because it is very compact.
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