• Godot Help
  • gdscript add CollisionShape to scene in code

I've figured out how to get a list of files and create Meshinstances and have them appear properly in a scene but I also need to create Colliders for them which I can't quite seem to figure out. Although no errors are reported any collisionshapes I create turn out to be null. Here's where I've gotten to

	for arm in armors:
		var file = _path + arm + ".obj"
		var arraymesh = load(file)
		var mesh = MeshInstance.new()
		mesh.mesh = arraymesh
		add_child(mesh)
		var coll = CollisionShape.new()
		coll.shape = arraymesh
		coll.name = arm
		print(coll.shape)

I've tried setting the shape to arraymesh, mesh, and mesh.mesh but coll.shape still remains null and no collisions occur in the scene so although I've created colliders they are empty. Anyone know how to create the shapes properly (or am I barking up the wrong tree entirely?).

P.S. Yes, the meshes are valid and I can see them in the scene when I run it.

I've tried create_convex_collision and the other create. If you look at the docs though they return VOID so end up with nothing anyway. Can't figure out why that would even be included in the engine,

According to the documentation, it "creates a StaticBody child node with a ConvexPolygonShape collision shape calculated from the mesh geometry." Does it not do that?

Not in a way I can see. It returns NULL and no children appear (I used print(get_children() to check).

I just tested it (Godot 3.5.2-rc2), and it performs as the documentation states. I placed a call to create_convex_collision() in the _ready() function of a script attached to a MeshInstance. It created a StaticBody child, which has a CollisionShape child.

If I set a breakpoint after the create_convex_collision() call, I can select the Remote tab in the scene dock, and view the added nodes.

I must be missing something then! Can you post code on how you did that?

I'm using a built-in primitive for the MeshInstance, rather than loading an .obj model from a file. I wonder if that's the reason you're getting a different result.

Could you try using one of the built-in primitives in the Inspector, such as New SphereMesh, instead of loading the .obj file, and see if that makes create_convex_collision() work?

I get colliders but they are empty and they don't function because the shape is NULL. Can I see your code so I can see what I'm doing wrong?

extends MeshInstance

func _ready() -> void:
	create_convex_collision()
	print_tree()
        pass # put break point here

I don't know if the result is actually useful, though. I don't know what purpose is served by adding a StaticBody child with a CollisionShape child to a MeshInstance.

Isn't a MeshInstance normally a child of a CollisionObject, and the CollisionShape a child of that CollisionObject, rather than a child of the MeshInstance?

So I tried it simply using a cubemesh and I get the same result. No child CollisionShape and no collision. If I add one using the Mesh Menu then it shows a child and collisions work.
print_tree() a shows a child but that's all

func _ready():
	var meshI = get_node("MeshInstance")
	meshI.create_convex_collision(true, true)
	print(get_children())

Ok I figured it out!!!! Of course the problem was my ignorance and it's actually pretty simple (I figured it would be). We had the right function but I was using it on the wrong object. This works

func _ready(): # It's only a debugging tool on a meshinstance but it returns the proper type on an ArrayMesh

	var arrayMesh = load("res://Models/Tiger1/Hull_Bot_arm.obj")
	var meshI = MeshInstance.new()
	meshI.mesh = arrayMesh
	var Collider = CollisionShape.new()
	var meshShape = arrayMesh.create_convex_shape(true, true)
	Collider.shape = meshShape
	Collider.name = "Collider"
	Collider.transform = meshI.global_transform
	add_child(meshI)
	add_child(Collider)

	print(get_children())		

Now the collider exists and works perfectly.

8 days later

Very nice find! I was trying to figure this exact thing out!!!!

a year later

Hi
Is this for Godot 4 or Godot 3?