ConvexPolygonShape3D in Godot – Complete Guide

Navigating the exciting world of game development introduces us to a variety of tools and concepts that can bring our digital dreams to life. Among these is the ConvexPolygonShape3D class in Godot 4, which is pivotal for enabling accurate physics collision in a game’s 3D environment. This robust feature not only enhances the realism of interaction within the game but it also ensures the mechanics are operating under conditions that mimic the real world. Whether you’re a budding game developer or a seasoned coder, grasping the functionalities and applications of ConvexPolygonShape3D will significantly enhance your game’s physics. So buckle up as we dive into the details of this powerful class—no math degree required, we promise!

What Is ConvexPolygonShape3D?

ConvexPolygonShape3D is a class found in Godot’s robust engine, designed for incorporating physics collisions into your 3D game projects. It serves as a collision shape that you can attach to a CollisionShape3D node within Godot. This shape is specifically tailored to represent solid objects, eliminating the ability for other entities to pass through unnoticed, unlike its counterpart, the ConcavePolygonShape3D.

What Is It For?

In game development, physics collision is crucial for creating interactive and believable environments. ConvexPolygonShape3D aids in materializing these collisions, ensuring that when objects come into contact, they do so in a manner that reflects their physical properties. It’s about convincing players that the virtual world adheres to familiar laws of physics, enhancing immersion and gameplay experience.

Why Should I Learn It?

Understanding ConvexPolygonShape3D empowers you to represent complex objects with collisions that won’t be practically captured by simpler shapes like spheres or boxes. While the primitive shapes are more performance-friendly, they sometimes fall short in mimicking the real contours of an object. Hence, learning to use ConvexPolygonShape3D is a stepping stone to mastering the nuanced physics interactions in a more detailed 3D game environment, giving you the flexibility to go beyond basic collisions and into the realm of advanced gameplay dynamics.

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

Creating a Basic ConvexPolygonShape3D

To start using the ConvexPolygonShape3D, you first need to create a new shape and attach it to a CollisionShape3D node in your scene. Here’s how to do it from the Godot editor:

# Assuming we are in the script attached to the node that should have the collision.
var collision_shape = CollisionShape3D.new()
var convex_shape = ConvexPolygonShape3D.new()

# Now, set the shape of the collision
collision_shape.shape = convex_shape

# Finally, add it as a child to the node it should protect
add_child(collision_shape)

Setting the Points of ConvexPolygonShape3D

A ConvexPolygonShape3D is defined by a set of points that make up its vertices. Let’s define a simple pyramid shape:

# First, create the shape as before
var convex_shape = ConvexPolygonShape3D.new()

# Define the points of the pyramid
var points = PoolVector3Array([
    Vector3(0, 1, 0),   # Top Point
    Vector3(1, 0, 1),   # Base - Bottom Right
    Vector3(-1, 0, 1),  # Base - Bottom Left
    Vector3(-1, 0, -1), # Base - Top Left
    Vector3(1, 0, -1),  # Base - Top Right
])

# Assign the points to the shape
convex_shape.set_points(points)

These points should form a convex shape. Godot will not prevent you from entering concave shapes, but the resulting behavior might not be what you expect because ConvexPolygonShape3D expects a convex set of points.

Attaching ConvexPolygonShape3D to Physics Bodies

A ConvexPolygonShape3D isn’t much use without a physics body. Let’s attach it to a RigidBody3D:

# Let's assume you've already created the ConvexPolygonShape3D as in previous examples.
var body = RigidBody3D.new()
var collision_shape = CollisionShape3D.new()

collision_shape.shape = convex_shape

body.add_child(collision_shape)
add_child(body)

The same concept applies to StaticBody3D and KinematicBody3D. The collision shape will adapt to the type of physics body to which it’s attached, affecting how it interacts with the world.

Adjusting CollisionShape3D Transformation

Customizing the position and orientation of your ConvexPolygonShape3D within your physics body can be fundamental for correct collision detection. We can adjust the transform of our CollisionShape3D to do so:

# Continuing from the previous snippet where we have our CollisionShape3D:
collision_shape.global_transform = Transform(Basis(), Vector3(5, 0, 2))

