How to make Among Us in Unity | Part 1 — Basic Gameplay and Art

Redefine Gamedev
6 min readOct 14, 2020

--

Among Us — the game that took the Internet by storm. Let’s find out the secrets of this game and see how you can make a game similar to Among Us in Unity Game Engine.

Get the Game Kit and start building an Among Us-like game in minutes!

An image depicting a game similar to Among Us game
Among Us in Unity

This tutorial is a companion to the How to Make Among Us in Unity series on my channel, Redefine Gamedev. If you prefer the video version, I highly recommend you check that one as well.

Episode list:

#1 — Basic Gameplay and Art (this one) [video]

#2 — Make it Multiplayer [video]

#3 — The Keypad Task [video]

#4 — The Card Swipe [video]

#5 — Player Kill functionality | Using Photon RPCs [video]

#6 — The Wire Task [video]

#7 — Multiplayer Lobby and Rooms [video]

#8 — Putting everything together [video]

#9 — Selecting the IMPOSTOR [video]

#10 — Multiplayer Chat [video]

#11 — Lights, Sounds and Animations [video]

#12 — Unlock Manifolds Task [video]

#13 — Start Reactor Task [video]

By the end of this tutorial you will have a working prototype of a game similar to Among Us.

Tools to Get You Started

Let’s get right into action with these free tools:

  • Game Engine: Unity 2020 is used for this purpose
  • Drawing Tool: Inkscape / Alternatively, you can use Gimp or Paint as well
  • Multiplayer: Photon Cloud (has a free tier for 20 users)

How to create Basic Art

You don’t need to be an artist to create art. What you need is the will to do so. I have a video about “programmer art” where you can see different ways to make nice art for your game.

I used Draw Bezier in Inkscape but any line tool would do the job.

A simple sketch that shows the current drawing progress
A simple sketch created by pointing the corners

How to create Basic Gameplay

For the gameplay, we will focus on the following:

  • Player Movement
  • Camera Follow
  • Environment Creation

Player Movement

2D movement is very easy to achieve in Unity. There are two main ways to go:

  • Directly move the object up/down/left/right
  • Move the rigidbody of the object in the desired direction

What is the main difference? The rigidbody is responsible of handling things like collision, which would be good to have for the walls. This is why we will go for the rigidbody.

In Unity an object that is simulated by physics needs two main components:

  • the Rigidbody — which allows the physics engine to understand how the object should work e.g. it’s mass
  • and the Collision Shape — which allows the physics engine to understand how the object looks

We will need both for our player:

Screenshot from unity depicting the Rigidbody 2D component
Unity physics components for the player
Screenshot showing the collision box for the player
Player’s 2d Box Collider

After we set up everything about the object’s physics, we can proceed into transforming the object into a prefab.

A prefab acts like a blueprint e.g. you can spawn as many objects of a prefab as you want in the scene. The main benefit being that if you apply a change to one, all will change as well.

To create a prefab, drag & drop an object from the hierarchy to the project view.

Unity screenshot showing how a prefab is created by drag & drop
Prefab creation in Unity

For the actual movement, we will need to head over into scripting. Let’s create a new script called Move.cs:

public class Move: MonoBehaviour {

public float speed = 15;
private Vector2 velocity;
private Rigidbody2D rb;
private void Awake() {
rb = GetComponent<Rigidbody2D>();
velocity = Vector2.zero;
}
private void Update() {
velocity.x = Input.GetAxisRaw("Horizontal");
velocity.y = Input.GetAxisRaw("Vertical");
}
private void FixedUpdate() {
rb.MovePosition(rb.position +
(velocity.normalized * speed *
Time.fixedDeltaTime));
}
}

speed — the speed which the Player will move

velocity — a structure that contains 2 values X and Y and will store the direction of the movement

rb — the Rigidbody component used to manipulate the object’s physics

As for the actions in the script, we have 3 functions that are called.

private void Awake() - Called only once, when the object is created

In awake() usually we will have all the initializations. In this case, it’s the rigidbody and the velocity.

private void Update() - Called every frame

Update() is called every frame. We can use this step to gather player inputs.

private void FixedUpdate() - Physics frame update

FixedUpdate() is used to update physics objects. Here we will take the velocity which was previously initialized in Update() and apply it to the rigidbody.

rb.MovePosition(rb.position + 
(velocity.normalized * speed * Time.fixedDeltaTime));

rb.position represents the current position. This is added to a product by velocity, speed and delta time. The delta time is used to make the movement frame independent.

Note: don’t forget to add the script to the player. This is done by drag & drop the script component from the project to the player in the scene (or the inspector).

Camera Follow

The camera is the object which makes the scene rendering possible. Beside the script, we need to make some changes to the camera object to adapt it to a 2d game.

Camera Adjustments — by default, Unity’s camera is set up for perspective view. Since we are developing a 2d game, it might be a good idea to change the camera rendering to orthographic.

Setting the unity camera’s perspective
Camera settings for a 2d Game

CameraFollow.cs

public class CameraFollow : MonoBehaviour {     public Transform target;     public float smoothTime = 0.3f;     private Vector3 velocity = Vector3.zero;
private void FixedUpdate() {
if (target == null) { return; }
Vector3 targetPosition =
target.position + new Vector3(0, 0, -1);
transform.position = Vector3.SmoothDamp(
transform.position,
targetPosition,
ref velocity,
smoothTime);
}
}

target — represents the current target of the Camera. To assign this, head to the inspector by selecting the camera in the scene and by using drag & drop assign the player

Drag & drop the player onto the camera to make it work
Assign the player to the camera, making it the current target

smoothTime — represents the smooth factor of the camera movement

velocity — is used by the Vector3.SmoothDamp function

Moving on to Update() method which runs every frame, we first need to check if the camera has a target assigned. If not, the camera cannot reposition correctly.

if (target == null) { return; }

Next, the camera’s new position needs to be computed. The value will be stored in a local variable called targetPosition.

Vector3 targetPosition = 
target.position + new Vector3(0, 0, -1);

Notice that the final position is not the same as the target.position. We need this + new Vector3(0, 0, -1) to create a small displacement for the camera. This needs to be even if the camera is orthographic.

The final step is to apply the position. For this, instead of just assigning the value transform.position = transform.position, we make use of Vector3.SmoothDamp function available in Unity. This will assure a smooth transition between two different points.

transform.position = Vector3.SmoothDamp(
transform.position,
targetPosition,
ref velocity,
smoothTime);

Environment Creation

The environment is the most simple part. It’s mostly done by copy/pasting walls and floors in the scene.

Hint: make the Wall and the Floor Prefabs (they are marked with blue in the scene if they are prefabs). This way by modifying a single one will propagate to the others, simplifying the work.

Don’t forget to add a BoxCollider2D to the wall and a Rigidbody2D. Because the wall is static, we need to set the body type to Kinematic.

Collision box and rigibody for the wall
Wall Collision Settings
Image depicting an environment for the game
Environment creation in Unity

Want More?

You are covered! Head over to Youtube at Redefine Gamedev channel and check the video tutorial.

How to Make Among Us in Unity, Part 1

--

--