vargonian
vargonian

Reputation: 3234

Is it possible to inject a component that doesn't have a prefab/GameObject associated with it?

I have a game object (a cube, let's say) which exists in the scene, and I want it to have an injectable component. I want to be able to say, for example: My cube has an IShotFirer member, which can resolve to either a BoomShotFirer or a BangShotFirer MonoBehavior component, both of which implement IShotFirer. When binding happens, I want this component to be added to the cube object.

public class CubeBehavior : MonoBehaviour
{
    [Inject]
    private IShotFirer shotFirer;
}

Is it possible to do this without 1) needing an existing prefab which contains one of these Bang/Boom components, or 2) needing an existing scene object which has one of these components attached?

In other words, I want to be able to dynamically add the component to my game object depending on the bindings, and not relying on anything other than the script files which define either BoomShotFirer or BangShotFirer. But the docs seem to imply that I need to find an existing game object or prefab (e.g. using .FromComponentsInChildren(), etc.)

Upvotes: 1

Views: 1911

Answers (1)

hugo
hugo

Reputation: 3231

Is it possible to do this without 1) needing an existing prefab which contains one of these Bang/Boom components, or 2) needing an existing scene object which has one of these components attached?

Yes, it is.

Zenject provides a host of helpers that create a new components and bind them -- quoting the docs:

  • FromNewComponentOnRoot - Instantiate the given component on the root of the current context. This is most often used with GameObjectContext.

    Container.BindInterfacesTo<BoomShotFirer>().FromNewComponentOnRoot();
    
  • FromNewComponentOn - Instantiate a new component of the given type on the given game object

    Container.BindInterfacesTo<BoomShotFirer>().FromNewComponentOn(someGameObject);
    
  • FromNewComponentOnNewGameObject - Create a new game object at the root of the scene and add the Foo MonoBehaviour to it

    Container.BindInterfacesTo<BoomShotFirer>().FromNewComponentOnNewGameObject();
    

    For bindings like this one that create new game objects, there are also extra bind methods you can chain:

    • WithGameObjectName = The name to give the new Game Object associated with this binding.
    • UnderTransformGroup(string) = The name of the transform group to place the new game object under.
    • UnderTransform(Transform) = The actual transform to place the new game object under.
    • UnderTransform(Method) = A method to provide the transform to use.

That list is not even exhaustive, be sure to check the readme and the cheatsheet (from both of which I have extracted the info above).


Also understand that, as usual, you can append .AsSingle(), .AsTransient() and .AsCached() to achieve the desired result.

Upvotes: 3

Related Questions