Going down a rabbit hole on this just trying to test something…
I wanted to try the following:
- Save all of the cached shaders from the device into a folder in the Unity project
- Build the game, then at runtime, copy the cached shader files from the folder in Unity into the device’s cached shader folder
My first attempt was to create a StreamingAssets folder in my project, copy the cached shader files into this folder, then use System.IO to iterate over all the files in the StreamingAssets folder and copy them to the device’s folder like so
public const string SourceCachePath = "ShaderCache";
public const string DestinationCachePath0 = "cache";
public const string DestinationCachePath1 = "UnityShaderCache";
public static void LoadCache()
{
DirectoryInfo rootDir = Directory.GetParent(Application.persistentDataPath);
string destPath = Path.Combine(rootDir.FullName, DestinationCachePath0, DestinationCachePath1);
// Attempt to create directory if it doesnt already exist
Directory.CreateDirectory(destPath);
string[] cache = Directory.GetFiles(Path.Combine(Application.streamingAssetsPath, SourceCachePath));
for (int i = 0; i < cache.Length; i++)
{
// Remove source path from file name
string f = cache[i].Substring(SourceCachePath.Length + 1);
// Copy file to destination
File.Copy(cache[i], Path.Combine(destPath, f));
}
}
I found out that you cant access StreamingAssets directly on Android and need to use a UnityWebRequest. However, the UnityWebRequest requires that you specify each file name, which is difficult as there are thousands of files. I could generate a text file with all of the names of these cached shader files, put that in the StreamingAssets folder, read that file then use that to read the rest of the files, but this is a huge PITA for such a simple task.
Going over the other options; theres AssetBundles and Addressables. In either case, Im not sure if loading the files into memory would allow me to write them into the device’s destination folder, or how to do that. Additionally, it looks like a lot of these functions require you to specify the Type of the asset that youre loading, and these cached shader files dont have any extension, so Im not sure what type to specify, or if just using Object as a type will work.
Im avoiding doing all this work as I dont even know if copying the cached shader files into the device folder will actually accomplish the goal of eliminating the shader compile hitches, or if Ill just be copying junk data over. Are the names of these generated files unique to the shader variant? Are they random? Will it work across different Quest headsets with the same GPU??
Any info from Unity or someone whos perhaps tried this would be extremely helpful and save me a lot of potentially wasted time.
Thanks.