Access global variables (singleton) in an export var?

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

I’m trying to make a template for collectibles in my game so I can use the template to create different collectibles (coins, health, mana etc.). Of course collecting one of these will update a global variable in my autoload/singleton script. I wanted to try to save time and use export variables to set these up without having to write/duplicate the same script for each item. I thought this was a great idea but I can’t figure out how to access a global variable within a script using an export var. I’ve searched online and maybe my phrasing is wrong because i’m drawing zero results so thought i’d ask here. Is this possible? Is there some clever creative workaround? Code below as an example:

export(int) var value
export(???) var collectible #This is where I want to be able to select the global variable.

func _on_Collectible_body_entered(body):
	collectible += value
	queue_free()

Any help would be appreciated.

I’ve never tried
export(Script)

////// I don’t quite understand but is that the problem?
or
Global.gd ==> collectible
/////// collectible // Global script
var number: int = 0
///////////////

onready var global = collectible

func _on_Collectible_body_entered(body):
           global.number += 1
           queue_free()
     

ramazan | 2022-02-06 20:54

I want to be able to select the global variable from the UI where export vars are displayed (on the right side of the UI). I’ve tried:

export(Script) var collectible

But that just lets me select a script, not select a variable within that script, I was hoping to access the global variables using the export var so I can select different global variables on the fly.

Pixelope | 2022-02-06 21:36

I told you I never tried. I’m sure you can handle the rest. :wink:

ramazan | 2022-02-06 21:50

:bust_in_silhouette: Reply From: rossunger

that’s not quite how export variables work… you can’t put a variable into an export variable… at least not easily (there’s some hacky workarounds.

An export variable has to have a type that is one of the built-in godot types.

One solution you might consider is using Enums… have a global named enum, and make the export variable use that enum as it’s type

in globals.gd, which you autoload under the name globals:
enum MyGlobalVars { firstVar, secondVar, ThirdVar }

in your other script:
export (globals.MyGlobalVars) myVariable

This will show a dropdown box in the inspector with the values firstVar, secondVar, and thirdVar.

Then when you need to check which one was selected, you do:
if myVariable == globals.firstVar:
or something like that

Oooh let me try this and I’ll get back to you. I figured as this wasn’t a ‘documented standard’ it would involve some kind of hack to make work which I’m happy to do!

Pixelope | 2022-02-06 22:01

Also, here’s a script I made that abstracts this a little for use as runtime if that’s something you need:
https://github.com/rossunger/GodotExtraGUI/blob/main/addons/ExtraGui/EnumDropdown.gd

rossunger | 2022-02-06 22:05

So this worked perfectly, in my global script I have my variables as a global enum as suggested like this:

enum PlayerCollectibles { keys, health, mana }

Then I have a a script attached to a generic collectible template:

extends Area2D

export(int) var value
export(Globals.PlayerCollectibles) var collectible

func _on_Item_body_entered(body):
	if collectible == Globals.PlayerCollectibles.health:
		GameGlobals.health += value
		queue_free()
	if collectible == Globals.PlayerCollectibles.keys:
		GameGlobals.keys += value
		queue_free()
	if collectible == Globals.PlayerCollectibles.mana:
		GameGlobals.mana += value
		queue_free()

With the two export variables now available in the UI, when I create an inherited scene for a particular collectible, I can assign the value and (more importantly) the type without having to open a script.

You may be asking “Wouldn’t it be easier to just create all of them separately?”, the simple answer is yes, this was mainly a proof of concept, but then maybe you could use this for creating trick items without having to have numerous assets. Perhaps you just want to prototype some features and not get bogged down churning out the same script over and over.

Or maybe you’re just too lazy (like me) to deal with multiple repeat scripts and want to focus on other things! But it’s got me thinking now of other applications this can be used for like dynamically loading sprites based on type etc.

Thanks again to @rossunger for the help, you’re a legend.

Pixelope | 2022-02-07 20:43