1

I've been trying to fix this for several days now and I'm not really sure how. First I'm creating AssetBundles which have prefabs and GameObjects with Textures. After building the AssetBundle, it's uploaded to a server, and in another Android app, I retrieve it and unload its assets. Everything works fine on the Unity editor "Game View", but on the android phone, the textures of dynamic GameObjects appear black. Static textures, like the texture I'm using for the background, appear normally on both the editor and the android device. The textures which appear black are those that I retrieve from the AssetBundles.

When I searched about it, I came across these suggestions:

  1. It might have to do with compression. The problem is, these textures are retrieved from AssetBundles on the server dynamically. I can not "build" the project with the suggested settings after I unload them from the bundle. I tried automatically compressing the images to "Compressed ETC 4 Bits" before loading them in the AssetBundle, and it didn't solve the issue. https://forum.unity.com/threads/black-textures-on-some-devices-android-versions.195328/
  2. I also tried to do it manually by loading the texture (and material) from the AssetBundle and assigning it to the loaded object, but it still only appears in the Editor, not the phone. https://answers.unity.com/questions/238109/problem-with-materials-after-creating-asset-bundle.html
  3. I tried saving the image as a sprite before loading it to the AssetBundle. And in the app I tried creating a new texture with that sprite, but that approach also didn't work. https://answers.unity.com/questions/651984/convert-sprite-image-to-texture.html

First I drag and drop the image for the texture and it gets automatically compressed using this function:

// Automatically Compress all imported textures to the project to ETC_RGBA
void OnPreprocessTexture(Texture2D t)
{
    EditorUtility.CompressTexture(t, TextureFormat.ETC_RGBA8_3DS, TextureCompressionQuality.Normal);
}

Then I manually add the texture to a 3D GameObject in the editor and create a prefab and add that GameObject to it. I add the prefab itself, the material and the image to the AssetBundle and do this to export the AssetBundle: (Now the AssetBundle contains 3 assets in total. I upload it to a server)

//Creates a new menu (Build Asset Bundles) and item (Normal) in the Editor
[MenuItem("Assets/Build Asset Bundles/Normal")]
static void BuildABsNone()
{
    BuildPipeline.BuildAssetBundles("Assets/AssetBundle", BuildAssetBundleOptions.None, BuildTarget.Android);
}

In the app, I dynamically load the AssetBundle from a server and I want to show it on top of an ImageTarget using Vuforia. This is part of the IEnumerator DownloadAndCache() function in the CloudHandler class which loads the material asset and instantiates the GameObject "mBundleInstance". I then display that "mBundleInstance" on an image target:

            bundle = www.assetBundle;

            var materials = bundle.LoadAllAssets(typeof(Material));
            containsMaterial = (materials.Length > 0);

            if (AssetName == "")
            {
                mBundleInstance = Instantiate(getMainAsset(bundle)) as GameObject;
            }
            else
            { 
                mBundleInstance = Instantiate(bundle.LoadAsset(AssetName, typeof(GameObject))) as GameObject;
            }
            Debug.Log(mBundleInstance.GetComponent<Renderer>().material.mainTexture.name);
            //returns the correct name of the compressed png image
            if (containsMaterial)
            {
                foreach (Material m in materials)
                {
                    var shaderName = "Standard";
                    var newShader = Shader.Find(shaderName);

                    if (newShader != null)
                    {
                        m.shader = newShader;

                        mBundleInstance.GetComponent<Renderer>().material = m;
                        Debug.Log("actual texture name: " + mBundleInstance.GetComponent<Renderer>().material.mainTexture.name);
                        //returns the correct name of the png image
                    }
                    else
                    {
                        Debug.LogWarning("unable to refresh shader: " + shaderName + " in material " + m.name);
                    }
                 }
              }

Here is how it looks like in the Editor's GameView: Texture of GameObject appears: (The King of Diamonds image)

And this is how it looks like on the Android device: Texture of Gameobject does not appear.

Since there's no visible error, I'm not really sure why this bug happens. Any help or suggestion why this happens or what I can do to fix it?

Sara Nagui
  • 11
  • 1
  • 4
  • You have to include the actual code you are using to download and access the texture from the server. Also show the code that assigns the texture to your object. Without them, we can't tell what you are doing wrong – Programmer Jun 10 '18 at 08:46
  • I agree with @Programmer, and also I think adding some screenshots and if you are using special package for managing asset bundles, and which version of unity you are using. – WaleedYaser Jun 10 '18 at 09:25
  • @Programmer I edited the question now to include the scripts and more details. I also uploaded two pictures to show how it's supposed to work (it's already working in the editor play mode) and how it shows on the Android device. – Sara Nagui Jun 10 '18 at 13:03
  • @WaleedYaser I'm using Unity 2018.1.0f2 with Vuforia API. I'm new to both Unity and Vufiria actually so I'm not sure if I'm using a "special package" but I don't think so. – Sara Nagui Jun 10 '18 at 13:07
  • I'm not sure how to make it run, a lot of variables are missing and but I have some notes. first, check the unity tutorial on asset bundles https://unity3d.com/learn/tutorials/topics/scripting/assetbundles-and-assetbundle-manager Second try to use this from the asset store https://assetstore.unity.com/packages/tools/utilities/asset-bundle-browser-93571 – WaleedYaser Jun 11 '18 at 17:54

0 Answers0