Dynamically reference textures or objects?

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By Mfaraka
:warning: Old Version Published before Godot 3 was released.

I’ve been using Godot for 48 hours, so to say I’m a newbie is an understatement. . .

Trying to make a simple application that randomly generates 3 planets. I have 3 sprites on the viewport called Planet0, Planet1, and Planet2. They are duplicated, not instanced. I want to randomly generate each planet’s type and change the texture of the sprite accordingly. Here’s the code I’m using, which is on the parent node all 3 sprites share:

extends Node

    func _ready():
    	var MapFertile = preload("../Planets/Fertile.png")
    	var MapBarren = preload("../Planets/Barren.png")
    	var Planets = ["Barren", "Barren", "Fertile"]
    	var Length = Planets.size()-1
    	for i in range(3):
    		randomize()
    		var Ref = round(rand_range(0, Length))
    		var Planet = Planets[Ref]
    		var PlanetPic = str("Map",Planet)
    		var PlanetRef = "Planet" + str(i)
    		get_node(PlanetRef).set_texture(PlanetPic)

The error message I get is:
“Invalid type in function ‘set_texture’ in base ‘Sprite’. Cannot convert argument 1 from String to Object.”

The code works if I replace the last line with:

		get_node(PlanetRef).set_texture(MapBarren)

Or:

		get_node(PlanetRef).set_texture(MapFertile)

But then of course all 3 will be the same texture and it defeats the point.

Please help a poor soul who hasn’t learned a new language since Actionscript 2. . .

:bust_in_silhouette: Reply From: kidscancode

You are doing this:

var PlanetPic = str("Map", Planet)

so PlanetPic is a string, and will of course give an error when passed to set_texture(). You have to give set_texture() a Texture object. Instead of using strings, just put your actual textures into the list and pick one:

func _ready():
    randomize()  # don't need to call randomize multiple times
    
    # load the textures
    var MapFertile = preload("../Planets/Fertile.png")
    var MapBarren = preload("../Planets/Barren.png")

    # put the textures into a list
    var Planets = [MapBarren, MapBarren, MapFertile]
    #  var Length = Planets.size()-1  # don't need this

    # list of node names - could make this automatically using get_children
    var nodes = ["Planet0", "Planet1", "Planet2"]
    # loop through the node names
    for node in nodes:
        # pick a random item from list
        var PlanetPic = Planets[randi() % Planets.size()]  
        # assign the texture
        get_node(node).set_texture(PlanetPic)