- Home /
Button Images Disappearing
I've got a very peculiar situation where my button images are disappearing in certain situations. At the start of the Scene, I am creating a line of buttons based on an array, and these buttons load in Image Resources for their sprites. I also have an effect, whereby a set of curtains on a canvas drop and rise, obscuring what's behind them. The Curtain Object is parented to another Curtain Object, which is itself parented to a Canvas. The Buttons are parented to a Canvas (to structure the button with other images), which is itself parented to an overall Canvas. The objects do not share a Canvas.
I've tracked down the exact line of code it occurs on. It's line 3 in the following method:
GameObject curtainsCanvas = transform.Find("CurtainsCanvas").gameObject;
curtainFallObject = Instantiate(curtainFallPrefab, curtainsCanvas.transform);
curtainFallObject.transform.SetParent(curtainsCanvas.transform.Find("Curtains").transform);
The really strange thing, is that if I pause the game in the editor, the images reappear, and then of course disappear once play is resumed.
Are there any ideas about what could be causing this?
Answer by Link17x · Mar 16, 2020 at 11:16 PM
To be honest, I don't know your exact issue but I will point out a few things!
You should avoid using "Find", it is bad practice and can often cause problems later on if you make changes. You're best to set up a reference to that gameObject.
I'm not sure why you have multiple Canvas' for this? Are your curtains in world-space or are they UI elements? If they are world-space, then ok. If they are UI elements, then you will only need one Canvas which will make it less messy and easier to keep track of.
These two suggestions may or may not fix your problem. But it should at least make it a bit easier to work with. The next thing I can say is, how did you narrow it down to that third line of code? What has indicated that, is there an error?
Tbh, if all your doing is a "curtain fall" I think it would be much easier to make a really simple animation clip that animates the curtain dropping down. Then you can put a "Canvas Group" component on the parent object, you can access this via code to disable/enable it (including making it invisible and visible) as and when you need it. Then reset it and replay the animation when you need it next.
Thank you for the response. I'll certainly change the usages of Find; to be honest, I rarely use it throughout the Project, this area of code has just been undergoing a refactor.
They are UI elements. The reason having multiple Canvas is I need to be able to order them, and the only way I could find to be able to control which order the elements appear in was through the Canvas Override Sorting functionality.
I know it's that specific line of code because I commented out the whole block, and re-enabled each line in turn, and as soon as that line was enabled, then the images started disappearing.
Essentially, this is all done for a UI effect; the Curtains remain there at all times (as part of a static 'scene manager' object), and the scenes change within them. It creates an illusion that the scene is changing behind the curtain each time it drops.
Ok sure, that all makes a bit more sense.
If I'm honest, I would personally go down the animation route. You can the curtains there at all times, then play a "close curtain" animation, then "open curtain" animation. Then trigger these two clips as and when you need to do a "scene change" illusion. It would be much cleaner I$$anonymous$$O.
However, if you don't want this approach... I would probably make some sort of "Curtain $$anonymous$$anager" script that is on your overall Canvas (parent object) that keeps a reference to the individual parent objects ins$$anonymous$$d of using "Find" then do the same as you are now, but using the references. See how that behaves? The other thing is... Do you really need to instantiate and parent the game object every time you do this? I think it would be much better to just hide/show it when you need it (either by enabling/disabling the gameObject or using a Canas Group component)
The animation route might be better. I don't have the graphical skills to do this myself though, and essentially want a method which I can implement should this not be possible.
I managed to resolve this particular issue though, although it's simply through another solution similar to what you mentioned at the end. I now have a single Canvas Object which doesn't get destroyed, and which I move up and down, in and out of sight of the camera Once I implemented this (which made the code cleaner anyway), the buttons stopped behaving weirdly. So must have been something to do with the parenting and maybe the ordering as a result...
Your answer
Follow this Question
Related Questions
Button's sprite swap works fine but it doesn't change the related image's source image! why? 1 Answer
Drag handler is blocking image IPointerClick but not button OnClick 0 Answers
How to Change transparency of button image in Unity 5.0? 3 Answers
How do i set screenshot image of Scene2 to Scene1(Button) in unity. Thanks in adavance 1 Answer
UI drag and drop 1 Answer