cak3_lover
cak3_lover

Reputation: 1938

override functions / extend during runtime?

I have 3 scripts like this:

A.gd:

extends Node

func something():
    print("A something")

B.gd:

extends "res://A.gd"

func something():
    print("B something")

func something_else():
    print("B something_else")

C.gd:

extends "res://A.gd"

func something():
    print("C something")

is there a way I can extend B in C during runtime so that I can override something() with C but I don't loose the functionality of something_else() from B?

like the runtime equivalent of:

C.gd:

extends "res://B.gd"

func something():
    print("C something")

Why am I doing this?

I have multiple B_1.gd, B_2.gd, etc
so if I want to extend anyone of them with C.gd
I have to make multiple files C_1.gd, C_2.gd etc for every individual one
which becomes annoying when I'm using the same C.gd for every B_<number>.gd file

so is something like this possible (maybe in c#)? or is there any workaround?

Note:
Both C.gd and B_<number>.gd always inherit from A.gd

Upvotes: 1

Views: 1832

Answers (1)

Theraot
Theraot

Reputation: 40210

You can create an script at runtime.

A minimal example is like this:

var script = GDScript.new()
script.source_code = "func run():print('hello world')"
script.reload()

If you define static methods there, you can use them right away. You can also instance the script. Or set the script of an existing Object to it.


Thus, you can use your existing code as template. First read the source code from the original script file:

var file := File.new()
file.open("res://C.gd", File.READ)
var source_code := file.get_as_text()
file.close()

Addendum: As alternative, you could use a String literal.

Then replace the path with the one you want in the source code:

source_code = source_code.replace("res://A.gd", "res://B_1.gd")

Addendum: As alternative, you could have a String prepared for String.format.

Then create an GDScript with that modified source code:

var script := GDScript.new()
script.source_code = source_code
script.reload()

Addendum: reload returns an Error (int), which would be non zero (OK) if there is something wrong with the code.

Then use that script however you want. For example instance it:

var instance := script.new()

Or set it to an existing instance:

instance.set_script(script)

Upvotes: 1

Related Questions