Search Unity

Instantiate API: Other than GameObject type does not work

Discussion in 'Addressables' started by optimise, Nov 9, 2018.

  1. optimise

    optimise

    Joined:
    Jan 22, 2014
    Posts:
    2,129
    Currently when you put type other than GameObject like SomeScript, it will fail at Packed Mode and real player build. Not sure it's still work in progress or bug.
     
  2. 5argon

    5argon

    Joined:
    Jun 10, 2013
    Posts:
    1,555
    In InstanceProvider.cs it says that the type must be strictly GameObject.

    Code (CSharp):
    1.         /// <inheritdoc/>
    2.         public bool CanProvideInstance<TObject>(IResourceProvider loadProvider, IResourceLocation location)
    3.             where TObject : Object
    4.         {
    5.             if (loadProvider == null)
    6.                 return false;
    7.             return loadProvider.CanProvide<TObject>(location) && ResourceManagerConfig.IsInstance<TObject, GameObject>();
    8.         }
    The key you use for Addressables point to a game object (blue box dragged to Addressable panel), the returned object type is GameObject. The generic here is the type to load, not the type to instantiate. Addressables.Instantiate is a load operation, then instantiate the thing loaded with `Object.Instantiate(loaded)`.

    This generic type eventually go to assetbundle.LoadAssetAsync<T>, in which the only correct choice is GameObject if your key point to a game object. So you have to use GameObject.

    If you want to be able to use the generic as anything that is currently attached on your Addressable-loaded GameObject, then you could write a wrapper script that use a normal Addressables.LoadAsset<GameObject> with the same key. You would get a game object variable without the instantiation step. Then, c = go.GetComponent<T> and then `Object.Instantiate(c)`. But it would give the same result as Instantate<GameObject> in the first place, as Object.Instantiate(component) will just ask for the containing game object to be instantiated along with all components.
     
    Last edited: Nov 10, 2018
  3. unity_bill

    unity_bill

    Joined:
    Apr 11, 2017
    Posts:
    1,053
    @5argon is right that you have to load the game object, then retrieve the component. The fact that you don't have to do that in fast or virtual mode is something we intend to remove. It happens to work there, but doesn't actually make sense to work in the context of a real built player. So on our to-do list is to disable it in fast and virtual.

    -Bill
     
  4. AlkisFortuneFish

    AlkisFortuneFish

    Joined:
    Apr 26, 2013
    Posts:
    973
    I was pondering on this API a while ago. Since there is no way to load a component on a prefab directly since 5.0, I wonder if the very idea of the API used for this being generic even makes any sense anymore. Maybe there should be an Instantiate that returns GameObject and an Instantiate<T>() where T : ScriptableObject, rather than even allowing Instantiate to take a type parameter for prefabs.
     
  5. unity_bill

    unity_bill

    Joined:
    Apr 11, 2017
    Posts:
    1,053

    not a bad idea. I'll note that as we explore our options. thanks!