In this post we will discuss the implementation of an Interactive Narrative Game in Unity. The projects were created by a team of 3 as part of a class project for Introduction to Computer Graphics at Rutgers University. We used this Interactive Narrative to create a game in Unity called “Pacman: Come on and Slam Edition”
Background Story
The story takes place in a post-apocalyptic world, ravaged by the Chaos Dunk which wiped out most life on Earth and turned some people into zombies. Daniel and his four friends, Michael, Charles, Jordan, and Barkley, are former basketball players hiding in a safe house in the countryside. Each day they take turns running into the surrounding hedges to scavenge for food for survival.
Part 1
You can play the Unity Game by clicking on the link here.
Controls This part is just a narration, there are no controls for this part.
Part 2
You can play the Unity Game by clicking on the link here.
Controls
You can use the left mouse button
to control the player.
Part 3
You can play the Unity Game by clicking on the link here.
Controls
You can use the left mouse button
to control the player. Use the A
and D
keys to switch characters.
Vidoes
Here are the video recordings of each part. The audio has not been recorded.
Part 1
Part 2
Part 3
Narrative
To win the game, Daniel and his friends much collect all the food items in the arena before the zombies attack all of them. The game starts off with Daniel in control while his friends walk around randomly in the safe house (nonlinear and ambient characters). Daniel first walks up to the door and opens it by clapping. After exiting the safe house, Daniel walks around picking up food collectables as he goes (either autonomously or controlled by the user). The zombies in the surrounding area each randomly spawn in one of three possible places (nonlinear complexity), to ensure a slightly different game experience each time. If Daniel picks up a basketball, a song remixed with the Space Jam theme song begins playing and Daniel becomes super-powered. He runs faster and can attack and kill zombies by running into them. The power only lasts for about a minute and then the game returns to normal. The zombies chase down the player. If a zombie gets too close to Daniel, he will die and control goes to a randomly selected friend. The user has five chances (five friends) to collect all of the food and win the game. If the user loses all five friends to the zombies, the player loses.
Interaction
The user can control Daniel and his friends by left clicking with the mouse (if in part 2 or part 3). If in part 3, the user can switch between controlling a human and controlling a zombie by pressing ‘a’ or ‘d’ to cycle through the characters. This allows the user to play as zombies if they desire. The overhead shows how close each zombie or human is to one another in the hedge maze.
List of interactions and events:
- Current human opens the door to the safe house by clapping
- When a human gets close to a zombie, they perform a scared animation and move more slowly.
- When close to a basketball, the human pick it up through an animation.
- While holding a basketball, a Space Jam remix song plays in the background.
- If a zombie reaches a human, the human falls into the ground, dead.
- If a basketball holding human runs into a zombie, the zombie disappears and dies, respawning in its original location.
- The humans currently inside the safe house wander around randomly.
- When either all the food is collected or all the humans are dead, a message appears saying whether the humans or the zombies won.
Above shows the entire interactive behavior tree for Part 3. For parts 1 and 2, the behavior tree is essentially the same, but part 1 does not have the nodes pertaining to user clicks and the nodes for switching characters, and part 2 does not have the nodes pertaining to user key presses to switch characters.
Play Through
The User starts the game as a player. The player can walk and pickup food items (either by user clicks or autonomously).
When the player confronts the zombie, he will either become scared or be able to attack the zombie if the powerup is in play.
In part3, the zombie can be controlled by the user as well.
The user wins by collecting all the food items.
The zombie wins by defeating all the players.
Brief Implementation Description
Behavior Tree created with KADAPT: Link
The MainStory Story loop for the narrative.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
return new DecoratorLoop (
new SequenceParallel (
this.BuildMainTreeRoot (friends[0],0),
this.BuildMainTreeRoot (friends[1],1),
this.BuildMainTreeRoot (friends[2],2),
this.BuildMainTreeRoot (friends[3],3),
this.BuildMainTreeRoot (friends[4],4),
this.AssertNextToPowerUp(friends[4],4),
this.ZombieAssertAndGetHurt(zombie,1),
this.ZombieAssertAndGetHurt(zombie1,2),
this.AssertUserClickedA(),
this.AssertUserClickedD(),
this.BuildZombieTreeRoot(),
this.BuildZombie1TreeRoot(),
this.BuildDoorRoot(),
this.UserControlsPlayer()
));
The spawn point of the zombie is randomized at the start of the game. This adds nonlinearity to the game.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
spawnPos [0] = zombie1.transform.position;
spawnPos [1] = zombie1.transform.position + new Vector3 (40, 0, 0);
spawnPos [2] = zombie1.transform.position + new Vector3 (70, 0, 0);
int spawnPoint = 0;
spawnPoint = Random.Range(0, 3);
Zombie1InitialPosition = new Vector3(spawnPos[spawnPoint].x,spawnPos[spawnPoint].y,spawnPos[spawnPoint].z);
print (spawnPoint + "\n");
zombie1.GetComponent<SteeringController> ().Warp (Zombie1InitialPosition);
spawnPos [0] = zombie.transform.position;
spawnPos [1] = zombie.transform.position + new Vector3 (60, 0, -180);
spawnPos [2] = zombie.transform.position + new Vector3 (90, 0, 0);
spawnPoint = 0;
spawnPoint = Random.Range(0, 3);
ZombieInitialPosition = new Vector3(spawnPos[spawnPoint].x,spawnPos[spawnPoint].y,spawnPos[spawnPoint].z);
print (spawnPoint + "\n");
zombie.GetComponent<SteeringController> ().Warp (ZombieInitialPosition);
This loads the song when the PlaySong
int is set to 1. This script is added
to an empty object in Unity with the component AudioSource
having an
AudioClip
link to your song file.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
using UnityEngine;
using System.Collections;
[RequireComponent(typeof(AudioSource))]
public class Basketballsong : MonoBehaviour {
public int PlaySong;
private AudioSource audioS;
private AudioClip Song;
// Use this for initialization
void Start ()
{
audioS = GetComponent<AudioSource>();
Song = audioS.clip;
PlaySong = 0;
}
// Update is called once per frame
void Update ()
{
if (PlaySong == 1 && audioS.isPlaying != true)
{
audioS.PlayOneShot(Song, 0.7F);
}
if(PlaySong == 0 && audioS.isPlaying == true)
{
audioS.Stop();
}
}
}
Github Link: Here
Credit
This game took a great deal of work to make, and we would like to give special thanks to the movie Space Jam (1996) and the independent video game, Barkley, Shut Up and Jam Gaiden for inspiring our concept, storyline, and music.
We used these Space Jam mashups in our game:
Carry On Wayward Slam
U Can’t Slam This
Ghostslammers
Can’t Hold the Slam