As a software engineer, I've always been fascinated by the intricate world of game development. Despite my experience in coding, stepping into this realm felt like opening a door to an entirely new universe. This blog aims to share my journey as a beginner in Unity game development, along with some initial tips and tricks I've picked up along the way.
Why would I make a video game when I can just play them?
I have been playing video games as long as I can remember. I have always used them as a release from stress and anxiety, but its also how I met some of my best friends. Countless nights of staying up late on a variety of games, weekends of competing in fps (first person shooter) tournaments, and even hosting LAN parties at my house.
Often, I hoped for a way to combine some features from different games. I began to think, "What if I could merge these fun mechanics into a single game?" The idea grew even more exciting when I imagined my friends' voices as the characters' voice lines.
Then it dawned on me…..
Why not create a game that combines the best elements of my favorite games, featuring the unique touch of my friends' voices? That's when this journey began.
Let's Start Simple.
Learning The Basics: First thing I did was look up some tutorials for Unity on Youtube. I quickly found one called "The Unity Tutorial for Complete Beginners". This video helped me create a new project, understand the Unity ui, and create a simple flappy bird style game.
Starting Small: I knew I was brand new to this and needed something that wouldn't require extensive knowledge of advanced features in Unity and something that would get my feet wet in game development. Therefore, I decided to start with a 2D Zombie Survival Game. This would also allow me to practice leveraging what I learned in the tutorial video and also add some custom flair to the project.
Leveraging Online Resources: Now that I had my project idea and some new base principles to try out, I went back to Youtube to find some examples of similar style games to what I was looking to build. That's where I found "Make a 2D Top Down RPG in Unity". This video series is quite long (~100 videos), but I was able to jump around a bit and utilize some core teachings they offered.
Practice, Practice, Practice: Watching someone else implement a new sprite with new animations and collision does not grant you the ability to do it yourself. It also won't help you retain that knowledge. Practice is key when implementing and improving anything in your game. This is something that I have carried over from being a software engineer for the past 10 years.
Join or Create a Community: A community is crucial for feedback and improvements to your game. It also can provide the help you need for new ideas, bug fixes, and even with new assets to add to your game! I was fortunate enough to have a group of Discord friends that were willing to help with this. We opened a channel and ideas started flooding in. "What should the zombies look like?" or "What should the sniper class look like?" which was then followed by someone from the community adding some new sprites to use.
Setup The New Project: Once I figured out I wanted to make a 2D Zombie Survival Game, I created the project in Unity with the prebuilt "2D" template and pushed the code to a new private Github repository. This allows you to add any contributors to the project later and also serves as a way to rollback if you make a mistake or change your mind on something (it will happen). Also PC issues happen, so never hurts to have a backup.
Lets get started on the game!
Building this game in 2D largely determines how I will have to control the character. While I enjoy the classic full keyboard controls of games like Final Fantasy XI, most users prefer using the mouse to control the direction the character is facing. Additionally, using the mouse makes fighting hoards of zombies easier since they will be coming from every direction. Therefore, I decided to go with simple WASD movement, having abilities set to 1–2–3–4 , and mouse for camera directional controls.
How does Unity handle player movement?
Unity offers various methods for handling movement inputs, including Transform, Rigidbody, and CharacterController. For my project, I am utilizing Rigidbody. Below are some examples of Rigidbody methods essential for the PlayerMovement script:
Update() Handles input for movement (WASD keys) and call the RotateTowardsMouse method to rotate the player towards the mouse position.
void Update()
{
movement.x = Input.GetAxis('Horizontal');
movement.y = Input.GetAxis('Vertical');
RotateTowardsMouse();
}
FixedUpdate() Moves the player based on the movement vector and speed.
void FixedUpdate()
{
rb.MovePosition(rb.position + movement * moveSpeed * Time.fixedDeltaTime);
}
RotateCharacterTowardsMouse() Calculates the angle between the player and the mouse position, then rotates the player to face the mouse.
void RotateCharacterTowardsMouse()
{
Vector3 mousePosition = Camera.main.ScreenToWorldPoint(Input.mousePosition);
Vector2 direction = (Vector2)(mousePosition - transform.position);
float angle = Mathf.Atan2(direction.y, direction.x) * Mathf.Rad2Deg;
rb.rotation = angle;
}
Most components created for the project will require scripts for customization. Note that Unity will automatically update the script as you make changes through the UI.
Once you have created the PlayerMovement script, you can assign it to the player GameObject by dragging and dropping it from the Project window into the Inspector window. Alternatively, you can click the Add Component button in the Inspector window, search for PlayerMovement, and select it.
After configuring the movement, you will be able to move an empty square model around.
Lets add some custom sprites!
Setting up the player and zombie sprites is a fun process that I enjoyed. My friend Joey created the sprites and I was able to build all the surrounding pieces to make them work. I imported the custom sprites for player models, zombies, and scenery into their folder, plugged them in, and worked on setting up idle/running states.
Wow, I got stuck on a bush in the dark and couldn't get the zombie off me!
Nothing is worse than getting stuck on an object and your character dying due to poor coding. This is something that I wanted to make sure I got right. I added a combination of Collider and RigidBody2D to set a collision perimeter for the player, the zombies, and all scenery that was added. Unity fortunately does a good job with the ability to duplicate the models and maintain their collision.
How should the zombies behave?
For the Zombie AI I want them to behave similar to how they do in Project Zomboid. If you are detected in their sight or hearing range, they will immediately start trying to attack and chase you. The player should have a slight speed advantage over the zombies while sprinting. However, there should be a balance between choosing to outrun the zombie at the risk of depleting stamina or confronting the zombie and potentially attracting more due to the noise.
What should we do next?
Combat: Animations and feedback will require a significant amount of time because each weapon type has unique requirements. Melee weapons need different rotations, ranged weapons need distinct animations, and any change to the weapon's size necessitates updates to the animations.
UI: Creating a clean UI is crucial for maintaining game fluidity and providing players with essential information about their health, stamina, and, if applicable, mana for magic mechanics. It's also important to have visibility into ability cooldowns and which weapon is currently equipped.
Advanced Animations: Implementing features like player death, bullet animations, destructible objects, and blood can be challenging, but they significantly enhance the game's depth.
Add Multiplayer: To add multiplayer, you will likely need to do some research on implementing Photon or mirror. These will give you the networking you need for adding other players to be controlled.
Don't forget to play your game!
After investing countless hours in building your game, I recommend taking some time to play it. Identify areas for improvement and jot them down. Many of the enhancements I worked on originated from bugs I discovered in existing features.
Thank you for reading!
As I conclude this talk about my Unity adventure, I reflect on the invaluable lessons learned along the way. It has been filled with challenges, creativity, and continuous learning.
Each bug fixed and feature implemented brought new insights and a deeper understanding of game development. It is important to identify areas for improvement, and embrace every obstacle as a stepping stone to growth.
Thank you for following along, and I hope my experiences inspire you to pursue your own adventures in the world of Unity and game development.
References: