Home > Enterprise >  button.transform.parent = shopPanel; and button.transform.SetParent(shopPanel); not working
button.transform.parent = shopPanel; and button.transform.SetParent(shopPanel); not working

Time:12-19

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: Example of the correct child hierarchy

The shopPanel assigned in the Inspector:

Example of the shopPanel being assigned

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.

  • Related