Scene Decorators - mariaheine/Zenject-But-Wiki GitHub Wiki
Scene Decorators offer another approach to using multiple scenes together with zenject in addition to scene parenting described above. The difference is that with scene decorators, the multiple scenes in question will all share the same Container and therefore all scenes can access bindings in all other scenes (unlike with scene parenting where only the child can access the parent bindings and not vice versa).
Another way to think about scene decorators is that it is a more advanced way doing the process described for injecting data across scenes. That is, they can be used to add behaviour to another scene without actually changing the installers in that scene.
Usually, when you want to customize different behaviour for a given scene depending on some conditions, you would use boolean or enum properties on MonoInstallers, which would then be used to add different bindings depending on the values set. However, the scene decorator approach can be cleaner sometimes because it doesn't involve changing the main scene.
For example, let's say we want to add some special keyboard shortcuts to your main production scene for testing purposes. In order to do this using decorators, you would do the following:
- Open the main production scene
- Right click on the scene name within the scene hierarchy and select
Add New Scene
- Drag the scene so it's above the main scene
- Right Click inside the new scene and select
Zenject -> Decorator Context
- Select the Decorator Context and set the 'Decorated Contract Name' field to 'Main'
- Select the SceneContext in the main scene and add a contract name with the same value ('Main')
- Create a new C# script with the following contents, then add this MonoBehaviour to your decorator scene as a gameObject, then drag it to the
Installers
property ofSceneDecoratorContext
public class ExampleDecoratorInstaller : MonoInstaller
{
public override void InstallBindings()
{
Container.Bind<ITickable>().To<TestHotKeysAdder>().AsSingle();
}
}
public class TestHotKeysAdder : ITickable
{
public void Tick()
{
if (Input.GetKeyDown(KeyCode.Space))
{
Debug.Log("Hotkey triggered!");
}
}
}
Note the following:
-
If you run your scene it should now behave exactly like the main scene except with the added functionality in your decorator installer. Also note that while not shown here, both scenes can access each other's bindings as if everything was in the same scene.
-
The Validate command (
CTRL+ALT+V
) can be used to quickly verify the different multi-scene setups. If you find that scenes are unloaded when you do this see here. -
🔥 Decorator scenes must be loaded before the scenes that they are decorating.
-
Unity currently doesn't have a built-in way to save and restore multi-scene setups. We use a simple editor script for this that you can find here if interested.
-
Finally, if you want to save yourself some time you could add a default scene for the contract name that you are using above