Falling death

I’m sure this has been thought about a lot but what is the best way to see when a player using FPS prefab has fallen a height that would kill them. Basically how do you detect velocity and collisions.

Thanks

You’d use Physics, it lets you get the velocity of a rigidbody as well as detect when it collides with something. So you’d check for an OnCollisionEnter event for example, when that happens you’d see if the collision was enough to do fatal damage. Have you used or experimented with physics in Unity at all yet? If not then give it a go! :slight_smile:

I actually did this without physics, which is necessary if you’re using the character controller. Basically, store the position the moment it becomes not grounded, and when it’s grounded, get that position. Then you can use Vector3.Distance to see what the distance between the two points is.

–Eric

Hi, I coded something myself:

var hitPoints = 100;
var deadReplacement : Transform;
var dieSound : AudioClip;
var DMGheight1 = 12.0;
var DMGheight2 = 18.0;
var DMGheight3 = 24.0;
var DMGheight4 = 32.0;
var apply : boolean = false;
var cameraMover1 : Transform;
var hitSound : AudioClip;
function ApplyDamage (damage : float) {
	// We already have less than 0 hitpoints, maybe we got killed already?
if (apply == true) {
	if (hitPoints <= 0.0)
		return;

	hitPoints -= damage;
	if (hitPoints <= 0.0)
	{
		Detonate();
		}
	}
}
function Detonate ()
{
	// Destroy ourselves
	Destroy(gameObject);
	
	// Play a dying audio clip
	if (dieSound)
		AudioSource.PlayClipAtPoint(dieSound, transform.position);

	// Replace ourselves with the dead body
	if (deadReplacement)
	{
		var dead : Transform = Instantiate(deadReplacement, transform.position, transform.rotation);
		
		// Copy position  rotation from the old hierarchy into the dead replacement
		CopyTransformsRecurse(transform, dead);
	}
}

static function CopyTransformsRecurse (src : Transform,  dst : Transform)
{
	dst.position = src.position;
	dst.rotation = src.rotation;
	
	for (var child : Transform in dst)
	{
		// Match the transform with the same name
		var curSrc = src.Find(child.name);
		if (curSrc)
			CopyTransformsRecurse(curSrc, child);
	}
}

function OnCollisionEnter (col : Collision) {
	if (col.relativeVelocity.magnitude > DMGheight1  col.relativeVelocity.magnitude < DMGheight2  col.relativeVelocity.magnitude < DMGheight3  col.relativeVelocity.magnitude < DMGheight4) {
		hitPoints -= (col.relativeVelocity.magnitude)/2;
		audio.PlayOneShot (hitSound, 0.3);
		}
	if (col.relativeVelocity.magnitude > DMGheight2) {
		hitPoints -= (col.relativeVelocity.magnitude);
		audio.PlayOneShot (hitSound, 0.3);
		}
	if (col.relativeVelocity.magnitude > DMGheight3) {
		hitPoints -= (col.relativeVelocity.magnitude) * 2.5;
		audio.PlayOneShot (hitSound, 0.3);
		}
	if (col.relativeVelocity.magnitude > DMGheight4) {
		hitPoints -= (col.relativeVelocity.magnitude) * 3;
		audio.PlayOneShot (hitSound, 0.3);
		}
	if (hitPoints <= 0.0) {
		Detonate ();
		}
	if (col.relativeVelocity.magnitude > DMGheight1) {
		cameraMover1.animation.Play ();
		}
	}

And to think I just had it do damage based on the time spent not grounded… The time counts up when not grounded, and any time over a certain amount causes damage based on a variable. It’s certainly a lot simpler. Heh!

This code looks great, I’ll try it out.

Thanks

@ Gargareth: I think that your idea is not the best, because if the player perhaps jumps into the water, he gets damaged. When he isn’t grounded, because he was swimming over the lake instead of walking over the ground, he dies, because he wasn’t grounded for about 10 seconds… :?

Not really. My grounded isn’t the one that’s built in, you know… It’s a very custom technique.

hi, i’m trying to gey my player killed when he falls from high places
So i’ve written this script and assigned to Terrain but it’s not working…

var dieSound : AudioClip;
var damHeight = 1;

function OnCollisionEnter(Collision : UnityEngine.Collision){
        if((Collision.gameObject.tag == "Player")(Collision.relativeVelocity.magnitude > damHeight)){
      Debug.Log ("died");
      audio.PlayOneShot (dieSound, 0.3);
		}
}

no errors no logs. Player is controlled via character controller.

changed it a bit but still the same result…

var dieSound : AudioClip;
var damHeight: float = 0.5;

function OnCollisionEnter(Collision : UnityEngine.Collision){
        if((Collision.gameObject.tag == "ground")(Collision.relativeVelocity.magnitude > damHeight)){
      Debug.Log ("died");
      audio.PlayOneShot (dieSound, 0.3);
		}
}

now script is applied to a player and terrain as tagged “ground”

Do you have a rigidbody component on the character (or the ground)? If you don’t the collision won’t be reported.