Exported Variables Are Not Changing, are Returning 'NIL'

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

Godot 3.0

I think I may have gotten a bad tutorial.

I wanted to be able to change motionspeed in the inspector, so I created

export(int) var MOTION_SPEED

This causes MOTION_SPEED to appear as a script variable in the inspector. Very Unity-esque.

I modified my motion vectors in the appropriate place with:

motion = motion*MOTION_SPEED

However, when I try to run the script, this line returns "Invalid operands ‘Vector2’ and ‘Nil’ in operator ‘*’. If MOTION_SPEED is hardcoded with a number, this problem vanishes and the hardcoded multiplier controls. But no inspector manipulation.

So I read up on the export variable cheat sheet, and found out about setget. So now my exported variable is like this:

export(int) var MOTION_SPEED setget setterfunc, getterfunc

and setterfunc and getterfunc are implemented.

func getterfunc():
	return MOTION_SPEED

func setterfunc(newvalue):
	MOTION_SPEED = newvalue

I really don’t understand either of these functions, or why calling them would be necessary. I dimly recognize that assuming two-way communication with a process called ‘export’ is maybe a little naive, but like I said, I think I got a bad video tutorial which implied a bare export var varname would be good enough to get an entry in the inspector that you could change to alter the number used in the script.

tl;dr export var is not working how I was lead to believe it would. Failing to hardcode a value returns Nil, so the inspector value isn’t getting sent over. Setter and getter don’t alter this. If a variable is both exported and hardcoded, e.g.,

export(int) var MOTION_SPEED = 10 setget setterfunc, getterfunc

the 10 value will control and no amount of screwing with the inspector entry will change things.

Am I just going crazy? Is this a Godot 2.0 vs. 3.0?
Here is the tutorial and location and origin of my ‘export creates i/o variable in inspector’ assumption: https://youtu.be/0UiAEdEAQ74?t=5m38s

:bust_in_silhouette: Reply From: pgregory

The reason for your problem is that while you’ve declared your variable, you’ve not assigned it any value, so it defaults to Nil.

Note: the (int) is just a hint to the inspector UI to represent the variable with an editor that befits an integer value, it doesn’t make any difference to the type or value of the variable in the script, it is still just a variable, that can readily hold any type, and until it is assigned, it holds Nil.

You can verify this, by setting up the project exactly as you originally describe, with just…

export (int) var MOTION_SPEED

…and then run, you’ll get the error message that you cannot multiply a value by Nil. Then go to the inspector, and set the value to something other than the default. You can verify this visually by the appearance of the recycle icon next to the value, this means it has been modified from the default value. Run again, and it should work, as the exported variable now has a value. To avoid having to set the value in the inspector, the solution is to give the variable in your script a default value…

export (int) var MOTION_SPEED = 0

…this will ensure that even in it’s default state, before you modify the value in the inspector, the variable is assigned a valid numerical value that can be used in the calculation.