Replace a part of script

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By Ingeniou5

Hello, can I replace a part of a script by code? Example:

for i in arr.size():
  var script = load("res://myscript.gd")
  script.source_code.replace("99", str(i))
  get_node("Button" + str(i)).set_script(script)

myscript.gd:

extends Button
func _pressed():
  get_node("Label99").queue_free()

This is a simplified example of what I’m trying to do, the idea is to set dynamic scripts for buttons to remove the corresponding things. The script I wrote here should take the original script file and replace the part of it, for the Button0 to remove the Label0 etc. I think I messed up variable types or something and it doesn’t work :(.

Can I make it work?

I continued to figure it out and it seems that replace() works with strings, but GDScript isn’t a String. I found a way to convert GDScript to String:

var source = load("res://remove_item.gd")
var source_code :String = source.source_code
print(source_code)
source_code = source_code.replace("111", str(i))
print(source_code)
var script := GDScript.new()
script.source_code = source_code

It works. But now I can’t convert it back to GDScript to assign it.

Ingeniou5 | 2022-11-02 11:02

Then I tried to save the original script to temporary gd file and change it there, but it doesn’t seem to work either. Now I hope someone will tell me if I can do the thing somehow.

Ingeniou5 | 2022-11-02 11:22

Just wanna chip in and say that what you are asking for is definitely not something that is commonly done in programming, and I would advice taking another route unless you are absolutely sure that’s what you need to do.

As for your example, what can be done in this case is that instead of hardcoding get_node(“Label99”), you add a variable that holds the name of the node you want to access. Like this:

extends Button
var node_path: String

func _pressed():
    get_node(node_path).queue_free()

Then in your first script you set the value of that variable, after the script has been assigned to the node. Something like this:

var button = get_node("Button" + str(i))
button.set_script(script)
button.node_path = "Button" + str(i)

Ninfur | 2022-11-02 13:33

Thanks, I actually just ended up doing the similar thing. Instead of changing the script, I figured I just can name the Button “Button”+str(i), then use this name inside the button script to choose what it deletes. You suggested about the same. I forgot I can save variables this way too, it is even more elegant, actually. Thank you! This is what I ended up with for now:

var button_index = name
button_index.erase(0,13) # "TextureButton15" - deleting first 13 symbols, "15" is left
button_index = int(button_index)
array.remove(button_index)

Ingeniou5 | 2022-11-02 16:05

:bust_in_silhouette: Reply From: Ingeniou5

Problem solved in the comments to the post, it wasn’t necessary in this case to change a script by code.