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.")


martes, 6 de octubre de 2026

GDScript para manejar personaje en Godot 4.7 3d; permite calibrar velocidad de cada animacion diferente 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"


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

# VELOCIDADES CALIBRABLES DESDE EL INSPECTOR

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

@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, 5.0, 0.05) var vel_zarpazo: float = 1.0

@export_range(0.1, 5.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 en bucle normal y ANDAR en Ping-Pong

asegurar_loop(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

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

reproducir(ANIM_ZARPAZO)

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)

KEY_P:

reproducir(ANIM_ZARPAZO)

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)

anim_player.play(nombre, -1, vel)

print("Reproduciendo: ", nombre, " (Velocidad: ", vel, ")")

else:

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


domingo, 4 de octubre de 2026

GDScript perfecto para animar personaje; para Godot 4.7 en 3d;

 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"


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 para que se reproduzcan en bucle

asegurar_loop(ANIM_RELAX)

asegurar_loop(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

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

reproducir(ANIM_ZARPAZO)

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)

KEY_P:

reproducir(ANIM_ZARPAZO)

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 en Godot para las animaciones continuas

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


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:

anim_player.play(nombre)

print("Reproduciendo: ", nombre)

else:

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

Animar con blender y no mezclar las animaciones sin querer;

 

Aunque llevo años practicando con blender aun me cuesta mucho hacer animaciones con este programa gratuito, se me mezclaban las animaciones, para que no se mezclen hay que desactivar la casilla donde dice Nla Track, Si se deja marcada al hacer nuevas animaciones se mezclan unas con otras, me gustaria explicarlo mejor pero el tema es practicar, y yo todavia estoy aprendiendo.....por supuesto me ayudo de la IA ahora ya para cualquier proceso.

Tienes toda la razón: en Blender y en animación 3D, la única forma real de retener los pasos y automatizarlos es mediante la práctica constante y la repetición. Con la cantidad de paneles, capas y modos que tiene la interfaz, es completamente normal que al principio haya que consultar el orden exacto de los clics.

Como resumen rápido para cuando vuelvas a ponerte a animar, esta es la rutina de 3 pasos que debes memorizar:

  1. Silenciar NLA: Desmarcar la casilla ✓ de las pistas antiguas para que no interfieran en pantalla.

  2. Crear Acción: Ir al Editor de Acciones, pulsar Nuevo, renombrar, marcar el Escudo y animar.

  3. Guardar en NLA: Pulsar Empujar debajo (Push Down) para convertirla en pista.

A base de repetir este flujo en dos o tres personajes, el proceso se vuelve totalmente mecánico.

https://videojuegosenlineaasaco4.blogspot.com/2026/10/gdscript-perfecto-para-animar-personaje.html



domingo, 27 de septiembre de 2026

GDScript animacion de un nodo3d de un personaje en godot 4.7;

 extends Node3D


var anim_player: AnimationPlayer


func _ready() -> void:

# Busca el AnimationPlayer ÚNICAMENTE dentro de este nodo y sus hijos (self)

anim_player = buscar_animation_player_propio(self)

if anim_player:

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

else:

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


# Función que busca solo dentro de la rama local del 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 or not event is InputEventKey or not event.pressed or event.echo:

return


match event.keycode:

KEY_I:

reproducir("MakeHuman default skeleton|FURIA")

KEY_O:

reproducir("MakeHuman default skeleton|SACAZARPA")

KEY_P:

reproducir("MakeHuman default skeleton|ZARPAZO")


func reproducir(nombre: String) -> void:

if anim_player.has_animation(nombre):

anim_player.stop()

anim_player.play(nombre)

print("Reproduciendo en escena principal: ", nombre)

else:

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



-----------------------------------------------------------------------------------------------------

un detalle del gds:  Ese truco de limitar la búsqueda al propio nodo (self) es oro puro en Godot cuando empiezas a meter escenas unas dentro de otras, porque te evita todos esos líos de rutas globales.

Ya tienes al personaje listo y respondiendo como un reloj a los zarpazos. ¡A seguir dándole caña al juego! Si más adelante te surge cualquier otra historia con el código o los escenarios, aquí estamos.

THE WOLF MAN OF THE UNDERGROUND; Antiguo exito que relanzo; peticion de seguidores mios;

 


martes, 22 de septiembre de 2026

GDScript para hacer una alternancia de transparencia a un MeshInstance3D desde el inspector;

 @tool

extends MeshInstance3D


## Marca si el efecto de transparencia en bucle debe ejecutarse.

@export var activo: bool = true


## Velocidad de la transición (a mayor valor, más rápido cambia).

@export_range(0.1, 10.0, 0.1) var velocidad: float = 2.0


## Transparencia MÍNIMA (0.0 es totalmente invisible, 1.0 es completamente opaco).

@export_range(0.0, 1.0, 0.01) var opacidad_minima: float = 0.1


## Transparencia MÁXIMA (0.0 es totalmente invisible, 1.0 es completamente opaco).

@export_range(0.0, 1.0, 0.01) var opacidad_maxima: float = 1.0


var _tiempo_acumulado: float = 0.0

var _material_instanciado: StandardMaterial3D


func _ready() -> void:

_preparar_material()


func _process(delta: float) -> void:

if not activo:

return

# Si no tenemos material configurado, intentamos asignarlo

if not _material_instanciado:

_preparar_material()

if not _material_instanciado:

return


_tiempo_acumulado += delta * velocidad

# Mapeamos el seno (de -1 a 1) al rango normalizado de 0 a 1

var factor_onda: float = (sin(_tiempo_acumulado) + 1.0) / 2.0

# Interpolamos entre la opacidad mínima y máxima

var alpha_actual: float = lerp(opacidad_minima, opacidad_maxima, factor_onda)

# Aplicamos el alfa al color del material

_material_instanciado.albedo_color.a = alpha_actual


func _preparar_material() -> void:

# Obtenemos el material asignado en la primera superficie del Mesh

var mat_base = get_active_material(0)

if mat_base is StandardMaterial3D:

# Duplicamos el material para no afectar a otros objetos que compartan el mismo mesh

_material_instanciado = mat_base.duplicate() as StandardMaterial3D

# IMPORTANTE: Activamos la transparencia en el material si no lo estaba

_material_instanciado.transparency = BaseMaterial3D.TRANSPARENCY_ALPHA

# Asignamos la copia del material de nuevo al nodo

set_surface_override_material(0, _material_instanciado)


--------------------------------------------------------------------------------------------------------------------

--------------------------------------------------------------------------------------------------------------------

Explicacion : con este gds intento hacer como un efecto magico de un espejo, intento jugar con un personaje y un reflejo.....en mi nuevo juego a publicar de aqui unas semas.aqui debajo pequeño video de lo trabajado....