StaticBody3D in Godot – Complete Guide

When it comes to game development, understanding the physics of your virtual world is paramount for creating an engaging and realistic experience. In this detailed tutorial, we’ll dive into the world of Godot 4, focusing on one of its fundamental physics components, the StaticBody3D class. Perfect for both beginners and experienced coders, we aim to shed light on how StaticBody3D operates and why mastering it can elevate your game development skills. Prepare to enrich your knowledge and add a valuable tool to your development toolkit!

What is StaticBody3D?

StaticBody3D is a node in Godot 4’s robust physics engine, designed to represent objects that are not supposed to be moved by physical interactions in the game world. These could be anything from the immutable ground beneath your character’s feet to walls and other structures that are fixed within the game environment.

What is StaticBody3D Used For?

This class is versatile – it can serve as the unmovable foundation for your game’s elements or as part of dynamic systems like conveyors or rotating platforms, with its properties allowing for consistent motion effects. In essence, it’s the silent, sturdy hero of the physics world, ensuring everything interacts just the way you intend.

Why Should I Learn About StaticBody3D?

Understanding StaticBody3D is crucial for game developers because it allows you to create realistic static elements within your game. Whether you’re looking to build a rigid set piece or an interactive element in your game’s 3D space, StaticBody3D provides the groundwork, acting predictably under any circumstance you craft. Familiarity with such components will bolster your capacity to design compelling and immersive game worlds with Godot 4.

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

Adding a StaticBody3D to Your Scene

Let’s start by adding a StaticBody3D node to your scene. This simple process begins with right-clicking on your chosen parent node in the Scene dock and selecting ‘Add Child Node’. Here, you’ll choose StaticBody3D from the list of available nodes. The StaticBody3D will now be part of your scene, ready for further configuration.

// Assuming you have an existing parent node named 'Level'
const NodePath PARENT_NODE = "Level";

func _ready():
    var static_body = StaticBody3D.new()
    get_node(PARENT_NODE).add_child(static_body)

Note that the StaticBody3D is not visible in the game until it has a shape. For that, we need to add a CollisionShape3D or a CollisionPolygon3D as a child.

Assigning a Collision Shape

For an object to participate in physics collision detection, it must have a shape. Here’s how you can add and specify a CollisionShape3D to your StaticBody3D:

// Continuing from the previous code, assuming 'static_body' is your StaticBody3D

func _ready():
    var static_body = StaticBody3D.new()
    # Adds a new CollisionShape3D as a child of the StaticBody3D
    var collision_shape = CollisionShape3D.new()
    # Creates a box shape for collision
    collision_shape.shape = BoxShape3D.new()

    static_body.add_child(collision_shape)
    get_node(PARENT_NODE).add_child(static_body)

The BoxShape3D is just one of many shapes you can assign. Depending on your needs, you might want to use a different shape like a CapsuleShape3D, CylinderShape3D, or SphereShape3D.

Configuring StaticBody3D Properties

After you have your StaticBody3D with its collision shape in place, you might want to adjust some properties to suit your game’s mechanics. Some of the properties you can set include ‘friction’ and ‘bounce’:

// Continuing from the previous code. 

func _ready():
    var static_body = StaticBody3D.new()
    # Adding a CollisionShape3D...
    # ...

    # Set the friction property
    static_body.friction = 1.0
    # Set the bounce property
    static_body.bounce = 0.5

    # ...

These properties influence how dynamic objects interact with the static object. High friction will make dynamic objects slow down when in contact, and bounce determines how much they rebound.

Creating a Floor with StaticBody3D

A common use for StaticBody3D is creating a floor. This is straightforward as it involves adding a StaticBody3D node with a corresponding collision shape to represent the floor’s surface.

// This example demonstrates creating a simple floor with StaticBody3D

var static_body = StaticBody3D.new()
get_node(PARENT_NODE).add_child(static_body)

var collision_shape = CollisionShape3D.new()
collision_shape.shape = BoxShape3D.new(Vector3(10, 1, 10)) // The size can be adjusted

static_body.add_child(collision_shape)

Keep in mind to adjust the shape’s size to fit the floor area you need for your particular scene. In the example above, a 10×10 floor is being created with a negligible height since it’s a flat surface.

By mastering these fundamental uses of StaticBody3D, you pave the way to more complex setups, like walls and platforms, which share similar steps in terms of setup but with different shapes and positions.

