Collision not stopping movement

Godot Version

Godot Engine v4.2.2.stable.official.15073afe3

Question

I have created a CharacterBody3D with a CollisionShape3D but when I move it through another CollisionShape3D it continue to move, it doesn’t stop. I am pretty sure I need to check for the collision in my movement function and prevent movement deeper into the object the CharacterBody3D is colliding with.

image

func horizontalmove(delta : float) -> void :
	var direction := Input.get_vector("flc_camera_left", "flc_camera_right", "flc_camera_foreward", "flc_camera_back")
	var direction3d := Vector3(direction.x, 0, direction.y)
	var prev_pos = dolly.position
	dolly.translate_object_local(direction3d * zoom_speed * delta)

What do I need to add, or modify my horizontal_move function which is called in _physics_process()

Since you’re using CharacterBody3D you should be modifying velocity which will be automatically applied, accounting for collisions, to the position whenever you call move_and_slide

CharacterBody3D should be moved by setting its velocity and calling move_and_slide() to collide with other physic object.

To quickly get the code for this create a new character body 3d node, click new script and select as template the characterbody3d.
Then you can copy and modify the script as you need, for example your input.

Unfortunately doing that changed the motion so instead of moving based on the angle of the node, it moves on the cardinal directions of the world.

When I comment out the dolly.translate_object_local and change to move and slide it changes.

I don’t think setting the velocity.x and velocity.y is the solution.

var direction := Input.get_vector("flc_camera_left","flc_camera_right","flc_camera_foreward","flc_camera_back")
	var direction3d := Vector3(direction.x, 0, direction.y)
	var prev_pos = dolly.position
	#dolly.translate_object_local(direction3d * zoom_speed * delta)
	
	if direction:
		velocity.x = direction3d.x * dolly_speed
		velocity.z = direction3d.z * dolly_speed
	else:
		velocity.x = move_toward(velocity.x, 0, dolly_speed)
		velocity.z = move_toward(velocity.z, 0, dolly_speed)
	
	move_and_slide()

Using the velocity and move_and_slide() is definitely the solution - if you don’t, then there’s no point in using CharacterBody3D at all. Your problem with global vs. local axis is entirely solvable.

Since we want to move along direction3d in local space, we need to take that vector and calculate what it should be in global space. This is easy enough to do by multiplying it with the basis of the object whose local space we want to use. In your case, I think it’s your dolly object, right? I assume you have some code that rotates that somewhere.

velocity = (dolly.global_basis * direction3d).normalized() * dolly_speed

That should give you movement relative to whatever direction the dolly is facing.

Hokay, I was able to get the motion to move on camera, but it is still not colliding.

func horizontal_move(delta : float) -> void :
	var direction := Input.get_vector("flc_camera_left","flc_camera_right","flc_camera_foreward","flc_camera_back")
	var direction3d := Vector3(direction.x, 0, direction.y)
	direction3d = direction3d.rotated(Vector3.UP, dolly.rotation.y)
	if direction:
		velocity.x = direction3d.x * dolly_speed
		velocity.z = direction3d.z * dolly_speed
	else:
		velocity.x = move_toward(velocity.x, 0, dolly_speed)
		velocity.z = move_toward(velocity.z, 0, dolly_speed)
	
	move_and_slide()

All collisions are set to layer and mask 1 for simplicity

image

Well, Area3Ds aren’t made to stop movement, just to detect if something enters them. If you want a wall that blocks movement, use a StaticBody3D instead. You should be able to right-click on one of your Area3Ds and choose “change type”, then select StaticBody3D.

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.