Keep in mind some of the things I’m saying are grossly over simplified…
extends Node2D
This means the script extends, or is based on Node2D
. Meaning, all of the features added in Node2D
apply to your script.
@onready var animated_sprite := $AnimatedSprite2D
This makes an @onready variable of guns animated sprite. You can now use this variable to play animations and other stuff. Normally when the script runs, everything WONT already be loaded. So, if you make a variable referencing to something that isn’t loaded, and use said variable in some code, it will somtimes error, or even crash. @onready just makes it so the variable can’t be used until it’s loaded.
Edit: The := symbol combination means the script will guess which type of variable to use, which is ok in this scenario, it’s 10:19 rn so I don’t feel like explaining the why tho…
@onready var cooldown_tracker:SceneTreeTimer
This is an empty variable that we use to create timers, in this case a cooldown for shooting your gun. Adding a colon “:” after a variable name allows you to lock it to a specifc type of variable like int, which is a number. Or string, which is a word. You don’t have to add the :SceneTreeTimer
but it will help prevent errors and improve fps/performance.
@export var cooldown:float = 1
This is an @export variable that keeps track of how long you want the cooldown to be. The colon “:” makes it so it can only be a specific type of variable, in this a case a float. Floats are basically just numbers with decimals. The @export part lets you edit the variable it without starting the game in the inspector. The inspector should be on the left side of your screen.
const REVOLVER_BULLET = preload("res://Scenes/revolver_bullet.tscn")
This is a value referencing a preload of your bullet scene. Costs cannot be change in the code but run faster in turn. Since you’re not going to be changing this, it’s good to have it as a const. Even though this is referencing something, we don’t need it to be a @onready variable because it’s accessing your files which are more reliable than the scene tree, aka the nodes. Consts also cannot be @onready vars either way.
func _ready() -> void:
#Make fire_cooldown not equal to null
cooldown_tracker = get_tree().create_timer(0)
The function _ready()
runs 1 time. If the cooldown is’nt created before you shoot, it won’t be able to check if the cooldown is over or not, so it creates a temporary replace meant which equals nothing.
The get_tree().create_timer(0)
basically makes it a timer, specifically a SceneTreeTimer
, that lasts 0 seconds.
func _process(delta: float) -> void:
#Rotate The Gun To Face The Same Direction As The Player
look_at(get_global_mouse_position())
#Limit Rotation
rotation_degrees = wrap(rotation_degrees, 0, 360)
if rotation_degrees > 90 and rotation_degrees < 270:
scale.y = -2
else:
scale.y = 2
I’m going to skip this part because I didn’t do any changes.
if Input.is_action_just_pressed("LMB"):
#When The Coodown Is Done Fire
if not cooldown_tracker.time_left > 0:
shoot()
In here, whenever you press LMB the script checks if the timer has any time left, then inverses that. So, if there is time, it won’t run shoot()
, but if there isn’t it will. This is exactly how a cooldown works in every other game.
func shoot():
#Play the shoot animation
animated_sprite.play("Shoot")
#Spawn bullet and mirror players rotation and position
cooldown_tracker = get_tree().create_timer(cooldown)
var bullet_instance = REVOLVER_BULLET.instantiate()
get_tree().root.add_child(bullet_instance)
bullet_instance.global_position = global_position
bullet_instance.rotation = rotation
This is similar to your method, but I put it a separate function for easier to read code. The only thing I did was to restart the cooldown whenever you shoot.
If you have any question, please ask away. Ill update you about the other scripts sometime tomorrow. (probably)