I have a custom UI element and I would like to instantiate it from Hierarchy like you do with any other UI element (button, text etc.). I know how to do this so it is instantiated in the scene but how to make it instantiate exactly like UI elements so it gets instantiated onto a canvas?
1 Answer
Ok so I figure it out here is the creation code:
public static void CreateUIObject(string path)
{
GameObject selectedObject = Selection.activeGameObject;
if(selectedObject != null)
{
//If selected object contains canvas
if(selectedObject.GetComponentInParent<Canvas>())
{
GameObject newObject = GameObject.Instantiate(Resources.Load(path),
Selection.activeGameObject.transform) as GameObject;
newObject.name = path;
Place(newObject);
}
else
{
GameObject newCanvas = GameObject.Instantiate(Resources.Load("Canvas"),
Selection.activeGameObject.transform) as GameObject;
newCanvas.name = "Canvas";
Place(newCanvas);
GameObject newObject = GameObject.Instantiate(Resources.Load(path),
newCanvas.transform) as GameObject;
newObject.name = path;
Place(newObject);
}
}
else
{
GameObject newCanvas = GameObject.Instantiate(Resources.Load("Canvas")) as GameObject;
Place(newCanvas);
newCanvas.name = "Canvas";
GameObject newObject = GameObject.Instantiate(Resources.Load(path),
newCanvas.transform) as GameObject;
newObject.name = path;
Place(newObject);
}
}
public static void Place(GameObject gameObject)
{
// Find location
SceneView lastView = SceneView.lastActiveSceneView;
gameObject.transform.position = lastView ? lastView.pivot : Vector3.zero;
// Make sure we place the object in the proper scene, with a relevant name
StageUtility.PlaceGameObjectInCurrentStage(gameObject);
GameObjectUtility.EnsureUniqueNameForSibling(gameObject);
// Record undo, and select
Undo.RegisterCreatedObjectUndo(gameObject, $"Create Object: {gameObject.name}");
Selection.activeGameObject = gameObject;
// For prefabs, let's mark the scene as dirty for saving
EditorSceneManager.MarkSceneDirty(EditorSceneManager.GetActiveScene());
}
And here is the part that calls this methode in the asset menue:
[MenuItem("GameObject/UI/ArrowSelector(TMP)", priority = -50)]
private static void CreateArrowSelector()
{
CreateUtility.CreateUIObject("ArrowSelector");
}
So first I get the selected object from the hierarchy. If it isn't null I check if that object or any of his parents contains canvas GameObject, if it does I instantiate my object Under it. If not I create new canvas (note that I put a canvas prefab into a resource folder because I don't know how to use Unitys default one) and use it as a parent for my UI object.
If selected object is null I just do the same thing as if there is no canvas on selected gameobject but without assigning a parent to the canvas.
I copied place function from a tutorial it handles some Unity tooling stuff like undo redo and not sure what else.
These are editor scripts so make sure to place them in Editor folder.