Create game object from UI button click even
I know that variations of this question have been asked about 1000 times on this HELP system.
However as a new user, and still new to coding literally none of the answers and or code snippets appear to actually work for my purposes or within my implementation.
This may all be 'basic' to the rest of you however it's just more frustration that make me think that Unity isn't well 'unified'.
Here is what I have, a game object as a prefab (yes I figured that part out.
A UI Button
Desired result, when I click the UI button I would want a copy (clone, instantiation) of my prefab to appear somewhere on my canvas,
I'm not posting any code sample, because as stated nothing I have tried so far works.
What I need, and I expect many other users need this as well. One clearly working example in C# of a script that when added to a UI button either with OnClick event or as Event Trigger that produces one new copy of my prefab game object on the screen somewhere each time that button, and ONLY that button is clicked on by the player.
If it helps, the game object prefab has a name of Equip.
Answer by TBruce · Dec 16, 2016 at 12:28 AM
Hi @mfarrell80,
Here is a small unity package that shows how to instantiate an object when a button is pressed. The demo will instantiate a prefab (which is just a cube for demo purposes) anywhere within the bounds of the screen.
Below is the script file (which is also in the package) that is used (somewhat commented). If you look at the demo, you will see that the script is attached to the Canvas
.
using UnityEngine;
using UnityEngine.UI;
using System.Collections;
using System.Collections.Generic;
// rename this class to suit your needs
public class TestIntanstiation : MonoBehaviour
{
// the Equip prefab - required for instantiation
public GameObject equipPrefab;
// list that holds all created objects - deleate all instances if desired
public List<GameObject> createdObjects = new List<GameObject>();
private float minX, maxX, minY, maxY;
void Start()
{
// get the screen bounds
float camDistance = Vector3.Distance(transform.position, Camera.main.transform.position);
Vector2 bottomCorner = Camera.main.ViewportToWorldPoint(new Vector3(0,0, camDistance));
Vector2 topCorner = Camera.main.ViewportToWorldPoint(new Vector3(1,1, camDistance));
minX = bottomCorner.x;
maxX = topCorner.x;
minY = bottomCorner.y;
maxY = topCorner.y;
}
public void CreateObject()
{
// a prefab is need to perform the instantiation
if (equipPrefab != null)
{
// get a random postion to instantiate the prefab - you can change this to be created at a fied point if desired
Vector3 position = new Vector3(Random.Range(minX + 0.5f, maxX - 0.5f), Random.Range(minY + 0.5f, maxY - 0.5f), 0);
// instantiate the object
GameObject go = (GameObject)Instantiate(equipPrefab, position, Quaternion.identity);
createdObjects.Add(go);
}
}
}
Thanks so much, and GREAT Job!
I know that to some this is or should be a basic task, however not one tutorial or video that I watched showed this type of object creation. Lots of simple scene load demonstrations but not this. I did wind up commenting out several lines to meet my simple needs.
But I left them in so I can study what they do and why they were in there.
Of specific interest
Vector2 bottomCorner = Camera.main.ViewportToWorldPoint(new Vector3(0,0, camDistance));
Vector2 topCorner = Camera.main.ViewportToWorldPoint(new Vector3(1,1, camDistance));
$$anonymous$$X = bottomCorner.x;
maxX = topCorner.x;
$$anonymous$$Y = bottomCorner.y;
maxY = topCorner.y;`
Why was this part used or needed? I've commented that stuff out, and it still works.
The code in the Start()
function that you mention is calculating the screen boundaries and storing them in the global variables $$anonymous$$X, maxX, $$anonymous$$Y, maxY
which are used in the CreateObject()
function to randomly position the instantiated Equip
prefab.
One could easily do
Instantiate(equipPrefab);
but the object would alway be created at where ever the prefab is positioned to. Or you could also set the position to a predeter$$anonymous$$ed fixed point like so
GameObject go = (GameObject)Instantiate(equipPrefab, Vector3.zero, Quaternion.identity);
or
GameObject go = (GameObject)Instantiate(equipPrefab, new Vector3(0, 0, 0), Quaternion.identity);
or
GameObject go = (GameObject)Instantiate(equipPrefab, new Vector3(2, 3, 0), Quaternion.identity);
for example. But it is not needed, I just added it to show how to randomly position the created object and ensure that its position is visible on screen as well.
I basically used one of your methods:
Vector3 position = new Vector3(0,0,120);
then I had to revise where the prefab had been positioned.
Again I thank you.
I pretty sure that your example, and assistance will help more than a few others. Best clearest and actually working example I've seen in a week of searching and trying various other posted solutions.
I am glad I could help. Good luck on your game.
Oh, BTW, if you feel strongly enough about my answer I would appreciate if you could upvote it. Upvoting also helps others to recognize answers. Thanks.
Hey, I have a big question... Your code fits what I am trying to do perfectly except for that I am trying to have multiple buttons generate different objects. I am using your script on the canvas but I am trying to have one giant list that contains every instantiated object. I also want specific lists for each specific object.
The idea is that if I wanted to create buttons that could clear only cubes, only spheres, or clear all objects in the scene that the lists could do that.