https://perico415.itch.io/
Desarrollo creacion videojuegos.Godot, Unity, Blender,Gimp,Game Maker,
Godot, scripts para Godot estudios y aprendizajes, Creacion de videojuegos. Creacion y publicacion de videojuegos en internet. Como hacer videojuegos. C# unity. Animaciones unity blender. Personajes videojuegos graficos dibujos. Diseño grafico. Comic. Animaciones gif. Dibujo de retratos. Realidad virtual. Cine y realidad virtual.
lunes, 19 de octubre de 2026
Captura de pantalla, de mi proximo prollecto de terror humor y gore que publicare antes de navidad en itchio; 19-10-26;
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;
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:
Silenciar NLA: Desmarcar la casilla
✓de las pistas antiguas para que no interfieran en pantalla. Crear Acción: Ir al Editor de Acciones, pulsar
Nuevo, renombrar, marcar el Escudo y animar. 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.htmldomingo, 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.

