0
\$\begingroup\$

My game has a lot of different materials, shaders and textures. When a bunch of players are dropped into the same game, I want those assets to be loaded from an external source instead of being built into the game from the start.

Problem is, with C# being such a non-agile language, and UnityWebRequest being unable to read .mat or .shader from the box, I don't know how to work with those files.

Ideally, I just want to write:

UnityWebRequest req = UnityWebRequest.Get("http://pathToMaterials/material.mat");

Material material = req.downloadHandler;

Or something...

\$\endgroup\$
  • 2
    \$\begingroup\$ Shader and material files are typically tiny — are you sure this is a worthwhile investment of time & code complexity to try to stream these assets? Textures can be quite bulky, so it makes sense to stream them in many cases. Have you tried profiling your memory use & performance when streaming just the textures, while keeping the materials built-in? \$\endgroup\$ – DMGregory Oct 16 '18 at 12:31
  • \$\begingroup\$ @DMGregory No I certainly am not sure! The biggest advantage I wanted to reach was the ability to create new materials without having to update the code/game. \$\endgroup\$ – Yeats Oct 17 '18 at 1:30
1
\$\begingroup\$

Put your assets into an asset bundle file.

After you retrieved the raw binary data representation of your asset bundle from your UnityWebRequest, use AssetBundle.LoadFromMemory (or the non-blocking variant LoadFromMemoryAsync) to get an AssetBundle object and then call the method LoadAsset (or LoadAssetAsync) on it to retrieve the material asset from it.

But just as DMGregory wrote in a comment: This really only makes sense if you allow users to program their own shaders. When the materials you want to load at runtime use the same shader and only differ by their texture (and maybe other shader parameters), then it might be better to ship a material with that shader but without a texture with the game. Download only the texture (and other parameters) and set it at runtime via the renderer.material of your game object.

By the way: when you change something at renderer.material, then Unity actually creates a new, nameless material and assigns it to the renderer. If you want to change the material directly in a way which affects all game objects with the same material, use renderer.sharedMaterial.

\$\endgroup\$
  • \$\begingroup\$ I was hoping to avoid asset bundles since they seem so needlessly complicated and tedious to create. It's beyond my current abilities, which is why I hoped to make a custom UnityWebRequest to handle materials directly. But you're also right that it might only be necessary for the textures themselves. \$\endgroup\$ – Yeats Oct 17 '18 at 1:28

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.