Once you’re comfortable creating static floors, you can expand your knowledge to include walls and other structures that dictate your game’s play area and design. Creating these structures follows a similar method to the floor, but with different orientation and positioning.

Here’s how to add a vertical wall to your scene using StaticBody3D:

// Adding a wall to the scene
var static_body_wall = StaticBody3D.new()
get_node(PARENT_NODE).add_child(static_body_wall)

var wall_collision_shape = CollisionShape3D.new()
wall_collision_shape.shape = BoxShape3D.new(Vector3(1, 5, 10)) // Represents the height and width

static_body_wall.add_child(wall_collision_shape)
static_body_wall.translation = Vector3(5, 2.5, 0) // Position the wall correctly

You might also encounter scenarios where more complex shapes are required for your game’s static elements. In these cases, you can use a ConcavePolygonShape3D or a ConvexPolygonShape3D. Below is an example of how you could define a custom-shaped static object.

// Creating a static body with a custom convex shape
var static_body_custom = StaticBody3D.new()
get_node(PARENT_NODE).add_child(static_body_custom)

var custom_collision_shape = CollisionShape3D.new()
var convex_shape = ConvexPolygonShape3D.new()

# Assuming 'mesh_instance' is a MeshInstance3D node from which we want to make a collision shape
convex_shape.points = mesh_instance.mesh.get_faces()
custom_collision_shape.shape = convex_shape

static_body_custom.add_child(custom_collision_shape)

For objects that do not move but require detection of entering and exiting bodies, such as triggers for game events, you can leverage the StaticBody3D node in combination with an Area3D node. Here’s a simple example:

// Setting up a trigger area using StaticBody3D
var trigger_area = Area3D.new()
get_node(PARENT_NODE).add_child(trigger_area)

var area_shape = CollisionShape3D.new()
area_shape.shape = BoxShape3D.new(Vector3(2, 2, 2))

trigger_area.add_child(area_shape)

# Connect signal for entering bodies
trigger_area.connect("body_entered", self, "_on_Body_Entered")
func _on_Body_Entered(body):
    if body.name == "Player":
        print("Player has entered the trigger area!")

And, if you want your static object to apply a constant force, such as a wind blowing or a conveyor belt moving, you can use the ConstantLinearVelocity or ConstantAngularVelocity properties of the PhysicsMaterial assigned to the StaticBody3D.

// Assign a material that simulates wind to a StaticBody3D wall
var static_body_wall = StaticBody3D.new()
var wind_material = PhysicsMaterial.new()

# Assuming we want the wind to blow with a constant speed to the east
wind_material.constant_linear_velocity = Vector3(1, 0, 0)

var wall_shape = CollisionShape3D.new()
wall_shape.shape = BoxShape3D.new(Vector3(1, 10, 10))

static_body_wall.physics_material_override = wind_material
static_body_wall.add_child(wall_shape)
get_node(PARENT_NODE).add_child(static_body_wall)

Keep in mind, ConstantLinearVelocity will move objects in a straight line, while ConstantAngularVelocity will spin objects around. Given that StaticBody3D objects should not move, these properties typically affect other bodies in contact with the StaticBody3D.

Working with StaticBody3D is a fundamental skill in Godot 4 game development. As you can see, Godot’s physics system allows for flexible design and behavior customizations, enabling you to create intricate and engaging game mechanics. By incorporating these techniques into your projects, you’re well on your way to building more dynamic and interactive game worlds.

Expanding on our use of the StaticBody3D class, we’ll explore how to make static objects interact with the environment in various ways. This includes making your platforms “active” without moving them, creating slippery surfaces, and mimicking environmental effects like damp areas or ice patches.

Let’s say you want to create a slippery surface, like ice. You can do so by adjusting the friction property of the PhysicsMaterial:

// Creating a slippery surface using StaticBody3D
var static_body_slippery = StaticBody3D.new()
var icy_material = PhysicsMaterial.new()
# Set very low friction for ice
icy_material.friction = 0.05

var slippery_shape = CollisionShape3D.new()
slippery_shape.shape = BoxShape3D.new(Vector3(5, 0.1, 5)) // A thin, flat surface

static_body_slippery.physics_material_override = icy_material
static_body_slippery.add_child(slippery_shape)
get_node(PARENT_NODE).add_child(static_body_slippery)

In contrast, you may want an area that slows down entities, simulating movement in water or through a dense environment:

