Getting "Play Again" and "Menu" buttons to appear when player ship is destroyed

This is actually something I tried to before I got to this lecture, but I decided to wait for a good time to ask about this, and that time is now!

So I thought it would be cool if the “Play Again” and “Menu” buttons appeared in the same scene when the player ship is destroyed. I made two different text gameobjects, made sure they take you to the correct scene, made them prefabs, and instantiated them in the player script after health hits 0, using:

Instantiate (restart, gameObject.transform.position, Quaternion.identity);
Instantiate (menu, gameObject.transform.position, Quaternion.identity);

Then I wired the prefabs up in the inspector. So, so far so good! But when I play it and get destroyed, the buttons don’t appear in the scene, but they do in the hierarchy.

Of course, the problem is they’re not appearing under the Canvas. So I figure I need to do some adoption, and make the Restart and Menu buttons children of the Canvas in the script. After looking around online how to do this I decided to try the SetParent method, and going by the Unity docs I tried this:

public void Adoption (Canvas newParent) {
	restart.transform.SetParent (Canvas); 

And this gives me a CS1503 error message saying:

“cannot convert UnityEngine.GameObject' expression to type UnityEngine.Transform’”.

Also when I hover over SetParent in the script it says “Unknown resolve error”. So here I am! Would love any help on this. Am I going about this completely wrong or have just got some of the code a bit wrong? Of course I realize I need to sort the positions of the buttons as well, but first I just need to get them to appear! Here’s my entire “PlayController” script for better context:

James, they have to be instantiated inside the canvas for this method to work as you realized, you should set it children to the Canvas Transform and not to the Canvas component itself (this is what is causing the error). But IMO you can leave them in the scene since the very beginning, just deactivate them in the hierarchy and activate it when you want to make those options available, you can make a small panel as their parent and turn it on/off as your will, it should be way easier to do this way.

Let me know if you got it solved

OK, so I exposed the Canvas as a Transform instead of a GameObject, and instantiated the buttons as:

Instantiate (restart, Canvas.transform.position, Quaternion.identity);
Instantiate (menu, Canvas.transform.position, Quaternion.identity);

Instead of:

Instantiate (restart, gameObject.transform.position, Quaternion.identity);
Instantiate (menu, gameObject.transform.position, Quaternion.identity);

I am indeed no longer getting errors! But this is what the scene is now looking like:

So they’re in the canvas, but not under it in the hierarchy! Interestingly if I remove my SetParent method nothing changes, I suppose that’s still not working. I tried changing it from:

public void Adoption (Canvas newParent) {
	restart.transform.SetParent (Canvas); 


public void Adoption (Canvas newParent) {
	restart.transform.SetParent (newParent); 

But that gives me the same error as before:

“cannot convert UnityEngine.Canvas’ expression to typeUnityEngine.Transform’”.

Which I don’t get because I thought it WAS a Transform now! Anyway, I feel like I’m really close here! Would appreciate anymore advice.

You are using canvas as the input type of the method, use Transform instead. The code don’t even need to know that you are using a canvas

So it should be this?

public void Adoption (Transform newParent) {
	restart.transform.SetParent (newParent); 

Yes sir!
But this method is more complicated than it should be, even if you make everything right code wise, you will probably have some problems with anchors and scale to fix.
If you make everything start in the scene deactivated and just activate when you want it to appear, it should take 1/10 of the time to implement

Thanks so much for you help. Unfortunately it’s still not working and not appearing in the Canvas. I decided to try the deactive and reactivate thing, so I put both the Restart and Menu prefabs in to the Canvas, and the in the PlayScript, in Start, I put:

restart.SetActive (!true); 
menu.SetActive (!true); 

And after ship’s health hits 0:

restart.SetActive (true); 
menu.SetActive (true); 

Well, the buttons are disappearing when the game starts, but they don’t reappear when the ship is destroyed. I did some reading and it seems that when they’re deactivated it stops all updates, so telling them to reactivate doesn’t do anything. Am I using the wrong method? I would try to work this out but unfortunately I need to go bed now… and this is giving me a headache. >.<

It should work, can you share the whole script so I can take a look?
It shouldn’t be a problem as long as you activate/deactivate it using a script within an active GameObject.

Sure, here it is.

I don’t see any error, the code inside the “if (health<=0)” runs without a problem?

Would you mind trying two things? Comment the Destroy(gameObject) to make the ship “persists” after the health gets below 0 (just for the sake of debugging), also, try to start the game with the objects deactivated in the hierarchy so you won’t need to do it in the start method

It is losing the reference somehow (possible because of the Start() method):

Strange Behave, but I think that if you set it to deactivated in the hierarchy instead doing so in runtime, it will probably keep the reference (I’ve used this same method dozens of times for this purpose and never had any problem)

OK, I’ve commented Destroy(gameObject) and deactivated Menu and Restart in the hierarchy, and removed the code in Start that deactivates them. Unfortunately I’m still getting the same result and they’re not appearing when the ship’s health hits 0. :\ Would you like me to send the project? Not really sure how to do that, though, hehe.

Sure, just zip the game folder without the library folder and send through dropbox/google drive

Hm OK I’ve zipped it but er, how do I send it using OneDrive? Not done that before hehe.

To share through google drive:

Although you can use any service, is another good option too for example

OK @James27 , found the problem.

You have dragged the prefab of the menu/restart to the Player GameObject, so when you die it will be looking for an active instance of the Menu and Restart. If you drag the instance itself (the one in the hierarchy), it will save the ID of the GameObject’s specific instance and will access it even if it is deactivated.

You can also make those two private and add this to the beginning of the code (with both objects activated in the scene):

        menu = GameObject.Find("Menu");
        restart = GameObject.Find("Restart");

This way your prefab won’t break if you use it in another level (“Prefab ~ Instance” does breaks when you reuse)

1 Like

Thanks so much. Unfortunately it’s bed time for me again, and I’ll be away for the next few days. I’ll have a look and try what you said as soon as I can.

1 Like

No problem,

Let me know if I can be of any help!

It works! I dragged Restart and Menu from the hierarchy instead of the prefab and that did it! I then did what you suggested, made the GameObjects private and added that bit of code, and it still works fine.

So glad it’s finally working! Thank you for all your help.

1 Like

I’m happy to see that you have it working now!
Let me know if I can help you with something else.
Best regards,

Privacy & Terms