Tasharen Entertainment Forum
Support => NGUI 3 Support => Topic started by: alexv on March 13, 2015, 09:56:34 AM
-
Running unity 4.6.1 with NGUI 3.8.0
I've got a script with the following actions
foreach(Transform child in someParent.transform) Destroy(child.gameObject);
GameObject newChild = NGUITools.AddChild(someParent, myPrefab);
myPanel.Refresh();
basically: it destroys all background sprites, spawns a new one, and forces panel in charge of rendering it to draw it right away, but it is not rendering it the same frame the sprites get deleted... it happens exactly 1 frame after.
is there any workaround?
so far I'm doing coroutines that skip 1 frame before deleting the old sprites, in order to to avoid the visual flickering of having 1 black frame in between background sprite deletion/creation.
I even tried to call Refresh() on every single panel on the scene, but I allways get it rendered 1 frame after creation..
ArenMook, do you have any ideas what could be wrong?
-
Object.Destroy is a delayed call. The object you're trying to destroy will still be there when you do a Refresh() and won't actually disappear until the frame has ended.
Use NGUITools.Destroy instead.
-
Like Aren says, the actual destroying only happens at the end of the frame, which means you need to do something that removes immediately.
NGUITools.Destroy is an option.
Object.DestroyImmediate is also but generally not recommended.
You can also do funky stuff like SetActive(false) set transform.parent = null and then destroy so it will be out of the hierarchy when you refresh.
-
I don't think you guys understood my problem, here I go again:
Let's say I have background sprite covering the whole screen (it's actually not 1 sprite, but for simplification, lets consider it only 1)
I want to delete that background sprite and inmediatly create a new background sprite which also covers the whole screen.
for that purpose i do:
Destroy( oldBackground );
GameObject newBackground= NGUITools.AddChild(someParent, myPrefab);
myPanel.Refresh();
the result?
frame n: the background is gone
frame n+1: new background appears
so I see a black background when swapping out background sprites this way.
my workaround?
IEnumerator DeleteBGOnNextFrame() {
yield return null; // skip one frame
Destroy( oldBackground );
}
then I call:
// create new background NOW
GameObject newBackground= NGUITools.AddChild(someParent, myPrefab);
// delete existing background on Next Frame:
StartCoroutine("DeleteBGOnNextFrame");
this way I avoid the black background between deletion and creation.
instead of having to delay the deletion one fame, can't I force the creation of the sprite inmediatly?
I thought UIPanel.Refresh is exactly for that... but re-read now my first original post and see what happens... same thing.
-
Ah, ok it's the old infamous blinking issue that's rearing its ugly head again.
This happens because while destroying happens this frame, creating a new widget tends to only get counted in the next frame, since the UIPanel has to run an update an a lateupdate while the widget has to run an update to get registered in the panel the drawn properly.
To force it you can run NGUITools.ImmediatelyCreateDrawCalls but it's a bit of a bitch to run (quite heavy), so use sparingly. UIPanel.Refresh doesn't work, because it only refreshes the widgets that it already knows about - I can see how that would be confusing though.
It might be nice to have refresh look through the children automatically and "grab" any stragglers. You might be able to use the UIPanel.AddWidget and then call refresh, but I haven't tested or run into this issue in a while.
-
To force it you can run NGUITools.ImmediatelyCreateDrawCalls but it's a bit of a bitch to run (quite heavy), so use sparingly.
that nailed it !! thanks!
I might ispect the actions ImmediatelyCreateDrawCalls performs, and call the min set of calls to get the result, but so far, that call fixes my issues.