+ Let's say we want to do a raycast in order to check what texture a face is so we can play an appropriate
+ sound effect such as snow for snowy textures and stone for stone textures.
+
+
+ Firstly, you will need a Raycast3D. Secondly, you will need a FuncGodotFGDSolidClass. In the Mesh metadata
+ you will need to tick "Add Textures Metadata". The collision mask for the Racyast3D must match a collision
+ layer of the FuncGodotFGDSolidClass, otherwise it will not report a collision.
+
+
+ Ticking "Add Textures Metadata" adds two metadata properties to generated nodes. It adds "textures" which is
+ a PackedInt32Array, where the index in the array is the face index, and the value at any point is an
+ integer. This integer is then used by the "texture_names", the 2nd metadata property which is added.
+ Indexing that array with that integer gets us the texture name string. So how do I get the face index?
+ Raycast3D has a handy method called get_collision_face_index()
+
+
NOTE: If you are using Jolt Physics as your Physics Engine, you must tick Enable Ray Cast
+ Face Index in your project settings! This can be found in Project Settings > Physics > Jolt Physics 3D >
+ Queries > Enable Ray Cast Face Index.
+
Putting this all together, as a script on our Raycast3D, the following function returns the Texture Name when
+ we call it.
+
func do_check() -> String:
+ var col := get_collider()
+ if !col:
+ return "" # No collision, no texture
+ if !col.has_meta("func_godot_mesh_data"):
+ return "" # Metadata not added
+ var metadata: Dictionary = col.get_meta("func_godot_mesh_data")
+ if !("textures" in metadata):
+ return "" # Textures Metadata not added
+ if !("texture_names" in metadata):
+ return "" # Textures Metadata not added
+ var textures: PackedInt32Array = metadata["textures"]
+ var texture_names: Array = metadata["texture_names"]
+ var texture: String = texture_names.get(
+ textures.get(
+ get_collision_face_index()
+ )
+ )
+ return texture;
+
+ When we call do_check();, we now get the texture String for the face the Raycast3D collided
+ with, if it collided with anything at all. The rest of the implementation of material based footsteps is
+ left as an exercise to the reader.
+
+
+ As a note you can also use this same approach for running code on specific textures. For example damage on
+ lava textures, slowness on cobweb textures, though these may be better accomplished with a
+ FuncGodotFGDSolidClass that creates an Area3D instead. You can also use this to get material-specific decal
+ textures.
+
+
+
+
+
+
\ No newline at end of file
diff --git a/FuncGodot Manual/pages/tips_worldspawn.html b/FuncGodot Manual/pages/tips_worldspawn.html
index 1ed68ac..ab7106a 100644
--- a/FuncGodot Manual/pages/tips_worldspawn.html
+++ b/FuncGodot Manual/pages/tips_worldspawn.html
@@ -53,18 +53,6 @@
Occlusion Culling
In exchange for full automation, FuncGodot instead gives you full control.
-
Surface "Materials"
-
- A common question a lot of Godot devs have is how do I get the texture of the surface my character is stepping on or shooting? and the answer is... you don't!
- Well, the short answer anyway. Since Godot's CollisionObjects are completely separate from the MeshInstance3Ds, there's no real good performant way to actually
- do it surface by surface. Any possible solutions that involve getting the stage mesh's texture on a particular face are just not worth it. But why work against the
- engine when you can work with it?
-
-
- If we can control how our stage geometry is split up, we can also provide that stage geometry with key value properties, including one that supplies a Material Type
- that can easily be passed to any character stepping on or shooting it. This is something that can't be done with a singular Worldspawn entity.
-
-
How Do I Live Without Worldspawn?
You'll want to create a Solid Class entity that matches the Worldspawn entity definition.
From 9256efd972dc86ff2c27b88a05f6c9f1f6613c3a Mon Sep 17 00:00:00 2001
From: RisingThumb
Date: Thu, 20 Nov 2025 00:11:14 +0000
Subject: [PATCH 2/4] Add a few links
---
.../pages/tips_material_based_footsteps.html | 15 ++++++++-------
1 file changed, 8 insertions(+), 7 deletions(-)
diff --git a/FuncGodot Manual/pages/tips_material_based_footsteps.html b/FuncGodot Manual/pages/tips_material_based_footsteps.html
index 65e505e..3b7e243 100644
--- a/FuncGodot Manual/pages/tips_material_based_footsteps.html
+++ b/FuncGodot Manual/pages/tips_material_based_footsteps.html
@@ -11,20 +11,20 @@
Material Based Footsteps
- Let's say we want to do a raycast in order to check what texture a face is so we can play an appropriate
- sound effect such as snow for snowy textures and stone for stone textures.
+ To do this we need to raycast in order to check what texture a face is so we can play an appropriate
+ sound effect such as snow sounds for snowy textures and stone sounds for stone textures.
- Firstly, you will need a Raycast3D. Secondly, you will need a FuncGodotFGDSolidClass. In the Mesh metadata
- you will need to tick "Add Textures Metadata". The collision mask for the Racyast3D must match a collision
+ Firstly, you will need a Raycast3D. Secondly, you will need a FuncGodotFGDSolidClass. In the Mesh metadata
+ you will need to tick "Add Textures Metadata" found under Mesh Metadata. The collision mask for the Racyast3D must match a collision
layer of the FuncGodotFGDSolidClass, otherwise it will not report a collision.
- Ticking "Add Textures Metadata" adds two metadata properties to generated nodes. It adds "textures" which is
+ Ticking "Add Textures Metadata" adds two metadata properties to generated nodes of that Solid Class. It adds "textures" which is
a PackedInt32Array, where the index in the array is the face index, and the value at any point is an
integer. This integer is then used by the "texture_names", the 2nd metadata property which is added.
Indexing that array with that integer gets us the texture name string. So how do I get the face index?
- Raycast3D has a handy method called get_collision_face_index()
+ Raycast3D has a handy method called get_collision_face_index() which we use.
NOTE: If you are using Jolt Physics as your Physics Engine, you must tick Enable Ray Cast
Face Index in your project settings! This can be found in Project Settings > Physics > Jolt Physics 3D >
@@ -53,7 +53,8 @@
Material Based Footsteps
When we call do_check();, we now get the texture String for the face the Raycast3D collided
with, if it collided with anything at all. The rest of the implementation of material based footsteps is
- left as an exercise to the reader.
+ left as an exercise to the reader as it is project specific, but you will likely want some way to convert
+ from a texture name to a Stream and to then play that Stream with an AudioStreamPlayer.
As a note you can also use this same approach for running code on specific textures. For example damage on
From 288634eefe3c84a2d03464f5bd872fa800dc7243 Mon Sep 17 00:00:00 2001
From: RisingThumb
Date: Thu, 20 Nov 2025 00:15:14 +0000
Subject: [PATCH 3/4] Note memory cost for Jolt
---
FuncGodot Manual/pages/tips_material_based_footsteps.html | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/FuncGodot Manual/pages/tips_material_based_footsteps.html b/FuncGodot Manual/pages/tips_material_based_footsteps.html
index 3b7e243..ec42e38 100644
--- a/FuncGodot Manual/pages/tips_material_based_footsteps.html
+++ b/FuncGodot Manual/pages/tips_material_based_footsteps.html
@@ -28,7 +28,7 @@
Material Based Footsteps
NOTE: If you are using Jolt Physics as your Physics Engine, you must tick Enable Ray Cast
Face Index in your project settings! This can be found in Project Settings > Physics > Jolt Physics 3D >
- Queries > Enable Ray Cast Face Index.
- FGD SolidClass entity definition that generates a mesh from Brush Data .
+ FGD SolidClass entity definition that generates a mesh from Brush Data.
A MeshInstance3D will be generated by FuncGodotMap according to this definition's Visual Build settings.
If node_class inherits CollisionObject3D then one or more CollisionShape3D nodes will be