Fix UnityPrepareRendererResources trying to destroy texture assets #402
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Fixes #344.
Currently, when UnityPrepareRendererResources frees a tile, it calls
DestroyImmediate
on the material and all of its textures. This is fine and in fact desired behavior for the materials and textures Cesium creates at runtime - we need to make sure these texture resources get cleaned up so we don't leak memory. This is also fine for user-provided materials, as we create a new instance of the material - as long as the material doesn't have any texture assets set for its texture properties. Textures aren't copied when you copy a material, so whenfreePrimitiveGameObject
goes through all of the material's texture properties and callsDestroy
on everything it finds, it ends up attempting to destroy the assets the end user specified on the material. This produces a "Destroying assets is not permitted to avoid data loss" error.There are two ways we can solve this. The first way would be to make a new instance of all the textures the same way we make a new instance of the materials. However, it would be simpler to just keep track of all the textures we're creating at runtime, and just not try to destroy textures we didn't create. There's a few ways to do this, but I went with the simplest - setting the
UnityEngine::HideFlags::HideAndDontSave
hideFlag on each texture created, and checking it before destroying. This prevents assets from being destroyed.One caveat is that if the user sets a texture they created on the material that also has
UnityEngine::HideFlags::HideAndDontSave
set, our code will attempt to destroy it too. This won't result in errors, just undesirable behavior. However, I think this possibility is pretty slim, and in the case where it's an issue we can suggest that they simply useUnityEngine::HideFlags::DontSave
instead.