Here, we’ve moved the CollisionShape3D to position (5, 0, 2) in global space. You can also rotate and scale the transform as needed, but be aware that non-uniform scaling (different scale factors for each axis) may produce unexpected results. Uniform scaling and rotations, however, will update the collision shape correctly.Sometimes, you might want to programmatically inspect or modify the vertices of your ConvexPolygonShape3D in response to game events. For instance, you may need to adjust the shape based on damage to an object, or dynamically construct shapes based on player interactions. Here’s how you might access and modify the points of your shape in code:

# Accessing the points of an existing ConvexPolygonShape3D
var points = convex_shape.get_points()

# Let's say we want to modify the top vertex of our pyramid to make it taller
points[0].y += 1.0

# After modifying the points array, you need to set it back to the shape
convex_shape.set_points(points)

Remember to ensure that the modified shape is still convex; otherwise, you might run into some unexpected physics behavior.

Moreover, you may find yourself in a situation where you want to apply an offset to the entire shape. For example, if you’re instantiating a shape onto objects generated at runtime, and you want to shift the collision shape to align with the model:

# Apply an offset to all points in the ConvexPolygonShape3D
var offset = Vector3(2, 0, 0)
for i in range(points.size()):
    points[i] += offset

# Update the shape with the new points
convex_shape.set_points(points)

In some game mechanics, you may want to check at runtime whether a given point in space intersects with your ConvexPolygonShape3D. This could be helpful for things like custom gameplay interactions, determining line of sight, or even debugging. Here’s a simple check you can perform, assuming `convex_shape` is part of a physics body:

# Assuming you have a Vector3 representing the point in space
var point_to_check = Vector3(1, 2, 3)
var is_inside = convex_shape.is_point_inside(point_to_check)

if is_inside:
    print("The point is inside the ConvexPolygonShape3D!")

It’s also possible that during the course of developing your game, you will need to completely replace the shape of a `CollisionShape3D` with a new `ConvexPolygonShape3D`. This could be triggered by gameplay, such as an object changing form or breaking apart:

# Assuming we already have a CollisionShape3D instance named collision_shape
var new_shape = ConvexPolygonShape3D.new()

# Define the new points array for your updated shape
var new_points = PoolVector3Array([
    # New points go here
])

# Assign the points to your new shape
new_shape.set_points(new_points)

# Replace the old shape with the new one keeping the same node structure
collision_shape.shape = new_shape

Ultimately, whether it’s through transformation of a collision shape, adjusting its points dynamically, or even querying and replacing them based on gameplay events, the ConvexPolygonShape3D class provides Godot developers with robust tools for exercising detailed control over 3D physics interactions. These powerful features help to ensure that your game world behaves as expected, creating an immersive and reliable experience for your players.Manipulating the scale of your collision shape can be an important tool in your game development arsenal. Suppose you’re working on a game where objects can grow or shrink—this means their collision bounds need to adjust accordingly. This is how you can dynamically scale a ConvexPolygonShape3D:

# Scaling up the ConvexPolygonShape3D by a factor of 2
var scale_factor = 2
collision_shape.global_transform = collision_shape.global_transform.scaled(Vector3(scale_factor, scale_factor, scale_factor))

Recall that scaling should generally be uniform to prevent unusual collision behaviors.

There will be times when you need to check if your ConvexPolygonShape3D overlaps with another shape in the world, which is a common requirement for triggering events or interactions in games. In Godot, you can use the PhysicsServer to do this:

# Assuming convex_shape refers to a ConvexPolygonShape3D instance
# Prepare the query parameters
var shape_state = PhysicsServer.shape_create(PhysicsServer.SHAPE_CONVEX_POLYGON)
PhysicsServer.shape_set_data(shape_state, convex_shape.points)

var query_parameters = PhysicsServer.space_create()
PhysicsServer.area_add_shape(query_parameters, shape_state)

# Then, you can perform the intersection check like this
var result = PhysicsServer.space_get_direct_state(query_parameters).intersect_shape(shape_state, Transform())

# Cleaning up by removing the query
PhysicsServer.free_rid(query_parameters)

