Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

StateMachineBehaviour injection causes assert (Cannot use FromComponentSibling...) #517

Closed
zakarntson opened this issue Aug 1, 2018 · 3 comments

Comments

@zakarntson
Copy link

zakarntson commented Aug 1, 2018

Environment:
Unity 2018.2.1f1, Zenject 7.0.0 (from Asset Store)

Steps to Repro:

  1. Create an animation controller with states that contain StateMachineBehaviours.
  2. Call Instantiator.InstantiateComponent on a gameObject.
  3. Call foreach (var behaviour in animator.GetBehaviours()) { Container.Inject(behaviour); }
  4. Alternately to Step 3, Instantiator.InstantiateComponent(gameObject);
  5. Run game.

NOTE:
The MonoBehaviour calling this code is injected via Container.Bind().FromComponentSibling().AsSingle();

Expected:
StateMachineBehaviours to be properly injected.

Results:
Assert: ZenjectException: Assert hit! Cannot use FromComponentSibling to inject data into non monobehaviours!

Callstack:
ZenjectException: Assert hit! Cannot use FromComponentSibling to inject data into non monobehaviours!
ModestTree.Assert.That (Boolean condition, System.String message) (at Assets/Plugins/Zenject/Source/Internal/Assert.cs:319)
Zenject.FromBinderGeneric1[GameStateManager].<FromComponentSibling>m__1 (Zenject.InjectContext ctx) (at Assets/Plugins/Zenject/Source/Binding/Binders/FromBinders/FromBinderGeneric.cs:205) Zenject.MethodProviderMultiple1[GameStateManager].GetAllInstancesWithInjectSplit (Zenject.InjectContext context, System.Collections.Generic.List1 args, System.Action& injectAction) (at Assets/Plugins/Zenject/Source/Providers/MethodProviderMultiple.cs:52) Zenject.CachedProvider.GetAllInstancesWithInjectSplit (Zenject.InjectContext context, System.Collections.Generic.List1 args, System.Action& injectAction) (at Assets/Plugins/Zenject/Source/Providers/CachedProvider.cs:78)
Zenject.IProviderExtensions.GetAllInstances (IProvider creator, Zenject.InjectContext context, System.Collections.Generic.List1 args) (at Assets/Plugins/Zenject/Source/Providers/IProviderExtensions.cs:28) Zenject.IProviderExtensions.GetAllInstances (IProvider creator, Zenject.InjectContext context) (at Assets/Plugins/Zenject/Source/Providers/IProviderExtensions.cs:19) Zenject.DiContainer.GetDecoratedInstances (IProvider provider, Zenject.InjectContext context) (at Assets/Plugins/Zenject/Source/Main/DiContainer.cs:1140) Zenject.DiContainer.SafeGetInstances (Zenject.ProviderInfo providerInfo, Zenject.InjectContext context) (at Assets/Plugins/Zenject/Source/Main/DiContainer.cs:1079) Zenject.DiContainer.Resolve (Zenject.InjectContext context) (at Assets/Plugins/Zenject/Source/Main/DiContainer.cs:1004) Zenject.DiContainer.InjectExplicitInternal (System.Object injectable, System.Type injectableType, Zenject.InjectArgs args) (at Assets/Plugins/Zenject/Source/Main/DiContainer.cs:1409) Zenject.DiContainer.InjectExplicit (System.Object injectable, System.Type injectableType, Zenject.InjectArgs args) (at Assets/Plugins/Zenject/Source/Main/DiContainer.cs:1357) Zenject.DiContainer.InjectExplicit (System.Object injectable, System.Collections.Generic.List1 extraArgs) (at Assets/Plugins/Zenject/Source/Main/DiContainer.cs:1313)
Zenject.DiContainer.Inject (System.Object injectable, IEnumerable`1 extraArgs) (at Assets/Plugins/Zenject/Source/Main/DiContainer.cs:2232)
Zenject.DiContainer.Inject (System.Object injectable) (at Assets/Plugins/Zenject/Source/Main/DiContainer.cs:2224)
Zenject.ZenjectStateMachineBehaviourAutoInjecter.Start () (at Assets/Plugins/Zenject/Source/Util/ZenjectStateMachineBehaviourAutoInjecter.cs:31)

@zakarntson
Copy link
Author

NOTE: I wanted to inject via an already existing component since I have serializable data I'm using. I worked around this issue by hardcoding my serializable data and using:
Container
.Bind()
.To()
.FromNewComponentOnNewGameObject()
.WithGameObjectName("GameStateManager")
.AsSingle();

@svermeulen
Copy link

You can't use FromComponentSibling for non-monobehaviours because Zenject cannot figure out, from a non-monobehaviour, what game object should be used for the new monobehaviour (unless we do something like https://github.com/svermeulen/Zenject/pull/300). And StateMachineBehaviours are non-monobehaviours which is why I assume this is happening. So I'm not sure this is fixable.

By the way, StateMachineBehaviour should automatically be injected now when the game object that it's on gets injected as of zenject 7

@svermeulen
Copy link

If there was a way to find out the game object from a StateMachineBehaviour reference we could make a special case for this though, but as far as I can tell there isn't

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants