Answer the exact question first
AssetBundle.LoadFromFile does not compute or enforce a checksum on the file it reads. It simply streams the binary data into memory. The only indicator of success that Unity exposes is the isValid property of the returned AssetBundle instance, which is set after the load operation completes.
Likely explanation
AssetBundle.LoadFromFile will throw an exception or return a bundle with isValid == false if the file is truncated or otherwise unreadable.
- Unity’s
AssetBundleManifest can contain a hash for each bundle, but the API does not consult it automatically. It is only useful if you retrieve it yourself and compare it.
- Because the API does not pre‑validate, a corrupted file can still cause a crash during load if the corruption is deep enough to break the internal parsing logic.
Confirmed facts
- LoadFromFile never performs a checksum as part of its internal logic.
- The
isValid flag is only set after the load attempt.
- Typical practice is to compute a cryptographic hash (e.g., SHA‑256) of the file on the client and compare it to a known good value before calling LoadFromFile.
Recommended verification workflow
- Store a known‑good hash. Keep the expected SHA‑256 value in a secure manifest or fetch it from a trusted server at runtime.
- Read the file into a byte array. Use
File.ReadAllBytes or a streaming API that preserves the exact binary contents as delivered.
- Compute the hash. In C#:
var hash = System.Security.Cryptography.SHA256.Create().ComputeHash(fileBytes);
var hashString = BitConverter.ToString(hash).Replace("-", "");
- Compare. If
hashString does not match the expected value, abort the load and report an error.
- Load the bundle. Wrap
AssetBundle.LoadFromFile in a try/catch block. Immediately after loading, check bundle.isValid. If it is false, treat the bundle as unusable.
- Log both the hash and
isValid status. This aids post‑mortem analysis if a crash occurs.
Sample code snippet
using System.IO;
using System.Security.Cryptography;
public AssetBundle LoadVerifiedBundle(string path, string expectedHash)
{
byte[] data = File.ReadAllBytes(path);
string actualHash = BitConverter.ToString(SHA256.Create().ComputeHash(data)).Replace("-", "");
if (!string.Equals(actualHash, expectedHash, StringComparison.OrdinalIgnoreCase))
{
Debug.LogError($"Hash mismatch for {path}. Expected {expectedHash}, got {actualHash}");
return null;
}
try
{
var bundle = AssetBundle.LoadFromFile(path);
if (bundle == null || !bundle.isValid)
{
Debug.LogError($"Failed to load bundle {path} or bundle is invalid.");
return null;
}
return bundle;
}
catch (System.Exception ex)
{
Debug.LogError($"Exception while loading bundle {path}: {ex.Message}");
return null;
}
}
Ask for missing diagnostic detail
If you do not already have a trusted hash source for each bundle, consider adding a lightweight server‑side manifest that serves the SHA‑256 values. This eliminates the risk of storing the hash on the client in an insecure manner.