- Home /
How does setting the hideFlags resolve leaking issues? (Texture 2D leaking)
I've been having this issue for quite some time. I found this question (exact same issue).
But I am not able to understand how setting the hideFlags solves the issue. The answer didn't tell which flag to set to, but I assume it's DontSave
.
From the docs, setting that flag means that the object will not be saved to the scene, and the object's management (Destroying it) is on the programmer's shoulders.
I'm not sure what does "not saved in the scene means" (apart from it being non-persistent between editor sessions)
I also noticed that setting that flag on a an object, will keep that object alive when I switch scenes.
Can somebody explain?
Thanks!
Answer by immersiveGamer · Feb 23, 2014 at 08:41 AM
The reason setting the hide flags solves the problem is because you are defining the scope of the object you are creating. When you work with game objects and all that goes with it you are creating objects that are rooted in the scene. So when Unity re-compiles it's assembly code it has a place to be saved, that is the scene. Also when you save an object as an asset it is saved in the assets folder, thus has a place. in your case you are working with 2D textures that you aren't saving. Not in the scene because it doesn't have root in a game object, and you aren't saving it as an asset either. This means to Unity the object is lost, doesn't have a parent that will take care of it so to speak. So Unity does it's job and cleans it up when you save and load. This is where the hide flags come in. By setting the hide flags you are telling Unity 'Don't worry! This is my object, I'm going to take care of it.' and then Unity won't try to save it and end up clean it up because it doesn't have any root. This is also why it will persist between scene loads because it isn't tied to the scene.
Ok, so that wasn't a very technical answer but hopefully you understand why it helps and it is actually solving a problem and not sweeping it under a rug. As you said in the comments Tim Cooper goes over it in this video: http://youtu.be/MmUT0ljrHNc
Thanks for your answer. Couple of things though, can't I 'take care of it' without setting the flags? where 'taking care' means manually destroying the object.
Also, the object isn't 'really' lost, otherwise how would unity know it's been leaked? ;)
Finally, I noticed that with these leaks around, first thing: the longer I have unity opened, the more stuff gets leaked (like first it starts leaking a couple of textures, and then hundreds!) second thing: the longer I keep Unity open the slower it becomes with time (compiling becomes really slow....) - which brings the question: Is unity 'really' cleaning up?! if so why the slow down?...
This is true, you can take care of it but Unity will still complain and spit errors at you because it doesn't know you are going to manage that object. And yes you are correct, it isn't lost, you are referencing it from your script and Unity is aware of everything that it creates. What I meant was it isn't connected to anything in the scene.
Your problem sounds like one I had when I was editing materials. Each time I edited the material on a render it would create a new modified material out of the shared material and since I wasn't first assigning the material to my own variables it would just make one and let it out into the open! A scary thought that.
Since you are dealing with textures and I haven't seen the code it really could be anything else. I would try setting the flags to get rid of the errors. If the debug log is really going at it and gets really loaded that is going to slow things down a ton. If it still slows down it is probably something funny going on where textures are being generated and you don't know about it. Submit your code and we can take a look and see if there is a problem somewhere.
Well TBH, I did try the set the flags and institute textures in OnEnable and destroy in OnDisable and so far I'm not getting any leak messages. But I was just arguing to try and make sense of things.
Also fortunately there's not a lot of places where I'm creating textures also my code is well encapsulated so it's easy to track things down - I usually create textures for my editor styles via:
public static Texture2D GetTexture(Color color, HideFlags flags)
{
var texture = new Texture2D(1, 1);
texture.SetPixel(0, 0, color);
texture.Apply();
texture.hideFlags = flags;
return texture;
}
ex:
public static GUIStyle SelectedStyle
{
get
{
if (selectedStyle == null || selectedStyle.normal.background == null)
selectedStyle = new GUIStyle(GUI.skin.textField)
{
alignment = TextAnchor.$$anonymous$$iddleLeft,
margin = new RectOffset(0, 0, 0, 0),
padding = new RectOffset(0, 0, 4, 4),
normal = new GUIStyleState
{
background = Utils.GetTexture(61, 128, 223, 255, HideFlags.DontSave),
textColor = Color.white
}
};
return selectedStyle;
}
}
Answer by MakeCodeNow · Feb 19, 2014 at 04:07 PM
Those flags are mostly to help you create temporary objects but not show them to the user (hide) and/or not save them with the scene (dontsave). They should have no impact on the lifetime of an object.
I'm somewhat surprised that this flag causes an object to persist between scenes. I've never seen that. Is the object a GameObject? If so, I'd expect it to be destroyed on scene change unless its referenced by an asset or other global-type object. If it's an asset itself (i.e. ScriptableObject) then I'd expect it to persist across sessions because that's what assets do.
As far as I know, not saved in the scene means exactly what you think it means.
Those flags are mostly to help you create temporary objects but not show them to the user (hide) and/or not save them with the scene (dontsave). They should have no impact on the lifetime of an object.
I totally agree with that.
I'm somewhat surprised that this flag causes an object to persist between scenes. I've never seen that
Well check it out yourself, create a new GO, set the hideFlags
to DontSave
and navigate through scenes, see what happens ;) Tim cooper mentioned in one of his talks that HideAndDontSave
creates a new root node for the object, I guess it's the same case with DontSave
(not sure what that means in detail)