Instantiated Child Node2D's Not Appearing in Game

Godot Version

Godot Engine v4.4.1.stable.mono.official

Question

Just starting out. My goal is to have a game board that automatically generates a multitude of cells as child nodes under it. This is working well.

The issue is that these child nodes called “Square.cs” are not showing up despite having a sprite attached, being in the scene and having CanvasItem set to visible.

Here is a photo of the scene view showing that the squares have no textures attached but the node type does:

Any help is appreciated!

This is my code for creating the game board:

using Godot;
using System;
using System.Runtime.CompilerServices;
using System.Security.Cryptography.X509Certificates;

public partial class Board : Node2D
{
public const int gameBoardHeight = 3;
public const int gameBoardWidth = 3;

public const int squareSize = 16;
private Square[,] gameBoard;

public override void _Ready()
{
gameBoard = new Square[gameBoardHeight, gameBoardWidth];
PopulateBoard();
}

public void PopulateBoard()
{
Vector2 boardPosition = GlobalPosition;
int xOffset = 0;
int yOffset = 0;
GD.Print("Starting position: " + boardPosition);

  for (int x = 0; x < gameBoardHeight; x++)
  {
  	for (int y = 0; y < gameBoardWidth; y++)
  	{
  		xOffset = x * squareSize;
  		yOffset = y * squareSize;

  		var square = new Square(new Vector2(boardPosition.X + xOffset, boardPosition.Y + yOffset));
  		AddChild(square);
  		GD.Print("Added square at: " + square.Position.X + ", " + square.Position.Y);
  	}
  }
  ViewChildren();

}

public void ViewChildren()
{
foreach (Node2D _childNode in GetChildren())
{
GD.Print("Child: " + _childNode.Name);
// GD.Print(“Child position” + _childNode.GlobalPosition);
}
}

You need to instantiate the whole scene, instead of just newing the script class. The latter will just create a new single node with the script attached.

Look at the first code example here:

1 Like

Thanks for replying so quickly! That code did help me get the square to appear but now it is only letting me create one before it stops. Even though its in a nested “for” loop. Also I can no longer access the childs position like above.

public void PopulateBoard()
{
Vector2 boardPosition = GlobalPosition;
int xOffset = 0;
int yOffset = 0;
GD.Print("Starting position: " + boardPosition);

  Sprite2D sprite = new Sprite2D();
  Texture2D texture = (Texture2D)GD.Load("res://Assets/TileSheet.png");
  sprite.Texture = texture;
  sprite.RegionEnabled = true;

  for (int x = 0; x < gameBoardHeight; x++)
  {
  	for (int y = 0; y < gameBoardWidth; y++)
  	{
            xOffset = x * squareSize;
            yOffset = y * squareSize;

  		var scene = ResourceLoader.Load<PackedScene>("res://Square.tscn").Instantiate();
  		AddChild(scene);
  		
  		gameBoard[x, y] = (Square)scene;
  	}
  }
  ViewChildren();

}

Are you sure it’s only one? Look at your remote scene tree. Any errors reported by the debugger?

1 Like

I did see an error. The constructor for the square had a parameter for Vector2 position. I removed this constructor overload and it created all of them. Now, how can I access the position of the children?

You can make a function in Square class that positions them, put the positioning code from the constructor in there, and call it on scene

1 Like

Thank you for all your help! It is working as expected.

1 Like