Hello, I took a few minutes to implement AddExplosionForce rather than using the random deaths of the Ragdolls.
First I created a new class (above the GrenadeProjectile class) to hold the explosion info from the grenade:
public class ExplosionDetails
{
public float BlastForce { get; set; }
public Vector3 Origin { get; set; }
public float Radius { get; set; }
public float UpwardModifier { get; set; }
}
Then I added it in to the damage:
var explosionDetails = new ExplosionDetails
{
BlastForce = explosionForce,
Origin = _targetPosition,
Radius = explosionRadius,
UpwardModifier = explosionUpwardsModifier
};
targetUnit.Damage(damage, explosionDetails);
Then I passed it through the unit Damage method:
public void Damage(int damageAmount, ExplosionDetails explosionDetails)
{
_healthSystem.Damage(damageAmount, explosionDetails);
}
Then in the HealthSystem I added ExplosionDetails to the OnDeath event and passed it through Damage and into Die:
public event EventHandler<ExplosionDetails> OnDeath;
public void Damage(int damageAmount, ExplosionDetails explosionDetails)
{
health -= damageAmount;
if (health < 0)
{
health = 0;
}
OnDamaged?.Invoke(this, EventArgs.Empty);
if (health == 0)
{
Die(explosionDetails);
}
}
private void Die(ExplosionDetails explosionDetails)
{
OnDeath?.Invoke(this, explosionDetails);
}
Then I changed the RagdollSpawner to apply the Explosion Force:
private void HealthSystem_OnDeath(object sender, ExplosionDetails e)
{
var ragdoll = Instantiate(ragdollPrefab, transform.position, transform.rotation);
if (e != null)
{
Rigidbody[] rigidbodies = ragdoll.GetComponentsInChildren<Rigidbody>();
foreach (Rigidbody rigidbody in rigidbodies)
{
rigidbody.AddExplosionForce(e.BlastForce, e.Origin, e.Radius, e.UpwardModifier);
}
}
}
And then finally in the ShootAction when the Damage method is called, I passed null for the ExplosionDetails:
private void Shoot()
{
var args = new OnShootEventArgs
{
targetUnit = _targetUnit,
shootingUnit = _unit
};
OnShoot?.Invoke(this, args);
OnAnyShoot?.Invoke(this, args);
_targetUnit.Damage(40, null);
}
I also serlialized all of the fields for the ExplosionDetails (other than origin, of course since that comes from the blast location) in the GrenadeProjectile class so one could easily change the values. My favorite ended up being:
BlastForce = 400,
Radius = 50,
UpwardModifier = 5
I don’t entirely understand why the radius had to be so dramatically different from the radius for damage, but oh well, it looks great and I guess that’s all that matters!
I hope this was helpful to someone and thanks for the course, Code Monkey!!!