So far, life has been a little bit too easy on the hero. The marine is impervious to death! Let’s put our Doctor Evil hats on and talk about how we’ll kill our hero (mwuahaha). Death in Bobblehead Wars will work in this fashion:
- Once the marine gets hurt, the camera will shake and you’ll hear grunting to indicate the marine’s agony.
- The more hits, the harder the shake.
- Finally, when the marine suffers that final blow, he’ll emit a blood-curdling cry to signal his inglorious death and his head will pop off. I mean, why wouldn’t it?
You’ll start with the camera shake effect; this script is pre-included with the project for convenience.
Note: This tutorial is part of a collection that teaches Unity development from the ground up. You can read the entire series over here. This series is free and does not require any account creation. All assets are provided. If you find it useful, feel free to buy me a coffee.
Hurting the marine
In the Project window, select the CameraShake script and drag it to Main Camera in the Hierarchy. This script works by providing a shake intensity, then it calls Shake()
. Select Main Camera in the Hierarchy and, in the Inspector, change Shake Decay to 0.02
to set the shake’s duration.

Next up is providing intensity values. Open PlayerController in your code editor and add the following instance variable:
[SerializeField]
private float[] hitForce;
This provides an array of force values for the camera. Save and switch to Unity. Select SpaceMarine in the Hierarchy and find the Player Controller component in the Inspector. Click the disclosure triangle next to Hit Force and set the Size to 3
. Add the following values for the elements: 0.1
, 0.2
, 0.3
:

At this point, you could call CameraShake()
each time an alien collides with the hero, but it’ll be a little problematic. When the hero is swarmed by aliens, he could die in a matter of seconds, and the game would cease to be fun.
Adding some “buffer”
To avoid this frustration, you’ll add a delay between each hit to give the player time to react and escape a bad situation.
Open PlayerController in your code editor and add the following instance variables
[SerializeField]
private float timeBetweenHits = 2.5f;
private bool isHit = false;
private float timeSinceHit = 0;
private int hitNumber = -1;
timeBetweenHits
is the grace period after the hero sustains damage.isHit
is a flag that indicates the hero took a hit.
The above variables mean the hero won’t accrue damage for a period of time after taking a hit.
timeSinceHit
tracks of the amount of time in the grace period.hitNumber
references the number of times the hero took a hit. It’s also used to get the shake intensity for the camera shake.
Add the following method:
void OnTriggerEnter(Collider other)
{
Alien alien = other.gameObject.GetComponent<Alien>();
if (alien != null)
{ // 1
if (!isHit)
{
hitNumber += 1; // 2
CameraShake cameraShake = Camera.main.GetComponent<CameraShake>();
if (hitNumber < hitForce.Length) // 3
{
cameraShake.intensity = hitForce[hitNumber];
cameraShake.Shake();
}
else
{
// death todo
}
isHit = true; // 4
SoundManager.Instance.PlayOneShot(SoundManager.Instance.hurt);
}
alien.Die();
}
}
Here’s the breakdown:
- First, you check if the colliding object has an
Alien
script attached to it. If it’s an alien and the player hasn’t been hit, then the player is officially considered hit. - The
hitNumber
increases by one, after which you get a reference toCameraShake()
. - If the current
hitNumber
is less than the number of force values for the camera shake, then the hero is still alive. From there, you set force for the shaking effect and then shake the camera. (You’ll come back to thedeath todo
in a moment.) - This sets
isHit
to true, plays the grunt sound and kills the alien.
You’re getting closer to making the hero’s day, but not quite there yet. Once isHit
is set to true, there’s no unsetting it and the hero becomes invincible — the opposite of what you want to do here.
Add the following code to Update()
to strip away those divine powers:
if (isHit)
{
timeSinceHit += Time.deltaTime;
if (timeSinceHit > timeBetweenHits)
{
isHit = false;
timeSinceHit = 0;
}
}
This tabulates time since the last hit to the hero. If that time exceeds timeBetweenHits
, the player can take more hits.
Play your game and charge those aliens. Resistance is futile.

