Script in Godot – Complete Guide

Let’s dive into the exciting world of Godot 4, and more specifically, the Script class—a cornerstone of game development and a vital resource for any aspiring game developer. Through this tutorial, you will learn about the fundamentals of scripting within the Godot engine, gain an understanding of the Script class and its descendants, and discover why mastering this class can significantly enhance the functionality and interactivity of your game projects. Enthusiasts and professionals alike will find valuable insights here, so let’s unlock the power of scripting in Godot together and add that spark of life to your virtual worlds!

What is the Script Class?

The Script class in Godot is the backbone for creating dynamic and interactive content in your games. It’s a type of resource that defines the behaviors and functionalities you can attach to various objects in your game scene. Scripts are what make your characters move, your enemies react, and your game respond to player inputs.

What is it for?

Think of the Script class as a blueprint. Just as an architect uses blueprints to define the structure and features of a building, game developers use scripts to outline what each object does, how it interacts with the world, and how it reacts to the player’s actions. Without scripts, your game objects would be static and lifeless—mere decorations in a digital space.

Why Should I Learn About the Script Class?

Understanding the Script class is essential because it enables you to:

– Breathe life into your game’s static objects.
– Customize object behaviors, leading to complex and engaging gameplay.
– Respond to player inputs and create interactive gaming experiences.
– Use the versatility of GDScript, CSharpScript, or ScriptExtensions to fit your project’s needs.

Whether you’re starting your journey in Godot or looking to refine your skills, knowledge of the Script class is a powerful tool in your game development arsenal.

CTA Small Image
FREE COURSES AT ZENVA
LEARN GAME DEVELOPMENT, PYTHON AND MORE
ACCESS FOR FREE
AVAILABLE FOR A LIMITED TIME ONLY

Understanding Basic Script Creation

Let’s begin with the most fundamental step in Godot—creating a script. Once you have an object selected in your scene, you can attach a script to it by clicking the “Attach Script” button. By default, it will create a GDScript, which is Godot’s Python-like scripting language.

// Example of creating a new GDScript
extends Node

# Your script contents go here
func _ready():
    print("Hello, world!")

The sample above demonstrates the basic structure of a GDScript file attached to a Node.

Manipulating Node Properties

Moving on, we’ll look at how to manipulate node properties through scripts. Here’s how you can adjust the position of a ‘Sprite’ node:

// Example of modifying a node property
extends Sprite

func _ready():
    # Setting the position of the Sprite to (100, 100)
    position = Vector2(100, 100)

This code changes the position of the sprite when the game starts. The ‘_ready()’ function is called when the node enters the scene tree.

Handling User Input

Handling user input is an integral part of game design. In the example below, we’ll make the node move when the player presses an arrow key:

// Example of handling input
extends KinematicBody2D

# Speed is a variable that determines how fast the node will move
var speed = 100

func _process(delta):
    var movement = Vector2()
    
    if Input.is_action_pressed('ui_right'):
        movement.x += 1
    if Input.is_action_pressed('ui_left'):
        movement.x -= 1
    if Input.is_action_pressed('ui_down'):
        movement.y += 1
    if Input.is_action_pressed('ui_up'):
        movement.y -= 1

    movement = movement.normalized() * speed * delta
    move_and_slide(movement)

This is an example of a script for a player character that moves in response to arrow key inputs, adjusting the character’s velocity accordingly.

Signals and Event Handling

Godot’s signal system allows nodes to ‘communicate’ with each other. Here, we’ll connect a button’s ‘pressed’ signal to a script function that prints a message:

// Example of connecting a signal in GDScript
extends Button

func _ready():
    connect("pressed", self, "_on_Button_pressed")

func _on_Button_pressed():
    print("The button has been pressed!")

In Godot, when the button is pressed, it emits the ‘pressed’ signal. The ‘connect’ method links that signal to the ‘_on_Button_pressed’ function, which will be called each time the button is pressed.

Extending Script Functionality

Scripts can also extend the functionality of other scripts. Assuming we have a ‘Vehicle’ script that defines basic vehicle behavior, a ‘Car’ script could extend it to add car-specific features:

// Vehicle.gd (Parent script)
extends RigidBody2D

var speed = 50
func accelerate():
    # Code for accelerating the vehicle
    pass

// Car.gd (Child script that extends Vehicle.gd)
extends "res://Vehicle.gd"

var turbo_speed = 100
func _ready():
    speed = turbo_speed

This is a demonstration of inheritance in Godot scripts. The ‘Car’ script inherits all properties and methods from the ‘Vehicle’ script and modifies the speed property within its ‘_ready()’ function. The car now has a turbo speed feature, thanks to the inherited and extended script functionality.

These examples are just the start of what you can achieve with the Script class in Godot. By understanding and applying these concepts, you’re well on your way to creating intricate and captivating game mechanics.

In the world of game development, diversity in functionality is key to creating unique gameplay experiences. Let’s continue exploring various implementations of the Script class with more examples that you can use to enhance your projects in Godot.

Scripting Animations

Animating sprites or 3D models is a common task in games. The following example switches an ‘AnimatedSprite’ to a different animation sequence when the player presses the spacebar:

// Switching animations with a key press
extends AnimatedSprite

func _process(delta):
    if Input.is_action_just_pressed('ui_select'):
        if animation == "run":
            play("jump")
        else:
            play("run")

This script toggles between a ‘run’ animation and a ‘jump’ animation on the AnimatedSprite node, enhancing the visual feedback for player actions.

Next, let’s delve into timers, which are invaluable for creating delays or timing events. Here’s a simple countdown timer that notifies when the time has run out:

// Implementing a countdown timer
extends Node

func _ready():
    var timer = Timer.new()
    add_child(timer)
    timer.wait_time = 5
    timer.one_shot = true
    timer.start()
    timer.connect("timeout", self, "_on_Timer_timeout")

func _on_Timer_timeout():
    print("Countdown finished!")

This snippet demonstrates the creation of a Timer node in code, setting it up for a one-time 5-second countdown, and defining how the scene reacts when the timer completes.

Creating UI Elements Dynamically

Dynamic user interface (UI) generation is another compelling functionality. Let’s spawn a label with a custom message at runtime:

// Creating a label dynamically
extends Node

func _ready():
    var label = Label.new()
    add_child(label)
    label.text = "Welcome to the game!"
    label.rect_position = Vector2(200, 100)

In this piece of code, you’re using Godot’s Label class to create a new UI element that displays text on the screen at a given position. This is particularly useful for notifications, score displays, and other in-game messages.

Scripted interactions between objects, such as a player picking up an item, are pivotal in gameplay dynamics. Below is a simple example of how a script on a ‘Player’ node could handle an item pickup:

// Item pickup functionality
extends KinematicBody2D

# Signal emitted when an item is picked up
signal item_picked_up(item)

func _on_Item_body_entered(body):
    if body.has_method("pick_up"):
        body.pick_up()
        emit_signal("item_picked_up", body)

This code checks for collisions with objects that can be picked up, calls their ‘pick_up’ function, and emits a custom ‘item_picked_up’ signal to further handle the pickup event, maybe updating the UI or player’s inventory.

Lastly, let’s look at how to control audio playback. Here’s how to play a sound effect when an event occurs, such as an enemy being hit:

// Playing a sound effect
extends Node

onready var hit_sound = $HitSound

func _on_Enemy_hit():
    hit_sound.play()

This snippet is referencing an ‘AudioStreamPlayer’ node called ‘HitSound’ that is a child of the current node. When the ‘_on_Enemy_hit’ function is called, perhaps from a signal emitted when an enemy takes damage, the sound effect is played.

These script examples are crucial stepping stones in game development. By utilizing them and building upon their foundations, you can craft intricate games filled with engaging features that entertain and challenge your players. God for it and infuse your game creations with the power and flexibility of Godot’s scripting capabilities.

As we explore further into the possibilities the Script class offers in Godot, we’re going to take a look at more interactive examples that can be incorporated into your games. These examples emphasize different aspects of scripting, like physics manipulation, saving game data, and more.

Physics interactions are often a vital part of gameplay. Here’s how you can apply a force to a ‘RigidBody2D’ object in response to an event, such as an explosion:

// Applying a force to a RigidBody2D
extends RigidBody2D

func apply_explosion_force(explosion_center, force_magnitude):
    var direction = global_position - explosion_center
    apply_impulse(Vector2(), direction.normalized() * force_magnitude)

This method calculates the direction from the explosion to the object and applies an impulse to it, simulating the effect of an explosion pushing the object away.

Now let’s look at a script demonstrating how to save data, such as the player’s high score:

// Saving the player's high score
extends Node