// Creating a high-friction surface using StaticBody3D
var static_body_sticky = StaticBody3D.new()
var sticky_material = PhysicsMaterial.new()
# Set high friction for a sticky effect
sticky_material.friction = 10.0

var sticky_shape = CollisionShape3D.new()
sticky_shape.shape = BoxShape3D.new(Vector3(5, 0.1, 5)) // A thin, flat surface

static_body_sticky.physics_material_override = sticky_material
static_body_sticky.add_child(sticky_shape)
get_node(PARENT_NODE).add_child(static_body_sticky)

Moreover, you might want your static object to affect the dynamic objects in other ways. For instance, let’s create a StaticBody3D that simulates a magnetic field, drawing metallic objects towards it:

// Simulating a magnetic field with StaticBody3D
var static_body_magnet = StaticBody3D.new()
var magnet_area = Area3D.new()

# Configure the magnetic influence area (a sphere for this example)
var magnet_shape = CollisionShape3D.new()
magnet_shape.shape = SphereShape3D.new(3.0)
magnet_area.add_child(magnet_shape)

static_body_magnet.add_child(magnet_area)
get_node(PARENT_NODE).add_child(static_body_magnet)

# Connect a signal to react when a body enters the magnetic field
magnet_area.connect("body_entered", self, "_on_Body_Entered_Magnetic_Field")
func _on_Body_Entered_Magnetic_Field(body):
    if "Metallic" in body.tags:
        body.apply_central_impulse((static_body_magnet.global_transform.origin - body.global_transform.origin).normalized() * MAGNETIC_FORCE)

Lastly, consider a scenario where your StaticBody3D platforms need to carry objects, like a conveyor belt. Although the platform itself won’t move, the objects on top should be transported across it. This effect can be achieved by setting the ConstantLinearVelocity property:

// Creating a conveyor belt effect with StaticBody3D
var static_body_conveyor = StaticBody3D.new()
var conveyor_material = PhysicsMaterial.new()

# Conveyor moves objects along the X axis at a speed of 2
conveyor_material.constant_linear_velocity = Vector3(2, 0, 0)

var conveyor_shape = CollisionShape3D.new()
conveyor_shape.shape = BoxShape3D.new(Vector3(5, 0.1, 5))

static_body_conveyor.physics_material_override = conveyor_material
static_body_conveyor.add_child(conveyor_shape)
get_node(PARENT_NODE).add_child(static_body_conveyor)

In this case, objects in contact with the conveyor belt will start to move along the X-axis at a constant speed, simulating the effect of a moving conveyor belt without the need for a physically animated object.

Through these examples, you can see how a StaticBody3D can be more than just an immovable object in your game world. By carefully configuring its properties and the physics material attached to it, your static entities can actively contribute to the gameplay dynamics, enriching the player’s interaction with the environment. These features are just a subset of the powerful tools available in Godot 4, and understanding how to utilize them can significantly boost the quality and complexity of your projects.

Next Steps in Your Game Development Journey

Congratulations on deepening your understanding of the StaticBody3D class in Godot 4! You’ve added a powerful tool to your game developer’s toolkit, and this knowledge will serve as a stepping stone as you continue to perfect your craft.

To keep progressing on your journey to becoming a game development pro, consider exploring our Godot Game Development Mini-Degree. This comprehensive course collection will guide you from the fundamentals of Godot 4 to creating complete games across a variety of genres. You’ll delve into GDScript, 3D asset utilization, UI systems, combat mechanics, and much more.

And if you’re looking for an even broader spectrum of Godot content, our selection of Godot courses caters to all skill levels, offering everything from beginner-friendly introductions to advanced game creation techniques. With our flexible and project-based learning approach, you can continue to grow at your own pace and on your own schedule. So, why wait? Take the next step and start building the game of your dreams with us today!

Conclusion

Embracing the fundamentals of the StaticBody3D class opens up new vistas in game development, and we hope this tutorial has sparked your imagination to experiment and integrate these techniques into your own projects. Remember, the beauty of game creation lies in bringing mechanics and gameplay to life, transforming static elements into an interactive, dynamic part of your virtual worlds.

Now that you’re equipped with this knowledge, don’t stop here! Join us at Zenva to unlock the full potential of Godot 4 and beyond. Whether you’re just starting out or looking to refine your existing skills, our Godot Game Development Mini-Degree is the perfect next step on your journey. Let’s build something amazing together!

FREE COURSES
Python Blog Image

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