The hero will now react to each hit until the maximum number of hits. At that point, nothing will happen — but you’ll fix that next, in a dramatic way!
Removing the head in code
There’s nothing more terrifying to a bobblehead than losing its precious head. Your space marine is no different. It’s only fitting that the head rolls off the body to make the game’s end spectacular and undeniable.
Time for a little more scripting. Open PlayerController in your editor and add the following instance variables:
[SerializeField]
private Rigidbody marineBody;
private bool isDead = false;
marineBody
is, well, the marine’s body. You’re adding this because you’ll make some physics alterations when the hero dies. And, of course, isDead
keeps track of the player’s current death state. Together, they let the script know if the space marine is dead.
Now you need a method that manages the death, so add the following:
public void Die()
{
bodyAnimator.SetBool("IsMoving", false);
marineBody.transform.parent = null;
marineBody.isKinematic = false;
marineBody.useGravity = true;
marineBody.gameObject.GetComponent<CapsuleCollider>().enabled = true;
marineBody.gameObject.GetComponent<Gun>().enabled = false;
}
You set IsMoving
to false
since the marine is dead and you don’t want a zombie running around. Next, you set the parent to null
to remove the current GameObject from its parent. Then, by enabling Use Gravity
and disabling IsKinematic
, the body will drop and roll, and you enable a collider to make this all work. Disabling the gun prevents the player from firing after death.
At this point, the head and body still share a joint. You need to destroy the hinge joint to enable the hero’s inevitable disembodiment. Add the following code beneath the previous block:
Destroy(head.gameObject.GetComponent<HingeJoint>());
head.transform.parent = null;
head.useGravity = true;
SoundManager.Instance.PlayOneShot(SoundManager.Instance.marineDeath);
Destroy(gameObject);
First, this destroys the joint to release the head from the body. Then, like the body, you remove the parent and enable gravity. Now that head can roll! Finally, you destroy the current GameObject while playing the death sound.
Now to trigger the death. In OnTriggerEnter()
in the else block of the condition hitNumber < hitForce.Length
, replace the comment with the following:
Die();
Save the file and go back to Unity.
Adjusting the head in Unity
Select SpaceMarine in the Hierarchy. In the Inspector, drag the BobbleMarine-Body to the new Marine Body property.

The space marine’s body can fall now, but you need to attach a collider to it. Select BobbleMarine-Body and click the Add Component button. Select the Physics category and choose Capsule Collider.
Set Center to (-1.61, 3.58, 0), Radius to 2.08 and Height to 0.24. Make sure the Direction is set to Y-axis. Finally, disable the collider by unchecking the checkbox in the upper left of the component.

Currently, the GameManager may spawn more aliens after the space marine dies. There’s no need to subject the hero to an inevitable feeding frenzy!
Open GameManager in your code editor, and add the following before any of the existing code in Update()
:
if (player == null)
{
return;
}
If there’s no player, the GameManager won’t spawn enemies. Save and switch to Unity. Play your game and charge the aliens. After a bit of time, the marine successfully loses that head. Why is the marine’s body still standing around?

Adjusting gravity
This strange behavior is due to gravity and scaling. The typical gravity level is set to -9.81. If you scaled the models to one meter per unit, then they’d play well with gravity. However, your models are somewhat larger. You can fix this by scaling down the models or scaling up the gravity — you’ll scale up the gravity in this book.
Click Edit ▸ Project Settings ▸ Physics and set Gravity to (0, -150, 0).
Now the player’s death makes both the head and body fall like you’d see in a good episode of Game of Thrones.
Setting up the alien head
If the space marine gets his head knocked off, it seems only fair for the alien to suffer the same fate. In the Project window, open the Prefabs folder and double-click the Alien prefab. This will open your Prefab editor.
From the models folder, drag a BobbleEnemy-Head. You’ll discover the material is not configured correctly.

