Created
December 4, 2021 17:44
-
-
Save Brin-o/dce146ad94ad64805a463abd7daedf53 to your computer and use it in GitHub Desktop.
A godot utility script. Should be used as an autoload and provides a load of handy functions that I use in my style of programming.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
extends Node | |
# --------------- | |
# JUICE FUNCTIONS | |
# --------------- | |
# HITSTOP | |
# stops the node from functioning for a certian amount of time | |
func hit_stop(_node, _time): | |
set_pause_scene(_node, true) | |
yield(get_tree().create_timer(_time), "timeout") | |
set_pause_scene(_node, false) | |
# PAUSE FUNCTIONS - Credit: https://old.reddit.com/r/godot/comments/bkrtzi/utility_functions_to_pause_a_scenea_node/ | |
# (UN)PAUSE SINGLE NODE | |
func set_pause_node(node : Node, pause : bool) -> void: | |
node.set_process(!pause) | |
node.set_process_input(!pause) | |
node.set_process_internal(!pause) | |
node.set_process_unhandled_input(!pause) | |
node.set_process_unhandled_key_input(!pause) | |
# (UN)PAUSE A SCENE | |
# Ignored childs is an optional argument, that contains the path of nodes whose state must not be altered by the function | |
func set_pause_scene(rootNode : Node, pause : bool, ignoredChilds : PoolStringArray = [null]): | |
set_pause_node(rootNode, pause) | |
for node in rootNode.get_children(): | |
if not (String(node.get_path()) in ignoredChilds): | |
set_pause_scene(node, pause, ignoredChilds) | |
# FREEZE FRAMES | |
var t : float = 0 | |
var t_gate : float = 1 | |
func _ready(): | |
pause_mode = Node.PAUSE_MODE_PROCESS | |
func freeze(_seconds : float): | |
t = 0 | |
t_gate = _seconds | |
get_tree().paused = true | |
func _process(delta): | |
if(get_tree().paused == true): | |
t+=delta | |
if(t >= t_gate): | |
t = 0 | |
get_tree().paused = false | |
# ----------------- | |
# FIND FUNCTIONS | |
# ----------------- | |
# finds game objects that are common in my programming stlye :) | |
# no clue if this is smart but it works | |
func find_player(): | |
var ply = get_tree().get_nodes_in_group("player") | |
if(ply.size() == 0): | |
#print("ERROR: Can't find player node!") | |
return null | |
else: | |
print("player found!") | |
return ply[0] | |
func find_camera(): | |
var cameras = get_tree().get_nodes_in_group("camera") | |
return cameras[0] | |
# ----------------- | |
# RETURN FUNCTIONS | |
# ----------------- | |
# Normalizes any number to an arbitrary range | |
# by assuming the range wraps around when going below min or above max | |
func normalize_repeating(value:float, start:float, end:float): | |
var _width = end - start | |
var _offset = value - start | |
return (_offset - ((_offset/_width)*_width)) + start | |
# returns degs from a vector 2 | |
func vector2deg(_vec : Vector2) -> float: | |
return rad2deg(_vec.angle()) | |
# takes a vector and returns it rotated by _rot degrees | |
func vector2rotated(_vec : Vector2, _rot : float) -> Vector2: | |
return _vec.rotated(deg2rad(_rot)) | |
#im not sure if this works lol? takes a deg. angle and returns it as a directional vector2. 0 returns Vector2.RIGHT | |
func angle2vector(_angle : float) -> Vector2: | |
var _x = cos(deg2rad(_angle)) | |
var _y = sin(deg2rad(_angle)) | |
return Vector2(_x, _y) | |
# sign function but if given 0 it returns 1 | |
func sign_positive(_num : float) -> int: | |
var a = sign(_num) | |
if(a == 0): a = 1 | |
return a | |
# sign function but if given 0 it returns -1 | |
func sign_negative(_num : float) -> int: | |
var a = sign(_num) | |
if(a == 0): a = -1 | |
return a | |
# returns 1 or -1 randomly | |
func rand_one(): | |
var r = rand_range(0, 1) | |
if r > 0.5: return -1 | |
else: return 1 | |
# returns an integer from 0-A1 or from A1-A2 | |
func rand_int(a1 : int, a2 = null): | |
if(a2 != null): return round(rand_range(a1, a2)) | |
else: return round(rand_range(0, a1)) | |
# lerp delta | |
# based on https://www.construct.net/en/blogs/ashleys-blog-2/using-lerp-delta-time-924 | |
# frame-rate indipendant lerp where t should be 0-1 | |
func lerp_delta(delta, a, b, t): | |
var _t = 1 - t | |
return lerp(a, b, 1 - pow(_t,delta)) | |
func round_decimal(number, decimal_count : int): | |
var tenner = pow(10, decimal_count) | |
return (float(round(number*tenner)/tenner)) | |
func round_decimal_str(number, decimal_count : int): | |
return str(float(round_decimal(number, decimal_count))) | |
# Finds ANY node, children or not of other nodes | |
func find_node_by_name(node_name): | |
return get_tree().get_root().find_node(node_name) | |
# gets the node by name. Can NOT find any children | |
func get_node_by_name(node_name): | |
return get_tree().get_root().get_node(get_tree().current_scene.name+"/"+node_name) | |
# Sends A towards B regardless if that requieres addition or substraction | |
func towards(a,b,rate): | |
if a+rate<b:return a+rate | |
if a-rate>b:return a-rate | |
return b | |
# Remaps the number from its old scale to new scale (eg. a 4 on a scale of 1-10 will become a 2 on a scale of 1-5). The value is clamped, with the min/max being new_bottom/new_top. | |
func remap(value : float, old_bottom : float, old_top : float, new_bottom : float, new_top): | |
return clamp(new_bottom + (value - old_bottom)*(new_top - new_bottom)/(old_top - old_bottom), new_bottom, new_top) | |
# Remaps the number from its old scale to new scale (eg. a 4 on a scale of 1-10 will become a 2 on a scale of 1-5) | |
func remap_unclamped(value : float, old_bottom : float, old_top : float, new_bottom : float, new_top): | |
return new_bottom + (value - old_bottom)*(new_top - new_bottom)/(old_top - old_bottom) | |
# -------------- | |
# WAVE FUNCTIONS | |
# -------------- | |
# returns sin/cos waves | |
# pass in a time parameter, magnitude (how far do you want it to go), frequency in seconds, delay (how much should it start at | |
func wave_sin(t, magnitude, freq, delay = 0): | |
var new_freq = 1/freq | |
var wave = sin((t+delay)*new_freq)*magnitude | |
return wave | |
func wave_cos(t, magnitude, freq, delay = 0): | |
var new_freq = 1/freq | |
var wave = cos((t+delay)*new_freq)*magnitude | |
return wave | |
# ------------------- | |
# ANIMATION FUNCTIONS | |
# ------------------- | |
# Changes the sacle of the node following Squash & Stretch aniamtion principle | |
# applied any time a nodes scale is not 1 | |
# use inside of _process | |
func squash_to(delta, node : Node2D, squash_speed : float, target_scale : float): | |
var target_x = lerp(node.scale.x, target_scale, delta*squash_speed) | |
var target_y = target_scale/target_x | |
node.scale = Vector2(target_x, target_y) | |
func rotate_to(delta, node : Node2D, speed, target_rotation): | |
node.rotation_degrees = lerp(node.rotation_degrees, target_rotation, delta*speed) | |
func get_input_axis(): | |
return Vector2(Input.get_action_strength("ui_right") - Input.get_action_strength("ui_left"), Input.get_action_strength("ui_up") - Input.get_action_strength("ui_down")).normalized() | |
## GENERAL LOADING FUNCTIONS | |
func load_level(num : int): | |
get_tree().change_scene("res://Levels/Level"+ str(num)+".tscn") | |
# Restarts current scene | |
func restart(): | |
get_tree().reload_current_scene() | |
## NOTES ## | |
# not actual code just notes of what i find confusing in godot and need to check in on every so often | |
# | |
# NOTE - QUICK TIMER | |
# a shortcut for creating timers works like this | |
func note_timer(_time_to_wait): | |
# code that you want before the timer | |
yield(get_tree().create_timer(_time_to_wait), "timeout") | |
# code that you want after the timer | |
# NOTE - SPRING CODE | |
# I actually have no fucking clue how this works, thank ash the god of juice | |
func note_spring(delta, position = 0, speed = 0, target = 100, springiness = 15, excitement = 8): | |
speed = lerp(speed, (target - position) * springiness, delta * excitement) | |
position.x += speed * delta |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment