Explore Free Unity 2D Game Tutorials – GameDev Academy https://gamedevacademy.org Tutorials on Game Development, Unity, Phaser and HTML5 Mon, 17 Apr 2023 08:21:45 +0000 en-US hourly 1 https://wordpress.org/?v=6.1.1 https://gamedevacademy.org/wp-content/uploads/2015/09/cropped-GDA_logofinal_2015-h70-32x32.png Explore Free Unity 2D Game Tutorials – GameDev Academy https://gamedevacademy.org 32 32 How to Create Game Over State in Unity in 10 Minutes https://gamedevacademy.org/unity-game-over-tutorial/ Fri, 21 Apr 2023 01:00:04 +0000 https://gamedevacademy.org/?p=22034 Read more]]>

You can access the full course here: CREATE YOUR FIRST 2D GAME IN UNITY

Game Over – Part 1

In this lesson, we’ll set up the Game Over state for our game. In our game, the Game Over state will happen either when the Player hits an Enemy, or when the Player falls from the level.

The Game Over Function

To implement the Game Over state, we’ll go to the PlayerController script and do the following changes:

  • Add the SceneManagement library at the top of the script
  • Add the GameOver function to the PlayerController script
  • In the GameOver function, use the LoadScene function to reload the current scene
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement; // Add me!!

public class PlayerController : MonoBehaviour
{
    // Older code omitted for brevity
    // Called when we get hit by an enemy or if we fall below the level.
    public void GameOver ()
    {
        SceneManager.LoadScene(SceneManager.GetActiveScene().buildIndex);
    }
}

And here’s what the PlayerController script looks like at the moment:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;

public class PlayerController : MonoBehaviour
{
    public float moveSpeed;
    public Rigidbody2D rig;
    public float jumpForce;
    public SpriteRenderer sr;

    private bool isGrounded;

    void FixedUpdate ()
    {
        float moveInput = Input.GetAxisRaw("Horizontal");
        rig.velocity = new Vector2(moveInput * moveSpeed, rig.velocity.y);

        if(rig.velocity.x > 0)
        {
            sr.flipX = true;
        }
        else if(rig.velocity.x < 0)
        {
            sr.flipX = false;
        }
    }

    void Update ()
    {
    // If we press the jump button and we are grounded, then jump.
        if(Input.GetKeyDown(KeyCode.UpArrow) && isGrounded)
        {
            isGrounded = false;
            rig.AddForce(Vector2.up * jumpForce, ForceMode2D.Impulse);
        }
    }

    private void OnCollisionEnter2D (Collision2D collision)
    {
        if(collision.GetContact(0).normal == Vector2.up)
        {
            isGrounded = true;
        }
    }

    // Called when we get hit by an enemy or if we fall below the level.
    public void GameOver ()
    {
        SceneManager.LoadScene(SceneManager.GetActiveScene().buildIndex);
    }
}

The Fall Game Over Challenge

As a bit of a challenge, we want you to implement one of the game-over cases yourself. In this challenge, you should make the fall-from-the-level scenario work as a game-over.

One of the ways to do so is to check whether the Player’s vertical position is below some level. Checking could be done in the Update function.

In this lesson, we implemented the Game Over function. In the next lesson, we’ll implement the game-over scenarios.

Game Over – Part 2

In this lesson, we’ll implement the Game Over scenarios.

The Fall Game Over

To make the Game Over happen when the Player falls from the level, we should make the following changes to the Player Controller > Update function:

  • In the Update function, check whether the vertical position of the Player is less than -4
  • If so, call the GameOver function
// Using directives omitted for brevity

public class PlayerController : MonoBehaviour
{
    // Older code omitted for brevity


    void Update ()
    {
    // Older code omitted for brevity


    // If we fall below -4 on the Y, then game over.
    if(transform.position.y < -4)
    {
    GameOver();
    }
}

    // Older code omitted for brevity
}

If you start the game now and jump from the level, in a couple of seconds, the level will reload from the beginning.

game level

game level

Here’s what the PlayerController script looks like now:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;

public class PlayerController : MonoBehaviour
{
    public float moveSpeed;
    public Rigidbody2D rig;
    public float jumpForce;
    public SpriteRenderer sr;

    private bool isGrounded;

    void FixedUpdate ()
    {
        // Get the horizontal move input.
        float moveInput = Input.GetAxisRaw("Horizontal");

        // Set our velocity.
        rig.velocity = new Vector2(moveInput * moveSpeed, rig.velocity.y);

        // Flip the sprite to face our moving direction.
        if(rig.velocity.x > 0)
        {
            sr.flipX = true;
        }
        else if(rig.velocity.x < 0)
        {
            sr.flipX = false;
        }
    }

    void Update ()
    {
        // If we press the jump button and we are grounded, then jump.
        if(Input.GetKeyDown(KeyCode.UpArrow) && isGrounded)
        {
            isGrounded = false;
            rig.AddForce(Vector2.up * jumpForce, ForceMode2D.Impulse);
        }

        // If we fall below -4 on the Y, then game over.
        if(transform.position.y < -4)
        {
            GameOver();
        }
    }

    private void OnCollisionEnter2D (Collision2D collision)
    {
        if(collision.GetContact(0).normal == Vector2.up)
        {
            isGrounded = true;
        }
    }

    // Called when we get hit by an enemy or if we fall below the level.
    public void GameOver ()
    {
        SceneManager.LoadScene(SceneManager.GetActiveScene().buildIndex);
    }
}

The Enemy Hit Game Over

We should also go to the Game Over state once the Player hits an Enemy. We’ll do this from the Enemy script.

But first, we need to add a way for an Enemy to know that it hits the Player, and not something else. Here’s what we’ll do:

  • Select the Player game object
  • Go to the Inspector window
  • Set the Tag property at the top of the Inspector window to the Player value

Now our Player is tagged as a Player. Well done!

Player game object

And here’s what we’ll do in the Enemy script:

  • Add the OnTriggerEnter2D function. This function is called when something enters the trigger collider
  • In this function, check whether we have a collision with an object tagged as a Player
  • If so, get the PlayerController component from that object and call the GameOver function on it
// Using directives omitted for brevity
public class Enemy : MonoBehaviour
{
    // Older code omitted for brevity
    private void OnTriggerEnter2D (Collider2D collision)
    {
        // Did the player hit us?
        if(collision.CompareTag("Player"))
        {
            // Trigger the game over state on the player.
            collision.GetComponent<PlayerController>().GameOver();
        }
    }
}

Now, if you jump into an Enemy, the game will reload as well. Here’s what the full Enemy script looks like:

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Enemy : MonoBehaviour
{
    public float moveSpeed;
    public Vector3 moveOffset;
    private Vector3 startPos;
    private Vector3 targetPos;
    // Start is called before the first frame update
    void Start()
    {
        startPos = transform.position;
        targetPos = startPos;
    }
    // Update is called once per frame
    void Update()
    {
        // Move towards the target position.
        transform.position = Vector3.MoveTowards(transform.position, targetPos, moveSpeed * Time.deltaTime);
        // Are we at the target position?
        if(transform.position == targetPos)
        {
            // Is our target pos our start pos? If so, set it to be the other one.
            if(targetPos == startPos)
            {
                targetPos = startPos + moveOffset;
            }
            // Otherwise, do the opposite.
            else
            {
                targetPos = startPos;
            }
        }
    }
    private void OnDrawGizmos()
    {
        Vector3 from;
        Vector3 to;
        if (Application.isPlaying)
        {
            from = startPos;
        }
        else
        {
            from = transform.position;
        }
        
        to = from + moveOffset;
        
        Gizmos.color = Color.red;
        Gizmos.DrawLine(from, to);
        Gizmos.DrawWireSphere(to, 0.2f);
        Gizmos.DrawWireSphere(from, 0.2f);
    }
    private void OnTriggerEnter2D (Collider2D collision)
    {
        // Did the player hit us?
        if(collision.CompareTag("Player"))
        {
            // Trigger the game over state on the player.
            collision.GetComponent<PlayerController>().GameOver();
        }
    }
}

In this lesson, we implemented the Game Over scenarios. In the next lesson, we’ll work on the collectible Coins.

BUILD GAMES

FINAL DAYS: Unlock 250+ coding courses, guided learning paths, help from expert mentors, and more.

Transcript – Game Over – Part 1

Welcome back everyone. In this lesson we are going to be working on setting up our game overstate for our 2D platform here.

So the way the game over state is gonna work is pretty much whenever our player gets hit by an enemy or if they fall off the edge and down below our level, they are going to basically reset, okay?

The level is gonna restart and the player will spawn back up here. Okay, so how do we do this? Well, let’s go over and open up our player controller script right here.

Now inside of the player controller script, we are gonna go down and create a brand new function. And this function is gonna be a public void called GameOver. Okay? Like so.

Now the reason we are making this function a public function is because we need to be able to call this from outside of the script. For example, our enemy script here is going to be able to call that function.

So in order to do that, we need to make it public. Now, inside of this function, what we are going to do is basically reload our current scene.

So in order to do that, we first of all need to tell the script that we want to be able to access Unity’s scene manager. And to do that we need to go to the top and you’ll see here we have these three lines of code, okay?

They’re basically using, and then we have a library here. Now, the way code and C Sharp especially works is that you don’t have everything at your disposal right at the start, okay?

So for certain things you may need to access a library. In our case, we are accessing the Unity engine library which allows us to access things such as mono behavior, rigid body, sprite renderer, the fixed update function, the update function, okay?

These are all things that are built into the Unity engine itself. Now, the Unity engine doesn’t always give us everything we need since there are a lot of different code libraries that we can access.

So if we wanna get specific, we do need to actually add them here. So for example, in order to access our scene manager, we need to be using the scene management library.

Now to do that, we can go to a new line here and just go using Unity engine dot scene management like so, and now we have access to our scene manager. So let’s go back down to our GameOver function.

And inside of here what we are going to do is go scene manager dot load scene, okay? And this function right here, basically we need to give it either a scene name, so we can just go level one like so, which is the name of our scene, or we can give it a build index.

And our build index for level one is zero. Basically, the levels go 0, 1, 2, 3, 4, 5, et cetera. But what if we’re on level five, for example? We don’t wanna have to hardcode every single level we have.

So, instead what we can do is we can just get whatever our current scene is and reload that. So to do this, I’m gonna go SceneManager dot GetActiveScene.

Now this is a function call, so make sure to add the two empty brackets like so, and then dot buildIndex. So this here is basically getting the index for the current scene and loading that.

So this line of code essentially reloads our current scene. So we have our game over function, but at the moment it’s not hooked up to anything just yet. So if we were to play our game, nothing would happen.

So in order to make something happen, we are first of all gonna make it so that if our player is jumping along the level here and they fall off the platform we don’t want them to keep on falling down forever.

Let’s say once they reach below, we’ll say below negative four, okay? Once they go below negative four on the Y axis that is when we will basically call the game over function.

So to do this, we are gonna go up to our update function right here. And as a bit of a challenge, I want you to have a go at implementing this.

Here’s a hint. Basically, we are gonna have an if statement that checks to see if our Y position is below negative three or negative four, I’m pretty sure we said, and if that’s the case call the game over function. So have a go at that and I’ll be right back to see how you’re done.

Transcript – Game Over – Part 2

Pretty much what we want to do is inside of our PlayerController’s update function we want to check every single frame if our player’s y position is below a certain number.

So what we’re gonna do is we’re gonna create an IF statement here. We’re gonna go, if transform.position.y is less than, let’s just say negative four then what we are going to do is we are going to call the GameOver function like so, okay?

So that is what we need to do here and make sure it is inside of the update function since we do want to check this every single frame. So we can save that, we can then go back inside of Unity now.

And if we press play, we should be able to test this out. So let us go over to the side right here and jump off the edge. And as you can see, once we go below negative four our scene basically gets to reset.

So we are back at the start and there we go. Now one more thing and that is our enemy. As you can see right now our enemy is just passing directly through us.

So we need a way of making it so that when the enemy hits us the GameOver function gets called. So how do we do that? Well, let us go over to our enemy script right here, and inside of the enemy script we need to create ourselves a brand new function.

Now this is going to be the OnTriggerEenter2D function. So we’re gonna go void OnTriggerEenter2D. Now OnTriggerEenter works very similar to OnCollisionEnter yet they both differ in a certain way.

Collision is basically a solid hit, so you can think of when our player lands on the ground their feet are being planted on the ground’s collider, whereas a trigger is passing through something, okay?

So maybe you might want to have some sort of trigger when a player walks through a door that would be a trigger, okay? The player isn’t blocked, they can pass through it, yet we can detect when that pass through happens.

And that is what a trigger is. So what we need to do is we basically need to make it so that when the player is hit by the enemy we call the GameOver function. But how do we do that?

Well, we’ve got the function here that detects when a trigger has happened, but how do we know if it was a player or not? How do we know that what the enemy hit is a player and not a wall, or a coin, or another enemy?

Well, the way we can do this is by checking to see what the player’s tag is. And before we continue writing code, let’s go back inside a Unity and we need to give our player a tag.

So I’m gonna select our player here and if we go over to the inspector, you’ll see underneath their name they have this little tag dropdown. Now tag is basically a label that we can attach to a game object.

So I’m gonna click on where it says untagged and you’ll see there are a few preset ones here. We can click add tag to add a new one. But we’ve got player, sorry, I’m just gonna select that.

And now our player game object is tagged as player. And you can of course, create tags for other things as well if that’s needed.

But we’re just gonna tag our player for now. So back inside of our script, what we’re gonna do is we are going to check to see if the collision.CompareTag is Player. So the parameter here is collision.

This is basically going to be our player’s collider when the enemy hits us and we are checking to see if that game object’s tag is player, and if so then the condition is true and we can call the GameOver function.

Now, in order to call the players GameOver function, we need to access their player controller component. So to access another game objects component or get any component in general, we need to do a certain function call.

So I’m gonna go collision.GetComponent, and then inside of these two angled brackets we need to define the type of component we are searching for which is gonna be PlayerController, and then two empty brackets like so.

And then we can go .GameOver. Whoops, not GameObject, GameOver, like so. So basically what we have done here is we have accessed the collision component that we have hit.

In this case it will be the player after we do this IF statement. Then we are getting another component on that GameObject we are searching for the PlayerController and then we are calling the GameOver function on the PlayerController.

So we can save that, go back inside of Unity and let’s test it out to see if it works. So I’m going to press play right here and if we jump up into our enemy, we should see that when it hits us the scene gets reset and we can even jump into the enemy here to make sure it works.

There we go. So we’re able to reset the scene by having our enemy run into us. So we need to avoid them on this jump here. And if we jump off our level and fall down below that will also reset the level as well.

So yeah, that is a look at our GameOver state inside of Unity. Now, in the next lesson, we are gonna be looking at setting up our coins, okay? These are basically going to be the collectibles that our player will collect and that will increase their score over time. So thanks for watching, and I’ll see you then in the next lesson.

Interested in continuing?  Check out our all-access plan which includes 250+ courses, guided curriculums, new courses monthly, access to expert course mentors, and more!

]]>
Free Course – Learn Unity Engine in 90 MINUTES https://gamedevacademy.org/unity-beginner-tutorial/ Fri, 14 Apr 2023 01:00:29 +0000 https://gamedevacademy.org/?p=21848 Read more]]>

Start your journey into becoming an expert game developer by learning one of the world’s most popular Unity game engine – all for free in the complete Unity engine tutorial above! You can also download the project files used for the course below.

Download the project files

About

In this Unity tutorial created by Daniel Buckley, you’ll dive into the basics of the Unity game engine which allows you to develop 2D, 3D, VR, and AR games, mobile content, training apps, and more. You’ll first discover the Unity Engine platform, how to create a Unity project, navigate Unity’s Editor, edit game objects, apply materials to objects, and adjust lights and physics in various ways. After, you’ll dive into the C# Scripting system and learn a few core scripting techniques to build your first interactive project!

Whether you want to build games, training apps, or something similar, these foundations will form the core knowledge you’ll need to build any sort of Unity Engine game or project in the future!

New to Unity Engine? Enroll in UNITY 101 – GAME DEVELOPMENT FOUNDATIONS on our website and find quick access to additional resources!

BUILD GAMES

FINAL DAYS: Unlock 250+ coding courses, guided learning paths, help from expert mentors, and more.

]]>
Unity vs Godot – Choosing the Right Game Engine for You https://gamedevacademy.org/unity-vs-godot/ Tue, 11 Apr 2023 05:44:19 +0000 https://gamedevacademy.org/?p=20270 Read more]]> Most modern video games are developed using a game engine – which allows developers to focus on building their game rather than the tedious backend systems that run it. This makes finding a game engine that works for your project essential, since you’ll be spending quite a bit of time working with it.

With a ton of game engines available, though, how do you pick?

In this article, we’ll be exploring Unity and Godot – two powerful and popular game engines used for 2D & 3D games.

When looking for a game engine, it’s essential to assess its versatility, power, and popularity within the industry. We’ll be taking a look at several factors – such as their versatility and industry presence, and also get you learning resources so you can dive into the engine of your choice.

If you’re ready to pick your game engine, let’s get started!

What is a game engine?

Before we get started, for those new to game development, we first want to talk a bit about what a game engine is. In this way, the reason why a game engine can help you is more clear (and you can temper your ambitions by thinking you need to make your own).

A game engine, sometimes referred to as game architecture or game framework, is a software development environment complete with settings and configurations that improve and optimize the development of video games, integrating with various programming languages.

Game engines can include 2D and/or 3D graphics rendering engines that are compatible with different import formats. They will also often include a physics engine that simulates real-life properties, AI that is designed to respond to the player’s actions, and a sound engine that controls the sound effects within the game.

As stated previously, game engines are primarily designed to make your life easier. Without them, not only would you have to program your game mechanics, but instructions for your computer on how to access and play sounds, how to display your graphics, and so on. This quickly becomes a huge tedium of work – which is often why a big deal is made whenever a AAA company makes a new in-house engine; they really change everything about how a game runs in general.

To summarize, game engines are simply a powerful tool for your game development arsenal. They make sure you aren’t stuck programming every single tiny detail (unless you want to), and get to have fun with the stuff most players actually care about.

BUILD YOUR OWN GAMES

Get 250+ coding courses for

$1

AVAILABLE FOR A LIMITED TIME ONLY

Versatility

There are a variety of different types of games that you can choose to develop, from 2D to virtual reality. A good game engine will support coders in creating a wide range of games, and both Unity and Godot do this. Here are the different types of games you can choose to develop and how Unity and Godot can support your development journey:

  • 2D. Both engines are more than capable of developing 2D games, with Unity giving its users a broad tool set. However, new updates to Godot 4 have significantly improved its ability to create 2D games, including 2D lighting, 2D materials, 2D light & shadow support, and 2D masking and clipping. It’s also worth noting that Godot offers an actual dedicated 2D engine, while Unity still technically uses its 3D engine to render 2D games. This has some performance implications for more complicated projects.
  • 3D. While Godot is capable of making 3D games, it isn’t as powerful and doesn’t have as many features as Unity. In terms of graphic fidelity, Unity is therefore the superior choice. That said, Unity is consequently the heavier-duty engine and may not work as well on older computers as Godot.
  • Augmented Reality (AR). There are currently no AR capabilities for Godot, whereas Unity has an established AR interface and has been contributing to AR output for years.
  • Virtual Reality (VR). Unity is an excellent game engine in terms of VR, as the plugins used are versatile and are able to integrate into the XR infrastructure. While VR capabilities have improved with Godot 4, export doesn’t yet work for meta quests due to licensing issues. For now, Unity is still the superior choice.
  • Mobile. Both Godot and Unity have mobile capabilities. That said, Unity perhaps offers a few more tools when it comes to the actual development process, such as the Device Simulator.
  • Multiplayer. Both platforms have multiplayer features to offer. The Godot 4 update in particular has massively improved the ability to make complex multiplayer games. The update includes improvements in scene replications, RSET, and state updates. As for Unity, with the recent release of the Unity Multiplayer Networking features, it’s easier than ever to develop multiplayer projects. In this area, both over a relatively good basis to work from.

Unity vs Godot - Choosing the Right Game Engine for You

Coding

The coding language you are most comfortable with will have a determining factor in what game engine you decide to use.

Unity uses C# for its scripting logic, which is generally considered a fairly well-balanced language to learn. This language offers some enhanced readability compared to C++, but has a plethora of advantages that other high-level languages can’t offer.

If coding plainly isn’t your thing, Unity also does offer a visual scripting option in its newest versions. This drag-and-drop approach means you don’t have to learn tedious C# syntax, but still get all the game logic you would with regular coding.

In comparison, while Godot is compatible with a few languages, its main language focuses are GDScript and C#. We’ve spoken about C# already for Unity, but GDScript is perhaps Godot’s “main” language. This Python-like language is made to be super easy to read and use with the Godot engine specifically (as it was developed by the Godot team). While this doesn’t have the versatility of C#, it does come with a variety of benefits for making games that much easier to make.

Industry Presence & Popularity

The game engines that professional developers are using is a good way to judge the versatility and usability of the software. Unity and Godot are both popular game engines used to create high-powered games that are popular on the market. However, each has different uses.

Unity is popular with AAA and indie developers alike because of its abundant resources. These resources include things like instant assets, online community assistance, Unity-provided tutorials, and intuitive tools for a variety of applications. It offers a lot of developer support along the way, and makes the coding process easier compared to other similar game engines. Plus, Unity offers tons of companion services (such as monetization for mobile games), making it a one-stop shop for many users.

There’s also the benefit that the Unity game engine is as powerful as it is popular. Thus, it’s been able to spread to a ton of other industries such as film, architecture, and so much more.

Popular games created using Unity include Hearthstone, Cities: Skylines, Rust, Ori and the Blind Forest, and the majority of mobile games.

In comparison, Godot is a lot younger than Unity and doesn’t have the same presence. However, Godot is quickly rising to become a major competitor. Godot also has an advantage that Unity does not in terms of development: it’s open source. As such, developers get ultimate control over the engine itself and, if push comes to shove, can make the engine do what it wants.

Despite its youth, Godot has been used to create many successful games including Kingdoms of the Dump, Cruelty Squad, Rogue State Revolution, and Dungeondraft.

Unity vs Godot - Choosing the Right Game Engine for You

Community

A strong and supportive community is very important when choosing a game engine, as you’ll be able to seek support from subreddits, YouTube channels, Discord chats, and whatever else there is to offer (plus, asset stores count here too). Luckily, both Unity and Godot have thriving communities offering help to new and seasoned developers.

  • Unity has a game developer convention held yearly called Unite. The event mostly focuses on how to use Unity with some YouTubers teaching engaging classes.
  • Unity also has a subreddit providing expert advice and knowledge, and a YouTube channel with tutorials from expert developers.
  • Godot also hosts many in-person and online events, such as Godot @ GDC 2023, where developers will showcase their new games made using Godot.
  • Godot helps its community with a subreddit, and has their own YouTube channel as well.
  • Godot is active in a ton of other channels such as Discord, Twitter, and so forth – all of which are viewable on their promoted Community page.

Both Unity and Godot also have an asset store – a marketplace for 3D models, textures, systems, etc. that can be used on the engine (with free and paid options). These assets are beneficial for developers who need extra assistance in design or coding, and are largely community supported.

This said, if we had to pick, we would note that Unity’s community is larger simply because of its longer-established reign as a popular game engine.

Cost

Last but certainly not least, let’s talk about money. What would using these game engines cost you?

Unity has a free plan – but there is a catch. In general, the rule of thumb is that once you’re earning $100K annually, you need to purchase a paid plan. That said, the majority of users will be fine with the free plan (so unless you become a AAA overnight, don’t worry too much about it).

This said, the free plan does come with fewer features, though this centers more so around developer support. For the most part, the free version still includes things like the platform itself, core features like visual scripting, and even the Unity Plastic SCM for version control (3 users and 5GB of storage).

The paid plans are as follows, though, if you’re interested:

  • Plus – $399 per year per seat
  • Pro – $2,040 per year per seat
  • Enterprise – Custom quotes depending on need

By comparison, since its open-source Godot is entirely free, with absolutely no strings attached. Of course, this does mean it doesn’t offer the same sort of premium services Unity does, but it can be less stressful to know there can’t be any shenanigans.

Unity vs Godot - Choosing the Right Game Engine for You

Tutorials & Courses

At this point, you’re probably leaning one way or another on whether to pick Unity or Godot. However, the best way to find out your preference is simply to try them out. So, to get you started (and demonstrate the quality of learning materials available), we’ve listed out some of our favorite resources.

Unity

  • Unity Game Development Mini-Degree, Zenva. With this curriculum, you’ll explore a variety of tools and features Unity has to offer. In addition, you’ll get the chance to build a ton of projects suitable for a professional portfolio. You’ll not only learn the fundamentals of game development, but make real games including RPGs, idle games, and FPS games.
  • Unity 101 – Game Development Foundations, Zenva. This free course teaches you the very basics of how Unity works and allows you to start playing with your first game objects. You’ll also learn skills needed to build your own games in any genre you choose.
  • How to Program in C#, Brackeys. This free YouTube course teaches you how to read, write, and understand C# coding from scratch, and lays the foundation for learning Unity.
  • C# Tutorial, Derek Banas. In this tutorial, you’ll learn how to install Visual Studio and Xamarin. You’ll then cover key programming knowledge including input, output, loops, data types, and more.
  • C# Basic Series, Allan Carlos Claudino Villa. In this free course, you’ll cover everything there is to know about C# to give you the knowledge needed to create games with Unity.

Godot

  • Godot 101 – Game Engine Foundations, Zenva. With Godot 101, you’ll learn the fundamentals of working with the Godot 4 editor, including understanding the core difference between Nodes and scenes. Plus, you’ll get experience working with both 2D and 3D objects!
  • Godot 4 Game Development Mini-Degree, Zenva. This comprehensive collection of courses gives you the knowledge needed to build cross-platform games using Godot. You’ll be given the tools needed to create 2D and 3D games including RTS games, platformers, and survival games.
  • Make Your First 2D Game with Godot: Player and Enemy, GDQuest. Learn to create your own games using Godot in this beginner tutorial series, hosted on YouTube. This course gives you an entire run-through on using Godot to program different game types, perfect for complete novices.
  • Make your first 2D platformer game In Just 10 Minutes, Eli Cuaycong. In this short tutorial, you’ll learn the basics to help you with your game development journey, including tile maps, world scene, and spritesheets.

Conclusion: Unity vs Godot – which is better?

Now we’ve covered the differences between Unity and Godot, let’s get back to the ultimate question – which game engine is better?

This entirely depends on what type of game you want to make, the game’s style and needs, and what kind of knowledge you’re bringing to the table.

For instance, for 3D, AR, or VR games, Unity is definitely the superior choice as it offers all the tools needed and the power to make those games work. However, on the opposite end of the spectrum, Godot is definitely the winner when it comes to 2D given it’s the dedicated and more performant rendering engine for this aspect.

Even then, there are exceptions even to the above! For example, a game like Paper Mario would probably work better with Unity, whereas a 3D game might work better with Godot in cases where you need to work with the engine’s code itself.

Regardless, both are truly great options, and you can’t go wrong with either. Plus, with plenty of courses available for both, they’re both easy to learn.

Regardless of your choice, we wish you the best of luck with your future games!

BUILD GAMES

FINAL DAYS: Unlock 250+ coding courses, guided learning paths, help from expert mentors, and more.

]]>
The Beginner’s Guide to Unity Certification https://gamedevacademy.org/unity-certifications-tutorial/ Sat, 28 Jan 2023 06:09:24 +0000 https://gamedevacademy.org/?p=19413 Read more]]> How does a Unity game developer prove their skills?

Whether you’re just starting out or have been making games for a long time, this is a difficult question. However, it’s a question that comes up often in the professional world. Numerous situations will require you to show evidence you actually do know what you’re doing.

While portfolios are definitely a necessity, for Unity developers, there is another fantastic option: Unity Certification.

In this article, we will endeavor to explore what Unity Certification is, why Unity Certification is definitely worthwhile to pursue, and how you can start preparing to earn your certification.

Let’s jump in!

BUILD YOUR OWN GAMES

Get 250+ coding courses for

$1

AVAILABLE FOR A LIMITED TIME ONLY

An Overview of Unity Certification

In this section, we will discuss what Unity Certification is for those new to the topic. If you already have a good idea of what Unity Certification is, feel free to skip ahead to find out why Unity Certification can help you and get guidance on prepping for an exam.

What is Unity Certification?

The Unity Certification program is a set of exams aimed at testing Unity developers’ core skills in game development and the Unity engine. The exams were developed meticulously by Unity through research, and with coordination between both testing specialists and game development experts.

At current, the tests are administered by Pearson VUE, a branch of the widely-recognized educational company Pearson, which is aimed at specifically providing testing for professional certifications. As such, Unity Certifications are regarded very highly in the professional world due to the extensive work and credentials associated with them.

The exams for Unity Certification are divided between a few different specialties and different levels of experience – giving every user an opportunity to pursue certification. Likewise, this division allows the prices to vary – starting as cheap as $60 and going all the way up to $350 for experts (with some bulk purchasing options for schools).

Screenshot of the Unity Certifications available

How are the Unity Certifications Structured?

As mentioned above, the Unity Certifications consist of several different exams depending on your level of experience and your specialty in that experience level. We will briefly discuss what exams are available so you can get a grasp on what you personally may wish to pursue.

Certified User Unity Certification

This is the beginner’s level exam aimed at people who’ve just learned a little bit of Unity. To put it into better perspective, this exam was one that was made to be appropriate for high school level students as well, so there’s no expectation you’ve necessarily even made more than a couple of hobby games.

At this level, Unity offers three different certification specialties, each with a separate exam.

  • Programmer: This is probably what would be considered the main certification for Unity itself at this level. In this one, users are evaluated on how well they know the fundamentals of using Unity, such as how to make projects and Prefabs, navigate the editor, and so forth. This exam will, of course, also test your basic C# knowledge – including quite a lot of focus on Unity-specific library functions and accessing components. However, the main point is to see if you’re able to read, write, understand, and debug basic code elements that will be used all the time.
  • Artist: This level tests how well you know Unity’s tools in order to design 2D and 3D scenes. This includes things like importing the assets correctly and manipulating objects in the scene. You’ll also be expected to know a little bit about lighting, materials, and cameras.
  • VR Developer: For this certification, users are tested specifically on how well they can adapt a Unity project for VR. This includes elements related to understanding how to even set up a VR project, how to deal with movement based on hardware, and how to optimize your elements to be VR-ready.

Certified Associate Unity Certification

This certification is primarily designed for those ready to actually start working in professional development. The general assumption is that you’ll probably already have a few simple projects under your belt, and be ready to justify the fact you can, in fact, build games.

Like the User Certification level, this level also has three different exam options to specialize in:

  • Game Developer: This particular exam focuses on testing whether you can make a game with Unity. While there is some C# programming involved, of course, the major aspects are much larger in scope. You’ll be expected to understand how to take a game from idea to completion. You’ll also be expected to know, relatively well, all the tools Unity offers such as audio, animation, physics, and so forth. Another way to think of it is this exam is for those looking to make sure they understand the bigger picture of game development.
  • Programmer: At the Associate-level, the Programmer Certification focuses a ton more on C# scripting. You’ll be expected to have a solid understanding of working with Unity’s API to script behaviors and objects (including UI elements). This level also starts examining code efficiency, such as if you understand best practices for data structures. There is also a strong focus on being able to debug.
  • Artist: Continuing somewhat from the Artist User Certification, the Artist Associate Certification focuses on more advanced uses of the Unity tools for artistry. This includes working with tools like Shader Graph and ProBuilder, understanding different lighting effects, implementing Level of Detail, and beyond. If it has to do with presenting the assets, be prepared for it to be on this exam.

Screenshot of a splitscreen racing game made with Unity

Certified Professional Unity Certification

The Professional Unity Certification is where we really start getting into more advanced users. This certification level is focusing specifically on those who have probably up to 4 years of making professional Unity games. Another way to think about it is this certification is perfect for those who are already game developers but want that coveted promotion and need something extra to prove themselves.

This level focuses on two specific specializations for its exams:

  • Programmer: At this level, you’re already expected to have long since mastered the fundamentals. So, the focus on this exam turns to more advanced C# programming. You’ll be tested on things like being able to program a render pipeline, working with teams on coding, and even being able to optimize the game with how you code. There is also some focus on applications as well at this level.
  • Artist: At this level, artists aren’t tested much differently than before – the only expectation difference is your level of understanding. As such, you’ll need to be a pro at being able to light scenes, work with particle systems, deal with animations, and similar. There is also a bigger focus on teamwork aspects to ensure you can work with big-budget productions.

Certified Expert Unity Certification

This is the last level of certification, and as expected, it’s focused on the bravest and most experienced game developers. In general, this certification is best for those who have worked with Unity for at least 5 years, if not more. It’s also a relatively safe assumption that if you need this certification, you’re working in the wider game industry as a whole.

At this level, there is only one certification exam for Programmer. The exam focuses on two things. The first is simple project management principles, such as being able to scope the project and review it to polish and refine the game. The second is obviously the coding part – where you’re going to have to know how to work with advanced algorithms and mathematics, as well as evaluate your code to improve it to its utmost efficiency.

Woman working on a laptop

Why You Should Get Unity Certification

So, why should you get Unity Certification? Is Unity Certification worth it? In this section, we’re going to discuss the three major reasons why Unity Certification may help boost your position regardless of your personal goals.

Unity Certification Helps With Job Hunting

One of the core reasons the Unity team invested in their Unity Certification program was to help Unity developers with job hunting.

Job hunting for any position, game development or not, is very tough. You’re generally up against 10s or 100s of other applicants for the same position. Even if your application is lucky enough to get past the initial resume review process, the competition will only get thicker.

As such, the key goal of any applicant is to make themselves stand out from their competition. When it comes to game development, the more you can prove you know how to make games (or provide the subspeciality the company is looking for), the better your standing.

However, almost every game development applicant will have two items: their work history (or education history for those starting out), and their game developer portfolio. So, even if you make great games, you’re going to need to find another angle to help push yourself to the top of the pile.

This is where Unity Certification comes in. In an industry where certifications are extremely rare, Unity Certification stands apart. It is widely recognized as a solid credential to prove your skills due to the exams themselves and the cost & time involved in obtaining the certification. They are so accepted in the industry that a good number of Unity-based job postings will even list Unity Certifications as a preferred requirement for the position.

To put it another way, if you were in HR, who would you hire:

  1. The applicant who has previous experience and a portfolio OR…
  2. The applicant who has previous experience, a portfolio, and certification proving they know Unity

The answer here is probably going to be two – so you can see how Unity Certification can be an extra boost that will help you shine compared to other job hunters. It’s just a good piece of evidence you know how to make games, and since not everyone will get certified, it can only help you professionally speaking.

Unity Certification Prepares Teachers

Teaching is a challenging skill set to develop. Not only do you have to understand the subject matter you’re teaching, but know how to tailor that content to your audience.

This second part is particularly important. If what you’re teaching is too easy for the audience, they’re going to get bored and disengage. If what you’re teaching is too difficult for the audience, they’re going to get frustrated and disengage. There is a reason we don’t teach physics and calculus to kindergartners or teach high school students the Alphabet song.

So, when it comes to Unity, how can a teacher prepare? Surprisingly, the Unity Certification process is a great answer to this.

Obviously, by preparing for a Unity Certification exam, you’ll have to fulfill that first part of actually learning Unity and proving that you do know the subject matter. Thus, this benefit speaks for itself.

However, as Unity divides its certifications by experience level, you can also choose to prepare for the exam that suits the audience you most want to teach. By forcing yourself to prepare for the proper level exam, you achieve two things. First, you make sure you’ve refreshed in your mind the materials most relevant to your audience. Second, you unintentionally use Unity to guide you on what fundamentals you actually need to convey to your students.

So, once you pass your exam, you can use the exam as an example of how you should structure your own learning materials. This helps you save tons of time, and makes sure you have the right direction for what you want students to take away.

As a side benefit, for teachers focused on self-guided learning online by providing online courses, having Unity Certification can also be a great selling point!

Man teaching at a projector screen

Unity Certification Challenges Hobbyists

The last benefit of getting Unity Certification may surprise you – as it has nothing to do with the professional world.

Plenty of Unity developers out there would qualify more as hobbyists. While the professional world may be a long-term goal, the main goal is simply to have fun, make some awesome games, and learn more Unity skills along the way.

That being said, learning more Unity skills is a big component for hobbyists, especially as many are self-taught. And, if you’ve ever tried to teach yourself a new skill, you know it can be extremely hard to plan an ideal learning path. Even with numerous courses out there, you can still often hit a wall at one point wondering, “Where to next?”

This is the sneaky way in which Unity Certification can benefit the hobbyist. As mentioned, these certification exams are divided into different levels, going from beginner to expert developer. While not required, the subtle idea here is you take the certification exams in order since it’s a designed progression.

However, this subtle idea of taking them in order also gives you a core learning path to subscribe to. By following this progression and prepping for each exam, you can challenge yourself to learn exactly what would be expected of you at each level. In this way, you don’t have to question, “What’s next?” Unity Certification guides you exactly on the skills you’ll want to learn in order to hit the next step of your Unity development journey.

Likewise, this means you can more easily choose courses to achieve those goals, plan projects that would implement elements you need to know, and so forth. Plus, if the need should arise, you’ll be ready to take the Unity Certification exams at any point.

Overall, though, Unity Certification can still play a key role for hobbyists and helps describe an ideal path for developers to follow.

How to Prepare for Unity Certification

So perhaps at this point, we’ve convinced you to obtain Unity Certification – or at least convinced you that looking into these certifications is worth your time. This is where we come to our final section: how to prepare for Unity Certification. We’re going to cover the three major steps that will be involved, though the second part of this is the most important.

Understand Unity Certification Testing Procedures

Before you jump into other prep work, you’ll first want to do a bit of research into the Unity Certifications. Even though this seems common sense, it’s also an easy step to just skip over and take the “you only live once” route.

The most important aspect here is to simply tailor your expectations to understand what is required of you when the testing day rolls around. This way you can make sure to set aside enough time to take your exam, and also just generally prepare your environment to best suit your exam-taking needs.

However, you’ll also want to be sure to use this research time to narrow down your focus as well as to which exam you’re actually going to take.

Below, we’ve made a quick list of some of the most crucial information you’ll want to know going into your exam:

  • These exams are proctored – so you are going to have to deal with a person watching over your shoulder.
  • While Pearson VUE does have some scatterings of on-site testing centers, the exams are primarily designed to be taken online.
  • The number of questions varies by exam, ranging from as little as 40 questions up to 100 questions in total.
  • With the possible exception of the User Certification level, the tests are timed. We’ve listed the time limits below, but keep in mind it’s recommended you add an extra 15 minutes to your schedule to allow time for reading instructions and so forth:
    • Associate: 90 minutes
    • Professional: 105 minutes
    • Expert: 165 minutes
  • If you fail, you can retake the test. For a second attempt, you must wait 15 days. Additional attempts require a 90-day waiting period.
  • Unity Certifications are only good for 3 years. You must retake the test routinely to maintain your certification.

There are more questions you might have than we answered here, so we highly suggest checking out the FAQ section from Unity’s own website for further details. Regardless, do the legwork and make sure you have a solid understanding of your specific certification aims.

Screenshot of an AR training app made with Unity

Unity Certification Prep Courses

Perhaps not surprisingly, if you’re going to get a Unity Certification, you kind of have to learn Unity and game development. How much you have to learn will depend on the exam you’re taking – which is why the step above is crucial. That’s the juncture you decide what level you want to aim for, which informs which kind of coursework you want to look for.

This being said, it’s important to consider the kinds of courses you pick. There is no shortage of Unity learning material out there, as it is a very popular engine. However, some coursework is definitely better than others. Our advice? Make sure to pick courses that aren’t aimed solely at exam passing. Instead, you’ll want courses that help encourage you to fully understand game development so you can continue to expand your skills.

We also highly recommend finding courses that have a project-based focus. Not only does this force you to learn in a more practical manner, but also helps you discover different game mechanics and build a portfolio. This way, you essentially kill two birds with one stone.

As a bonus, you may wish to search for courses that are intended as a series (i.e. curriculums). It’s much easier to build your skills consistently when courses are designed around that single idea of continuity. While not required, obviously, it can be a lot easier than picking and choosing courses at random from sites like YouTube or Udemy.

For those just getting started with Unity, though, here are some fantastic resources to start your Unity education off with (all of which are beginner-friendly):

Unity Game Development Mini-Degree

This curriculum is designed around learning a little of everything that Unity has to offer. This includes things such as working with the UI, working with art tools like ProBuilder, using particle systems, building worlds, and so forth. There are also several different kinds of projects featured, including an FPS game, an idle clicker, a kart racing game, and so on.

Virtual Reality Mini-Degree

As the name suggests, this curriculum is all about VR. Of course, you’ll learn the coveted fundamentals of Unity. Past that, though, you’ll get to experience a lot of VR-specific mechanics such as how to get players to move, how to work with different controller setups, and other essential knowledge. The curriculum also covers the XR Interaction Toolkit, which has become a core focus for VR development with Unity.

Retro Game Development Academy

With this curriculum, the focus is entirely on 2D game development. Students will make a constant stream of retro-inspired games such as Pong, platformers, base defense, and more. The curriculum even covers a bit of how to implement local multiplayer as well. Given the simple nature of the projects, this curriculum is fantastic for those wanting to build up their portfolio.

2D RPG Academy & 3D RPG Academy

Although two different curriculums, these resources have the same focus of covering RPG creation (just with different kinds of assets). The courses cover a variety of skills required for these games, including action and turn-based combat styles, roguelike procedural generation, character customization, and beyond.

Strategy Game Development Academy

This course series covers strategy games and their specific mechanics. This includes RTS games, turn-based games, city-builders, and tower defense games. Along the way, students explore a good number of required features, ranging from technology trees to designing enemy AI – all fantastic skills transferable to other projects.

Survival Game Development Academy

This curriculum entry on the list is a bit unique. Instead of many small projects, this curriculum has you build one big, complex survival game project. Starting from the zero-Unity experience, you can learn player mechanics, inventory systems, crafting, base building, and enemy combat. You’ll also get to explore making a save system – a core need for many games.

EdTech Game Development Academy

Last on the list, this curriculum focuses a bit more on making educational game projects and utilizing more advanced technology. Students can learn things as simple as making quizzes with Unity or working with Cinemachine to create cutscenes. On the other end, though, students can also learn to utilize tools like Azure to make voice-commanded applications or to bring in third-party API data.

Police car chase scene animation made with Unity

Take Unity Certification Practice Tests

Last in the preparation steps is something kind of obvious: take practice tests.

Much like any sort of certification or big test like the SATs, there are plenty of resources out there that let you practice the tests. Obviously, legitimate sites won’t have the same content exactly as the exam. However, they will give you a fantastic idea of the sorts of stuff you may have to know and a better understanding of the experience level you’ll need to reach to pass.

This being said, be aware of two things. First, this step is optional. It can definitely help if you’re nervous, but it’s not required. If you feel confident, you can go straight to the exam if you wish. The practice tests are just there if you need them, as everyone practices in different ways.

Second, there are a lot of illegitimate sites out there that offer practice tests. There are evens some shady sites that claim to offer the actual exam in advance. Obviously, this would hardcore violate the Terms for these exams, so they are not recommended.

Instead, your best bet is to actually purchase practice tests from Pearson VUE itself. After all, who better to give you practice exams than the people running the exams in the first place?

There are some free resources available as well, but your mileage will vary with them. However, if you feel they’ll help you practice, by all means, use what you can.

Unity Certification Takeaways

Despite all the big talk, we acknowledge Unity Certification isn’t for everyone. Some developers absolutely prefer going the pure portfolio route – and this is a totally valid way to go about showcasing your skills. In fact, even with Unity Certification, having a portfolio can only help (and it’s also free for the budget conscious).

However, Unity Certification is nothing to ignore either. For many Unity developers, it can be a great piece of evidence to add to one’s resume. On the other spectrum, it can also be a simple way to structure how you learn Unity to ensure the best results for your time. It’s also a very accessible certification compared to others in the tech space. So, all in all, Unity Certification can be a fantastic and worthwhile pursuit to aim at.

We hope this article has given you some essential stepping stones to choose the right path for you when it comes to Unity Certification. Good luck with your Unity game development, and we wish you the best.

BUILD GAMES

FINAL DAYS: Unlock 250+ coding courses, guided learning paths, help from expert mentors, and more.

]]>
Best Unity Lighting Tutorials – Light up Your Game Levels https://gamedevacademy.org/best-unity-lighting-tutorials/ Mon, 23 Jan 2023 08:06:29 +0000 https://gamedevacademy.org/?p=15380 Read more]]> Lighting is an often overlooked aspect of a game’s look.

Whether a sunny day, quiet night, or dark dungeon, lighting plays a big role in aesthetics. It determines not only what players are seeing, but can add a layer of atmosphere to create a specific mood. After all, would a horror game that has no darkness or sparse lighting be as scary as one with those elements?

Through this article, we wish to explore the topic of lighting, and set you up with the best Unity lighting tutorials available. These tutorials will not only get you familiar with how Unity’s lighting system works, but show you how you can use it for very specific effects.

If you’re ready to light up your worlds, let’s get started.

BUILD YOUR OWN GAMES

Get 250+ coding courses for

$1

AVAILABLE FOR A LIMITED TIME ONLY

UNITY LIGHTING 2020 TUTORIAL For Beginners – Tips, Basics and Settings

Duration: 36 minutes

If you’ve never working with lighting in Unity before, this tutorial by TheUnityGameDev is a great place to start.

The tutorial covers a little bit of everything you might need to know about lighting fundamentals. This includes how to set up your basic lights and adjust them, and how to understand differences between direct and indirect lighting.

In addition to this, though, the tutorial also extensively covers the various light settings available in Unity. You’ll, of course, learn many of the foundations you’ll need for any setup, including settings for the global illumination. However, you’ll also dive into other concepts like baked vs realtime lighting, mixing lighting, and how these concepts can affect your final game’s performance.

LEARN NOW

LIGHTING in Unity

Duration: 16 minutes

For beginners who want to dive more into baked lighting, this tutorial by Brackeys will help you get started.

This tutorial is broken a up into two halves. The first half covers a lot of lighting fundamental theories on how it works. You’ll discover how global illumination plays a role in lighting, how lighting bounces around, how baking works, and so forth – all concepts needed regardless of the lighting you’re using.

The second half of the tutorial covers using the Progressive Lightmapper to light up a scene with different colored lights hitting the same object. This particular tool uses path tracing to more realistically determine how light would bounce around and how that would appear to your camera. You’ll not only learn how to use the Progressive Lightmapper, but also discover many of the settings you can adjust to get the look you want – all with near realtime updates in the editor.

LEARN NOW

3D LIGHTS and LIGHTMAPPING EXPLAINED in Unity 2021

Duration: 14 minutes

Need your baked lighting done quickly? This tutorial by Spectra is right up your alley then.

Like the tutorial above this one, this tutorial covers all the basics of setting up baked light with a lightmap. Whereas the other one focused more so on theory of how light works, this one skips over a lot of that. Instead, it takes a very practical step-by-step approach so you can focus primarily on getting your light set up and various settings that will help improve it as quickly as possible.

To add to this, the tutorial also dives a bit into the justification for lighting and its role in level design. Thus, if you are interested in some theory but as it practically applies to game development, this tutorial is definitely for you.

LEARN NOW

Mastering Unity Lighting Settings & Performance

Duration: 13 minutes

This tutorial by Game Dev Republic does exactly as the title suggests: explains settings available for Unity lighting.

Though knowing how to place and face your lighting in your scene is important, the light settings are where the real magic happens. You’ll get to explore each of these settings very thoroughly, from simply setting the range of your light to working with the lightmapping settings. With each explanation, you’ll also see realtime what each setting does visually, so you won’t have to guess as much when experimenting yourself.

As mentioned, this tutorial does explore performance as well. Using Unity’s own analytics tools, you’ll see with data-based evidence how each type of lighting changes how fast your game is, and consequently be able to make more informed choices for the future.

LEARN NOW

Basics of Lightmapping in Unity 2020.1

Duration: 14 minutes

In this tutorial by UGuruz, you’ll take your first step into lighting in the Universal Render Pipeline.

The Universal Render Pipeline (URP) is a a scripted renderer for Unity that is a bit more powerful in terms of how graphics are rendered compared to Unity’s default pipeline. Besides being able to get more realistic looking games, this pipeline also improves the quality of lighting you can get with your game.

The tutorial focuses particularly on making a scene using URP with lightmapping to create baked lighting. You’ll learn important concepts like setting up UVs correctly, parameters available (including options only available to URP), and optimizing your lighting for mobile. In addition, you’ll also explore ambient occlusion for softer shadows which is made particularly powerful by URP.

LEARN NOW

A Quick Lighting Guide for the URP Pipeline in Unity!

Duration: 9 minutes

While the tutorial above is pretty detailed about using lighting in URP, this tutorial by synty studios focuses on the nitty gritty of just getting your lighting working in that pipeline.

Using a fairly complex scene setup, this tutorial covers how to quickly add URP to your project and common settings you’ll work with to just get your scene lite. This includes concepts like setting up your skybox, or how to adjust things quickly just to make lighting suit your scene.

On top of this, this tutorial also covers a tiny bit about post-processes. Post-processes are a way to apply various filters and graphics tweaks to the final render of the game image. While we have other more in-depth tutorials on this topic further below, this tutorial will show you how to quickly work with these processes to add common effects like bloom and color tints – giving you a whole new way to change the look of your scene!

LEARN NOW

Unity HDRP Lighting Tutorial 2020.3 (Day Time)

Duration: 41 minutes

Similar to our previous entries, this tutorial by Amit Patpatia – Lighting Artist covers lighting as it pertain to another pipeline: the High Definition Render Pipeline (HDRP).

As the name of this pipeline suggests, this is Unity’s graphics rendering pipeline made specifically for high-definition, photorealistic graphics. Not only is it the most powerful of Unity’s pipelines, it vastly changes how aspects of the lighting work within the engine.

The tutorial featured here covers lighting as it works for HDRP fairly comprehensively. Like other tutorials, you’ll of course learn how to set up lights, which settings are available, how to use baked and realtime lighting, reflection & refraction, and so forth. However, this tutorial also covers HDRP specific issues related to workflow so you can make sure you’re getting the most out of this heavy duty pipeline.

LEARN NOW

2D Lights and Shadows in Unity 2019!

Duration: 8 minutes

Created by Unity itself, this tutorial dives into lighting for 2D games.

While previous tutorials have focused heavily on 3D graphics and all the great things you can do for them, you can do dynamic lighting for 2D in Unity thanks to the Universal Render Pipeline. With URP setup for your project, you can extend beyond default global lighting and add a variety of cool light and shadow effects previously not available.

The tutorial starts off by getting you set up with URP properly as is needed for 2D games specifically. You’ll then get to explore a variety of new lights offered – including spotlights, directional lights, and freeform lights. With these new lights, you’ll learn to adjust various properties to create specific lighting effects. Some of the things you’ll master include adding shadows under trees, creating sunshafts, and more, all in ways that work regardless of your specific camera view.

LEARN NOW

Octopath 2D Sprite Shadows And Lighting

Duration: 3 minutes

For advanced users out there, this short tutorial will show you how you can light games where you combine 2D and 3D game graphics.

Created by Allen Devs, this tutorial focuses on showing you how to improve your lighting and shadows to get a similar look to the game Octopath. This is primarily achieved through a few different methods. You’ll first explore the advanced topic of creating a shader with C#. While not specific to lighting itself, shaders do affect how light and shadow interact with your objects. As such, it is an important topic to learn, even if beyond the scope of this list.

After this, you’ll get to explore other fixes needed to create the proper effects, including how to adjust your shadows, how to adjust your environment’s lighting, and so forth. On top of this, you’ll also briefly work with post-processing effects until the final render is achieved – teaching you another valuable skill for other tutorials on this list!

LEARN NOW

REALISTIC LIGHTING in Unity!

Duration: 14 minutes

Have realistic graphics in need of realistic lighting? This tutorial by Sykoo has you covered then.

Assuming you’ve already covered the basics a billion times over at this point, this tutorial focuses on just quickly relating the best way to set up a realistic lighting look for your scene using, primarily, real-time lighting. You’ll cover quite a bit about which light settings work best for realism, where it’s often best to place lights, how to manipulate lights for your specific scene, and so forth.

On top of this, and similar to other tutorials, you’ll also cover the very basics of post-processing and learn those specific settings as well that will best bring about the realistic look. While not the most in-depth of tutorials here, given the popularity of realistic lighting, this is still a great one to check out even just for the sake of adding to your personal knowledge base.

LEARN NOW

Create a DAY and NIGHT Cycle in Unity

Duration: 25 minutes

With this tutorial by Zenva, you’ll create a day-night cycle with actual lighting for the sun and moon.

Whereas previous tutorials have been rather static in terms of their scenes, this tutorial will serve as the reminder that Unity is a game engine. As such, our lighting is not limited to a single spot in our level, but can be moved about via script or other similar mechanisms.

The short mini-course will show you how to create a sun and moon effect that seem to rotate around the level from horizon to horizon. This will be implemented along with an adjustable time scale so that, as time passes in your game, the lighting will mimic the cycle appropriately. On top of this, the tutorial also covers how to do things like add different gradients of color to the mix that also change with the time. In this way, you can also get that nice color match for dawn, noon, evening, and night!

LEARN NOW

Lighting And Post-Processing Low Poly Scene

Duration: 13 minutes

In this tutorial by LMHPOLY, you’ll learn the ins and outs of lighting for low-poly models.

To start this tutorial off, you’ll learn tips and tricks for setting up your lights in general. This includes things like where to place them, what settings to use, and also how to bake with lightmaps. Of course, the focus here will be specifically oriented for low poly models and how to achieve the best look for this particular art style.

The other half of this tutorial, though, takes a deep dive into post-processes. As covered earlier, post-processes are what allow you to apply “filters” to the game’s final rendered look. Unlike previous tutorials, though, this tutorial takes a more careful approach and covers a number of different settings, such as aperture, depth of field, chromatic aberration, grain, and exposure. Though you’re left free to experiment and find the look you want, the tutorial serves to demonstrate how lighting and post-processing can be companions in creating your game aesthetic.

LEARN NOW

Unity 2D lighting & post processing effects

Duration: 7 minutes

With guidance from Game Dev Republic, this tutorial covers 2D lighting, post-processing, and tips to make cool-looking scenes.

Of the tutorials on this list, this is one very “light” on the topic of adding lights to the scene itself – featuring really only a single directional light that works in realtime. However, the tutorial makes up for this by taking a much more thorough look into the world of post-processing.

Through this video, you’ll explore a lot of different settings available for post-processing. Of course, you’ll learn a few things already covered on this list, such as adding things like bloom or depth of field. However, the tutorial also covers new things, such as color grading for specific materials versus the entire scene. Altogether, you’ll learn numerous tricks for combining post-processing that works even with minimal lighting and allows you to bring out the best in your 2D graphics.

LEARN NOW

Level Design for Beginners

Duration: 1 hour

Though this tutorial talks about lighting the least, we did want to include it as a bonus resource.

Created by Zenva, this premium course covers principles of game design for creating levels. This includes concepts related to environmental storytelling, making considerations for the genre of your game, and more.

As this is a best Unity lighting tutorials list, though, there is obviously something about lighting here. In this case, you’ll learn quite a bit about how lighting works not only for the environment, but how it guides the player through your game. This includes things like subtlety hinting where players should go, and similar. Thus, if you want to also use lights to improve your levels design-wise, this course can help out in that regard!

LEARN NOW

Parting Words

As we come to a close, we hope you’ve found a tutorial you like from this best Unity lighting tutorials list. Lighting is a huge topic of study that goes beyond just how to implement it in Unity. As such, we encourage you to not only experiment with your lighting, but find out good rules of thumb for how to use it.

Remember, though, that lighting can be extremely powerful! It can take your cutscenes and levels to a new height, and make memorable experiences for your players they’ll never forget. It can also help you emphasize exactly what you’re hoping people will feel at certain parts, or even be used to simply provide player guidance in terms of the design.

Whatever you need to use lighting for, though, we wish you the best of luck in utilizing it for your game projects.

BUILD GAMES

FINAL DAYS: Unlock 250+ coding courses, guided learning paths, help from expert mentors, and more.

]]>
Best Unity Visual Scripting Tutorials – Making a Game https://gamedevacademy.org/best-unity-visual-scripting-tutorials/ Sun, 22 Jan 2023 08:06:11 +0000 https://gamedevacademy.org/?p=15377 Read more]]> Coding from scratch is hard, and frankly, just not for everyone. However, this should not stop you from making the games of your dreams!

This is where we come to the topic of visual scripting. As the name suggests, visual scripting allows you to add game functionalities visually in various ways – usually without the necessity to code at all. As such, as long as you know how to structure an algorithm, you can build just about any kind of game you might want. Many visual scripting tools also have full access to their engine’s API, so you don’t have to worry about missing out on useful engine tools either.

In this article, we’re going to take a look at some of the best visual scripting tutorials for Unity. Not only will these tutorials help you get started with visual scripting in general, but also show you how to tackle specific projects with it.

If you’re ready to start building games without code, let’s get on with it.

About Visual Scripting and Unity

Just as a brief pause for complete newbies out there, we want to talk about the topic of visual scripting itself and how it presents in Unity. This way, if you’ve never used visual scripting or Unity before, you won’t be lost.

What is Visual Scripting?

As described above, visual scripting is all about “programming” visually. In the case of Unity, this is presented in the form of draggable blocks or nodes that can be added to a canvas/graph. Each node/block has a specific functionality tied to it, such as adjusting an object’s transform, changing variable values, and so forth. By attaching this functionality to an object, you can apply those functions to the object via the block, instead of needing to code it by scratch.

Additionally, and what makes visual scripting powerful, is that you can easily connect blocks together. Say for a character “dying” you want to deduct one life from them and move them to a designated starting position from them. In this case, you’d simply take a block that is set to subtract the life score and connect it to a block that moves the character’s position. Then, you simply trigger this sequence when the character dies – no coding required at all.

Visual Scripting in Unity

When it comes to the popular engine Unity, there are two ways in which we can utilize visual scripting. Note that while accessing the visual scripting tool is different, both still can utilize the same tutorials with some minor differences. As such, you don’t need to get too hung up on which tutorial applies to you.

Unity Bolt

Bolt is a Unity-developed package you can download for any Unity project on version 2018.4.15 or later – up until version 2021.1. This asset gives you a simple graph to work with that comes with visual scripting capabilities. Until recently, this has been long-established as the primary way to use visual scripting in Unity, and is tried and tested through the years.

Unity 2021.1 and Later

Given the success of Bolt, since Unity 2021.1, Unity has packaged visual scripting with the editor by default. While there have been some minor bug fixes and improvements, it operates much the same as Bolt does. However, because it’s bundled with the editor, there’s nothing extra to download. Thus, this is slated to become the new default standard for games made in Unity now.

Make games without Code? Visual Scripting! (Unity, Bolt)

Duration: 13 minutes

For those brand new to visual scripting and interested in Bolt for older versions of Unity, this beginner’s tutorial by Code Monkey has you covered.

This tutorial first shows you how to get Bolt set up for your project – including some useful settings that may come up during this setup process. You’ll also get some tips on how to use Bolt depending on your interest in C# coding from scratch.

After that, the tutorial covers many useful basics, from adding nodes to your visual scripting canvas, to working with regular coding features such as variables. You’ll even learn how to access Unity components such as the Rigidbody component. Thus, regardless of what you want to work on next, this tutorial will at least get your foot in the door.

LEARN NOW

Unity Visual Scripting Getting Started

Duration: 6 minutes

While the above tutorial covers Bolt, this short tutorial by Dave Carrigg covers visual scripting foundations for Unity versions 2021.1 and later.

The main focus of this tutorial is showing you how to access the built-in visual scripting system that comes with your Unity installation. This includes just the set up process itself, as well as how to add nodes to your graph. You’ll of course also learn a tiny bit about how to connect the various mechanic nodes together.

Though this tutorial is probably used best in combination with the tutorial above (as Bolt isn’t dissimilar for the node process itself), it will definitely get you started with visual scripting – especially if you’re coming from an older version of Unity.

LEARN NOW

How to Make a Game with Unity 2021 Visual Scripting (Bolt)

Duration: 57 minutes

In this Bolt tutorial series by Smart Penguins – GameDev, you’ll move past just getting your visual scripting set up and actually build a functioning game.

The project focus of this series is a simple ski slope like game where the player needs to dodge obstacles as they move forward and collect coins down a predefined, straight path. Through this, you’ll learn several aspects required for almost all games. This includes applying physics, detecting input, setting up levels, managing objects, creating UIs, and more – all with visual scripting, of course.

Though the game probably won’t win you any awards, its simplicity makes it perfect for beginners. Not only do you get to learn how to use visual scripting, but also explore the game development fundamentals needed to make Unity games in general.

LEARN NOW

3D Movement Animation w/ Bolt

Duration: 20 minutes

Created by Playing games faster – Mr. Johnny Roo, this Bolt tutorial focuses exclusively on 3D player movement.

This topic comes with two specific components. Of course, the tutorial absolutely covers visual scripting. So, you will learn how to set up inputs and all around affect your player’s transform properties to simulate movement.

However, the second component of this tutorial is a focus on animation. In general, most developers want there player object’s to animate signs of their movement. For Unity, this is achieved with its Animator system, which allows you to set up animations to be played, when they should play, and how they should transition between each other. This tutorial covers not only this set up for your 3D character, but how to access your animations with a visual scripting set up. Thus, you’ll get to move past primitives and create more dynamic characters.

LEARN NOW

How To Use Bolt State Machines In Unity

Duration: 12 minutes

For those who are interested in how state machines work with visual scripting this tutorial by Dapper Dino is a fantastic resource to get a jump start on them.

State machines, for those who don’t know, are models used to control object behavior. Essentially, with a state machine, you define a particular set of states an object can be in, such as chasing the player vs. idle. With these states, you then add specific behaviors the object should exhibit, and define how those states are triggered. This is useful for everything from Unity’s Animator to enemy AI.

This tutorial covers the basics of setting a state machine up with Bolt. You’ll learn to add nodes for the states themselves, attach the behaviors to them, and even various ways you can trigger your states. This is also covered at a very practical but theoretical level, so its simple to adapt this material to whatever you need your state machine for.

LEARN NOW

Input in Unity Visual Scripting

Duration: 7 minutes

Games are nothing without input, and this tutorial by NotSlot will help you with input via the visual scripting method.

There are various ways through which we can interact with games, from touch mechanics to simple mouse clicks. As such, visual scripting offers you many different nodes for detecting these inputs. This tutorial covers a few sets of those nodes, particularly focusing on keyboard input, mouse clicks, and how you can use them to move characters and similar.

However, this tutorial also makes sure to cover Unity’s old Input Manager, which lets you define your key bindings essentially. Thus, you’ll also gain the knowledge you’ll need to personalize your input setup for your project.

LEARN NOW

Easy Way to Make 2D Games with Unity – Unity Visual Scripting

Duration: 6 minutes

If you’re more into the prospect of making 2D games, or want to have a new game for your portfolio fast, this tutorial by Smart Penguins has you covered.

The idea behind this tutorial is to strip back all the complicated mechanics you might see in other genres and focus mainly on movement, item collection, and obstacles. In the case of this tutorial, you’ll make an arcade-like space shooting game where you can move your ship around, shoot randomly spawning asteroids, and collect the coins that they drop.

While not as focused on visual scripting itself, this simplistic tutorial does serve to help you with game development fundamentals and actually using your visual scripting skills to make complete game projects.

LEARN NOW

Bolt FPS Tutorial

Duration: 36 minutes

Created by 1909Games, this short tutorial playlist will do exactly as it’s titled: show you how to make an FPS using only visual scripting.

The series featured is divided into three parts. In the first part, you’ll learn how to set up your level and player. The second part covers shooting mechanics, and the third part covers making enemies that patrol. The end result is a nifty FPS prototype that didn’t require a shred of manual C# coding.

Though there are many types of games one can learn to make with visual scripting, learning to make FPS games come with a few advantages. First, it teaches you the mechanics of first-person cameras, which come with a lot of quirks and are good to know how to make – regardless of whether you’re using visual scripting or not. Second, it also forces you to learn things such as object spawning, AI, and more – all which are aspects used throughout other genres.

LEARN NOW

Unity Visual Scripting Recommended Practices

Duration: 22 minutes

This tutorial by Gorilla Tactics is a bit unique for tutorials on this list, as this one actually expects you to also want to use C# coding.

Although first impressions may lead you to think that you can ONLY use visual scripting in your project or ONLY use C# scripting, this is false. In fact, because they are completely compatible with each other, you can mix and match visual scripting setups with other aspects you code manually. As such, even if you are a C# coder, you can take advantage some benefits visual scripting can provide.

The video focuses on this exact subject and tries to convey two things about this topic. The first, and less obvious, is the advantages and disadvantages between these two methods of “coding” your game. The second, and more implied by the title, is the best way to combine visual scripting and C# so you’re making clean code and keeping your game running effeciently.

LEARN NOW

Unity Visual Scripting Tutorials

Duration: 1 hour, 20 minutes

This playlist by munchmo is perhaps the best one for those who are looking to dive deep into visual scripting, even with some more intermediate concepts.

In the first part of this series, you’ll simply get a short introduction into the most important nodes, such as On Start, On Update, and so forth. This way, you can jump into the second part of the series understanding some of Unity’s most important triggers.

The second part of the series is where the deep dive begins. You’ll learn a variety of things, from the basics of using visual scripting itself (including subgraphs), to implementing complicated structures for singletons or coroutines. It even covers concepts related to data management. So if you’re ready for some intermediate level stuff, this tutorial will help you take that plunge.

LEARN NOW

How To Make Local Multiplayer Games W/ Unity Visual Scripting + New Input System

Duration: 39 minutes

Last but not least, this tutorial by Megahertzs will teach you how visual scripting works within the confines of Unity’s new Input System.

While there have always been ways to access input data – as was even covered in a tutorial above – Unity’s new Input System takes this to the next level. With this Input System, the idea was to create a level of abstraction between the inputs and the actions in game. In so doing, this would offer developers more freedom in how they mapped their controls – and came with the added bonus that local multiplayer games would be easier to create as well.

As the title probably clued you in, this particular tutorial focuses on the local multiplayer aspect of this Input System in particular. You’ll learn primarily how to set up moveable characters that can be accessed at the same time with different control sets – with, of course, an emphasis on visual scripting to get the job done.

LEARN NOW

Parting Words

We’ve reached the end of our list, and now you have some of the best Unity visual scripting tutorials at your fingertips. While visual scripting is often considered an easier entry point than coding, don’t think there isn’t any hard work involved. However, with visual scripting, you can focus even more so on the exact mechanics you want for your game – and worry less about pesky C# syntax.

Of course, learning how to code in Unity is always an option later – as there are just as many tutorials on that topic. Nevertheless, visual scripting is a great option for those who just aren’t interested in that part. So, find what works best for you in that regard!

Regardless of your choice, we hope you explore even more visual scripting topics, and we wish you the best of luck.

BUILD GAMES

FINAL DAYS: Unlock 250+ coding courses, guided learning paths, help from expert mentors, and more.

]]>
How to Write Program Logic & Objects with C Sharp (C#) https://gamedevacademy.org/c-sharp-tutorial/ Wed, 18 Jan 2023 05:33:13 +0000 https://gamedevacademy.org/?p=14139 Read more]]> So you want to get started making programs with C Sharp! How do you do that?

C Sharp (or C#) is a fantastic language that has robust desktop applications for software and game development. In fact, the TIOBE index frequently ranks the language in the top 5 of the most popular programming languages. As such, you can feel comfortable knowing you’re learning an in-demand language. Not only that, but C Sharp can be used for both software or games (this is even the default language for the popular Unity engine), making it an all-around a general-purpose powerhouse.

In this article, we’re going to help you expand your knowledge of C Sharp and teach you some fundamental techniques for creating actual program logic with your program data. We assume you already know common language infrastructure like how to control and manipulate data, but if not, you can check out our post on that topic. We also recommend downloading Visual Studio if you haven’t done so, since Visual Studio is the main IDE used for creating a Net project with C Sharp.

If you’re ready to learn more about C Sharp, let’s dive in!

What is C Sharp?

C Sharp, more commonly written as C#, is one of the world’s most popular programming languages available right now. Developed by Microsoft and based on the C programming language, C Sharp offers developers many features such as object oriented programming paradigms, automatic garbage collection, the ability to connect with LINQ extensions, and so forth. It is an efficient powerhouse that has been used for developing desktop applications, games (particularly games made with Unity), and even a few web applications.

As the language is developed by Microsoft itself, it also integrates well with many of Microsoft’s available web services. These web services allow you to add a variety of new and exciting features – particularly those related to machine learning and AI.

Decision Control in C#

An important part of coding is having your program make decisions. This is what enables your application to seem intelligent, controls the flow of code execution, determines which action to take, determines what to do based on user interaction such as data entered or where they clicked | tapped and so much more!

In C# there are two key Decision Control options:

  • IF Statement
  • SWITCH Statement

Hand writing down flow chart

IF Statement

The IF Statement controls the flow of an application by providing a Boolean ( bool ) condition check and a block of code to run IF the condition returns True.

How to code an IF Statement:

  • Start with the if keyword
  • Follow with a conditional check inside parens (condition-returns-boolean)
  • Open a code block with curly braces {}
  • Inside code block, place the code to run if the condition is True
  • Provide else if blocks, in the same way, to run if True and preceding conditions were False (optional)
  • Provide else block, in the same way, to run if all preceding conditions were False (optional)

Like most programming concepts this is best illustrated with a simple example. Let’s say we have a simple calculator. We perform math calculations based on whether the arithmetic operator is addition ( + ), subtraction ( ), multiplication ( * ) or division ( / ). Let’s run the code four times, changing the mathOperator value each time.

using System;

class MainClass {
  public static void Main (string[] args) 
  {    
    // IF Statement
    string mathOperator = "/";
    int num1 = 20;
    int num2 = 5;
    int calcResult;
    
    if (mathOperator == "+"){
      calcResult = num1 + num2;
    } else if (mathOperator == "-") {
      calcResult = num1 - num2;
    } else if (mathOperator == "*") {
      calcResult = num1 * num2;
    } else if (mathOperator == "/") {
      calcResult = num1 / num2;
    } else {
      calcResult = -1;
    }
    Console.WriteLine(num1 + " " + mathOperator + " " + num2 + " = " + calcResult);
  }
}

In the Console we get the following results:

Result for addition ( + ) is       20 + 5 = 25
Result for subtraction ( - ) is    20 - 5 = 15
Result for multiplication ( * ) is 20 * 5 = 100
Result for division ( / ) is       20 / 5 = 4

The first time a condition returns True, its associated code block runs and the IF Statement is exited without running any additional code inside. If no conditions return True, then the optional else code block runs; if available.

IF Statement – Multiple Conditions

C# can check more than one condition at a time. These multiple condition checks ( AND &&, OR || ) are very useful in IF-based Decision Control.

  • For AND ( && ) both conditions must be True for the result to be True. If the first comparison returns False the second condition is not checked and False is returned. If the first condition returns True then the second condition is checked and its value determines the result.
  • For OR ( || ) either condition can be True for the result to be True. Only if both conditions are False will False be the result.

For example, since we know Divide-By-Zero will throw an error, we can add an additional check if the mathOperator == “/”. Notice that when we set num2 to equal 0 the second part of the / condition fails and therefore the condition returns False and the calculation is not performed. With all previous conditions returning False, the code inside the else block is run, setting the final calculation result.

using System;

class MainClass {
  public static void Main (string[] args) 
  {    
    // IF Statement - Multiple Conditions
    string mathOperator = "/";
    int num1 = 20;
    int num2 = 0;
    int calcResult;
    
    if (mathOperator == "+"){
      calcResult = num1 + num2;
    } else if (mathOperator == "-") {
      calcResult = num1 - num2;
    } else if (mathOperator == "*") {
      calcResult = num1 * num2;
    } else if (mathOperator == "/" && num2 != 0) {
      calcResult = num1 / num2;
    } else {
      calcResult = -1;
    }
    Console.WriteLine(num1 + " " + mathOperator + " " + num2 + " = " + calcResult);
  }
}

In the Console we get the following results:

Result for addition ( + ) is       20 + 0 = 20
Result for subtraction ( - ) is    20 - 0 = 20
Result for multiplication ( * ) is 20 * 0 = 0
Result for division ( / ) is       20 / 0 = -1

The first time a condition returns True, its associated code block runs and the IF Statement is exited without running any additional code inside. If no conditions return True, then the optional else code block runs; if available.

SWITCH Statement

SWITCH Statements are a great way to have very clean code when you have a single variable that could have multiple values and you need to take different actions based on its value.

You may find that a switch is easier than coding many else if statements. While it takes up the same space and provides the same result the switch statement generally makes your code cleaner and easier to understand.

Let’s use the same simple calculator example we used to demonstrate IF Statements and convert the code to use a switch block instead. We can even place an if inside a switch case to cover the Divide-By-Zero issue we mentioned above when discussing IF Statements – Multiple Conditions.

// SWITCH Statement
string mathOperator = "/";
int num1 = 20;
int num2 = 4;
int calcResult = -9999;

switch (mathOperator) {
  case "+":
    calcResult = num1 + num2;
    break;
  case "-":
    calcResult = num1 - num2;
    break;
  case "*":
    calcResult = num1 * num2;
    break;
  case "/":
    calcResult = (num2 != 0) ? num1 / num2 : -1;
    break;
  default:
    Console.WriteLine("Please use one of the following four operators: +, -, *, /");
    break;
}

Console.WriteLine(num1 + " " + mathOperator + " " + num2 + " = " + calcResult);

The first time a condition returns True, its associated code block runs and the switch block is exited by the break; statement without running any additional code inside. If no conditions return True, then the optional default code block runs; if available.

In the Console, we get the following results (notice that we get the same output we get when using an IF Statement):

Result for addition ( + ) is       20 + 5 = 25
Result for subtraction ( - ) is    20 - 5 = 15
Result for multiplication ( * ) is 20 * 5 = 100
Result for division ( / ) is       20 / 5 = 4

Icon with recycling image

Loops in C#

Loops allow us to repeat a block of code as long as a certain condition is met. For example, if we wanted to print the numbers 1 through 10 and didn’t know about loops we might do something like this:

Console.WriteLine("1");
Console.WriteLine("2");
Console.WriteLine("3");
Console.WriteLine("10");

This does not make our code clean or DRY (don’t repeat yourself) so violates coding best practices and will become very tiresome – imagine if you want to print all the numbers between 1 and a 1000 or 10,000 or more!

To solve this in C# we have two primary loops:

  • WHILE Loop
  • FOR Loop

We also discuss a very common combination in programming which is using Loops and Arrays together.

WHILE Loops

The first type of loop we’ll look at is the WHILE Loop. This loop is great when we want to repeat code for as long as a certain condition is met. You will often use this in games by creating a game loop!

This loop syntax is the simplest and looks very similar to an IF-statement; we just use the keyword WHILE instead of IF; then we have the parens (condition) that hold the condition and curly braces {loop-code} that contains the code.

What happens inside the curly braces is very different though. The IF Statement runs a block of code IF the condition is True. The WHILE Loop runs a block of code UNTIL the condition is False.

The syntax of a WHILE Loop is: WHILE (condition-returning-boolean){code to repeat}. For example:

// WHILE LOOP
int i =0;
while (i == 0) {
  i++;
  Console.WriteLine(i);
}

Before the loop runs at all, it checks to see if the condition is true, the loop then continues until the loop condition is false. In this example:

  1. Condition i == 0 is true since it is set in the line above the loop
  2. Code runs and i is incremented by one
  3. Condition i == 0 is now false since i is now 1
  4. Loop exits

IMPORTANT NOTE: we must have a way for the loop to eventually return FALSE; otherwise we create what is known as an INFINITE-LOOP which will cause our app or website to hang and eventually crash! For example, be very careful of setting a condition like this:

// INFINITE WHILE LOOP - BAD
int i = 0;
while (i <= 0) {
  i++;
  Console.WriteLine(i);
}

In this example, the condition never becomes false so it will run forever or until your program crashes!

FOR Loops

FOR Loops are great when you want to repeat an action a set number of times such as printing the numbers 1 to 10 or iterating through all the items in an array. Instead of 10 lines of code to print numbers 1 to 10, we write one print line and run it for 10 iterations.

The FOR Loop keeps track of what iteration we are on; you’ll often see this iteration variable just called i unless there is reason to use a different name. When there are loops within loops you’ll often just see the inside loop variable called j. The name doesn’t matter.

Iteration variables almost always start at 0 (but could be started at a different number if you have a good use-case for doing so). i increases, usually by one on each iteration and we have access to its value inside our loop code.

The syntax of a FOR Loop is: FOR (initialize-loop-variable; condition-to-keep-looping; modify-loop-variable-after-each-iteration){code to repeat}. For example:

Console.WriteLine("How many numbers should we print?");
int count = Convert.ToInt32(Console.ReadLine());
for (int i =1; i<= count; i++) {
  Console.WriteLine(i);
}

This code produces the following Console output when the user enters 11 in response to the question:

How many numbers should we print?
11
1
2
3
4
5
6
7
8
9
10
11

Before the loop runs, we get the count (number of times the loop will run) from the user. In this example:

  1. Start i at one. This code runs only once – just before the loop starts.
  2. On each iteration, check i against the count value the user entered. If i is less than or equal the count then keep looping; if false then the loop ends. This check runs before each iteration.
  3. Run code inside the loop.
  4. After each iteration, increment i, before condition (step 2) is checked again.

Loops and Arrays

The most common use of a loop is with arrays. Using a FOR Loop, you can access and/or modify each element of an array in sequence.

// Arrays and Loops
int[] cards = new int[52];
for (int i=0; i<cards.Length; i++) {
  cards[i] = i+1;
  Console.WriteLine(cards[i]);
}

In this example, we create an empty array with 52 empty places to store data. Since empty places still count towards an array’s length ( cards.Length ) we can use this value in the condition of the FOR Loop. Recall that the Array length property starts with an uppercase L and is a property, not a method so has no parens () following it. We loop through each element setting its value to the current loop variable plus one (since the first Array index is always zero) and write that value to the console.

Nighttime cityscape behind computer screens showing binary

C# Methods

Every C# program has at least one method, called Main that is the entry point for every C# application and is called by .NET’s runtime (known as the common language runtime – CLR) when the program is started. So far we have written all our code inside of Main. To create methods, we must do it outside of Main (it can be above or below just not inside).

The main benefit of Methods is that they allow you to re-use code! Methods, sometimes referred to as Functions, are blocks of code that contain a series of statements that perform a task we can call over and over. They can have as many lines of code as you like but it should be limited to carrying out one particular task. This makes your code more reusable.

Methods allow us to encapsulate related code then execute that code as many times as we need to by calling the Method name. Any code put inside the curly braces {} is considered part of the Method.

using System;

class MainClass {
  public static void Main (string[] args) {
    Greeter();
  }

  static void Greeter() {
    Console.WriteLine("Hello World!!!"); // Hello World!!!
  }
}

Since only the code inside the Main method will be run when the program starts we must have a way for C# to reach our method. In this simple example, we called the method using its name followed by parens (). This is known in C# as Invoking a Method.

Once C# executes the code inside the method it returns to the line that called the method and continues with code execution as usual. For example, in some cases, this line has other work to do such as storing the returned result of the method in a variable or checking its value against another if it was called from within an if statement. If there is no return value then the next line of code below the method call is executed.

We can execute a Method as many times as we like, even though we have only written the code once. We will see this as being more powerful when we look at passing parameters to C# Methods.

Method Signature

Methods have several parts to their signature:

  • Access level (optional) such as public or private (default)
  • Return value data type or void if no value is returned
  • Method name
  • Parameters (optional)
    • enclosed by parens () – empty if no parameters
    • separated by commas , if more than one

Each signature must be unique but the name of the Method need not be. For example, in the Greeter Method below, the only difference is the parameters the method takes. Notice that we can call the method Greeter using either method signature:

using System;

class MainClass {
  public static void Main (string[] args) {
    Greeter();
    Greeter("C#");
  }

  // Greeter Method - NO PARAMETERS
  static void Greeter() {
    Console.WriteLine("Hello World!!!"); // Hello World!!!
  }

  // Greeter Method - WITH PARAMETERS
  static void Greeter(string name) {
    Console.WriteLine("Hello " + name +"!!!"); // Hello C#!!!
  }
}

C# Method Invocation

Methods are called or Invoked, based on whether they are Instance Methods or Static Methods.

Instance methods are part of Object-Oriented programming and are called on an instantiated object (more about this in the Class section). This type of method operates on the instance object and its state data.

In contrast, static methods are invoked using its name and can operate on the data passed to it via parameters but cannot directly access instance object data.

Notice that the Main method has the keyword static before it. We will create all our methods in this section the same way. While static methods may be created within a Class, it is independent of it. This will make more sense when we learn about Classes and Objected-Oriented programming in the next section.

Passing Parameters

Parameters provide power and smarts to our apps. We use parameters by including its data type followed by the name you want to give to the parameter. For example, in the code below our DogYears method accepts two parameters, name and age. You can use as many parameters as you like or none at all.

using System;

class MainClass {
  public static void Main (string[] args) {
    Console.Clear();

    DogYears("Rover", 4);
    DogYears("Spot", 2);
  }

  // MULTIPLE PARAMETERS
  static void DogYears(string name, int age) {
    int dogYears = age * 7;
    string message = "Hello "+name+"!, you are "+age+" in people years but "+dogYears+" in dog years!";

    Console.WriteLine(message);

    // Results:
    // When parameters are "Rover" and 4
    // Hello Rover!, you are 4 in people years but 28 in dog years!

    // When parameters are "Spot" and 2
    // Hello Spot!, you are 2 in people years but 14 in dog years!
  }
}

C# Method Return Statement

In C#, you can return a value from a Method. In the previous Method examples, you may have noticed that the Method Signatures included the void keyword which told C# that we were not returning anything from the Method.

If we do want to return a value we replace void with the data type of the value we want to return to the Method Caller. In this example we are returning a double so we create our Method like so:

using System;

class MainClass {
  public static void Main (string[] args) {
    Console.Clear();

    double resultAdd = AddValues(2, 5);
    Console.WriteLine(resultAdd);       // 7

    Console.WriteLine(AddValues(3,8));  // 11
  }
  // RETURN A RESULT FROM METHOD
  static double AddValues(double num1, double num2) {
    return num1 + num2;
  }
}

Notice you can call the method as many times as you like, passing in different values as parameters. The returned value can then be stored in a variable or used directly.

Let’s create a method to be called from multiple other methods. For this example, let’s check if a number is even or odd by using the C# modulus % operator.

using System;

class MainClass {
  public static void Main (string[] args) {
    Console.Clear();

    Console.WriteLine("---- Parameters - store result in variable");
    double resultAdd = AddValues(2, 5);
    Console.WriteLine(resultAdd); // 7

    Console.WriteLine("---- Parameters - use directly");
    Console.WriteLine(AddValues(3,7)); // 11

    Console.WriteLine("---- Array Parameter - add a list of numbers");

    double[] numbersToAdd1 = {1,3,5,7,9};
    double[] numbersToAdd2 = {1,3,5,7,9,1};

    Console.WriteLine(AddValues(numbersToAdd1));
    Console.WriteLine(AddValues(numbersToAdd2));
  }

  // RETURN A RESULT FROM METHOD
  static double AddValues(double num1, double num2) {
    double result = num1 + num2;
    Console.WriteLine("---- Even or Odd ----");
    // print if result is even or odd
    if (isEven(result)) {
      Console.WriteLine("Result "+result+" is even!");
    } 
    else {
      Console.WriteLine("Result "+result+" is odd!");

    }

    return result;
  }

  static double AddValues(double[] numbersToAdd) {
    
    double result = 0;

    for (int i=0; i < numbersToAdd.Length; i++) {
      result += numbersToAdd[i];
    }

    Console.WriteLine("---- Even or Odd ----");
    // print if result is even or odd
    if (isEven(result)) {
      Console.WriteLine("Result "+result+" is even!");
    } 
    else {
      Console.WriteLine("Result "+result+" is odd!");

    }

    return result;
  }

  // Create a Method to be called from multiple other methods
  static bool isEven(double num) {
    // check if even using modulus operator (%)
    return (num % 2 == 0);
  }
}

This code produces the following Console output:

---- Parameters - store result in variable
---- Even or Odd ----
Result 7 is odd!
7
---- Parameters - use directly
---- Even or Odd ----
Result 10 is even!
10
---- Array Parameter - add a list of numbers
---- Even or Odd ----
Result 25 is odd!
25
---- Even or Odd ----
Result 26 is even!
26

Banner for C Sharp Objects

C# Classes and Objects

A class allows us to bring together a named set of variables and methods to create a blueprint, model or specification that describes the attributes and functionality, in code, of an entity in the world.

Let’s say I want to represent “My Dog” in code. “My Dog is a unique instance of “A Dog. By creating a Dog class we can define a blueprint of the common characteristics and behaviours of a Dog. Then, using the class as a blueprint, we can create an Object Instance that represents “My Dog (the actual entity).

Object-Oriented C#

C# is an Object-Oriented programming language. Object-Oriented Programming (OOP) is a major subject in itself so this will just be a high-level overview of what you need to know to begin using Classes and Objects in C#. There are four pillars of OOP and we’ll touch on them in the following sections. The four pillars are:

  • Encapsulation
  • Abstraction
  • Inheritance
  • Polymorphism

We’ve already discussed ways of representing basic data types such as string for text, int and double for numbers and bool (booleans) to represent all types of true and false values and results. While these data types are foundational, they do not provide a way to model the attributes and interactions of complex entities (objects) in our real or virtual world. In C#, we can do this by defining a custom type using a class.

Class Syntax

Let’s explain class syntax by defining a Dog Class (custom type) and walking through its pieces.

class Dog {
  public string Name;
  public int Age;

  public void Bark() {
    Console.WriteLine(Name + " says Woof!!! I am "+ Age + " years old.");
  }
}

class Dog defines the class, or type, being created. Everything inside the curly braces {…} that follows the class declaration defines the attributes and actions this class represents. We can say that this simple class (Dog) has three members. Name and Age are properties that manage the data (state) to be stored by the Object Instance created from this class blueprint (for example – myDog). The other class member Bark() is a method. Methods are blocks of related code that should perform a single task and be named in a way that makes that task obvious to you and any other developers who may look at this code in the future (including future-you).

Access Modifier

Access Modifiers define where we can access the property or method of a Class. It can be private (default) or public. When private , the property or method can only be used within the class. When set to public it can be accessed outside the class.

Creating Class Instance Object

While the class is a specification or blueprint, an Instance Object is a representation of our actual dog (based on the blueprint defined by the class). We create this Instance in code outside our actual Dog Class by using the name of the class as if it were a data type, followed by the name we want to give our Object. We then set that equal to a new Object (Class Instance) using the assignment operator = followed by the new keyword and the class name followed by open and closing parens () as if we were calling a Method. Inside the Main Method, located inside the Main Class, its syntax looks as follows:

class MainClass {

  public static void Main (string[] args) {

    Dog myDog = new Dog();

  }
}

myDog is now a representation of an actual dog and we can assign a name, age and call its Bark() method as defined in the class Dog

using System;

class MainClass {

  public static void Main (string[] args) {

    Dog myDog = new Dog();
    myDog.Name = "Fido";
    myDog.Age = 5;

    Console.WriteLine("My dog's name is "+myDog.name);
    
    myDog.Bark();

  }
}

class Dog {
  public string Name;
  public int Age;

  public void Bark() {

    Console.WriteLine(Name + " says Woof!!! I am "+ Age + " years old.");

  }
}

When this code is run we get the following result in the Console:

Fido says Woof!!! I am 5 years old.

Class Constructor

The Class Constructor is a special method in C# that defines what to do when the class is created. It’s often used to set variables. To create a constructor, simply add a structure that looks very much like a Method except we do not define a Return type.

The Constructor is very easy to create and looks very much like a simple Method. As with a Method, you can use an access modifier (such as public) so it can be reached from outside the Class itself. As for a name, we must use the same name (including letter casing) as its class name. Finally, just like when creating a Method we can use parameters to allow property information to be passed in when the Class instance is created (referred to as Instantiated).

Let’s demonstrate this functionality by simply writing out a line to the Console when our Dog Class is created.

class Dog {
  public string Name;
  public int Age;

  public Dog() {
    Console.WriteLine("Creating Dog Object!");
  }

  public void Bark() {
    Console.WriteLine(Name + " says Woof!!! I am "+ Age + " years old.");
  }
}

When this code is run we get the following result in the Console:

Creating Dog Object!
My dog's name is Fido
Fido says Woof!!! I am 5 years old.

In C#, you can actually have multiple Constructors. Let’s say we want to keep our ability to create a Dog Object by passing in no parameters but we would also like the option of assigning the dog’s name and age when we create our Dog instance. We could do this by creating another Constructor for our Class. This time we create a Constructor for our Dog Class passing in two parameters: name and age. We’ll also modify our existing Constructor to take in a name (this means that when a new Dog is created, we must pass in at least a name).

class Dog {
  public string Name;
  public int Age;

  public Dog(string _name) {
    Name = _name;
  }

  public Dog(string _name, int _age) {
    Name = _name;
    Age = _age;
  }

  public void Bark() {
    Console.WriteLine(Name + " says Woof!!! I am "+ Age + " years old.");
  }
}

Notice that when we define the parameters for the Dog Class Constructor we include the data type and name of each parameter inside the parens (string _name, int _age) separated by commas in the same way we define parameters for any method. These parameter variables are private by default. One interesting convention you may see often in C# is that private properties are prefixed with an underscore ( _ ).

Now from main we can create a second Dog instance and assign its name and age in one line which makes our code much cleaner especially when we create multiple instances (more than one dog in our example).

using System;

class MainClass {

  public static void Main (string[] args) {

    Dog myDog = new Dog("Fido");
    myDog.Age = 5;
    
    Console.WriteLine("My dog's name is "+ myDog.Name);

    myDog.Bark();

    Dog myFriendsDog = new Dog("Buddy", 3);

    Console.WriteLine("My dog's name is "+ myFriendsDog.Name);

    myFriendsDog.Bark();

  }
}

When this code is run we get the following result in the Console:

My dog's name is Fido
Fido says Woof!!! I am 5 years old.
My friend's dog's name is Buddy
Buddy says Woof!!! I am 3 years old.

Class Properties

So far we’ve actually been using public class member variables and not true C# properties. So what’s the difference?

Since C# is an Object-Oriented programming language, a key principle is called Encapsulation. This essentially means that the internal state and functionality of Object (created from a Class blueprint) is hidden from the rest of our application. The only way to access or modify this state is through a public set of functions known as Getters and Setters.

In its simplest form, we really only need to make one small change to each class member variable to convert it to a property. We don’t need to make any changes to the code creating the Objects, setting properties and calling methods.

Change:

class Dog {
  public string Name;
  public int Age;

  // rest of class unchanged
}

To:

class Dog {
  public string Name {get; set;}
  public int Age {get; set;}

  // rest of class unchanged
}

When this code is run we get the same result in the Console:

My dog's name is Fido
Fido says Woof!!! I am 5 years old.
My friend's dog's name is Buddy
Buddy says Woof!!! I am 3 years old.

In this case, C# is automatically setting up a private “backing” field for each of the properties. This field is where the state data is actually stored.

The real power of Getters and Setters is in our ability to make properties read-only and in giving us an easy way to validate incoming data before storing it as state on our Object. To illustrate let’s:

  1. Modify Name to be a read-only property and modify our empty Constructor to take a string name parameter. This change now requires people to enter at least a name when creating a Dog Object.
  2. Add a rule to the Dog’s Age property that ensures the Age is zero or greater. We can modify the Getter and Setter for Age. Note, as soon as we add a body to either the Getter or Setter we must add it to both. This means we must create the private “backing” field ourselves as shown below for the property Age. To test, change age of myDog to be -1. Also, note that the value variable that appears in the Setter is magically supplied by C#.
  3. Add a read-only property DogYears with a Getter but no Setter. This allows code outside our class to use the property’s value but does not allow it to be changed. Now let’s take advantage of the fact that C# properties combine the power of Methods and the Simplicity of Variables to return from the DogYears property a calculated value.
using System;

class MainClass {

  public static void Main (string[] args) {

    Console.Clear();

    // #1 - updated code
    Dog myDog = new Dog("Fido");
    // #2 - deleted code
    // myDog.Name = "Fido"'
    // #2 - modified code
    myDog.Age = -1;
    
    Console.WriteLine("My dog's name is "+myDog.Name);

    myDog.Bark();

    Dog myFriendsDog = new Dog("Buddy", 3);

    Console.WriteLine("My friend's dog's name is "+myFriendsDog.Name);

    myFriendsDog.Bark();

    // #3 - new code
    Console.WriteLine(myFriendsDog.Name + " says Woof!!! I am "+ myFriendsDog.Age + " in human years. That is " + myFriendsDog.DogYears + " in Dog Years!");

  }
}

// --- separate from Main Class (usually in own file)
class Dog {
  public string Name {get;}
  // #2 - updated code
  private int _age;
  public int Age {
    get{
      return _age;
    }
    set {
      if (value >= 0) {
        _age = value;
      } else {
        _age = 0;
        Console.WriteLine("Age must be zero or greater!");
      }
    }
  }
  // #3 - new code
  public int DogYears {
    get {
      return _age * 7;
    }
  }

  // #1 - updated code
  public Dog(string _name) {
    Name = _name;
  }

  public Dog(string _name, int _age) {
    Name = _name;
    Age = _age;
  }

  public void Bark() {
    Console.WriteLine(Name + " says Woof!!! I am "+ Age + " years old.");
  }
}

Notice that we start the names of private variables with a lowercase letter. While not enforced by C#, this is common practice for private variables. Another common practice is to start private variable names with an underscore ( _ ) followed by a lowercase letter ( _age ). The above code yields the following results in the Console:

Age must be zero or greater!
My dog's name is Fido
Fido says Woof!!! I am 0 years old.
My friend's dog's name is Buddy
Buddy says Woof!!! I am 3 years old.
Buddy says Woof!!! I am 3 in human years. That is 21 in Dog Years!

Class Methods

Methods add functionality to Classes. Note that methods do not end with a semicolon as C# Class properties do. The Bark() method can be called after the Dog Object has been created.

class Dog {
  // existing code not shown
  
  public int DogYears {
    get {
      // updated code
      return ConvertToDogYears();
    }
  }

  // existing code not shown

  public void Bark() {
    Console.WriteLine(Name + " says Woof!!! I am "+ Age + " years old.");
  }
}

In this example, the public void Bark() method is available outside this Class ( public ), returns no value ( void ), has the name Bark and takes no parameters ().

Let’s add a second method that calculates dog years. This method private int convertToDogYears() is only available within its Class ( private ), returns an integer value ( int ), has the name convertToDogYears and takes no parameters ().

class Dog {

  // existing code not shown
 
  public int DogYears {
    get {
      // updated code
      return convertToDogYears();
    }
  }

  // existing code not shown

  // new code
  private int convertToDogYears() {
    return Age * 7;
  }
}

Notice that we start the name convertToDogYears() with a lowercase letter. While not enforced by C#, this is common practice for private methods.

Static vs. Instance

The static keyword can be applied to both Properties and Methods. It differs from the default Instance type of Property and Method in that it belongs to the Class itself and not an Object Instance of the Class. In other words, C# keeps a single copy of the variable or method at the Type level (Class), not the Object level.

This really means three important things. static Properties and Methods:

  • Are available to all Object Instances (shared)
  • Cannot access Instance Properties of a Class
  • Cannot call or be called by Instance Methods of a Class

Like most programming concepts this is best illustrated with a simple example. Continuing with the Dog Class we’ve been working with, let’s say we want to:

  1. Keep track of how many dogs our application has created. This type of information does not fit with any particular Object Instance so is a great use-case for static Properties and Methods.
  2. Refactor our convertToDogYears() Instance method to be a static method instead.

Solution:

  1. Add static NumberOfDogs property to our Dog class and increment its value each time a new Dog is created.
    • Since we want this value to be available to be read, but not updated, outside the Dog Class we use public static int NumberOfDogs {get; private set;} = 0; which gives us a public get and a private set.
    • Since the Constructor is called each time a new Dog Instance is created, this is a great location to place to code the increment logic for the static property that will represent our Dog Counter.
  2. Convert our convertToDogYears() Instance method to a static method.
    • Since this method will no longer have access to any Instance Object state, the Age value we use for the calculation will need to be passed in as a parameter.
    • Since the NumberOfDogs property resides at the Type level (Class), not the Object level, we must reference the number of dogs property in the Main Class using the Class name instead of the Object name ( Dog.NumberOfDogs ).
using System;

class Dog {
  public string Name {get;}
  private int _age;
  public int Age {
    get{
      return _age;
    }
    set {
      if (value >= 0) {
        _age = value;
      } else {
        _age = 0;
      }
    }
  }
  public int DogYears {
    get {
      // #2 - updated code
      return convertToDogYears(Age);
    }
  }
  // #1 - new code
  public static int NumberOfDogs {get; private set;} = 0;

  public Dog(string _name) {
    Name = _name;
    // #1 - new code
    NumberOfDogs++;
  }

  public Dog(string _name, int _age) {
    Name = _name;
    Age = _age;
    // #1 - new code
    NumberOfDogs++;
  }

  public void Bark() {
    Console.WriteLine(Name + " says Woof!!! I am "+ Age + " in human years. That is "+ DogYears + " in Dog Years!");
  }

  // #2 - updated code
  static private int convertToDogYears(int _age) {
    return _age * 7;
  }
}

When this code is run we get the following result in the Console:

Fido says Woof!!! I am 5 in human years. That is 35 in Dog Years!
We now have 1 dog running in the park!
Buddy says Woof!!! I am 3 in human years. That is 21 in Dog Years!
We now have 2 dogs running in the park!

Static Classes and Methods

Static classes are essentially the same as regular classes with two key differences:

  • A static class cannot be instantiated. In other words, you cannot use the new keyword to create an Object Instance of the Class.
  • All methods within a static class must be static methods.

Static classes are simply called using the class name itself. This makes a static class great for utility type containers where the methods don’t require an internal state. In other words, these methods take in a value and return a value based on the input or simply perform some type of action when called.

Several examples from C# and the .NET Framework include System.Math, System.Console and System.Convert classes which all contain many convenience methods that can be called directly. Let’s look at a simple example where we create a public static class Calculator with a static method inside. We then use our static class and its static method along with examples from the three C# static classes noted above.

In this example, we use the System.Console class to ask the user to provide a number. We then read that number (which comes in as a string ) and use the System.Convert class to convert it to type double so we can perform math calculations on it. We then take that result and pass it to the custom static double Sqrt method of our custom static class Calculator. We then use the System.Math class to calculate the square root of the passed-in number and return the result. When the Main Method receives our result it uses the System.Console class to write the answer to the Console.

using System;

class MainClass {

  public static void Main (string[] args) {

    Console.Clear();
    Console.Write("Enter number to calculate Square Root: ");
    double num = Convert.ToDouble(Console.ReadLine());
    Console.Write("Answer: ");
    Console.Write(Calculator.Sqrt(num));
  }

  // --- separate from Main Class (usually in own file)
  public static class Calculator {
      public static double Sqrt(double num) {
      return Math.Sqrt(num);
    }
  }
}

Let’s assume the user enters 81 in the console. Our program calculates the result and prints out 9 as the answer.

Enter number to calculate Square Root: 81
Answer: 9

Banner for C Sharp Object-Oriented Topics

C# Inheritance

An important concept in programming is reusability. You may hear this referred to as “keeping your code DRY” which is an acronym for “Don’t Repeat Yourself”. We’ve covered different ways of doing this already in C# such as Methods and Classes. In this section, we discuss another pillar of Object-Oriented Programming which is known as Inheritance.

We’ve talked about Classes as a place to store state (Properties) and functionality (Methods) as encapsulated models of “real world” objects. In this section, we take DRY to another level by abstracting out the state and functionality that are shared between objects (Classes in C#). A classic example is creating two classes to represent a Dog and a Cat. Since they are both animals, a “base” class could be created that holds everything dogs and cats have in common. This helps us reduce redundant code that would have been written (and maintained) in both the Dog and Cat classes. We do this by enabling both the Dog and Cat classes to “inherit” functionality from the Animal class and only add the state and functionality that is unique to them.

using System;

class MainClass {
  public static void Main (string[] args) {

    Animal[] animals = new Animal[] {
      new Animal("Furry", 2, "Animal"),
      new Dog("Rover", 4, "Dog"),
      new Cat("Garfield", 6, "Cat")
    };

    for (var i=0; i < animals.Length; i++) {
      animals[i].Walk();
      animals[i].Run();
      animals[i].Birthday();
      animals[i].Speak();
    }
  }
}

/* --- Animal Class --- (could be in separate file)
Animal is known as the "base" class
*/

public class Animal {
  public string Name {get; private set;}
  public int Age {get;private set;}
  public string BaseText {get; private set;}
  private string type;

  public Animal(string _name, int _age, string _type) {
    Name=_name;
    Age=_age;
    type=_type;
    BaseText = Name+" the "+type;
    Console.WriteLine("Animal, "+BaseText+", has been created!");
  }

  public void Birthday() {
    Age++;
    Console.WriteLine(BaseText+" is now "+Age+" years old! Happy Birthday, "+Name+"!");

  }

  public void Walk() {
    Console.WriteLine(BaseText+" is walking!");
  }

  public void Run() {
    Console.WriteLine(BaseText+" is running!");
  }

  public virtual void Speak() {
    Console.WriteLine(BaseText+" is speaking!");
  }
}

/* --- Dog Class --- (could be in separate file)
Dog is known as a "derived" class and 
inherits from its base class Animal 
using the following syntax:
*/
public class Dog: Animal {

  // Dog Constructor - notice how it calls the base class passing parameters
  public Dog(string _name, int _age, string _type):base(_name, _age, _type) {}

}

/* --- Cat Class --- (could be in separate file)
Cat is known as a "derived" class and 
inherits from its base class Animal 
using the following syntax:
*/
public class Cat: Animal {

  // Cat Constructor - notice how it calls the base class passing parameters
  public Cat(string _name, int _age, string _type):base(_name, _age, _type) {}

}

Notice that the Dog and Cat class constructors call the base class the passing parameters they received when created in the Main method. When this code runs we get the following result in the Console:

Animal, Furry the Animal, has been created!
Animal, Rover the Dog, has been created!
Animal, Garfield the Cat, has been created!
Furry the Animal is walking!
Furry the Animal is running!
Furry the Animal is now 3 years old! Happy Birthday, Furry!
Furry the Animal is speaking!
Rover the Dog is walking!
Rover the Dog is running!
Rover the Dog is now 5 years old! Happy Birthday, Rover!
Rover the Dog is speaking!
Garfield the Cat is walking!
Garfield the Cat is running!
Garfield the Cat is now 7 years old! Happy Birthday, Garfield!
Garfield the Cat is speaking!

C# Polymorphism

In this section, we discuss another pillar of Object-Oriented Programming which is known as Polymorphism. Polymorphism is a Greek word that basically means “many forms”. Like other Object-Oriented concepts, it can be a big topic in itself so we’ll just provide a simple example to illustrate why and how we might use it in C#.

Why? Polymorphism allows derived classes to have different functionality from their base class and their siblings. It provides an elegant opportunity to avoid complex IF or SWITCH Statements, especially when you have many derived classes, to achieve this different behaviour.

How? For the method that you want to be different in your derived class, two changes have to be made. The keyword virtual is added to the base class method and the keyword override is added to the derived class method.

For example, let’s say we want each animal to say something different when the speak() method is called.

using System;

class MainClass {
  public static void Main (string[] args) {

    Animal[] animals = new Animal[] {
      new Animal("Furry", 2, "Animal"),
      new Dog("Rover", 4, "Dog"),
      new Cat("Garfield", 6, "Cat")
    };

    for (var i=0; i < animals.Length; i++) {
      animals[i].Walk();
      animals[i].Run();
      animals[i].Birthday();
      animals[i].Speak();
    }

  }
}

/* --- Animal Class --- (could be in separate file)
Animal is known as the "base" class
*/
public class Animal {
  public string Name {get; private set;}
  public int Age {get;private set;}
  public string BaseText {get; private set;}
  private string type;

  public Animal(string _name, int _age, string _type) {
    Name=_name;
    Age=_age;
    type=_type;
    BaseText = Name+" the "+type;
    Console.WriteLine("Animal, "+BaseText+", has been created!");
  }

  public void Birthday() {
    Age++;
    Console.WriteLine(BaseText+" is now "+Age+" years old! Happy Birthday, "+Name+"!");

  }

  public void Walk() {
    Console.WriteLine(BaseText+" is walking!");
  }

  public void Run() {
    Console.WriteLine(BaseText+" is running!");
  }

  public virtual void Speak() {
    Console.WriteLine(BaseText+" is speaking!");
  }
}

/* --- Dog Class --- (could be in separate file)
Dog is known as a "derived" class and 
inherits from its base class Animal 
using the following syntax:
*/
public class Dog: Animal {

  // Dog Constructor - notice how it calls the base class passing parameters
  public Dog(string _name, int _age, string _type):base(_name, _age, _type) {}

  public override void Speak() {
    Console.WriteLine(BaseText+" says Woof!!!");
  }
}

/* --- Cat Class --- (could be in separate file)
Cat is known as a "derived" class and 
inherits from its base class Animal 
using the following syntax:
*/
public class Cat: Animal {

  // Cat Constructor - notice how it calls the base class passing parameters
  public Cat(string _name, int _age, string _type):base(_name, _age, _type) {}

  public override void Speak() {
    base.Speak();
    Console.WriteLine("Meow!!!");
  }
}

Notice that the Dog and Cat class speak() method implements different functionality than the base Animal class and from each other. Also notice that we can use the base keyword to also call the base class method in addition to our new code. When this code runs we get the following result in the Console:

Animal, Furry the Animal, has been created!
Animal, Rover the Dog, has been created!
Animal, Garfield the Cat, has been created!
Furry the Animal is walking!
Furry the Animal is running!
Furry the Animal is now 3 years old! Happy Birthday, Furry!
Furry the Animal is speaking!
Rover the Dog is walking!
Rover the Dog is running!
Rover the Dog is now 5 years old! Happy Birthday, Rover!
Rover the Dog says Woof!!!
Garfield the Cat is walking!
Garfield the Cat is running!
Garfield the Cat is now 7 years old! Happy Birthday, Garfield!
Garfield the Cat is speaking!
Meow!!!

C# Exception Handling

In applications, sometimes things don’t go as planned. For example, if you’re coding a C# Console Calculator and request the user enter a number, several things could go wrong:

  • The user enters a letter or symbol instead of a number
  • The user tries to divide by zero
  • etc, etc, etc.

In all these cases, C# has been handed data it cannot handle. In these cases, C# throws an exception error and your program crashes.

There are two basic ways to avoid a data error from taking your app down:

  • Proactive – prevent erroneous data from entering your code via “data validation”.
  • Reactive – instead of allowing your app to crash, be prepared to “catch” any exception that is thrown. In so doing you can handle the error any way you choose.

Let’s take the example of a calculator where we get two numbers from the user and multiple them together. What if the user enters a letter when we’re expecting a number.

The “reactive” approach is known as Exception Handling and you implement this by wrapping code that could break your app inside a Try-Catch Block. Basically, you place your code inside the “Try” portion and if the code works…great! If the code fails and an exception error is thrown by C#, the code in the “Catch” portion of the block will be executed instead of simply crashing your program.

using System;

class MainClass {
  public static void Main (string[] args) {
    try {
      Console.Write("Enter a number: ");
      double num1 = Convert.ToDouble(Console.ReadLine());

      Console.Write("Enter a number: ");
      double num2 = Convert.ToDouble(Console.ReadLine());

      Console.WriteLine(num1 / num2);

    } catch(Exception) {
      Console.WriteLine("Does Not Compute... Please Try Again!");
    }
  }
}

Let’s assume the user enters a letter in the console. Since our calculator program excepts numbers and is not designed to “divide” letters, C# throws an exception error. Since we have a Try-Catch block setup, when C# throws the error, our program catches and prints a message to the user.

Enter a number: d
Does Not Compute... Please Try Again!

Ending Words

And we’ve reached the conclusion of this C Sharp guide. Our hope with this guide is that you now better understand how to deal with programming logic when it comes to C Sharp. Whether we’re talking about conditionals, loops, functions, or objects, all of these serve to help guide our data through whatever functionality we’re trying to give our program. This applies whether we’re talking about something as simple as a calculator program, or as complex as a video game. C Sharp has been used for the creation of many amazing things, such as mobile games, multiplayer games, FPS games, animations, and more.

Nevertheless, all these are necessary steps for learning C Sharp. As one fo the most popular programming languages, it has a lot to offer you in terms of developing desktop applications. Though there are other languages out there, such as Python – another one of the most popular programming languages – C Sharp offers many unique benefits.

Of course, there is still more to learn – and the best way to learn a language is by exploring actual projects! So get out there, practice your C Sharp skills, and we can’t wait to see what you create!

BUILD GAMES

FINAL DAYS: Unlock 250+ coding courses, guided learning paths, help from expert mentors, and more.

]]>
The Definitive Guide to C# for Software and Video Games https://gamedevacademy.org/csharp-definitive-guide/ Wed, 18 Jan 2023 01:00:21 +0000 https://gamedevacademy.org/?p=13808 Read more]]> Do you want to build websites, mobile apps, or make awesome games with Unity? Then C# is the programming language for you!

The popular, powerful, and versatile Unity Game Engine utilizes C# as the programming language that powers its Scripting API – allowing you to implement game logic, trigger events, apply physics, respond to user input, check for collisions and so much more! However, C# is also a very popular language for software developers as well due to its high efficiency. Either way, knowing C# can be a big boost for your careers and hobbies alike.

This article seeks to demystify C#, get you started with some of the fundamentals, and give you a path to dive into further learning material. We’re assuming no prior programming experience here, so the information found here is suitable for complete beginners as well as developers coming from other programming languages. The intention of this guide is to cover much of the primary foundations of C# that will boost your knowledge and prepare you for more in-depth learning whether self-guided or within a school setting.

Let’s get started!

BUILD YOUR OWN GAMES

Get 250+ coding courses for

$1

AVAILABLE FOR A LIMITED TIME ONLY

About C#

Banner for About C Sharp

C# (pronounced C sharp) is one of the most popular programming languages in the world (and not to be confused with the C programming language). Developed by Microsoft more than 20 years ago, C# is built on top of the dotNET (.NET) Framework which is a free open-source, cross-platform developer platform for building different types of apps.

C# is an object-oriented, statically typed, general-purpose programming language widely used for:

  • Server-side web development using .NET
  • Desktop applications for Windows and macOS
  • Native mobile apps for iOS and Android using Xamarin
  • Microservices using Docker Containers
  • Cloud-based services
  • Machine Learning
  • Internet of Things
  • Game development for PC, Mac, Consoles, Mobile, and VR|AR with Unity

Banner for C Sharp Pros

Pros

C# is a statically-typed, object oriented programming language based on C which makes it very similar to other popular languages such as Java, C++, PHP, Swift, Objective-C and more. This means that once you learn one language, it would be very easy to understand and learn other programming languages.

Today, C# runs on .NET Core which is an open-source, cross-platform, high-performance, and scalable framework to build applications anywhere to run anywhere.

C# is a general-purpose, high-level, versatile, easy-to-learn programming language that when combined with technologies such as Xamarin for native mobile and desktop experiences and Unity for game development creates a powerful developer and execution experience.

There are a lot of great resources to help you code any app experience you want including courses, tutorials, code samples, and an active developer community.

Banner for C Sharp Cons

Cons

Most C# applications run on top of a Microsoft framework called .NET and for most of its life, this framework has been its best and worst feature. Originally .NET was a gigantic platform that Microsoft created to make it easy for developers to create powerful and complex applications. The framework allowed C# to be a relatively easy-to-learn language with low-level complex coding requirements (such as memory management) taken care of for us by the underlying framework. All of the languages that sat on top of .NET were compiled down (behind the scenes) to the same Microsoft Intermediate Language (known as MSIL). After that, .NET translated the MSIL code into a Just-in-Time language that computers could run. To make a long story short, C# was great as long as you were inside a Microsoft ecosystem.

Fast-forward to today and C# now only requires .NET Core which is an open-source, cross-platform, high-performance, and scalable framework to build applications anywhere to run anywhere. Combined with technologies such as Xamarin for native mobile and desktop experiences and Unity for game development, C# is a modern and versatile programming language and this con is largely a thing of the past.

Banner for C Sharp Getting Started

Getting Started with C#

Below you will find two options to start writing C# code quickly. The first is to set up a Desktop IDEIntegrated Development Environment (this will be important as you start to develop real apps). The second option is to learn the basics using an Online IDE (this option is great for learning since there is no setup required).

Desktop IDEIntegrated Development Environment

Writing C# code requires a code editor (often referred to as an IDEIntegrated Development Environment) and some basic setup which depends on the type of application you are creating and the associated technology you are using. For example, you may need to install the .NET framework, Xamarin for native mobile development or Unity for game development.

If needed, you can follow a video walkthrough of getting started with C# using Visual Studio Code by following the video instructions in the Learning Resources-Getting Started section below for Mac and Windows.

Online IDE – No Setup Required

For learning C# basics, you can use an in-browser IDE which requires no setup. For example:

    • Visit relpit.com
    • Press the Start creating button
    • Login/signup
    • Press New repl (this is your project)
    • Select C# as your coding language
    • Provide your repl (project) with a name (such as “Learn C#”)
  • Press the Create repl button

Steps to Create a new repl on replit.com

You are now ready to begin! Write your code in the main.cs file (on the left) and press the Run button (in the top centre) to see your output in the console (on the right).

If needed, you can follow a video walkthrough of getting started with C# on replit.com by following the video instructions in the Learning Resources-Getting Started section below.

C# Console App – Hello World

The best way to learn a new language is to keep your learning environment as simple as possible. To learn the basics, we’ll create a simple C# Console Application on replit.com using the steps outlined above in the Getting StartedOnline IDE section. While a Console App is not the most exciting app in the world, it is a great way to learn the fundamentals!

Replit.com provides the following C# file, called main.cs, to get started:

using System;

class MainClass {
  public static void Main (string[] args) {
    Console.WriteLine ("Hello World");
  }
}

To begin, ignore everything but the command Console.WriteLine(“Hello World”). Notice that this command is located inside curly braces {}. Inside these braces is where we will write all our C# code. Later in this tutorial, we cover class and the other C# syntax inside the code block. It’s perfectly fine to ignore it for now.

Press the Run button at the top of the replit.com IDE and notice “Hello World” is printed in the Console.

Image showing the Run Button and Console Output in the replit.com IDE

Note: If you’re new to C# and have opted to set up a Desktop Environment, you may notice a flash on the screen instead of seeing your expected output in a console window (sometimes referred to as a terminal). What happens, in some cases, is that your C# console app runs, prints the output to the console, then the program stops execution. Depending on your setup, this may result in the console closing automatically. You can easily prevent this by adding Console.ReadKey() on the line following your last Console.WriteLine(). This command prevents the console from closing until you press a key (any key).

C# Syntax Basics

In the “Hello World” Console example above we displayed an image of how the Console output would look on replit.com. Given the many IDE options available and the fact that we advised ignoring the class syntax and surrounding C# code, for now, the examples in the C# Fundamentals sections that follow will show only the code between the curly braces. In addition, we’ll use C# Comments to show the expected results of our simple inputs and outputs. As an example, the code above would like this instead:

    Console.WriteLine("Hello World"); // Hello World

As we begin learning the fundamentals of C#, it’s important to keep these points in mind:

  • Every C# statement must end with a semi-colon ;
  • All blocks of C# code are within curly braces {}
  • C# is case sensitive: C is not equal to c

Banner for C Sharp Comments

Comments in C#

Comments are lines in your code that are ignored by C#. They serve several purposes:

  • They are used to leave notes for people (including future-you)
  • They are useful when debugging to tell C# to ignore one or more lines of code (without having to delete the lines of code)
  • They can be helpful when planning out a piece of logic you need to code (sometimes referred to as pseudocode)

C# comments syntax has two forms:

  • Use // for a single line comment (everything after on the same line is ignored by C#)
  • Use /* */ for a block comment (everything in between is ignored by C#)
// Comments in C#
// This is a comment
Console.WriteLine("Hello World"); // this is a comment
/*
This is a
block of 
comments.
These lines are
ignored by C#
Console.WriteLine("This line is not executed");
*/

Variables in C#

Variables are an essential element of any programming language. They provide a place to store data we may need to reference or update later. In C# each variable has a data type and a name. We store values in variables using the assignment operator.

Assignment Operator

In C# the assignment operator is the equal sign =. In its most basic form, this operator takes the value from the right side of the = and stores it in the variable on the left.

// Assignment Operator 
int b = 10; 
Console.WriteLine(b); // 10

Data Types

The data type tells C# what kind of data will be stored in the variable. The four basic data types are:

  • int (+/- integer)
  • double (+/- number containing decimals)
  • string (any character inside quotes)
  • bool (True or False)

The name, or identifier, allows us to refer to that specific variable anywhere in our code. When naming a variable, we can use any combination of letters, numbers, underscore or dollar sign with the following exceptions:

  • Names cannot be a C# keyword
  • Names cannot have whitespace
  • Names cannot start with a number

Let’s create variables to store each data type and print each variable’s value to the Console. We can declare a variable and assign a value at the same time or declare a variable and assign it a value later.

    int score = 5;
    double gravity = 9.81;
    string language;
    bool isLearningFun;

    language = "C#";
    isLearningFun = true;
    
    Console.WriteLine (score);          // 5
    Console.WriteLine (gravity);        // 9.81
    Console.WriteLine (language);       // C#
    Console.WriteLine (isLearningFun);  // True

There are three parts to creating a variable and assigning it a value, whether done together or separately. They are the data type (int), the name (score) and the value (5). Notice, we use the equal sign = to assign a value to a variable of any type.

Image showing a lot of numbers

Numbers in C#

C# has two basic number types:

  • int (+/- integer)
  • double (+/- number containing decimals)

These types are distinguished based on whether or not they can contain decimals.

Math Operators

Math in C# works the same as it does in the real world. The most common math actions have the following arithmetic operators:

  • +  addition
  •   subtraction
  • *  multiplication
  • /  division
    Console.WriteLine (2 + 5);  // 7
    Console.WriteLine (10 - 2); // 8
    Console.WriteLine (3 * 3);  // 9
    Console.WriteLine (20 / 2); // 10

Unary Operators

Another concept is known as Unary operators and they are very useful when writing code because they allow us to perform the common calculation of incrementing or decrementing by one in a much more code compact way.

// Unary Operator 
int a = 10; 
Console.WriteLine(a);   // 10
a = a + 1;
Console.WriteLine(a);   // 11
a--;
Console.WriteLine(a);   // 10
a++;
Console.WriteLine(a);   // 11

Math and Assignment Together

We can also use the assignment operator together with the arithmetic operators in a single command that modifies a variable’s value (by the value on the right) before storing it. This differs from the Unary operator which only increments/decrements by one.

// Assignment and Arithmetic Operators Together
int c = 1;
c += 10; 
Console.WriteLine(c); // 11

c -= 5;
Console.WriteLine(c); // 6

c *= 4;
Console.WriteLine(c); // 24

c /= 6;
Console.WriteLine(c); // 4

It’s important to note three rules regarding modifying and assigning a variable’s value:

  • Variables cannot be declared and modified at the same time
  • Variables cannot be modified without including the assignment operator =
  • The arithmetic operator must come before the assignment operator +=

Order of Operations

Math in C# follows the same rules as regular math.

  1. Parenthesis first (3 + 2 )* 5 – 4
  2. Then multiplication and division (from left to right)
  3. Then addition and subtraction (from left to right)
// Order of Operations
int ooo = (3 + 2 )* 5 - 4;
Console.WriteLine (ooo); // 21

Banner for C Sharp Strings

Strings in C#

Required Syntax

To assign text to a variable we use double quotes “…”. Anything inside the quotation marks is considered text. This includes numbers and symbols as well as uppercase/lowercase letters. In its most basic form it looks like this:

string userName = "aBc_123";

It’s important to note that we must use double quotation marks ( “…” ) – anything else will cause an error.

Escape Characters

Having to use double quotes presents an issue if you want to use double quotes within your text string such as using a quote or dialogue. For example:

// Escape Characters
string dialogue = "When the player scored, his teammates shouted "We Win!"";

Console.WriteLine(dialogue);

If you run this code, the C# compiler generates an error. This is because the quotation marks close and open the string around “When the player scored, his teammates shouted “ and an empty string at the end “” leaving We Win! not within any quotes. C# does not know what to do with these characters so it throws an error.

To fix this we have to use something called escape characters. To do this we place the backslash \ symbol before the quotation marks \” we want to keep as part of the text string. The corrected code looks like this:

// Escape Characters
string dialogue = "When the player scored, his teammates shouted \"We Win!\"";

Console.WriteLine(dialogue); // When the player scored, his teammates shouted "We Win!"

String Methods

In C#, there are many operations we can perform on strings. These operations are known as string methods. C# has more than 40 string methods including operations to compare strings, find strings within strings, combine strings, format values, and more. Some methods are called on string variables while others are called against the C# String Class itself.

String Variable Methods

Some methods are called on a string variable such as ToUpper() and ToLower(). Using these methods we can:

  • Display a value as upper or lowercase without changing its value
  • Change the variable’s value using the assignment = operator
// Variable Methods
string caseExample = "Case!";
Console.WriteLine(caseExample);             // Case!

// Display Only - Value Not Changed
Console.WriteLine(caseExample.ToUpper());   // CASE!
Console.WriteLine(caseExample.ToLower());   // case!
Console.WriteLine(caseExample);             // Case!

// Value Changed
caseExample = caseExample.ToUpper();
Console.WriteLine(caseExample);             // CASE!
caseExample = caseExample.ToLower();
Console.WriteLine(caseExample);             // case!

String Class Methods

Some methods are called on the C# String Class such as String.Concat()

Strings can be combined in multiple ways including:

  • + sign
  • String.Concat() method

When combining strings:

  • You can use any combination of variables and string literals ( “…” )
  • You can use any combination of letters, numbers, and symbols (it all becomes text)
  • Combining strings does not automatically add space (but you can add it yourself)
// Class Methods
string hello = "Hello";
string world = "World";
int num = 1;

string HelloWorld;
// Join strings together with + sign
HelloWorld = hello+world+num+"!";
Console.WriteLine(HelloWorld);        // HelloWorld1!
HelloWorld = hello+" "+world+num+"!";
Console.WriteLine(HelloWorld);        // Hello World1!

// Join strings together with String Method Concat
HelloWorld = String.Concat(hello,world,num,"!");
Console.WriteLine(HelloWorld);        // HelloWorld1!
HelloWorld = String.Concat(hello," ",world,num,"!");
Console.WriteLine(HelloWorld);        // Hello World1!

String Length

If you need to know the length of a string, C# has a string property called Length.

// String Length
string helloWorld = "Hello World!";

int len = helloWorld.Length;

Console.WriteLine(len);  // 12

Notice that the length includes spaces. Also, note that Length is a property and therefore has no parens () after it like string methods do.

Various technology objects overlayed with binary

Booleans in C#

Boolean ( bool ) is the simplest data type because it can only have one of two values: True or False.

// Boolean Data Type
bool isLearningFun = true;

Console.WriteLine(isLearningFun); // True

This idea of true|false, yes|no, correct|not-correct, equal|not-equal, on|off, 0|1 and so on is really the essence of how computers work. That makes this simple data type very important in coding. Understanding what conditions return True or False will be very important when you learn C# Decision Control.

As is usually the case with programming, syntax is very important. Note that the exclamation point ! comes before the equal sign = to create !=. Coding these operators and those in the upcoming sections in reverse will throw an error. For now, let’s consider some of the situations that return a Boolean result.

Equality Operators

The equality operators check if two numbers are equal or not equal.

bool boolean1 = 2 == 2; // True
bool boolean2 = 1 == 4; // False

Notice that == is a comparison operator and different from the single equals = which is the assignment operator. In this case, the condition is evaluated and then the result is assigned to the bool variable on the left.

To check directly for inequality we use the exclamation point ! in front of the equal sign != as follows:

bool boolean1 = 2 != 2; // False
bool boolean2 = 1 != 4; // True

Notice that we get the exact opposite results as above.

Relational Operators

Relational operators are used for comparing two numbers beyond simple equality. These operators are:

  • > greater than
  • < less than
  • >= greater than or equal to
  • <= less than or equal to
bool booleanValue1 = 1 > 4;   // False
bool booleanValue2 = 2 < 3;   // True
bool booleanValue3 = 3 >= 2;  // True
bool booleanValue4 = 4 <= 1;  // False

Multiple Conditions

In C#, we have two ways to check more than one condition at a time. They are:

  • AND ( && )
  • OR ( || )
bool isTrue1 = 3 == 3 && 4 == 4;  // True
bool isTrue2 = 3 >= 3 && 4 >= 4;  // True
bool isTrue3 = 3 >= 3 && 4 < 4;   // False
bool isTrue4 = 3 > 3 || 4 == 4;   // True
bool isTrue5 = 3 > 3 || 4 > 4;    // False

For AND ( && ) both conditions must be True in order for the result to be True. If the first comparison returns False, the second condition is not checked and False is returned. If the first condition returns True then the second condition is checked and its result determines what is assigned to the variable on left.

For OR ( || ) either condition can be True in order for the result to be True. Only if both conditions are False, will False be assigned to the variable on left.

Banner for C Sharp Arrays

Arrays in C#

So far we’ve had a one-to-one match between variables and values. But what if you wanted to store a list of items such as your to-do list, your favourite movies or a player’s inventory of weapons in a game? You could store each item inside its own variable but that could get out of hand very quickly and would not be very flexible. It would great if we could store those lists of related items in a single variable! This is a great use-case for Arrays. Arrays allow you to store multiple values in a single variable.

Array Syntax

The syntax for an array starts with the type of data we want to store in the array followed by square brackets. If we want to store a list with a data type of string then we would code string[]. This tells C# we want to store an array instead of a single string value. We next code the name of the variable and the assignment operator ( = ) as we have done for other variables. Our actual list is stored within curly braces {} with each item separated by a comma. For example, a list of colour names (string data type) would be coded like this:

// Arrays in C#
string[] favColours = {"red", "green", "blue", "purple", "orange"};

It’s important to know that all items in an array must be the same data type.

Declaring Arrays

If we know the exact items we want to store in the array we can construct it as above. However, we can also construct dynamic arrays and this feature is what makes arrays powerful.

If we know the number of items our array will hold, we just don’t know the values, then we can declare it like this:

string[] items = new string[5];

This creates an empty array sized to hold five items. We put the length of the array inside the square brackets [5]. It’s important to know that this size cannot be changed later so we may want to create longer arrays depending on what we plan to store.

// Arrays
int[] cards = new int[52];
double[] prices = new double[100];
string[] names = new string[150];

Referencing Array Items

You can think of an array like a table where the first column is the array’s index. The index is the position of an item within the array. It’s important to note that the first item always has an index of zero. We reference array items by using the name of the array followed by the item index inside square brackets. For example:

// Referencing Array Items
string[] favColours = {"red", "green", "blue", "purple", "orange"};

Console.WriteLine(favColours[0]);   // red
Console.WriteLine(favColours[2]);   // blue
Console.WriteLine(favColours[4]);   // orange

We can also store a selected item in another variable such as:

// Storing an Array Item
string[] favColours = {"red", "green", "blue", "purple", "orange"};

string selectedColour = favColours[2];
Console.WriteLine(selectedColour);  // green

Array Length

It’s very common to need to know the length of an array. We find the length using the Array’s Length property.

string[] favColours = {"red", "green", "blue", "purple", "orange"};

// Array Length
Console.WriteLine(favColours.Length); // 5

It’s important to know that empty spaces count towards the array’s length.

// Empty Array
int[] cards = new int[52];
// Array Length
Console.WriteLine(cards.Length);    // 52

Learning Resources

We’ve helped you through a lot of basics – from variables to operators, and all the way to arrays. These materials will help with storing and controlling your data in a lot of ways. However, there is a ton more to learn (like multidimensional arrays, which we didn’t have remote time to cover)! If you want, you can dive to our companion post here, which helps cover a lot more fundamentals for C# programming logic. Or, you can dive into one of the links below and get started with a more in-depth look at C#!

Ending Words

As with any programming language, there is a seemingly endless amount you could learn. After all, we haven’t even touched on object oriented programming here.

While we’ve given you the resources above, remember the best way to truly learn more is by writing C# code in your own apps or games. However, with this guide, we hope you’ve absorbed key fundamentals that will help you dive into further C# topics! You can only benefit by learning C#, so we hope you’ll continue whether you want to create robust software for your career or make entertaining games as a hobby.

Enjoy the journey! Happy Coding!

BUILD GAMES

FINAL DAYS: Unlock 250+ coding courses, guided learning paths, help from expert mentors, and more.

]]>
What is Unity? – A Guide for One of the Top Game Engines https://gamedevacademy.org/what-is-unity/ Fri, 13 Jan 2023 09:08:24 +0000 https://gamedevacademy.org/?p=13601 Read more]]> If you’re an aspiring game developer, picking the right game engine to use for your game projects can be a bit tough. After all, what game engine you pick will ultimately affect the entire development process of your game. So, it’s not a decision to make lightly.

Assuming you’ve done any amount of research, though, you’ll have heard a ton of recommendations for Unity. Unity is definitely one of the most popular game engines being used today – particularly in the indie game development spheres. That being said, because of its popularity, these recommendations don’t always go into what Unity is, let alone why you should use it besides the fact “it’s great”.

Well today, we’re here to remedy that. We’re going to talk about not only “what is Unity” and what Unity offers you in terms of game development, but also why you would want to create games with Unity!

What is Unity?

Unity is a 2D & 3D game engine that has been around since 2005. Developed by Unity Technologies, it was made in order to provide more developers access to game development tools, which in those days was a novel venture. Over the course of its long life, the engine has changed and expanded dramatically, managing to keep up with the latest practices and technologies.

Even today, the game engine’s main focus is to both provide the most robust set of tools possible for the game development industry, as well as make it as easy as possible for game developers of any skill level to use the engine (yes, including beginner developers). They’ve also expanded their reach into other industries as well with a huge focus on real-time 3D development, making it one of the most powerful engines available.

Unity game engine logo

Key Features

Let’s talk about key features that the engine offers so you can decide if you want to download Unity.

3D and 2D Graphics Support

As mentioned at the beginning, Unity provides support for both 3D and 2D graphics – allowing you the freedom to choose the art style you want for your projects. Each graphic type comes with its own specialized set tools (such as sprite sheet cutting for 2D graphics) and even has its own script APIs to call upon for different physics options that are suited for each style.

3D graphics also offer an extremely robust set of tools as well with the ability to create custom materials, build shaders with the Shader Graph, customize lighting, utilize post-processing effects, and more. You can even generate 3D terrain or create 2D tilemaps right in the engine, so there are a well-rounded set of tools to use for whatever graphics you’re using.

Easy-to-Understand Architecture

Unity offers a very transparent method for composing your game architecture. Each “level” in a Unity game project is divided into a Scene, and each scene contains all the game objects needed for the player to use the level – whether that’s the background, player character, enemy, bullet, or something else.

Unity also offers the ability to have a parent-child relationship between objects in the Hierarchy, making it very easy to add multiple objects (like an outfit, gun, or collider for collision detection) to one parent player character object. Beyond this, Unity also features the Inspector tool which gives you quick access to all your object’s properties, meaning you can change things on the fly quickly without needing to dive into the code all the time.

Action RPG example project from Unity with character running towards enemy

Unity Scripting API

Rather than going in blind, Unity comes with a powerful scripting API that offers you quick access to the most commonly needed features. This includes both general game features, as well as specific API calls that allow you to access specific features and nuances for the engine.

For example, while you can adjust UI elements from the engine itself, such as text color, the Scripting API also exposes those elements so you can adjust them via code as well. This goes for everything that can be accessed from the Unity Inspector, including position, rotation, materials, audio playback, and more beyond name. Plus, there is a lot of documentation to help you out.

Cross-platform Build Support

Unity games support building to an immense number of platforms. As long as the developer downloads the appropriate kit, you can export games for Android, iOS, Windows, MacOS, Linux, PS4, Xbox One, and more. You can even export HTML5 games if you want to put your game on the web (assuming performance is optimal).

The engine also makes it so you have to make as few tweaks as possible for the various builds, limiting the need to have multiple versions of your project for each platform.

Demonstration of the Unity Device Simulator

Virtual Reality & Augmented Reality Capabilities

When it comes to VR and AR, which are newer technologies, Unity is one of the key supporters for developing with them. For VR, there are numerous packages available that support almost all VR headsets available, and they are constantly updated and kept flexible with this changing technology. You can even test your VR games in the engine.

AR is not to be left behind though, with numerous packages for ARCore and ARKit. Unity also offers AR Foundation, which Unity built to allow Unity developers to create AR apps for Android and iOS at the same time, eliminating the need for separate projects.

To boot, Unity also now has the XR Interaction Toolkit to make developing VR and AR games even easier. So, suffice it to say, Unity is one of the biggest supporters of XR technologies.

Large Asset Store

Whether you’re in need of graphical assets, specific game genre templates, audio, particle effects, or something else, Unity has got you covered. Its immensely large asset store comes with a variety of paid and free assets you can use for any game project.

While Unity does develop some of these, many of them are also made by the community, meaning you have a huge variety to choose from. Plus, Unity makes it very easy to add assets to your collection and install them into your project with the package manager, meaning no fussing with files manually.

Example of an AR block builder game made with Unity

Unity Developed Packages

In the same vein as above, Unity itself offers a ton of in-house developed packages and assets for free that extend the functionality of the engine in useful ways. For example, the Bolt asset offers a way to implement visual scripting into the Unity engine.

Meanwhile, Unity Playground offers a 2D game framework that allows you to learn game development without the need to code from scratch. Everything from free models to various game kits are offered by Unity for free, giving you quick access to Unity-approved assets to practice with.

Rendering Pipeline Options

Rendering graphics to the screen is no easy feat for a computer, and how it accomplishes this can have some significant effects on your games’ performance. This is why Unity has offered several built-in options for the render pipelines you can use to get your game from scene to play screen. This allows developers to choose the render pipeline that best suits their projects and the graphical needs of those projects.

Additionally, Unity also offers the Scriptable Render Pipeline API, which lets developers make their own pipeline if they feel up to it. Thus, there is a lot of freedom in terms of how the game gets rendered for your players!

Screenshot of the Unity Asset store showing Unity developed assets

Animation Tools

Unity offers a robust set of animation tools that work for both 3D and 2D graphics. While you absolutely can import animations from another program, such as Blender, Unity offers you the ability to animate your projects right within the engine itself. This includes adjusting the position and rotation of an entire object, to actually physically manipulating the bones in a 3D model. Unity even offers you the ability to add bone rigging to 2D images.

All these features can, of course, be accessed from the Scripting API as well, giving you unparalleled control of how your animations work.

In addition, its Animator system allows you to easily create an animation state machine. This means you can not only play animations based on what the player is doing (such as jumping), but transition between each animation appropriately and smoothly. Plus, as the Animator is presented in a more visual graph style, it’s easy to understand how everything connects.

Adaptability to Other Industries

While Unity is a game engine first and foremost, and the part we’re focusing on, it is worth noting Unity has also gone out of its way to add features and supplements to make the engine useful to other industries.

For example, because of its pipeline options and animation tools, Unity is actually capable of being used for high-fidelity CG films, which many indie filmmakers have taken advantage of. In another vein, Unity has also created things like Unity Reflect to provide building developers a way to visualize their projects and connect them with other CAD software.

There are many more examples, but Unity is easily able to extend far beyond what it was made for and provide generalized, real-time 3D support.

Analytics Tools

As you gain more skills as a game developer, it becomes more imperative to have a variety of analytics tools at your disposal. Unity offers several to help out, including tools to track performance issues and tools to simply observe how players are interacting with your game project.

Additionally, Unity also offers a number of ways to enhance debugging with these tools, providing a robust way to understand every aspect of your game.

AR crane job training app made with Unity

What Can Be Made with Unity

Basically, the only thing limiting what you can make in Unity is performance and your own imagination. Do you want to make RPGs, survival games, and platformers? Unity can do that. Do you want to make an animated short film? Unity can do that. Do you want to make the next VR hit to help schools with providing kids new ways to learn? Unity can do that.

This is one of those times where the sky is really the limit, as there are just endless opportunities and tools that have made Unity a popular engine for every industry. In fact, there are a ton of popular games you probably don’t realize were made with the engine. These include:

… and many more! In fact, we encourage you to read up on Unity’s own case studies! You can also view some of the showcases below to get a feel of the true power of Unity.

Why Choose Unity

Since there are many engines available, you might wonder why you should choose Unity. In this quick list, we’ll go into the main reasons why Unity is a fantastic engine to use for your game development needs.

For most beginning developers, it’s free.

Are you earning more than $100K on your Unity-made projects? No? Well, then Unity is absolutely free to use. You can even sell the games you make with Unity using the free version. It’s only when you hit that $100K threshold that you have to start worrying about expensive licenses. To start out though, you don’t need to worry about these extra costs and can focus on the game development process itself.

It is beginner-friendly.

While there is a slight learning curve in understanding the Unity UI, past that using Unity is a breeze. As mentioned above, the architecture of Unity is very easy to understand, and adding objects is as simple as right-clicking in the correct spot. Plus, with the Unity Inspector, most properties are readily exposed and can be adjusted from the engine itself – no coding from scratch needed if you don’t want to.

In addition, Unity does offer kits and frameworks to take out even more of the grunt work if you aren’t ready to learn C#, so being beginner-friendly is a specialty of the engine.

Screenshot of the Unity engine with a 3D platformer game open

It is simultaneously powerful and versatile.

There is no question with the features above that Unity is capable of just about anything. With its high-quality pipelines, you can render even the most intense of graphical projects. At the same time, though, Unity offers one of the most robust set of tools – from animation to its Shader Graph – that basically supports any kind of game or project you want to make. As such, if you only have a vague idea of what you’ll be doing with your project, Unity can suit just about anything.

Because of its popularity, there is a huge community.

This “why” is pretty self-explanatory. We aren’t kidding when we say that Unity is one of the most popular engines. As such, there are numerous discussion areas about Unity where you can talk shop with other developers, whether that be on Unity’s own forums or on a dedicated subreddit. With a larger community, this means you have more opportunities to network and get help with any kind of coding hiccups you might experience while developing.

For things like VR & AR, there are few better choices.

While there are a few engines that support VR & AR, like Unreal Engine, few do as well as Unity. Unity actively supports these technologies in every way it possibly can and has been on board with them since almost the beginning of their rise. While there are certainly improvements that could be made in how Unity implements these aspects, the sheer amount of support and integration with the engine make it just the best choice if you’re interested in developing projects for these technologies.

Example of a VR kitchen scene made with Unity

Many programs consider export or development for Unity.

Given that Unity is so popular, a lot of programs actually consider how their own assets might be imported into Unity. This might include something as simple as making sure file formats used are applicable in Unity. However, some companies partner with Unity to certain degrees and develop tools specifically for integration with Unity, such as the case with Unity Reflect.

Even further, other companies actually develop SDKs specifically for Unity so that developers have easy access the technologies they create. As such, just in terms of compatibility with other programs, Unity is one of the kings.

Unity is actively and caringly developed and updated.

While some engines and frameworks fall out of style and lose both developer and community support, not Unity. Unity is painstakingly updated constantly by Unity Technologies, whether that means packages natively used with Unity or the engine itself. Every year there is a new major version of Unity created with new and exciting features not seen before in the engine. Thus, game development with the engine only gets easier and easier as more and more features and tools are created to aid developers.

The asset store is a huge help.

If you’re not an artist, getting game assets can be a pain. Especially if you’re most interested in programming or are eager to prototype your game idea, it’s generally not something you want to deal with. Thus, having such a huge asset store available is heaven-sent. It allows you to get assets quickly and implement them into your project with just a few clicks. This means you can focus on what matters to you and just make sure the game is fun first and foremost – even if you want to replace the assets later with different ones.

3D environment made in Blender being prepared for Unity import

There are a lot of learning resources.

Similar to the large community aspect, Unity just flat out has a lot of learning resources available. Whether you want to make something as easy as a platformer or something as complicated as a multiplayer battle royale with procedurally generated levels, there are endless tutorials out there to help you. With this variety of tutorials, this also means you can usually find something that suits your own learning style. So, no worries about having only one resource that you find boring – you can always find another out there to learn from.

It is one of the best engines for mobile development currently.

Just as Unity supports VR and AR actively, it also puts a lot of emphasis on being compatible with mobile devices. Not only is its Scripting API friendly in most cases for mobile development, but it offers tons of tools to support mobile development.

For example, with the newer Unity Device Simulator, you can test out how the game appears on different devices – including planning where different phones have their bevel or camera. This is not to mention that building for mobile in Unity is as simple as just including the right SDK, so you don’t have to worry a whole lot about making separate projects for your games.

Road crossing game shown in the Unity Device Simulator

How to Learn Unity

So, maybe after all is said and done, you’re now ready to download Unity and make games with it! However, you obviously need to learn it first before going wild here. In the list below, you can find a collection of recommendations to get you going with your Unity projects.

Inventory screen created for a Unity survival game

Conclusion

Hopefully, we’ve covered Unity comprehensively enough for you to understand what it is. Love it or hate it, Unity is still one of the most popular engines, and for good reason. It offers a ton of features and benefits whether you’re building games or need real-time 3D graphics for some other industry. Thus, rest assured learning to use Unity is a great option for aspiring game developers out there.

Regardless, you should be better equipped to make your own decisions regarding Unity now. That being said, if it is the engine for you, we hope you download Unity soon and look forward to your future projects!

BUILD GAMES

FINAL DAYS: Unlock 250+ coding courses, guided learning paths, help from expert mentors, and more.

]]>
How to Create an RPG Game in Unity – Comprehensive Guide https://gamedevacademy.org/how-to-create-an-rpg-game-in-unity-comprehensive-guide/ Mon, 19 Dec 2022 09:44:57 +0000 https://gamedevacademy.org/?p=4665 Read more]]> In this tutorial, we are going to build an RPG game using Unity. Our game will have three scenes: a title scene, a town scene, that represent the game world, where the player can navigate and find battles, and the battle scene. The battles will have different types of enemies, and the player units will have different actions such as: regular attack, magic attack, and running from the battle.

In order to follow this tutorial, you are expected to be familiar with the following concepts:

  • C# programming
  • Using Unity inspector, such as importing assets, creating prefabs and adding components
  • Basic Tiled map creation, such as adding a tileset and creating tile layers

Before starting reading the tutorial, create a new Unity project and import all sprites available through the source code. You will need to slice the spritesheets accordingly.

Source code files & Requirements

You can download the tutorial source code files here.

The sprites used in this tutorial are from the Superpowers Asset Packs by Pixel-boy. All sprites are available under the Creative Commons Zero (CC0) license. So, you can use them in your games, even commercial ones.

BUILD YOUR OWN GAMES

Get 250+ coding courses for

$1

AVAILABLE FOR A LIMITED TIME ONLY

Tutorial Requirements

Before beginning, it is assumed that you have the basics of Unity under your belt. If not, you can feel free to check out some of our other Unity tutorials first. Alternatively, you can also jump into more comprehensive online courses designed to take you from zero to industry-ready developer.

For teachers, you may also want to check out Zenva Schools. This platform made specifically for classroom usage offers several Unity-based courses (alongside other in-demand digital technologies topics). There are also plenty of useful features for classrooms including classroom management tools, reporting, course plans, and more.

Title Scene

Background canvas

First of all, we are going to create a Canvas to show the background image in the Title Scene. You can do that by creating a new Canvas called BackgroundCanvas, and setting its render mode as Screen Space – Camera. In order to do so, we need to specify the camera of the canvas, which will be our main camera. Also, the UI Scale Mode (in Canvas Scaler) will be set to follow the screen size, with a reference resolution of 1280×960.

Creating a canvas for the background.

After doing that, we create a new Image object as a child of this canvas. The source image will be the background image, and we can set its native size in order to properly show it.

HUD canvas

Now, we need another Canvas to show the HUD elements. In the Title Scene, those elements will be a title text, and a play button.

Let’s start by creating another Canvas following the same process as the BackgroundCanvas. However, in order to show this canvas over the background one, we need to properly set its sorting layer. We are going to create another layer called HUD, and put the HUDCanvas on this layer.

Creating the HUD canvas.

Finally, we need to create the two HUD objects. The first one is a Text, while the second one is a Button. For the Text object we only need to set its message. On the other hand, for the Button object we need to set its OnClick callback.

Creating the title text for the main menu.

Creating the play button which will launch the town scene.

The PlayButton object will have the following ChangeScene script for the OnClick callback. This script will simply define a method to start a new scene given its name. Then, we set the OnClick callback of the play button to call the loadNextScene method with “Town” as parameter.

public class ChangeScene : MonoBehaviour 
{  
    public void loadNextScene (string sceneName) 
    {
        SceneManager.LoadScene(sceneName);
    }
}

Player party

In our game, we want to keep the player units data saved even when changing scenes. In order to do so, we are going to create a PlayerParty persistent object, which won’t be destroyed when changing scenes. You will also need to properly set its position so that it will be created in the correct position in Battle Scene.

Stored data for the player party.

In order to keep the PlayerParty alive when changing scenes, we are going to use the following script, called StartBattle. This script keeps the object from being destroyed when changing scenes in the Start method. It also adds a callback when a new scene is loaded and set the object as inactive, so that it won’t be shown in the title screen.

The configured callback (OnSceneLoaded) checks if the current loaded scene is the Title scene. If so, the PlayerParty object must be destroyed, to avoid duplicates. Otherwise, it should be set as active if the current scene is the Battle scene.

public class StartBattle : MonoBehaviour 
{
    // Use this for initialization
    void Start () 
    {
        DontDestroyOnLoad(this.gameObject);
        SceneManager.sceneLoaded += OnSceneLoaded;
        this.gameObject.SetActive (false);
    }

    private void OnSceneLoaded (Scene scene, LoadSceneMode mode) 
    {
        if (scene.name == "Title") 
        {
            SceneManager.sceneLoaded -= OnSceneLoaded;
            Destroy(this.gameObject);
        }
        else
        {
            this.gameObject.SetActive(scene.name == "Battle");
        }
    }
}

Also, the PlayerParty will have two children to represent the player units. So, first let’s create a PlayerUnit prefab with only a few things for now. Later on this tutorial, we are going to add the rest of its behavior.

For now, the PlayerUnit will have only the Sprite Renderer and a script called UnitStats, which will store the stats of each unit, such as: health, mana, attack, magic attack, defense and speed.

public class UnitStats : MonoBehaviour 
{
    public float health;
    public float mana;
    public float attack;
    public float magic;
    public float defense;
    public float speed;
}

The figure below shows the example of one player unit, called MageUnit. In this example the UnitStats script has other attributes, which will be used later (such as Animator and Damage Text Prefab), but you can ignore those attributes for now.

Mage unit prefab with the unit stats script.

By now, you can already try running your game with the Title scene. You can create an empty Town scene only to test the play button.

Title screen for "Unity RPG" game with play button

Town Scene

We will start by creating the Town Scene. So, create a new Scene in your project and call it Town.

Creating our Tilemap

The Town scene will have a tilemap for us to walk around. To begin, let’s download the 2D Tilemap Editor package in the Package Manager (Window > Package Manager).

Installing the 2D Tilemap Editor in the Package Manager.

Then open the Tile Palette window (Window > 2D > Tile Palette). Here, create a new palette and save it in a new folder called Tilemap.

Creating a new palette in the Tile Palette window.

Now we need to go to our tilemap image. Set the “Sprite Mode” to Multiple, the “Pixels Per Unit” to 64, then click “Sprite Editor”.

Here, we want to slice the image up into 20 columns and 12 rows.

Slicing the sprite sheet in the Sprite Editor.

Then we can drag our tileset into the window to create the tiles.

Creating the the tiles by dragging the sprite sheet into the Tile Palette window.

In the Town scene, right click and create a 2D Object > Tilemap.

Creating a new tilemap game object.

Now, we can select a tile and draw it on the tilemap. Let’s create a grass background.

Painting the screen with grass in the tilemap.

In order to layer tiles, we can create a new tilemap for anything above the grass.

Creating another tilemap for the tiles above the grass.

Set the grid child object’s sorting layer to 1.

Create a scene, something like this.

Our final town scene tilemap layout.

Player prefab

Now that we added our town map to Unity, we are going to create a Player prefab. The player will be able to move around the town, and must collide with the collidable Tiles.

So, let’s start by creating a GameObject called Player, adding the correct sprite renderer, a Box Collider 2D and a Rigidbody 2D as shown below. Observe that we need to set the Gravity Scale attribute of the Rigidbody2D as 0, so that the Player won’t be affected by the gravity.

Player object which is going to navigate the town scene.

We also need to create the Player animations. The Player will have four walking animations and four idle animations, one for each direction. So, first, we create all the animations naming them IdleLeft, IdleRight, IdleUp, IldeDown, WalkingLeft, WalkingRight, WalkingUp and WalkingDown.

The next thing we need is the player animator. So, we create a new animator called PlayerAnimator and add all the created animations to it. Once we add the animator to the Player object in the inspector, we can create its animations using the Unity animation window and the player spritesheet. The figure below shows the example of the WalkingUp animation.

WalkingUp animation for the player which will affect their SpriteRenderer's sprite property.

Now we need to configure the animation transitions in the player animator. The animator will have two paremeters: DirectionX and DirectionY, which describes the current direction of the player movement. For example, if the player is moving to the left, DirectionX is equal to -1, while DirectionY is equal to 0. Those parameters will be correctly set later in a movement script.

Each idle animation will have a transition to each walking animation. The direction parameters should have the values according to the animation direction. For example, the Idle Left animation will change to Walking Left if DrectionX is equal to -1. Also, each walking animation will have a transition for its correspondent idle animation. Finally, if the player changes its walking direction without stopping, we need to update the animation. So, we need to add transitions between the walking animations as well.

In the end, the player animator should look like the figure below. The next figures show examples of transitions between animations (IdleLeft -> WalkingLeft and WalkingLeft -> IdleLeft).

The player animator layout. Connecting the animation states with transitions which are determined by parameters.

Animator transition between the IdleLeft and WalkingLeft animation.

Animator transition between the WalkingLeft and IdleLeft animation states.

Now let’s create the PlayerMovement script. All movement happens in the FixedUpdate method. We use the horizontal and vertical axis inputs to check if the player should move horizontally or vertically. The player can move to a given direction if it is not already moving to the opposite direction. For example, it can move to the left if it is not already moving to the right. We do that for both vertical and horizontal directions. When moving to a given direction, we need to set the animator parameters. In the end, we apply the velocity to the Player Rigidbody2D.

public class PlayerMovement : MonoBehaviour 
{	
    [SerializeField]
    private float speed;

    [SerializeField]
    private Animator animator;

    void FixedUpdate () 
    {
        float moveHorizontal = Input.GetAxis("Horizontal");
        float moveVertical = Input.GetAxis("Vertical");

        Vector2 currentVelocity = gameObject.GetComponent<Rigidbody2D>().velocity;

        float newVelocityX = 0f;

        if(moveHorizontal < 0 && currentVelocity.x <= 0) 
        {
            newVelocityX = -speed;
            animator.SetInteger("DirectionX", -1);
        } 
        else if(moveHorizontal > 0 && currentVelocity.x >= 0) 
        {
            newVelocityX = speed;
            animator.SetInteger("DirectionX", 1);
        } 
        else 
        {
            animator.SetInteger("DirectionX", 0);
        }

        float newVelocityY = 0f;

        if(moveVertical < 0 && currentVelocity.y <= 0) 
        {
            newVelocityY = -speed;
            animator.SetInteger("DirectionY", -1);
        } 
        else if(moveVertical > 0 && currentVelocity.y >= 0) 
        {
            newVelocityY = speed;
            animator.SetInteger("DirectionY", 1);
        } 
        else 
        {
            animator.SetInteger("DirectionY", 0);
        }

        gameObject.GetComponent<Rigidbody2D>().velocity = new Vector2(newVelocityX, newVelocityY);
    }
}

In the end, the Player prefab should look like the figure below.

Player prefab with the Animator component attached.

For now, you can start your game and try moving the player around the map. Remember to check if the tile collisions are properly working.

What our town scene looks like when we press play.

Starting Battle

The player can start battles by interacting with enemy spawners. The enemy spawner will be an immovable object that,  when touched by the player will switch to another scene called Battle Scene.

Also, the enemy spawner will be responsible for creating the enemy units objects in the Battle Scene. This will be done by creating an EnemyEncounter prefab, with enemy units as children. Like the player units from the Title Scene, for now we are only going to add the UnitStats script and the Sprite Renderer to enemy units. The figure below shows an example of an enemy unit. You can create the EnemyEncounter by creating a new prefab and adding the desired enemy units as children to it. You will also need to properly set its position so that it will be created in the correct position in Battle Scene.

Enemy unit object with the Unit Stats script.

So, let’s create a prefab called EnemySpawner. This prefab will have a collision box and a Rigidbody2D, in order to check for collisions with the Player prefab.

Snake spawner object which spawns a new snake enemy encounter.

Also, it will have a script called SpawnEnemy as below. This script implements the OnCollisionEnter2D method to check for collisions with the Player prefab. We do so by checking if the other object tag is “Player” (remember to properly set the Player prefab tag). If there is a collision, it is going to start the Battle Scene and set a spawning attribute to true.

In order to create the enemy units in the Battle Scene, the script needs as an attribute the enemy encounter prefab, and the enemy spawner must not be destroyed when changing scenes (done in the Start method). When loading a scene (in the OnSceneLoaded method), if the scene being loaded is the Battle Scene, the enemy spawner will destroy itself and will instantiate the enemy encounter if the spawning attribute is true. This way, we can make sure that only one spawner will instantiate the enemy encounter, but all of them will be destroyed.

public class SpawnEnemy : MonoBehaviour 
{
    [SerializeField]
    private GameObject enemyEncounterPrefab;

    private bool spawning = false;

    void Start () 
    {
        DontDestroyOnLoad(this.gameObject);
        SceneManager.sceneLoaded += OnSceneLoaded;
    }

    private void OnSceneLoaded (Scene scene, LoadSceneMode mode) 
    {
        if(scene.name == "Battle") 
        {
            if(this.spawning) 
            {
                Instantiate(enemyEncounterPrefab);
            }

            SceneManager.sceneLoaded -= OnSceneLoaded;
            Destroy(this.gameObject);
        }
    }

    void OnTriggerEnter2D (Collider2D other) 
    {
        if(other.gameObject.tag == "Player") 
        {
            this.spawning = true;
            SceneManager.LoadScene("Battle");
        }
    }
}

By now, you can try running your game and interacting with the enemy spawner. Try creating an empty Battle Scene to allow changing the scenes.

Snake encounter in the town scene which we can interact with.

Battle Scene

Background and HUD Canvases

Let’s start by creating the canvases that we are going to use for Battle Scene. Similarly to Title Scene, we are going to use one for the background and another for the HUD elements.

The background canvas will be the same as for the Title Scene, so I’m not going to show its creation. The HUD canvas, on the other hand, will need a lot of elements to allow proper player interaction.

First ,we will add an actions menu, which will show the possible actions for the player. This will be an empty object used as parent of all action menu items. Each action menu item, by its turn, will be a button, added as child of the ActionsMenu.

We are going to add three possible actions: attacking with physical attack (PhysicalAttackAction), attacking with magical attack (MagicAttackAction) and running from the battle (RunAction). Each action will have its OnClick event but, for now, we are not going to add it. The figure below shows only the PhysicalAttackAction, since the other ones will only change the source image for now. The source images for those menu items are from the icons Sprite, which was sliced in many icons.

Physical attack action button.

The second menu we are going to add to the HUD canvas is the EnemyUnitsMenu. This menu will be used to show the enemy units, so that the player can choose one to attack. Similarly to the ActionsMenu, it will be an empty object used to group its menu items. However, the enemy menu items will be created by the enemy units, when the Battle scene starts.

In order to make the enemy unit to create its menu item, we need to create the menu item prefab. This prefab will be called TargetEnemy and will be a button. The OnClick callback of this button will be used to select this enemy as the target.

Target enemy button created using Unity's UI.

We need to add two scripts to the EnemyUnit prefab to handle its menu item: KillEnemy and CreateEnemyMenuItem.

Snake1 object with our components attached.

The KillEnemy script is simple. It will have as an attribute the menu item of this unit, and when the unit is destroyed (OnDestroy method), the menu item must be destroyed too.

public class KillEnemy : MonoBehaviour 
{
    public GameObject menuItem;

    void OnDestroy () 
    {
        Destroy(this.menuItem);
    }
}

Now let’s create the CreateEnemyMenuItem script. This script will be responsible for creating its menu item and setting its OnClick callback. All this is done in the Awake method. First, the menu item position is calculated based on the number of existing items. Then, it is instantiated as children of EnemyUnitsMenu, and the script sets its localPosition and localScale. In the end, it sets the OnClick callback to be the selectEnemyTarget method, and sets the menu item as the one for this unit in KillEnemy.

The selectEnemyTarget method should make the player to attack this unit. However, we don’t have the code to do that now. So, for now we are going to leave this method empty.

public class CreateEnemyMenuItems : MonoBehaviour 
{
    [SerializeField]
    private GameObject targetEnemyUnitPrefab;

    [SerializeField]
    private Sprite menuItemSprite;

    [SerializeField]
    private Vector2 initialPosition, itemDimensions;

    [SerializeField]
    private KillEnemy killEnemyScript;

    // Use this for initialization
    void Awake () 
    {
        GameObject enemyUnitsMenu = GameObject.Find("EnemyUnitsMenu");

        GameObject[] existingItems = GameObject.FindGameObjectsWithTag("TargetEnemyUnit");
        Vector2 nextPosition = new Vector2(this.initialPosition.x + (existingItems.Length * this.itemDimensions.x), this.initialPosition.y);

        GameObject targetEnemyUnit = Instantiate(this.targetEnemyUnitPrefab, enemyUnitsMenu.transform) as GameObject;
        targetEnemyUnit.name = "Target" + this.gameObject.name;
        targetEnemyUnit.transform.localPosition = nextPosition;
        targetEnemyUnit.transform.localScale = new Vector2(0.7f, 0.7f);
        targetEnemyUnit.GetComponent<Button>().onClick.AddListener(() => selectEnemyTarget());
        targetEnemyUnit.GetComponent<Image>().sprite = this.menuItemSprite;

        killEnemyScript.menuItem = targetEnemyUnit;
    }

    public void selectEnemyTarget () 
    {
		
    }
}

The final HUD elements we are going to add are those to show the player unit information, such as health and mana. So, we are going to start by creating an empty GameObject called PlayerUnitInformation, to hold all those HUD elements.

Then, we are going to add an image as child of this object called PlayerUnitFace. This element will simply show the face of the current unit. For now, let’s select any unit face.

UI image with the player's warrior face.

The next elements will be the health bar and its text. The health bar will be an image showing the health bar sprite, while the text will show the HP message. Finally we do the same for the mana bar, only changing the sprite and the text message. The figures below show only the health bar, since the mana bar is very similar.

Player unit health bar UI object.

Player unit health text UI element.

By now, your Battle Scene should look like this. This figure corresponds to the Scene viewer, and not the running game, since there is a lot of content we still need to add to properly run the Battle Scene. The righthand figure shows the objects hierarchy in the scene.

What our battle scene now looks like with the UI.

Our Unity hierarchy at the current time.

Units Animations

The next thing we are going to do is creating the units animations. Each unit will have four animatios: Idle, PhysicalAttack, MagicalAttack and Hit. So, let’s start by creating an animator for one of the player units (for example, the MageUnit), and adding it to its correspondent prefab.

Player unit object with the unit stats and animator component.

Now, if we select this prefab and open the Animator view, we can configure its animations state machine as below. We are going to create a state for each animation, with Idle being the default one, and all other ones having transitions to Idle when they end.

Player animator, connecting the various animation states.

Magical attack animation state.

Now, we need to create the four animations to add them to their correspondent states. The figure below shows the MagicalAttack animation for MageUnit. You can create all animations following the same process with the animation  view, so I’m not going to show them all. Also, you have to do the same for all units (including the enemy ones).

Mage magical attack animation, changing the sprite over time.

We still need to define when to play those animations. However, we are going to do so when adding more functionalities for the units. For now, the units will only play the Idle animation, as it is the default one.

If you play the game now, it should show the units with the Idle animation. However, remeber you have to play Title Scene and go until the Battle Scene, in order to see the units.

What our final game looks like.

Turn-Based Battle System

The next thing we are going to add to our game is a turn-based battle system. So, let’s start by creating an empty game object with a script called TurnSystem.

