Godot Version
v4.3.stable.official [77dcf97d8]
Questions
I’m using collide_shape to proactively check if rotating my RigidBody3D is going to cause a collision. If a collision is detected I want to adjust the rotation to stop the nodes overlapping (I still need them to collide, so signals are emitted).
I can’t figure out how to use the result of collide_shape to adjust the angle correctly.
- How can I use the resulting collision vectors from
collide_shapeto adjust the rotation? - Is there an alternative method I could/should use instead?
- I’ve also added some questions as comments directly in the code snippet below

More details
I’m using a tween to animate the rotation. This is done over a short timeframe 0.2 seconds, which results in a high move speed. This was causing my nodes to clip into each other and freak out. I’ve sort of worked around this by upping the physics tick to 120, but this didn’t feel like a real solution. This is why I started looking into checking for collisions before rotating.
The reason I rotate the RigidBody3D rather than using forces is because its frozen and following a Path3D. My entire game has been built around this and everything I’ve wanted to do so far seems to be working
So trying to use forces isn’t going to be a viable solution, I’d basically have to start everything from scratch ![]()
This is hopefully the important snippets from my code.
# pivot is a Node3D being rotated
# _rigid_body is a RigidBody3D that is a "child" of pivot (technically a RemoteTransform3D is the child, but that is transforming the _rigid_body)
func _create_jump_tween(final_rot: float, on_finished: Callable) -> void:
_jump_tween = create_tween()
_jump_tween.set_process_mode(Tween.TWEEN_PROCESS_PHYSICS)
# Should I be using `pivot.rotation` or another method?
_jump_tween.tween_method(_do_jump.bind(pivot), pivot.rotation, Vector3(0, final_rot, 0), 0.2)
_jump_tween.finished.connect(on_finished)
func _collision_test(adjust: Transform3D = Transform3D.IDENTITY) -> Array[Vector3]:
var space_state: PhysicsDirectSpaceState3D = _rigid_body.get_world_3d().direct_space_state
var psqp: PhysicsShapeQueryParameters3D = PhysicsShapeQueryParameters3D.new()
psqp.shape = BoxShape3D.new()
psqp.shape.size = model.aabb.size
psqp.collision_mask = 0b1100
psqp.exclude = [_rigid_body.get_rid()]
# Is this the correct way to adjust the transform?
psqp.transform = Transform3D(_rigid_body.global_transform) * adjust
return space_state.collide_shape(psqp, 1)
func _do_jump(rot: Vector3, pivot: Node3D) -> void:
# Is this the correct way to get the rotated transform?
var end_transform: Transform3D = pivot.transform.rotated(Vector3.UP, rot.y - pivot.rotation.y)
var collision_result: Array[Vector3] = _collision_test(end_transform)
if not collision_result.is_empty():
var collider_position: Vector3 = collision_result[0]
var other_position: Vector3 = collision_result[1]
# What do I do with these results to adjust the rotation?
pivot.rotation = rot
Diagram
This is an example top down look of what I’m doing
- The blue rectangle is the node I’m rotating around the black circle pivot point
- The yellow is something in the way the blue rectangle should collide with
- The red cross is a collision result
collide_shapeis giving me back - The dotted rectangle represents the full rotation
- I know the width and length of the blue rectangle (
floats) - I know the location of the black pivot point (
Vector3) - I know the location of the red cross (
Vector3) - I know the full rotation that would result in the dash rectangle (
Vector3)
I feel like there is some trigonometry that would allow me to work this out
but I just can’t figure it out, and I feel like I’m probably over complicating things…
Any help muchly appreciated as always!
