So I have two scripts, Character and PlayerInstaller
using UnityEngine;
using Zenject;
public class Character : MonoBehaviour
{
[SerializeField] private Vector3 VelocityWhenPressed = Vector3.up;
private Rigidbody m_Rigidbody;
[Inject]
public void Construct(Rigidbody rigidbody)
{
m_Rigidbody = rigidbody;
}
private void Update()
{
if(Input.GetMouseButtonDown(0))
{
m_Rigidbody.velocity += VelocityWhenPressed;
}
if(Input.GetMouseButtonUp(0))
{
m_Rigidbody.velocity -= VelocityWhenPressed;
}
}
}
using UnityEngine;
using Zenject;
public class PlayerInstaller : MonoInstaller
{
[SerializeField] private Rigidbody m_PlayerRigidbody;
[SerializeField] private Character m_TheCharacter;
public override void InstallBindings()
{
this.Container.Bind<Rigidbody>().FromInstance(m_PlayerRigidbody).AsSingle();
this.Container.Bind<Character>().FromInstance(m_TheCharacter).AsSingle();
}
}
If I create a game object with Rigidbody, add there Character component, create another game object, add there components GameObjectContext and PlayerInstaller and add PlayerInstaller to MonoInstallers of GameObjectContext, Construct method will not be invoked. But if I do the same thing with SceneContext instead of GameObjectContext, it will work. How to do that with GameObjectContext?
If I do the same thing with SceneContext instead of GameObjectContext, it works well.
The difference between SceneContext
and GameObjectContext
is that they handle a Scene and a GameObject respectively.
When you use your installer in SceneContext
it works because everything is part of the scene.
But when you use it in GameObjectContext
, it doesn't work because your Rigidbody/Character components belong to a separate GameObject hiearchy and thus injection doesn't happen.
In the installer itself, you only bind your components as references, so no injection into components happens either. This way you only make the context aware of these classes for future injections that the context could handle.
Plus, there are more issues with your setup:
If you have SceneContext
in your scene, SceneContext
will try to automatically inject into Character because Character
belongs to the scene and has [Inject]
attribute. And it will fail unless it knows about some Rigidbody (which is probably a wrong one anyway).
And if you don't have SceneContext
in your scene, then GameObjectContext
and your installer will not run at all.
So, to correctly use the GameObjectContext
here, make your Rigidbody/Character GameObject a child of it. With this setup, your GameObjectContext
will properly inject Rigidbody into Character and your SceneContext
will not interfere.