I'm attempting to create a new button game object. When I click the button to create the new game objects, it does not assign the game objects to the parent I'm telling it to.
public void DisplayUpgrades()
{
// Get the RectTransform component of the shop panel
RectTransform shopPanelRectTransform = shopPanel.GetComponent<RectTransform>();
// Set the initial position of the first button to 0
float yPos = 0;
foreach (var upgrade in upgrades)
{
// Create a new button game object
GameObject button = new GameObject();
button.name = "UpgradeButton";
// Set the parent of the button to the shop panel
button.transform.parent = shopPanel;
// Set the size of the button to 10 units wide and 10 units tall
button.transform.localScale = new Vector3(10, 10, 1);
// Add a RectTransform component to the button
RectTransform rectTransform = button.AddComponent<RectTransform>();
// Set the position of the button using the RectTransform component
rectTransform.localPosition = new Vector3(0, yPos, 0);
rectTransform.sizeDelta = new Vector2(150, 20);
// Add a Button component to the button
Button btn = button.AddComponent<Button>();
btn.transform.SetParent(shopPanel);
// Add a TextMeshProUGUI component to the button
TextMeshProUGUI text = button.AddComponent<TextMeshProUGUI>();
text.transform.SetParent(shopPanel);
// Set the font size of the text to 20 pixels
text.fontSize = 8;
text.alignment = TextAlignmentOptions.Center;
// Set the text of the button to the name and cost of the upgrade
text.text = $"{upgrade.Key}: cost: {upgrade.Value.cost}";
// Add a listener to the button to handle when it is clicked
btn.onClick.AddListener(() => PurchaseUpgrade(upgrade.Key));
// Increment the y position by 20 pixels for the next button
yPos = 90;
}
}
To give some more info, I have 2 GUI elements, a canvas named 'Canvas' (parent of shopPanel), and 'shopPanel'. When I create new objects, they are being created as children of 'Canvas' rather than 'shopPanel'. 'shopPanel' is a Rect Transform. 'Canvas', also is a Rect Transform. I am needing 'button' to be a child of 'shopPanel' because when I want to add additional GUI elements, I don't want the addtl GUI elements to be destroyed when I attempt to destroy the children of shopPanel.
I have attempted button.transform.parent = shopPanel;
, button.transform.SetParent(shopPanel)
. I have tried to see if 'button' is a child of 'shopPanel', and if it isn't, assign it as the Parent. I have tried creating different canvas's and different shop panels. I've tried restarting the program and my computer. Nothing has worked this far.
CodePudding user response:
From the code you provided, there is no reference to shopPanel
, only to shopPanelRectTransform
. As a result, your newly created GameObjects
are being parented to the Canvas
as opposed to your shopPanel
.
Testing your code, it appears to work as intended with the shopPanel
reference assigned:
The shopPanel
assigned in the Inspector
:
The code with a place-holder _upgrades
Dictionary:
[SerializeField] private Transform shopPanel;
private readonly Dictionary<int, float> _upgrades = new();
private void Start()
{
_upgrades.Add(3, 30.0f);
_upgrades.Add(2, 20.0f);
_upgrades.Add(1, 10.0f);
DisplayUpgrades();
}
public void DisplayUpgrades()
{
float yPos = 0;
foreach (var upgrade in _upgrades)
{
var button = new GameObject
{
name = "UpgradeButton",
transform =
{
// Set the parent of the button to the shop panel
parent = shopPanel,
// Set the size of the button to 10 units wide and 10 units tall
localScale = new Vector3(10, 10, 1)
}
};
var rectTransform = button.AddComponent<RectTransform>();
rectTransform.localPosition = new Vector3(0, yPos, 0);
rectTransform.sizeDelta = new Vector2(150, 20);
var btn = button.AddComponent<Button>();
btn.transform.SetParent(shopPanel);
var text = button.AddComponent<TextMeshProUGUI>();
text.transform.SetParent(shopPanel);
text.fontSize = 8;
text.alignment = TextAlignmentOptions.Center;
text.text = $"{upgrade.Key}: cost: {upgrade.Value}";
btn.onClick.AddListener(() => PurchaseUpgrade(upgrade.Key));
yPos = 90;
}
}
I also highly recommend that you look into using Prefabs. Instead of creating a new upgrade button from scratch, Prefabs
will enable you to reuse a GameObject
that you've previously created.