# Check if there was an overlap
if result.count > 0:
    print("Overlap detected with another shape!")

Sometimes, you’ll want to align your ConvexPolygonShape3D to the geometry of your 3D models. You can achieve this by using bounding boxes from MeshInstances to create collision shapes that closely match your models:

# Assuming you have a MeshInstance node called "model"
var bounding_box = model.get_aabb()
var center = bounding_box.position + bounding_box.size * 0.5

# Create points for ConvexPolygonShape3D based on bounding box dimensions
var points = PoolVector3Array([
    center + Vector3(bounding_box.size.x / 2, bounding_box.size.y / 2, bounding_box.size.z / 2),
    center + Vector3(-bounding_box.size.x / 2, bounding_box.size.y / 2, bounding_box.size.z / 2),
    # ... Add all the other vertices ...
])

# Now create and set up the ConvexPolygonShape3D with these points
var shape = ConvexPolygonShape3D.new()
shape.set_points(points)

# And attach this shape to a CollisionShape3D
collision_shape.shape = shape

Bear in mind that using the bounding box will give you a convex shape approximation of your model which may or may not be sufficient depending on your precision needs.

Lastly, when dealing with more complex models, you may wish to manually define a ConvexPolygonShape3D that consists of multiple component shapes, or “hulls.” This is a more advanced technique used to create collisions for intricate objects:

# Starting with two convex shapes to combine:
var hull_a = ConvexPolygonShape3D.new()
var hull_b = ConvexPolygonShape3D.new()

# Define points for each hull similar to the previous examples

# Once created, you normally would use a physics server to combine them:

# Create space state for queries
var space_state = PhysicsServer.space_create()

# Create shape states for the hulls
var shape_a_state = PhysicsServer.shape_create(PhysicsServer.SHAPE_CONVEX_POLYGON)
var shape_b_state = PhysicsServer.shape_create(PhysicsServer.SHAPE_CONVEX_POLYGON)

# Set the points for each shape
PhysicsServer.shape_set_data(shape_a_state, hull_a.points)
PhysicsServer.shape_set_data(shape_b_state, hull_b.points)

# Now you can use these shapes as needed to generate more complex collision objects

While combining shapes like this can be more CPU intensive, it allows for more accurate and realistic collision detection for complex objects, contributing to a richer gaming experience.

Through these examples, it’s clear that the ConvexPolygonShape3D class in Godot 4 gives developers a powerful suite of tools to accurately model the physical properties of 3D objects. By mastering these abilities, you can create engaging and dynamic interactions in your game worlds, enhancing both realism and player enjoyment.

Where to go next with Godot Game Development

Armed with knowledge of the ConvexPolygonShape3D class, your journey through the world of Godot 4 is just gaining momentum! If you’ve enjoyed this foray into the subtleties of 3D collision in Godot and are eager to explore further, our Godot Game Development Mini-Degree is the perfect next step. This comprehensive program covers everything you need to create stunning, cross-platform games using the state-of-the-art Godot 4 engine.

From mastering 2D sprites to orchestrating entire 3D worlds, our curriculum, suitable for all skill levels, will guide you in harnessing Godot’s flexible systems—making the leap from player to creator. Access our courses at your leisure and build up a professional portfolio to showcase your newfound skills.

Whether you’re starting out or refining your game development prowess, be sure to explore our broad collection of Godot courses, each designed to turbocharge your coding and game creation capabilities. We at Zenva are excited to help you transform your enthusiasm into tangible, interactive realities. Dive in and let the coding adventure continue!

Conclusion

Mastering the mechanics of ConvexPolygonShape3D is a game-changer for any aspiring Godot developer. As you harness the full potential of this class, you’ll watch as your 3D worlds come to life with intricate, reactive physics that captivate your players. Remember, the key to breathtaking games lies not just in their visual splendor, but also in the invisible, underlying mechanics that make the play experience feel real and responsive.

Embrace your newfound knowledge and let it be the catalyst for innovation in your game development journey. We at Zenva are here to support every step of your learning path with our Godot Game Development Mini-Degree. Keep experimenting, keep creating, and above all, keep enjoying the remarkable craft of game development!

FREE COURSES
Python Blog Image

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