Mostrando entradas con la etiqueta Excelente GDScript para manejar personaje en Godot 4.7. Mostrar todas las entradas
Mostrando entradas con la etiqueta Excelente GDScript para manejar personaje en Godot 4.7. Mostrar todas las entradas

domingo, 11 de octubre de 2026

Excelente GDScript para manejar personaje en Godot 4.7, calibacion de animaciones y sonidos desde inspector;

 extends Node3D


var anim_player: AnimationPlayer


# Nombres de las animaciones para tener el código limpio

const ANIM_RELAX: String = "MakeHuman default skeleton|RELAX"

const ANIM_ANDAR: String = "MakeHuman default skeleton|ANDAR"

const ANIM_ZARPAZO: String = "MakeHuman default skeleton|ZARPAZO"

const ANIM_MANOTAZO: String = "MakeHuman default skeleton|MANOTAZO"

const ANIM_FURIA: String = "MakeHuman default skeleton|FURIA"


# -------------------------------------------------------------

# AJUSTES CALIBRABLES DESDE EL INSPECTOR

# -------------------------------------------------------------

@export_group("Transición de Animaciones")

@export_range(0.0, 1.0, 0.05) var tiempo_transicion: float = 0.2 # Tiempo de suavizado entre animaciones


@export_group("Velocidad de Animaciones")

@export_range(0.1, 5.0, 0.05) var vel_relax: float = 1.0

@export_range(0.1, 5.0, 0.05) var vel_andar: float = 1.0

@export_range(0.1, 25.0, 0.05) var vel_zarpazo: float = 1.0

@export_range(0.1, 25.0, 0.05) var vel_manotazo: float = 1.0

@export_range(0.1, 5.0, 0.05) var vel_furia: float = 1.0


func _ready() -> void:

# Busca el AnimationPlayer dentro de este nodo y sus hijos

anim_player = buscar_animation_player_propio(self)

if anim_player:

print("¡AnimationPlayer propio del personaje encontrado con éxito!")

# Configura RELAX y ANDAR en Ping-Pong

asegurar_pingpong(ANIM_RELAX)

asegurar_pingpong(ANIM_ANDAR)

# Arranca en RELAX

reproducir(ANIM_RELAX)

else:

print("ERROR: No se encuentra ningún AnimationPlayer dentro de este personaje.")


func buscar_animation_player_propio(nodo: Node) -> AnimationPlayer:

if nodo is AnimationPlayer:

return nodo as AnimationPlayer

for hijo in nodo.get_children():

var resultado = buscar_animation_player_propio(hijo)

if resultado:

return resultado

return null


func _unhandled_input(event: InputEvent) -> void:

if not anim_player:

return


# -------------------------------------------------------------

# 1. CUANDO SE PRESIONA UNA TECLA O BOTÓN (ACCIONES)

# -------------------------------------------------------------

if event.is_pressed() and not event.is_echo():

# Clic Izquierdo -> ZARPAZO + Sonido del ratón

if event is InputEventMouseButton and event.button_index == MOUSE_BUTTON_LEFT:

reproducir(ANIM_ZARPAZO)

if has_node("AudioStreamPlayer3D2") and not $AudioStreamPlayer3D2.playing:

$AudioStreamPlayer3D2.play()

return

# Clic Derecho -> MANOTAZO

if event is InputEventMouseButton and event.button_index == MOUSE_BUTTON_RIGHT:

reproducir(ANIM_MANOTAZO)

return


# Teclado

if event is InputEventKey:

match event.keycode:

KEY_W:

reproducir(ANIM_ANDAR)

# Sonido al caminar con W (solo si no está sonando ya)

if has_node("AudioStreamPlayer3D2CAMINA2") and not $AudioStreamPlayer3D2CAMINA2.playing:

$AudioStreamPlayer3D2CAMINA2.play()

KEY_P:

reproducir(ANIM_ZARPAZO)

if has_node("AudioStreamPlayer3D") and not $AudioStreamPlayer3D2.playing:

$AudioStreamPlayer3D2.play()

KEY_I:

reproducir(ANIM_FURIA)

KEY_O:

reproducir(ANIM_RELAX)


# -------------------------------------------------------------

# 2. CUANDO SE SUELTA CUALQUIER TECLA O BOTÓN -> VOLVER A RELAX

# -------------------------------------------------------------

if not event.is_pressed():

# Si soltamos cualquier botón/tecla y no queda NINGUNA otra pulsada, pasa a RELAX

if not hay_entrada_activa():

reproducir(ANIM_RELAX)


# Comprueba si el usuario tiene mantenida alguna tecla o botón de acción

func hay_entrada_activa() -> bool:

return Input.is_mouse_button_pressed(MOUSE_BUTTON_LEFT) \

or Input.is_mouse_button_pressed(MOUSE_BUTTON_RIGHT) \

or Input.is_key_pressed(KEY_W) \

or Input.is_key_pressed(KEY_P) \

or Input.is_key_pressed(KEY_I) \

or Input.is_key_pressed(KEY_O)


# Activa el modo Loop lineal (bucle normal)

func asegurar_loop(nombre: String) -> void:

if anim_player.has_animation(nombre):

var anim = anim_player.get_animation(nombre)

anim.loop_mode = Animation.LOOP_LINEAR


# Activa el modo Ping-Pong (ida y vuelta continua)

func asegurar_pingpong(nombre: String) -> void:

if anim_player.has_animation(nombre):

var anim = anim_player.get_animation(nombre)

anim.loop_mode = Animation.LOOP_PINGPONG


# Devuelve la velocidad asignada a la animación indicada

func obtener_velocidad(nombre: String) -> float:

match nombre:

ANIM_RELAX: return vel_relax

ANIM_ANDAR: return vel_andar

ANIM_ZARPAZO: return vel_zarpazo

ANIM_MANOTAZO: return vel_manotazo

ANIM_FURIA: return vel_furia

_: return 1.0


func reproducir(nombre: String) -> void:

if anim_player.has_animation(nombre):

# Solo cambia si la animación solicitada no es la que ya está sonando

if anim_player.current_animation != nombre:

var vel: float = obtener_velocidad(nombre)

# Pasamos 'tiempo_transicion' como custom_blend (segundo parámetro)

anim_player.play(nombre, tiempo_transicion, vel)

print("Reproduciendo: ", nombre, " (Velocidad: ", vel, " | Transición: ", tiempo_transicion, "s)")

else:

print("La animación '", nombre, "' no existe en este AnimationPlayer.")