I’m working on a 3D game with a dialogue system, and I need the player to rotate their Y angle to a target position.
But if I rotate the player mesh it breaks this line of code that rotates the player to the direction angle.
Body.rotate.y = lerp_angle(Body.rotation.y, atan2 (direction.x, direction.z), delta * rotation_speed)
Send help
Need more info.
Please put code between ``` like this:
```gdscript
#Code here
```
#Code here
How are you rotating the player? Where is that code? Also, the one line you did show does wildly different things depending on where you put it. I’m assuming that it’s probably in _physics_process(), but I honestly don’t want to spend time this late at night giving you advice based on that assumption just to find out it’s somewhere else.
We can only help if you give us enough information to work with.
1 Like
Try this to rotate the object to face the to_target coordinates:
var target_rotation = atan2(to_target.x, to_target.z)
rotation.y = move_toward(rotation.y, target_rotation, delta * speed)
I suppose you use these lines in your _process or _physics_process function.
1 Like
extends CharacterBody3D
#region, Llamada a nodos y variables OwO
@onready var cam: Node3D = $Camara_centro/Brazo_angulo
@onready var Cuerpo :Node3D = $Chucho_cuerpo
@onready var Hurtbox: Node3D = $Hurtbox/CollisionShape3D
@onready var HitboxDaño :Node3D = $Chucho_cuerpo/Armature/Skeleton3D/Hitbox/CollisionShape3D
@onready var Salto_fx :GPUParticles3D = $Chucho_cuerpo/Salto #Efectos visuales
@onready var Pasos_fx :GPUParticles3D = $Chucho_cuerpo/Pasos
@onready var Fuego_fx :GPUParticles3D = $Chucho_cuerpo/Fuego
var dash_fantasma = preload("res://Personajes/Chucho/Visuales/dash.tscn")
@onready var Slash1 :MeshInstance3D = $Chucho_cuerpo/Armature/Skeleton3D/EspadaMano/Ataque1
@onready var Animador = $Chucho_cuerpo/Animador2
@onready var ataque_sonido = $Sonidos/Ataque
@onready var Dash_tiempo :Timer = $Temporizadores/Dash_tiempo #Tiempos de abajo
@onready var Dash_fantasma :Timer = $Temporizadores/Dash_fantasma
@onready var Ataque_tiempo :Timer = $Temporizadores/Ataque_tiempo
@onready var Coyote_tiempo :Timer = $Temporizadores/Coyote
# -> VARIABLES DE PERSONAJE
@export var Velocidad : float = 5.4
@export var Rotacion_velocidad : float = 10
@export var Salto : float = 22.4
# -> ESTADOS SPECIFICOS
var Angulo_Eloy_inicial_y : float
var Angulo_camaras_inicial_y : float
var Coyote :bool # Coyote time
var salto_caida :bool #Esta en el aire
var Estuvo_aire :bool
var Ataque_CD :bool #bloquea atacar si es verdadero
var Acciones_CD : bool #bloquea dash si es verdadero
# -> VARIABLES DE ANIMACION
var Quieto :bool
var Moverse :bool
var Ataques : bool
var Dashea :bool
var Ataque : int = 1 # Numero de animacion
#endregion, Llamada a nodos y variables OwO
#region, Habilidades del personaje [INPUT]
func _input(_event: InputEvent) -> void:
# -> Habilidad de ataque, todas las animaciones de ataque duran lo mismo
if Input.is_action_just_pressed("Ataca") and !Ataque_CD and !Dashea:
Ataque_CD = true
HitboxDaño.disabled = false
Ataque_tiempo.start()
_REINICIAR_ANIMS()
Ataques = true
ataque_sonido.play()
if Ataque == 1:
Animador["parameters/Ataques/blend_position"] = 0
Slash1.visible = true
return
if Ataque == 2:
Animador["parameters/Ataques/blend_position"] = 1
Slash1.visible = true
return
#if Ataque == 3:
#if Ataque == 4:
if Input.is_action_just_pressed("Dash") and !Acciones_CD and !Ataques:
Acciones_CD = true
Hurtbox.disabled = true
Coyote_tiempo.wait_time = 2.9
Dash_tiempo.start()
_REINICIAR_ANIMS()
Dashea = true
Fuego_fx.emitting = true
crear_fantasma()
Dash_fantasma.start()
$Sonidos/Dash.playing = true
if is_on_floor() and Coyote == false:
Coyote = true # Puede saltar si esta en el suelo
elif Coyote == true and Coyote_tiempo.is_stopped():
Coyote_tiempo.start(Coyote)
if Input.is_action_just_pressed("Salto") and Coyote:
Coyote = false # Desactiva el coyote time al saltar
velocity.y = Salto # Salta XD
Salto_fx.top_level = true
Salto_fx.position = $".".position
Salto_fx.emitting = true
$Sonidos/Salto.playing = false
$Sonidos/Salto.playing = true
#endregion, Habilidades del personaje [INPUT]
func _ready() -> void:
Cuerpo.rotation_degrees.y = Angulo_Eloy_inicial_y
$Camara_centro/Brazo_de_camara.rotation_degrees.y = Angulo_camaras_inicial_y
$Camara_centro/Brazo_angulo.rotation_degrees.y = Angulo_camaras_inicial_y
func _on_coyote_timeout() -> void:
Coyote = false
func _on_dash_tiempo_timeout() -> void:
Dashea = false
Coyote_tiempo.wait_time = 0.82
Fuego_fx. emitting = false
Dash_fantasma.stop()
Hurtbox.disabled = false
await get_tree().create_timer(0.6).timeout
Acciones_CD = false
# Desactiva las animaciones de ataque, inicia el temporizador de bloqueo, y desactiva hitbox de espada
func _on_ataque_tiempo_timeout() -> void:
Slash1.visible = false
Ataques = false
HitboxDaño.disabled = true
await get_tree().create_timer(0.15).timeout
if Ataque == 2:
Ataque = 1
else:
Ataque = 2
Ataque_CD = false
func _on_dash_fantasma_timeout() -> void:
crear_fantasma()
func crear_fantasma (): # Controla el fantasma que se crea al hacer dash
var fantasma: Node3D = dash_fantasma.instantiate()
get_parent().get_parent().add_child(fantasma)
fantasma.global_position = global_position
fantasma.rotation.y = Cuerpo.rotation.y
@export var objetivo :Node3D
func _MirarObjecto(_delta):
pass
func _REINICIAR_ANIMS():
Quieto = false
Moverse = false
Ataques = false
Dashea = false
salto_caida = false
### -> MOVIMIENTO, GRAVEDAD Y ANIMACIONES
func _physics_process(delta: float) -> void:
if not is_on_floor():
velocity += get_gravity() * delta # Matematicas de gravedad XD
if !Ataques and !Dashea: #ANIMACIONES
_REINICIAR_ANIMS()
salto_caida = true
Estuvo_aire = true
else: # Efecto visual al regesar al suelo
if Estuvo_aire == true:
Estuvo_aire = false
Salto_fx.top_level = true
Salto_fx.position = $".".position
Salto_fx.emitting = true
$Sonidos/Caer.playing = true
if Dashea: # Se mueve y hace dash chingon
self.position = $Chucho_cuerpo/Dash_ubi.global_position
if !is_on_floor():
velocity.y += 0.28
# Get the input direction and handle the movement/deceleration.
var input_dir := Input.get_vector("izquierda", "derecha", "delante", "atras")
var direction = (cam.global_basis * Vector3(input_dir.x, 0, input_dir.y)).normalized()
if direction and !Dashea:
velocity.x = direction.x * Velocidad
velocity.z = direction.z * Velocidad
Cuerpo.rotation.y = lerp_angle(Cuerpo.rotation.y, atan2 (direction.x, direction.z), delta * Rotacion_velocidad)
if !Dashea and !Ataques and is_on_floor():
_REINICIAR_ANIMS()
Moverse = true
else:
velocity.x = move_toward(velocity.x, 0, Velocidad)
velocity.z = move_toward(velocity.z, 0, Velocidad)
if !Dashea and !Ataques and is_on_floor():
_REINICIAR_ANIMS()
Quieto = true
# Pone una animacion
Animador["parameters/conditions/Moverse"] = Moverse
Animador["parameters/conditions/Quieto"] = Quieto
Animador["parameters/conditions/Salto_caida"] = salto_caida
Animador["parameters/conditions/Dash"] = Dashea
Animador["parameters/conditions/Ataques"] = Ataques
#Efecto visual de pasos mientras esta en el suelo
if Moverse == true:
Pasos_fx.emitting = true
else:
Pasos_fx.emitting = false
move_and_slide(); # Reorganizar codigo inporta
This is the script i want to make the character to look at to an object
@export var objetivo :Node3D
func _MirarObjecto(_delta):
pass
but i cant rotate 180 degrees the mesh of the player because the player rotates based on walking direction
if direction and !Dashea:
velocity.x = direction.x * Velocidad
velocity.z = direction.z * Velocidad
### Rotation
Cuerpo.rotation.y = lerp_angle(Cuerpo.rotation.y, atan2 (direction.x, direction.z), delta * Rotacion_velocidad)
### Rotation
if !Dashea and !Ataques and is_on_floor():
_REINICIAR_ANIMS()
Moverse = true
Here’s what I would do: Change the walking direction of the player to be pointing towards the way you want them to look during the dialog. There are other ways you could handle it, but since you’re already dealing with facing, just do it there. Then turn off player input during the dialogue.
1 Like
I found a line of code that works the way I want, but rotation isn’t smooth.
@export var target :Node3D
func _LookAtOwO(): # Call this function when is nesesary
self.look_at(target .global_position, Vector3.UP, true)
self.rotation_degrees.x = 0 # Resets the X rotation lol
You can just use the lerp function like you did above to smooth it out.
system
Closed
October 25, 2025, 9:22pm
8
This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.