Crear un efecto de sangre creíble en Unity 2D es simple si anclas la emisión de partículas en el hit point de la espada. Aquí verás cómo ajustar el sistema de partículas, preparar un prefab limpio y dispararlo desde C# al colisionar con el enemigo. Resultado: una explosión tipo one shot alineada a la punta del arma y fácil de personalizar.
¿Cómo preparar el hit point y el sistema de partículas en Unity?
Antes de nada, reestructura el jugador: renombra el área de ataque a swing zone y crea un objeto vacío hijo en la punta de la espada llamado hit point. Colócalo justo donde quieres ver las gotas de sangre. No importa si está rotado: visualmente el efecto seguirá funcionando.
Crea un sistema de partículas: menú Effects > Particle System. Para configurarlo con claridad, muévelo temporalmente fuera del personaje. Si el equipo se ralentiza, puedes pausar el particle system, aunque conviene verlo en vivo para ajustar bien.
Ajusta la sorting layer en el panel Renderer: ponla igual que la del player para evitar que se dibuje detrás del escenario.
Reduce el tamaño inicial: start size ≈ 0.25. Partículas más sutiles.
Reduce el tiempo de vida: start lifetime ≈ 2 s. Menos estela y mejor control.
Cambia el color: rojo para simular sangre.
Cambia la forma: shape a esfera y radio ≈ 0.25. Emisión en todas direcciones.
Emisión: en Emission ajusta el rate por segundo y usa Bursts para picos de partículas por golpe.
Evolución del tamaño: activa size over lifetime y usa una curva que empiece grande y se reduzca hasta cero.
Reproducción: desactiva looping para que sea one shot y fija duración cercana a 2 s.
Nombra el sistema: “blood burst”.
¿Cómo crear el prefab y asegurar un instanciado exacto?
Convierte el sistema en prefab: arrástralo de la jerarquía al proyecto y elimina la instancia de escena para que no se reproduzca al iniciar.
Buenas prácticas del prefab para instanciar con precisión:
Transforms limpios: posición 0,0,0; rotación 0; escala 1.
Capa correcta: misma sorting layer que el player.
Nombre claro: “blood burst” para localizarlo rápido en el inspector.
Con esto, el efecto se instanciará exactamente en la posición y rotación del hit point cuando lo invoques desde código.
¿Cómo instanciar la animación de sangre en el hit point con C#?
La lógica vive en el script de ataque, ahora ubicado en la swing zone. Añade referencias al prefab y al hit point, y dispara la instancia en el momento de colisión.
Variables públicas: referencia al prefab de sangre y al hit point.
Colisión: en OnTriggerEnter2D, además de dañar al enemigo, instancia el efecto en la posición y rotación del hit point.
Asignación en inspector: arrastra el prefab “blood burst” a la variable de animación y el objeto hijo de la espada a hit point.
Ejemplo de código en C#:
typedef usingUnityEngine;publicclassWeaponDamage:MonoBehaviour{publicGameObject hurtAnimation;// blood burst prefabpublicGameObject hitPoint;// child at sword tipprivatevoidOnTriggerEnter2D(Collider2D other){// Aquí iría la validación de enemigo si aplica.Instantiate(hurtAnimation, hitPoint.transform.position, hitPoint.transform.rotation);}}
Consejos de ajuste fino:
Si la velocidad o dispersión no convence: baja el radio del shape o reduce el start lifetime.
Si se ven demasiado grandes: baja start size o la curva de size over lifetime.
Si se ve detrás del mapa: revisa la sorting layer en Renderer.
Si se repite sin parar: confirma que looping está desactivado.
¿Ya lo pusiste en marcha? Comparte qué combinación de Emission y Bursts te dio el mejor “golpe” visual en tu juego y comenta tus ajustes favoritos.
Cambiar el nombre luego de hacer animaciones, puede provocar que se pierdan las referencias de las mismas. Me paso :(
Qué interesante el tema de las partículas. Le añadi tanto al enemigo como al jugador:
Al cambiarle el nombre al HitPoint inicial, la animacion queda con un objeto "missing" como corregimos esto?
NO SE SI SE HAN DADO CUENTA QUE EL OBJETO CREADO DE PARTÍCULAS NUNCA SE QUITA
cree un pequeño script para que se elimine solo se lo tienen que agregar al prefab blood burst para que lo elimine y le ponen el tiempo
using System.Collections;using System.Collections.Generic;using UnityEngine;publicclassdestruir_sangre:MonoBehaviour{public int tiempo_para_destruir;private float contador_tiempo;// Start is called before the first frame updatevoidStart(){ contador_tiempo = tiempo_para_destruir;//iguala el tiempo para destruir con el contador}// Update is called once per framevoidUpdate(){ contador_tiempo -=Time.deltaTime;//descuenta el tiempo del ultimo renderisado if(contador_tiempo <0)//si se acaba el tiempo se destruye el objeto{Destroy(gameObject);}}}
esta podría ser otra solución
.
Y esta otra (Stop Action)
Les comparto mi script, que instanciara las particulas y las agregara a una lista, las cuales posterior a su animación, estas se iran eliminando para evitar una sobrecarga de memoria
using System.Collections;using System.Collections.Generic;using UnityEngine;publicclassWeapons:MonoBehaviour{[SerializeField]private int weaponDamage;[SerializeField]private int weaponResistance;publicGameObject hurtAnim;publicGameObject hitPoint;List<GameObject> particlesGarbage =newList<GameObject>();private bool particlesActive;private float timeToDie=2;private float currentTimeToDie;privatevoidUpdate(){if(particlesGarbage.Count>0){if(currentTimeToDie <0){foreach(GameObject particle in particlesGarbage){Destroy(particle); currentTimeToDie = timeToDie;}} currentTimeToDie -=Time.deltaTime;}}privatevoidOnTriggerEnter2D(Collider2D collision){if(collision.CompareTag("Enemy")){ collision.gameObject.GetComponent<HealthManager>().DamageCharacter(weaponDamage);GameObject particlesAnim=Instantiate(hurtAnim, hitPoint.transform.position, hitPoint.transform.rotation); particlesGarbage.Add(particlesAnim); currentTimeToDie = timeToDie;}}}
esta podría ser otra solución sin la necesidad de utilizar el update.
Si le colocamos un tiempo de vida y quitamos el loop no se elimina por si misma?(desaparece del inspector)
Para que se necesita el HitPoint de la espada si la sangre se puede instanciar en la posición del enemigo?
Considero que la sangre debería instanciarse en el Enemy y no en la espada. Pero más alla de eso, hay que destruir el effecto para que no quede ahí vivo. Es simplemente asignar el effecto al gameObject y dsp destruirlo pasado un cierto tiempo. Dejo el codigo
publicclassWeaponDamage:MonoBehaviour{[Header("Configuration")]public int damage;publicGameObject bloodFX;publicGameObject hitPoint;privatevoidOnTriggerEnter2D(Collider2D collision){if(collision.CompareTag("Enemy")){ collision.gameObject.GetComponent<HealthManager>().DamageCharacter(damage);//Do damage to Enemy using his HealthManager Component.GameObject bloodEffect =Instantiate(bloodFX, hitPoint.transform.position, hitPoint.transform.rotation)asGameObject;Destroy(bloodEffect, 2f);//Destroy BloodEffect in 2secs}}}
increibles esos 12 + 1 segundos de pantalla en negro al inicio 🧐
Genial
Después de la Instantiate, solo agregenle destruir. A mi prefab le puse particulas.