0 votes

I have 3 types of Buildings. I want to create let's say 20 of them, at random, with their translate also random. I'm trying this code, but I think it overrides each one witht the latest one:

extends Spatial
onready var scenaryPlaneDims = get_node("Floor").scale

var building1Instance = preload("res://Buildings/Building1.tscn").instance()
var building2Instance = preload("res://Buildings/Building2.tscn").instance()
var building3Instance = preload("res://Buildings/Building3.tscn").instance()

# Called when the node enters the scene tree for the first time.
func _ready():
    randomize()
    for n in 20:
        call_deferred("add_building_to_root", building1Instance)
        call_deferred("add_building_to_root", building2Instance)
        call_deferred("add_building_to_root", building3Instance)


# Called every frame. 'delta' is the elapsed time since the previous frame.
#func _process(delta):
#   pass


func add_building_to_root(instance):
    get_tree().get_root().add_child(instance)
    instance.set_translation(Vector3(randi()%50,0,randi()%50))
    #instance.set_scale(Vector3(100,100,100))

How can I create individual instances of those Buildings with specific attributes?

Godot version 3.4.2
in Engine by (28 points)

Just set those attributes?
Or what did you mean?

The attributes I mean are mainly translate, to position each instance at a random translate (in 3D obvs).

Posted as an answer

1 Answer

+1 vote

Well, in addition to some minor issues like

  • global randomize() should be called only once (I'm not sure this is so) in project, preferably in autoload-nodes, or RandomNumberGenerator class instance should be used.
  • you're adding Spatial-based (are they?) node as a child of root (Viewport), while normally it's better to add it to another Spatial-based node like floor/ground (in its _ready()), thus you don't have to use call_deferred().
  • you're feeding integer values of randi() to a float Vector3 (should be randf(), or rand_range())
  • your overall generation algorithm: it does not guarantee you won't get overlapping results.

you have only 3 instances, which you're translating 20 times. You should move instance() under for loop:

var packedScene1  = preload("res://Buildings/Building1.tscn") 
# ...

for n in 20:
    var building =  packedScene1.instance()
    $someNode.add_child(building)
    building.set_translation(...)
by (1,648 points)

Thanks. I'm new to Godot in general so thanks for noticing those minor issues. Lemme try your answer.

Welcome to Godot Engine Q&A, where you can ask questions and receive answers from other members of the community.

Please make sure to read Frequently asked questions and How to use this Q&A? before posting your first questions.
Social login is currently unavailable. If you've previously logged in with a Facebook or GitHub account, use the I forgot my password link in the login box to set a password for your account. If you still can't access your account, send an email to [email protected] with your username.