var high_score = 0

func save_high_score():
    var save_file = File.new()
    if save_file.open("user://high_score.save", File.WRITE) == OK:
        save_file.store_var(high_score)
        save_file.close()

func load_high_score():
    var save_file = File.new()
    if save_file.file_exists("user://high_score.save"):
        if save_file.open("user://high_score.save", File.READ) == OK:
            high_score = save_file.get_var()
            save_file.close()

The ‘save_high_score’ function stores the high score in a save file, which can later be retrieved through the ‘load_high_score’ function to ensure persistence across game sessions.

Moving on to enemy AI, consider a simple script to make an enemy chase the player when they enter a certain range:

// Enemy AI chasing the player
extends KinematicBody2D

var player
var chase_speed = 100

func _ready():
    player = get_parent().find_node("Player")

func _physics_process(delta):
    if player:
        var direction = player.global_position - global_position
        if direction.length() < 300: # Start chasing
            move_and_slide(direction.normalized() * chase_speed)

When the player is within a range of 300 units, the enemy starts to chase by moving in the direction of the player, illustrating a basic form of AI behavior.

Next, let’s look at how to make a platform that moves between two points, often seen in platformer games:

// Moving platform between two points
extends KinematicBody2D

var point_a = Vector2(100, 100)
var point_b = Vector2(400, 100)
var speed = 50
var direction = 1

func _physics_process(delta):
    var current_position = global_position
    if direction == 1 and current_position.distance_to(point_b) < speed * delta:
        direction = -1
    elif direction == -1 and current_position.distance_to(point_a) < speed * delta:
        direction = 1

    move_and_slide(Vector2(speed, 0) * direction)

The platform moves back and forth between ‘point_a’ and ‘point_b’ by switching its direction when it gets close to each point. This provides a dynamic obstacle for the player to interact with.

Finally, scripts can be used to control cameras in Godot. Here is an example that keeps the camera centered on the player, creating a smooth following effect:

// Camera that follows the player
extends Camera2D

onready var player = get_parent().find_node("Player")

func _process(delta):
    if player:
        global_position = player.global_position

This snippet ensures the camera’s global position matches the player’s, ensuring the player is always in view.

These more advanced script examples illustrate just how powerful the Script class in Godot is. With them, you can create deep and dynamic gameplay, ranging from basic physics and AI to saving system and camera control, offering a wealth of opportunities to make your game stand out. As you experiment with these scripts and tweak them to fit your own unique vision, you’ll find that the only limit to what you can achieve in Godot is your imagination. So venture forth and script away!

Continuing Your Godot Journey

Delving into the Script class in Godot can be immensely rewarding, as it opens the door to crafting rich, interactive game worlds. If you’ve enjoyed this introduction and you’re eager to expand your game development skills, we’ve got just the resources to support your learning journey.

We invite you to explore our Godot Game Development Mini-Degree, where you can deepen your understanding of Godot 4 and elevate your game-making prowess. This comprehensive program covers a wide range of game development essentials, from mastering 2D and 3D assets to honing your gameplay control flow. You’ll gain hands-on experience in creating enriching game elements, like combat systems, item collection, and user interfaces for various game genres.

For those who desire an even broader selection of Godot courses, our extensive library can be found here. These courses cater to all skill levels, whether you’re just starting out or you’re an experienced developer looking to brush up on the latest practices. Our curriculum is specifically designed to give you a competitive edge in the industry. So whenever you’re ready to take the next step, we’re here to guide you through the exciting and evolving world of game development with Godot!

Conclusion

In the vibrant realm of game development, mastering the Script class in Godot is akin to discovering a treasure chest of creative potential. Each script you write is a brushstroke on the canvas of your game’s universe, allowing you to paint dynamic scenarios, build complex interactions, and breathe life into your visions. As with any craft, practice is key, and we’re thrilled to accompany you on this journey of growth and exploration.

Whether you’re just starting or looking to fine-tune your skills with the latest Godot developments, we at Zenva Academy are committed to providing you with the knowledge and tools to turn your game ideas into reality. Our Godot Game Development Mini-Degree is thoughtfully designed to be your guide through the thrilling challenges of game creation. So go ahead and unleash your creativity—the game you dream of is waiting to be made!

FREE COURSES
Python Blog Image

FINAL DAYS: Unlock coding courses in Unity, Godot, Unreal, Python and more.