You already have a material configured for the alien. Open the materials folder, and drag the Main Texture.001 onto the alien head.

Set the head to the following transform, rotation, and scale:
- Position: (0, 2.442, 0.470)
- Rotation: (-90, 0, 0)
- Scale: (64.123, 64.123, 64.123)
The second head should match the dimensions of the first head. It doesn’t need to perfect. Feel free to eyeball it in the case it doesn’t match.

Click the Add Component button and select Rigidbody from the physics category. Uncheck the Use Gravity option and check the Is Kinematic option.
Click Add Component once again, and select Sphere Collider from the physics category. Set Center to (0, 0, 0.02) and Radius to 0.03. Disable the component by unchecking the component checkbox.
Finally, assign it to the layer Alien Head and select Yes, change children when prompted. Finally, click Edit ▸ Project Settings ▸ Physics. Disable the Alien Head on the Player column.

Writing the decapitation code
Open the Alien script and add the following instance variables:
[SerializeField]
private Rigidbody head;
[SerializeField]
private bool isAlive = true;
head
will help you launch the head, and isAlive
will track the alien’s state.
Save and switch back to Unity. Drag the BobbleEnemy-Head to the Head property on the Alien script. Switch back to code. Replace Die()
with the following:
public void Die()
{
isAlive = false;
head.GetComponent<Animator>().enabled = false;
head.isKinematic = false;
head.useGravity = true;
head.GetComponent<SphereCollider>().enabled = true;
head.gameObject.SetActive(true);
head.gameObject.transform.parent = null;
head.linearVelocity = new Vector3(0, 26.0f, 3.0f);
}
This code works similarly to the marine’s death, but you disable the Animator for the alien. In addition, this code launches the head off the body. Add this code before the closing brace:
OnDestroy.Invoke();
OnDestroy.RemoveAllListeners();
SoundManager.Instance.PlayOneShot(SoundManager.Instance.alienDeath);
Destroy(gameObject);
You want to make sure that you don’t call Die()
more than once, so modify OnTriggerEnter()
as follows:
void OnTriggerEnter(Collider other)
{
if (isAlive)
{
Die();
SoundManager.Instance.PlayOneShot(SoundManager.Instance.alienDeath);
}
}
Here you check isAlive
first. Finally, in Update()
, surround the existing navigation code with a similar check to see if the alien is alive.
if (isAlive)
{
agent.destination = target.position;
}
Save and switch to Unity. Play the game. You’ll quickly discover lots of heads.

Head clean-up on aisle 2
It won’t take long to accumulate an excess of disembodied alien heads. After a while, the space marine will struggle to differentiate the dead aliens from the living. Stop your game. Open the Alien Prefab and select the BobbleEnemy-Head. In the Inspector, click the Add Component button and select New Script.
Name it SelfDestruct and click the Create and Add button. Open it in your editor. Inside the class, replace the contents of the class with the following:
[SerializeField]
private float destructTime = 3.0f;
public void Initiate()
{
Invoke("selfDestruct", destructTime);
}
private void selfDestruct()
{
Destroy(gameObject);
}
This deletes the attached GameObject after a given amount of time. You could have named it AlienHead
, but its general name makes it available throughout the game.
Open Alien and add the following to Die()
before the Destroy(gameObject);
line:
head.GetComponent<SelfDestruct>().Initiate();
Now play the game and watch those heads disappear after three seconds. Apologies to all the head hunters out there.
Where to go from here
That was a lot of decapitation! Hopefully, underneath all the rolling heads is a fun game to play. Removing the heads after a period of time is a minor optimization and it declutters the arena. This is something you don’t need to implement it in your own game.
There’s still more to be done. For instance, it would be nice to see lots of blood spray out of the decapitated head. I never said this was a PG game. You’ll employ some particle systems for this and you’ll do this in the next tutorial.
Discover more from Jezner Books
Subscribe to get the latest posts sent to your email.