Bite-Sized Godot: Five more small GDScript tips
In case the previous post wasn’t enough, here’s a few more quick tips for working with GDScript.
Better float comparison
Floating point numbers are prone to tiny inaccuracies that can make them a pain to work with, especially when trying to compare them to one another. We may not care whether or not two numbers differ at the 10th decimal place, but our code does, declaring any comparisons as not equal. To help deal with this, Godot offers two functions for comparing floats that takes this into account: is_equal_approx and is_zero_approx.
As the names imply, is_equal_approx
compares two floating point values and determines if they’re “close enough” based on their relative size, meaning smaller numbers will have tighter tolerances than larger numbers, while is_zero_approx
is a faster form of is_equal_approx
when you want to know if a number is approximately zero. Use these two functions to help prevent annoying comparison failures.
extends Node2D
func _ready() -> void:
# Will print 'false'
print(1.123456789 == 1.123456788)
# Will print 'true
print(is_equal_approx(1.123456789, 1.123456788))
# Will print 'false'
print(0.0000000001 == 0.0)
# Will print 'true'
print(is_zero_approx(0.0000000001))
Wrapping values
If you have a value you want to cycle through a certain range when modifying it, wrapf, for floats, and wrapi, for integers, are the functions for you. These functions will keep your number above themin
, inclusively, and below the max
, exclusively, wrapping the values around either end of the range as needed.
extends Node2D
func _ready() -> void:
# Will print 1
print(wrapi(4, 1, 4))
# Will print 3
print(wrapi(0, 1, 4))
# Will print 1.123
print(wrapf(4.123, 0, 3))
# Will print 0.5
print(wrapf(-0.5, 0, 1))
Smoother interpolation
Linear interpolation too linear for you? The smoothstep function lets you interpolate between two values using an S-curve instead, meaning values will gradually ease away from the from
parameter, have the maximum delta in the middle, and gradually ease back into the to
parameter.
extends Node
func _ready() -> void:
# Will print 0
print(smoothstep(0, 1, 0))
# Will print 0.15625
print(smoothstep(0, 1, 0.25))
# Will print 0.5
print(smoothstep(0, 1, 0.5))
# Will print 0.84375
print(smoothstep(0, 1, 0.75))
# Will print 1
print(smoothstep(0, 1, 1))
Manually throwing errors and warnings
Assertions are a great way to ensure your application is running as intended when debugging, but they also stop the application in its tracks when they fail. If you’d prefer to just be made aware of an undesirable condition without stopping the execution of the application, you can use the push_error and push_warning functions to throw errors and warnings in both the Godot debugger and the terminal of your application.
extends Node
func _ready() -> void:
push_warning('This is a warning')
push_error('This is an error')
Mapping a value to a range
This last one really just speaks for itself. With the range_lerp function, you can easily map a value from one range to another.
extends Node2D
func _ready() -> void:
# Will print out 30
# As 55 is halfway between 10 and 100
# and 30 is halfway between 20 and 40
print(range_lerp(55, 10, 100, 20, 40))
Conclusion
And that’s it for today!