Turn system object with the turn system script.

The TurnSystem script will keep a List with the UnitStats script of all units (player and enemy ones). Then, in each turn, it can pop the first element of the list, make the unit act and add it again to the list. Also, it needs to keep the list sorted according to the units acting turns.

This script is shown below. The UnitStats list is created in the Start method. This is done by iterating through all game objects with the tags “PlayerUnit” or “EnemyUnit” (remember to properly tag your objects). For each unit, the script gets its UnitStats script, calculate its next acting turn and add it to the list. After adding all units the list is sorted. Finally, the menus are disabled, since they will be used only on the player turns, and the first turn begins (by calling nextTurn).

The nextTurn method, by its turn, will start by removing the first UnitStats from the list and checking if it is not dead. If the unit is alive, it will calculate its next acting turn in order to add it again to the list. Finally, it will make it act. We still don’t have the acting methods of the units, so we are only going to print a message in the console for now. On the other hand, if the unit is dead, we are simply going to call nextTurn without adding it to the list again.

public class TurnSystem : MonoBehaviour 
{
    private List<UnitStats> unitsStats;

    [SerializeField]
    private GameObject actionsMenu, enemyUnitsMenu;

    void Start ()
    {
        unitsStats = new List<UnitStats>();
        GameObject[] playerUnits = GameObject.FindGameObjectsWithTag("PlayerUnit");
        
        foreach(GameObject playerUnit in playerUnits) 
        {
            UnitStats currentUnitStats = playerUnit.GetComponent<UnitStats>();
            currentUnitStats.calculateNextActTurn(0);
            unitsStats.Add (currentUnitStats);
        }

        GameObject[] enemyUnits = GameObject.FindGameObjectsWithTag("EnemyUnit");

        foreach(GameObject enemyUnit in enemyUnits) 
        {
            UnitStats currentUnitStats = enemyUnit.GetComponent<UnitStats>();
            currentUnitStats.calculateNextActTurn(0);
            unitsStats.Add(currentUnitStats);
        }

        unitsStats.Sort();

        this.actionsMenu.SetActive(false);
        this.enemyUnitsMenu.SetActive(false);

        this.nextTurn();
    }

    public void nextTurn () 
    {
        UnitStats currentUnitStats = unitsStats [0];
        unitsStats.Remove(currentUnitStats);

        if(!currentUnitStats.isDead()) 
        {
            GameObject currentUnit = currentUnitStats.gameObject;

            currentUnitStats.calculateNextActTurn(currentUnitStats.nextActTurn);
            unitsStats.Add(currentUnitStats);
            unitsStats.Sort();

            if(currentUnit.tag == "PlayerUnit")
            {
                Debug.Log("Player unit acting");
            } 
            else 
            {
                Debug.Log("Enemy unit acting");
            }
        } 
        else 
        {
            this.nextTurn();
        }
    }
}

Before moving on, we need to implement the UnitStats methods we used in TurnSystem, so let’s go back to the UnitStats script.

First, the calculateNextActTurn method is responsible for calculating the next acting turn based on the current one. This is done based on the unit speed, as shown below. Also, we need to make UnitStats to extend the IComparable interface, and implement the CompareTo method, so that we can properly sort the UnitStats list. The CompareTo method will simply compare the acting turn of the two scripts. Finally, we need to implement the isDead getter, which will simply return the dead attribute value. By default, this attribute is false, because the unit is alive at the beginning of the game.

public class UnitStats : MonoBehaviour, IComparable 
{
    public float health;
    public float mana;
    public float attack;
    public float magic;
    public float defense;
    public float speed;

    public int nextActTurn;

    private bool dead = false;

    public void calculateNextActTurn (int currentTurn)
    {
        this.nextActTurn = currentTurn + (int)Math.Ceiling(100.0f / this.speed);
    }

    public int CompareTo (object otherStats)
    {
        return nextActTurn.CompareTo(((UnitStats)otherStats).nextActTurn);
    }

    public bool isDead ()
    {
        return this.dead;
    }
}

For now, you can try playing the game again, to see if the turn message is being properly printed in the console.

Attacking Units

Now that we have our turn-based battle system we are going to allow units to attack each other. First, we are going to create Attack prefabs, which will be used by the units. Then, we are going to add the action scripts of both player and enemy units, so that they can properly attack. When receiving damage, units will show a Text prefab with the damage value.

The Attack prefab will be an inivisible prefab with an script called AttackTarget. This script will describe the attack properties such as attack and defense multipliers and mana cost. Also, the attack will have an owner, which is the unit currently attacking.

First, the script checks if the owner has enough mana to execute the attack. If so, it picks random attack and defense multipliers based on the minimum and maximum values. So, the damage is calculated based on those multipliers and the attack and defense of the units. Observe that, if the attak is a magical attack (this.magicAttack is true), then it will use the magic stat of the unit, otherwise it uses the attack stat.

In the end, the script plays the attack animation, inflicts the damage to the target unit and reduces the mana of the owner accordingly.

public class AttackTarget : MonoBehaviour 
{
    public GameObject owner;

    [SerializeField]
    private string attackAnimation;

    [SerializeField]
    private bool magicAttack;

    [SerializeField]
    private float manaCost;

    [SerializeField]
    private float minAttackMultiplier;

    [SerializeField]
    private float maxAttackMultiplier;

    [SerializeField]
    private float minDefenseMultiplier;

    [SerializeField]
    private float maxDefenseMultiplier;
	
    public void hit (GameObject target) 
    {
        UnitStats ownerStats = this.owner.GetComponent<UnitStats>();
        UnitStats targetStats = target.GetComponent<UnitStats>();

        if(ownerStats.mana >= this.manaCost) 
        {
            float attackMultiplier = (Random.value * (this.maxAttackMultiplier - this.minAttackMultiplier)) + this.minAttackMultiplier;
            float damage = (this.magicAttack) ? attackMultiplier * ownerStats.magic : attackMultiplier * ownerStats.attack;

            float defenseMultiplier = (Random.value * (this.maxDefenseMultiplier - this.minDefenseMultiplier)) + this.minDefenseMultiplier;
            damage = Mathf.Max(0, damage - (defenseMultiplier * targetStats.defense));

            this.owner.GetComponent<Animator>().Play(this.attackAnimation);

            targetStats.receiveDamage(damage);

            ownerStats.mana -= this.manaCost;
        }
    }
}

We are going to create two attack prefabs: PhysicalAttack and MagicalAttack, each one with its own multipliers.

Magical attack prefab with the attack target values.

Physical attack prefab with the attack target stats.

Now we need to implement the reiceveDamage method, used in the AttackTarget script. This will be a method from UnitStats that, besides reducing the unit health, it will also show the damage using a Text over the unit’s head.

This method is shown below. First, it will simply reduce the unit health and play the Hit animation. Then, it will create the damage text (using this.damageTextPrefab). Observe that the damage text must be a child of the HUDCanvas, since it is an UI element, and we need to properly set its localPosition and localScale. In the end, if the unit health is less than zero, the script set the unit as dead, change its tag and destroy it.

public void receiveDamage (float damage) 
{
    this.health -= damage;
    animator.Play("Hit");

    GameObject HUDCanvas = GameObject.Find("HUDCanvas");
    GameObject damageText = Instantiate(this.damageTextPrefab, HUDCanvas.transform) as GameObject;
    damageText.GetComponent<Text>().text = "" + damage;
    damageText.transform.localPosition = this.damageTextPosition;
    damageText.transform.localScale = new Vector2(1.0f, 1.0f);

    if(this.health <= 0)
    {
        this.dead = true;
        this.gameObject.tag = "DeadUnit";
        Destroy(this.gameObject);
    }
}

Now we can already implement the act method of the units. An enemy unit will always attack a random enemy with the same attack. This attack will be an attribute in EnemyUnitAction. In the Awake method we are going to create a copy of it for the unit and properly set its owner. We need to create a copy since we want each unit to have its own attack object instance.

Then, the act method will pick a random target and attack it. The findRandomTarget method, by its turn, will start by listing all possible targets given their tags (for example, “PlayerUnit”). If there is at least one possible target in this list, it will generate a random index to pick the target.

public class EnemyUnitAction : MonoBehaviour 
{
    [SerializeField]
    private GameObject attack;

    [SerializeField]
    private string targetsTag;

    void Awake () 
    {
        this.attack = Instantiate(this.attack);
        this.attack.GetComponent<AttackTarget>().owner = this.gameObject;
    }

    GameObject findRandomTarget () 
    {
        GameObject[] possibleTargets = GameObject.FindGameObjectsWithTag(targetsTag);

        if(possibleTargets.Length > 0) 
        {
            int targetIndex = Random.Range(0, possibleTargets.Length);
            GameObject target = possibleTargets [targetIndex];

            return target;
        }

        return null;
    }

    public void act () 
    {
        GameObject target = findRandomTarget();
        this.attack.GetComponent<AttackTarget>().hit(target);
    }
}

Player units, by their turn, will have two different attacks: physical and magical. So, in the Awake method we need to properly instantiate and set the owner of these two attacks. Also, we are going to set the current attack as the physical one by default.

Then, the act method will receive as parameter the target unit and will simply attack it.

public class PlayerUnitAction : MonoBehaviour 
{
    [SerializeField]
    private GameObject physicalAttack;

    [SerializeField]
    private GameObject magicalAttack;

    private GameObject currentAttack;

    void Awake () 
    {
        this.physicalAttack = Instantiate(this.physicalAttack, this.transform) as GameObject;
        this.magicalAttack = Instantiate(this.magicalAttack, this.transform) as GameObject;

        this.physicalAttack.GetComponent<AttackTarget>().owner = this.gameObject;
        this.magicalAttack.GetComponent<AttackTarget>().owner = this.gameObject;

        this.currentAttack = this.physicalAttack;
    }

    public void act (GameObject target) 
    {
        this.currentAttack.GetComponent<AttackTarget>().hit(target);
    }
}

Now, we can already call the enemy unit act method in the TurnSystem script. We still can’t do the same for player units, since we still need to properly select the current unit and its attack. This is the next thing we are going to do.

public void nextTurn () 
{
    UnitStats currentUnitStats = unitsStats [0];
    unitsStats.Remove(currentUnitStats);
    
    if(!currentUnitStats.isDead()) 
    {
        GameObject currentUnit = currentUnitStats.gameObject;

        currentUnitStats.calculateNextActTurn(currentUnitStats.nextActTurn);
        unitsStats.Add(currentUnitStats);
        unitsStats.Sort();

        if(currentUnit.tag == "PlayerUnit") 
        {
            Debug.Log("Player unit acting");
        } 
        else 
        {
            currentUnit.GetComponent<EnemyUnitAction>().act();
        }
    } 
    else 
    {
        this.nextTurn();
    }
}

Selecting Unit and Action

We need to properly select the current player unit each turn. This will be done by adding the following script (SelectUnit) to the PlayerParty object. This script will need references to the battle menus, so when the Battle scene is loaded it is going to set them.

Then, we need to implement three methods: selectCurrentUnit, selectAttack and attackEnemyTarget. The first one will set a unit as the current one, enable the actions menu, so that the player can choose an action, and update the HUD to show the current unit face, health and mana (this last method will be implemented later).

The selectAttack method, by its turn, will call selectAttack for the current unit, and will change the current menu, by disabling the actions menu and enabling the enemies menu. The selectAttack method also needs to be implemented in the PlayerUnitAction script. This way, now that the player has selected an attack, it can select the target.

Finally, the attackEnemyTarget will disable both menus and call the act method for the current unit, with the selected enemy as the target.

public class SelectUnit : MonoBehaviour 
{
    private GameObject currentUnit;

    private GameObject actionsMenu, enemyUnitsMenu;

    void Awake () 
    {
        SceneManager.sceneLoaded += OnSceneLoaded;
    }

    private void OnSceneLoaded (Scene scene, LoadSceneMode mode) 
    {
        if(scene.name == "Battle") 
        {
            this.actionsMenu = GameObject.Find("ActionsMenu");
            this.enemyUnitsMenu = GameObject.Find("EnemyUnitsMenu");
        }
    }

    public void selectCurrentUnit (GameObject unit) 
    {
        this.currentUnit = unit;
        this.actionsMenu.SetActive(true);
    }

    public void selectAttack (bool physical) 
    {
        this.currentUnit.GetComponent<PlayerUnitAction>().selectAttack(physical);

        this.actionsMenu.SetActive(false);
        this.enemyUnitsMenu.SetActive(true);
    }

    public void attackEnemyTarget (GameObject target) 
    {
        this.actionsMenu.SetActive(false);
        this.enemyUnitsMenu.SetActive(false);

        this.currentUnit.GetComponent<PlayerUnitAction>().act(target);
    }
}
public class PlayerUnitAction : MonoBehaviour 
{
    [SerializeField]
    private GameObject physicalAttack;

    [SerializeField]
    private GameObject magicalAttack;

    private GameObject currentAttack;

    public void selectAttack (bool physical) 
    {
        this.currentAttack = (physical) ? this.physicalAttack : this.magicalAttack;
    }
}

Now, we need to properly call all those three methods. The first one (selectCurrentUnit) will be called in TurnSystem, when it is a player unit turn.

public void nextTurn () 
{
    UnitStats currentUnitStats = unitsStats [0];
    unitsStats.Remove(currentUnitStats);

    if(!currentUnitStats.isDead ()) 
    {
        GameObject currentUnit = currentUnitStats.gameObject;

        currentUnitStats.calculateNextActTurn(currentUnitStats.nextActTurn);
        unitsStats.Add(currentUnitStats);
        unitsStats.Sort();

        if(currentUnit.tag == "PlayerUnit") 
        {
            this.playerParty.GetComponent<SelectUnit>().selectCurrentUnit(currentUnit.gameObject);
        } 
        else 
        {
            currentUnit.GetComponent<EnemyUnitAction>().act();
        }
    } 
    else 
    {
        this.nextTurn();
    }
}

The second one (selectAttack), will be called by the PhysicalAttackAction and MagicalAttackAction buttons in the HUDCanvas. Since the PlayerParty object is not from the same scene as these buttons, we can’t add the OnClick callbacks in the inspector. So, we are going to do that using the following script (added to those buttons objects), which will add the callback in the Start method. The callback will simply call the selectAttack method from SelectUnit. This same script should be added to both buttons, only changing the “physical” attribute.

public class AddButtonCallback : MonoBehaviour 
{
    [SerializeField]
    private bool physical;

    // Use this for initialization
    void Start () 
    {
        this.gameObject.GetComponent<Button>().onClick.AddListener(() => addCallback());
    }

    private void addCallback () 
    {
        GameObject playerParty = GameObject.Find("PlayerParty");
        playerParty.GetComponent<SelectUnit>().selectAttack(this.physical);
    }
}

Physical attack action button to attack the enemy.

Magical attack action button to magically attack the enemy.

The third method (attackEnemyTarget) will be called from the enemy unit menu item. When creating the CreateEnemyMenuItems script, we left the selectEnemyTarget (which is the button callback) empty. Now, we are going to implement it. This method is going to find the PlayerParty object and call its attackEnemyTarget method.

public void selectEnemyTarget () 
{
    GameObject partyData = GameObject.Find("PlayerParty");
    partyData.GetComponent<SelectUnit>().attackEnemyTarget(this.gameObject);
}

Finally, now we need to update the HUD to show the current unit face, health and mana.

We are going to use the following script to show the unit health and mana. This script will start its initial localScale in the Start method. Then, in the Update method it will update the localScale according to the current stat value of the unit. Also, it will have a method do change the current unit being showed and an abstract method to retrieve the current stat value.

public abstract class ShowUnitStat : MonoBehaviour 
{
    [SerializeField]
    protected GameObject unit;

    [SerializeField]
    private float maxValue;

    private Vector2 initialScale;

    void Start () 
    {
        this.initialScale = this.gameObject.transform.localScale;
    }

    void Update () 
    {
        if(this.unit) 
        {
            float newValue = this.newStatValue();
            float newScale = (this.initialScale.x * newValue) / this.maxValue;
            this.gameObject.transform.localScale = new Vector2(newScale, this.initialScale.y);
        }
    }

    public void changeUnit (GameObject newUnit)
    {
        this.unit = newUnit;
    }

    abstract protected float newStatValue();
}

Instead of directly using this script, we are going to create two other ones that specialize it, implementing the abstract method: ShowUnitHealth and ShowUnitMana. The only method in those two scripts will be newStatValue, which will return the correct unit stats (health or mana).

public class ShowUnitHealth : ShowUnitStat 
{
    override protected float newStatValue () 
    {
        return unit.GetComponent<UnitStats>().health;
    }
}
public class ShowUnitMana : ShowUnitStat 
{
    override protected float newStatValue () 
    {
        return unit.GetComponent<UnitStats>().mana;
    }
}

Now we can add those two scripts to the health and mana bar objects. Another thing to do is to change their Pivot in the X coordinate to be zero, so that it will change the scale only on the right side of the bar.

Player unit health bar UI element.

Player unit mana bar UI element.

Finally, we need to call the changeUnit method in those scripts when the current unit changes. This will start in the selectCurrentUnit method of SelectUnit. After setting the actionsMenu as active, it will call a method called updateHUD for the current unit.

public void selectCurrentUnit (GameObject unit) 
{
    this.currentUnit = unit;
    this.actionsMenu.SetActive(true);
    this.currentUnit.GetComponent<PlayerUnitAction>().updateHUD();
}

The updateHUD method, by its turn, will start by setting the sprite of the PlayerUnitFace object to be the current unit face (saved as an attribute of PlayerUnitAction). Then, it will set itself as the current unit in both ShowUnitHealth and ShowUnitMana.

[SerializeField]
private Sprite faceSprite;

public void updateHUD () 
{
    GameObject playerUnitFace = GameObject.Find("PlayerUnitFace") as GameObject;
    playerUnitFace.GetComponent<Image>().sprite = this.faceSprite;

    GameObject playerUnitHealthBar = GameObject.Find("PlayerUnitHealthBar") as GameObject;
    playerUnitHealthBar.GetComponent<ShowUnitHealth>().changeUnit(this.gameObject);

    GameObject playerUnitManaBar = GameObject.Find("PlayerUnitManaBar") as GameObject;
    playerUnitManaBar.GetComponent<ShowUnitMana>().changeUnit(this.gameObject);
}

By now, you can try playing the game to see if you can select different actions, and if the stats are being correctly updated. The only action from the menu that we still have to implement is the Run action.

What the final unity rpg game looks like.

Finishing the Battle

We still have to add ways of finishing the battle. There are three ways of doing that:

  1. All enemy units are dead, and the player has won the battle
  2. All player units are dead, and the player has lost the battle
  3. The player ran from the battle

If the player wins the battle, it will receive a reward from the enemy encounter. In order to do that we are going to use the following script, which will be added to the enemy encounter object. In the Start method, it will set the enemy encounter in the TurnSystem object. Then, the collectReward method (which will be called from TurnSystem), will equally divide the encounter experience among all living player units.

public class CollectReward : MonoBehaviour 
{
    [SerializeField]
    private float experience;

    public void Start () 
    {
        GameObject turnSystem = GameObject.Find("TurnSystem");
        turnSystem.GetComponent<TurnSystem>().enemyEncounter = this.gameObject;
    }

    public void collectReward () 
    {
        GameObject[] livingPlayerUnits = GameObject.FindGameObjectsWithTag("PlayerUnit");
        float experiencePerUnit = this.experience / (float)livingPlayerUnits.Length;
        
        foreach(GameObject playerUnit in livingPlayerUnits) 
        {
            playerUnit.GetComponent<UnitStats>().receiveExperience(experiencePerUnit);
        }

        Destroy(this.gameObject);
    }
}

Snake enemy encounter prefab with a collect reward script.

Now we need to implement the receiveExperience method used in collectReward. This will be a method from UnitStats used only to save the received experience. This can be used later to implement a level system in the game, but we are not going to do that in this tutorial.

public void receiveExperience (float experience) 
{
    this.currentExperience += experience;
}

Finally, let’s call the collectReward method in TurnSystem. We are going to change the nextTurn method to check if there are still living enemy units, by finding the objects with the “EnemyUnit” tag. Remember that when a unit dies, we change its tag to “DeadUnit”, so that it won’t be found by this method. If there are no remaining enemy units, it calls the collectReward method for the enemy encounter, and go backs to the Town scene.

On the other hand, if there are no remaining player units, that means the player has lost the battle, so the game goes back to the Title scene.

public void nextTurn () 
{
    GameObject[] remainingEnemyUnits = GameObject.FindGameObjectsWithTag("EnemyUnit");
    
    if(remainingEnemyUnits.Length == 0) 
    {
        this.enemyEncounter.GetComponent<CollectReward>().collectReward();
        SceneManager.LoadScene("Town");
    }

    GameObject[] remainingPlayerUnits = GameObject.FindGameObjectsWithTag("PlayerUnit");
    
    if(remainingPlayerUnits.Length == 0) 
    {
        SceneManager.LoadScene("Title");
    }

    UnitStats currentUnitStats = unitsStats [0];
    unitsStats.Remove(currentUnitStats);

    if(!currentUnitStats.isDead ()) 
    {
        GameObject currentUnit = currentUnitStats.gameObject;

        currentUnitStats.calculateNextActTurn(currentUnitStats.nextActTurn);
        unitsStats.Add(currentUnitStats);
        unitsStats.Sort();

        if(currentUnit.tag == "PlayerUnit") 
        {
            this.playerParty.GetComponent<SelectUnit>().selectCurrentUnit(currentUnit.gameObject);
        }
        else
        {
            currentUnit.GetComponent<EnemyUnitAction>().act();
        }
    } 
    else 
    {
        this.nextTurn();
    }
}

The last way of finishing a battle is by running from it. This can be done by selecting the run action in the actions menu. So, we need to attach the script below to the run button, and add its OnClick callback.

The RunFromBattle script will have a tryRunning method. This method will generate a random number between 0 and 1, and compare it with a runningChance attribute. If the generated random number is less than the running chance, the player successfully avoids the battle, and goes back to the Town scene. Otherwise, the next turn starts.

public class RunFromBattle : MonoBehaviour 
{
    [SerializeField]
    private float runnningChance;

    public void tryRunning () 
    {
        float randomNumber = Random.value;

        if(randomNumber < this.runnningChance) 
        {
            SceneManager.LoadScene("Town");
        } 
        else 
        {
            GameObject.Find("TurnSystem").GetComponent<TurnSystem>().nextTurn();
        }
    }
}

Run action button UI element which will make us run away.

Finally, by now you should have everything working. Try playing battles until the end to check if everything is working. Now you can also try adding different enemy encounters and tuning some game parameters, such as units stats and attack multipliers.

Also, try adding things that could not have been covered in the tutorial, such as more intelligent enemies and a level system. You might also consider mastering techniques for mobile development and optimizing your game for use on a smartphone!

Of course, you may wish to explore other genres as well to expand your skills further. So don’t be afraid to seek out other online courses or even find Unity courses to integrate into the classroom.

The sky is the limit here, so don’t be afraid to experiment!

Final appearance of RPG townFinal appears of the RPG battle screen

BUILD GAMES

FINAL DAYS: Unlock 250+ coding courses, guided learning paths, help from expert mentors, and more.

]]>