I can't do a normal character rotation

Godot Version

v4.1.3

Question

Hello, I want to make a normal rotation of the character, towards the mouse click, but it just spins in place, or something like that.

Code:

extends CharacterBody3D

const SPEED = 5
var target_position = null

func _physics_process(delta):

	if Input.is_action_just_pressed("mouse_left") or Input.is_action_pressed('mouse_left'): # Mouse position
		var viewport := get_viewport()
		var mouse_position := viewport.get_mouse_position()
		var camera := viewport.get_camera_3d()
		var origin := camera.project_ray_origin(mouse_position)
		var direction := camera.project_ray_normal(mouse_position)
		var ray_length := camera.far
		var end := origin + direction * ray_length
		var space_state := get_world_3d().direct_space_state
		var query := PhysicsRayQueryParameters3D.create(origin, end)
		var result := space_state.intersect_ray(query)

		target_position = result["position"]

	if target_position != null: # check
		var direction = target_position - position
		velocity = direction.normalized() * SPEED
		rotate_y(target_position.y - position.y) # Rotation
		velocity.y = 0

		if position.distance_to(target_position) <= 0.1:
			target_position = null
			velocity.y = 0
			velocity.x = 0
			velocity.z = 0

	move_and_slide()

Use global position as rat query is global.
var direction = target_position - global_position

Use dot product to get angle between vectors.
rotate_y(target_position.y - position.y) this isn’t doing what you think.

Or easier just use the look_at function.

1 Like

Thanks! Thanks to you, I realized my mistake! I decided to share the corrected code with you. I hope you like it)))

Code:

extends CharacterBody3D

const SPEED = 5
var target_position = null

func _physics_process(delta):

	if Input.is_action_just_pressed("mouse_left") or Input.is_action_pressed('mouse_left'): # Mouse position
		var viewport := get_viewport()
		var mouse_position := viewport.get_mouse_position()
		var camera := viewport.get_camera_3d()
		var origin := camera.project_ray_origin(mouse_position)
		var direction := camera.project_ray_normal(mouse_position)
		var ray_length := camera.far
		var end := origin + direction * ray_length
		var space_state := get_world_3d().direct_space_state
		var query := PhysicsRayQueryParameters3D.create(origin, end)
		var result := space_state.intersect_ray(query)

		target_position = result["position"]

	if target_position != null: # check
		var direction = target_position - global_position # Use global position
		direction = direction.normalized()

		# Rotate the character towards the target using look_at
		var char = $KnightHeadB
		char.look_at(-target_position, -Vector3.UP)
		char.rotation.x = 0
		char.rotation.z = 0

		velocity = direction * SPEED
		velocity.y = 0

		if position.distance_to(target_position) <= 0.1:
			target_position = null
			velocity.y = 0
			velocity.x = 0
			velocity.z = 0

	move_and_slide()
1 Like

Hello, I decided to share what I got. Here is the link —> I'm trying to create an RPG (I know it sounds silly)