DEV Community

nineismine
nineismine

Posted on

Create your first game using Unity and C# – Part 2 Creating your first script to handle player movement.

Character with collider

How to build a game in Unity and C# part 2 - Player Movement.

In the last tutorial we got our environment set up and worked through the process of adding a player character to our project. Now we are going to start doing some of the real work. Today we are going to learn how to build a game in Unity and C# .

In this lesson we will learn how to :

  1. Add physics to our Player object
  2. Add collision to the Player (so that he doesn't just run through walls)
  3. Write the code that allows our player to move.
  4. Test that our character can walk freely around our empty scene.

Lets add some physics!

In the last lesson we added a player object to our "Hierarchy" window. In this section we will add physics to our player by adding what's called "RigidBody" to our character.

Name your new object

 

 

 

Add a RigidBody component to the player object

Find the player in the Hierarchy and select it.

Next look to the Inspector widow, at the bottom you should see a button..

Press the "Add component" button.

Select the RigidBody2D item from the menu.

Rigidbodies enable your  GameObjects  to act under the control of physics. The Rigidbody can receive forces and torque to make your objects move in a realistic way. Any GameObject must contain a Rigidbody to be influenced by gravity, act under added forces via scripting, or interact with other objects.

Make sure the player is still selected in the hierarchy window and add another component

Press the Add Component button

Add a Box Collider 2D Component  

(be sure that the component that you add is a Box Collider 2D not the other one)

Modify the collider to surround your players feet. This particular collision will be used to make sure that your character isn't able to walk through blocks or other terrain while moving around the map.

With the player selected in the Hierarchy

Select the Box Collider from the Inspector

Then hit the Edit Collider button. 

A green box that surrounds your character will appear it has little squares on it which you can drag to resize your collision.

You can make this as big or as small as you want , but for right now you should make it look like mine. (Below)

 

Character with collider

 

 

 

 

 

 

 

Make a script for the player movement.

Add the script

Find the project Window 

Select the Scripts Folder 

Right click on it 

Select Create from the menu and C# Script from the menu that opens 

Be sure to name the Script at this time

Name it PlayerMovement.cs

Here is what it looks like initially.

Viewing the script in the project window.

 

 

 

 

Double click on the script in the project window

If you followed the instructions in the last Tutorial you will have set the External Editor to Visual Studio and when you double click the new script Visual Studio will open.

You should now be looking at the project in Visual studio.

If it didn't open please refer to my last article and find the section on opening your External Editor.

Modify the Script in Visual Studio

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

public class PlayerMovement : MonoBehaviour
{
    // Start is called before the first frame update
    void Start()
    {
        
    }

    // Update is called once per frame
    void Update()
    {
        
    }
}
First change the "class name" to match the name in the unity editor (this is important the script name MUST match the class name. More on this below) Change this line:
public class NewBehaviourScript : MonoBehaviour
to:
public class playerMovement: MonoBehaviour
In Unity  when you create a script the class name must match the script name EXACTLY. If you do not do this correctly then you will get an error which says :
"Cant Add Script - "Can't add script behaviour VisualContainerAsset",
Can't Add Script "The script needs to derive from MonoBehaviour!"
**You won't see this error though until you attempt to add the script to the player model later in this tutorial.**

Let's add our script to our player!

Open Unity back up (make sure you save all the work you did in Visual Studio) Find the Hierarchy window Select your player from the Hierarchy Now direct your attention to the Project view Find your scripts folder Select it and then select your PlayerMovement script Drag the newly created script to the Inspector window.  If you did it correctly you will now see a new component in the inspector window named Player Movement (Script)

Coding the Player Movement

Now that we have a script we need to do a few things to handle the movement.
  1. Create variables.
  2. Set their initial values
  3. Modify them as required for the program.
  4. Attach the script to an object in the editor.

Let's talk about variables! - (explanation)

If you are working on this tutorial without a solid programming background. Understanding the code in a necessary part of learning to build a game in Unity and C#. You might find the use of public and private in front of the variables we are instantiating here a little confusing. Everything in this section is general knowledge about variables. If you want to just get the code thats going in the game... skip to the next section. Without going into to much detail, let's just review a couple things about variables and how they are used in C#.
  • Variables must be "declared".
    • When you declare a variable you tell the compiler what the access level is "Public" Or "Private". Knowing how and when to use these is a whole topic in itself.
      • When it comes to Unity you can get by knowing only this much (below) about "Public / Private" Public variables will be available to modify in the Unity inspector.. private will not.
    • In general you will declare the TYPE of a variable when you instantiate it. This is what determines what kinds of values can be stored in the variable.
      • Often we think of a variable as single type like public int myNumber = 10;  but you can also declare a variable to hold an entire object. An object could be much more complex than a standard variable. It could be a whole range of values. Like for instance the Player that we are creating... at some point we will probably want to give this object some properties that separate him from other objects. The properties are one of the reasons that we use classes in C#. A claa is simply an object and the object acts like a container for these properties.
      • Our player might have
        • a name                        public string name = "chad";
        • hit points                     public int hitPoints = 10000000000000000;
        • lives                             public int remLives = 9;
      • All of the values could be contained in a "class" class Player()
        class Player()
        {
        
            public string name = "chad";
            public int hitPoints = 100000000000;
            public int remLives = 9;
          
        
        }
        
        
      • Now that we have a class we can create a variable to hold the entire object. This is not a totally correct example but as long as you understand that a variable declaration can look a couple different ways you should be good to go for the rest of this .
        public Player myPlayer = new Player();
        
        myPlayer.name = "Chad"; 
        myPlayer.hitPoints = 99999999999999999999;
        myPlayer.remLives = 99999999999999999;
        
        
    • You are able to give the variable a value when you declare it, but you do not have to.
    • Variables must be assigned in order to use them.


Ok so back to the Public private thing....

More specifically what that means is , once you add a script to an object in Unity. You can add variables to that script. In creating these variables you make a choice to either declare them public or private. A public variable will have a graphical representation in the editor that you can change via the Unity inspector interface. (see below)

view of public properties

 

 

 

 

 

 

 

 

 

As you can see above. The speed variable can be increased or reduced in the GUI.

When you make a change to a public variable in the GUI, the game will apply this value at runtime every time you start the game. If you make changes to this value in the code though, that change happens after the intial start and will now be the new value. (until you restart the game)

Let's assign our variables

OK so now that we have reviewed how to use variables let's get back to building this movement script.

Assign the three variables that we are going to need.

We need a value to hold our:

  • Speed
  • A reference to the RigidBody that we added earlier
  • A value to tell Unity the change in position that we are expecting.
public class PlayerMovement : MonoBehaviour

{

    public float speed;

    private Rigidbody2D myRigidbody; //rigidBody gives the player physics 

    private Vector3 change; // the value we will use to tell unity where we moved 

 

    // Start is called before the first frame update

    void Start()

    {
        

    }
**note RigidBody2D is a class and has several values attached to it. **

Get a reference to the Rigidbody component that we set up earlier.

Now that we have the Rigidbody reference we need to populate it. We do this by adding a statement to the void Start() method. Since Start() is called only once and at the beginning of an objects existence it only makes sense to do our initial setup for things in this method. We can do this by using the built in Unity function named GetComponent<Rigidbody2D>(); What this is going to do is look for the component that we named between the brackets, is it exists in the object to which we attach this script. (our player) When we attach this script to the Player object. Unity knows that it should look at the collection of components (attached to player) and find the one that matches what is between the < >. In other words we are telling Unity to look at the Player, and store a reference to the component named RigidBody2D in the value myRigidbody.

Whats is happening with this change variable? - (explanation)

**In this section all of the code is for explanation purposes. You do not need to use any of this code in your script.&& Next we assign our change variable. Because this is something that will be constantly changing we choose to do this in the Update() method. (In this case we are working on player movement so logically you would have the game checking for movement each frame. In other words, we are going to check for key input ,which tells the game which direction we are heading. When we get a command we will run a routine to animate the character (animation will be covered in the next article), and move them in the desired direction. This is stored in the change variable  ) If that wasn't clear.... in the update method we will:
  • set change to zero once per frame
  • check for movement
  • normalize the input (im not going into this too much just trust that we did it)
  • Have the character move to the new position
The change variable is just a set of values that represent changes to the players coordinates. Something important to note here is that Vector2 is class. It contains a set of coordinates X and Y. Unity will modify these coordinates to apply a simple movement algorithm. You can think of this like an x and y on a graph. Moving in any direction one point results in a change in the x and y which is either positive or negative.   Image result for x and y graph As we mentioned Vectors are classes and one Vector has multiple values assigned to it . These coordinates can be changed as you see below.
Vector2 change;

change.X = new value

change.Y = new value
You do not have to change both values but each change represents movement on the graph. In our code (which is below in full)  we are going to use some Unity libraries to get input in the form of keys pressed from the player. We will then covert that to our change variable. Don't think about this too hard right now, it just works. But later were going to use that movement along with another Unity function called MovePosition(). MovePostion() will take that change value that we stored and a couple other values to figure out where the player is moving and how fast. (WASD  or the arrow keys are tracked within unity and are converted to movement (change data))

Make the changes to the change variable

(This section might be hard to understand because there is a lot going on here and Unity is handling a lot of things for us with built in functions. I will do my best to explain what is happening here, if you don't fully understand it you can always come back later and play around with it until you do.) Now were going to tell Unity to make changes when the player moves. We're also going to add a Debug statement to the log so we can view the changes that occur due to movement in the Unity Console. Here is what our code looks like at this point.
using System.Collections;

using System.Collections.Generic;

using UnityEngine;

 

public class PlayerMovement: MonoBehaviour

{

    public float speed;

    private Rigidbody myRigidbody; //rigidBody gives the player physics 

    private Vector2 change; // the value we will use to tell unity where we moved 

    
    // Start is called before the first frame update

    void Start()

    {

        myRigidbody = GetComponent<Rigidbody>(); //add the rigidbody component to this script for use later. 

    }

 

    // Update is called once per frame

    void Update()

    {

        //Zero out the change

        change = Vector2.zero;
        

        //Get the current x and y as points on a graph

        change.x = Input.GetAxisRaw("Horizontal");

        change.y = Input.GetAxisRaw("Vertical");

        //print the change to the console 

        Debug.Log(change);
 

    }

}

Input the code and then save your work  in Visual Studio.

Go back to the Unity Editor

Select your player by either clicking on the sprite or selecting the node named "Player" in the Hierarchy tab of Unity.

Let's talk about the code that makes the player move..(explanation of functions/ methods)

OK guys we are almost done with this lesson but before we finish up let's talk about what we are about to do and then let's get it done and tested!

In the next section we are going to write our first "method". Methods , functions, sub routines.. these are all terms that get thrown around in programming but they are all basically the same thing.
A method is a bit of code that you can call from somewhere in your program. When it is called, the code inside the method will be processed. When the code inside the method is finished executing, the program will resume execution where the method was called. The next line of code after the method was called will then execute.

 

When should I create a new method?

Often as a software engineer you will be faced with the question of... "When should I create a new method?"

The simple answer is: When you encounter a verb.

Let's break that down a bit!
In our program we are going to create a method called MoveCharacter(). We could just add the movement code to the Update() method but then later in our program we might need to write the exact same code again (if we need to move again).

When it comes to deciding on when to create a new method you can can think of them as verbs. "Brad wants to run", "Brad attacks".... In both of these sentences, if we are writing code to make our player do some action it makes sense to create a method for both verbs.

Let's take this one step farther now.

Let's say that we want to write this code to handle PlayerMovement or "Move" (Player) if we are keeping with the Verb reference.

Each time we get a frameUpdate, we want to evaluate if the user pressed a button to tell the computer to Move() (our verb!).
What might happen in the Move() method then?
Well as we discussed earlier, when we move, we need change our players X and Y position.

void MoveCharacter()
{

     player.MovePostion(currentPostion +change) 

}
So when we Move(), we are actually telling the computer to move our player, some amount of degrees X, and move our player some amount of degrees Y. (There are those dang verbs again!) We can boil that down to MoveX and MoveY. (TWO Verbs!) If we look back at the psuedocode above, what do we see ? We have a method that Moves the character a,nd inside of it we have ANOTHER method call, which handles our MoveX and MoveY. Why is there another method there? Because we encountered another verb. (MoveX and MoveY) I can't say that this is a hard and fast rule because when it comes to programming, there will always be exceptions to every rule. But if you can take that simple statement with you then you have a good baseline to answer the question. "When should I create a new method?" Hope that helps this next part make a little more sense for you!

Writing the movement code.

OK so here it is.. all of the code we need for (now anyway) our player movement.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class PlayerMovement : MonoBehaviour
{
    public float speed;
    private Rigidbody2D myRigidbody; //rigidBody gives the player physics 
    private Vector3 change; // the value we will use to tell unity where we moved 


    // Start is called before the first frame update
    void Start()
    {
        myRigidbody = GetComponent<Rigidbody2D>(); //add the rigidbody component to this script for use later. 
    }

    // Update is called once per frame
    void Update()
    {
       
        //Zero out the change
        change = Vector3.zero;
         //Get the current x and y as points on a graph
        change.x = Input.GetAxisRaw("Horizontal");
        change.y = Input.GetAxisRaw("Vertical");
        //print the change to the console 
        Debug.Log(change);
        if (change != Vector3.zero)
        {
            MoveCharacter();
        }

    }
    void MoveCharacter()
    {
        //transform.position is the player position
        // add the "change" (x and y modifications) 
        //Time.Delta is the amount of time that has passed since the previous frame 
        //So what we are saying here is: Move my character TO my current poistion + the changes I asked to make (direction) * my current speed * the amount of time that has passed.
        //this last piece about the time change is to make it look more smooth when your character moves. 
        myRigidbody.MovePosition(transform.position + change * speed * Time.deltaTime);
    }

}

Breaking the code down

Each frame  (the update() method)
void Update()
    {
       
        //Zero out the change
        change = Vector3.zero;
         //Get the current x and y as points on a graph
        change.x = Input.GetAxisRaw("Horizontal");
        change.y = Input.GetAxisRaw("Vertical");
        //print the change to the console 
        Debug.Log(change);
        if (change != Vector3.zero)
        {
            MoveCharacter();
        }

Let's get our change x and change y and store it as our change variable.

change = Vector3.zero;
         //Get the current x and y as points on a graph
        change.x = Input.GetAxisRaw("Horizontal");
        change.y = Input.GetAxisRaw("Vertical");
log to the console the change values
Debug.Log(change);

and IF our change value is not 0 (you can read up on if statements an expressions here )

if (change != Vector3.zero)
       {
           MoveCharacter();
       }
THEN MoveCharacter() Within the Move character we use a unity function to Move an object to the given position. There is some other math happening here but I'm not going to go into that today.
void MoveCharacter()
  {
      //transform.position is the player position
      // add the "change" (x and y modifications) 
      //Time.Delta is the amount of time that has passed since the previous frame 
      //So what we are saying here is: Move my character TO my current poistion + the changes I asked to make (direction) * my current speed * the amount of time that has passed.
      //this last piece about the time change is to make it look more smooth when your character moves. 
      myRigidbody.MovePosition(transform.position + change * speed * Time.deltaTime);
  }

 

Finally! We are done and we can test.

Go back to the unity editor.

Hit play!

Hit the play button

 

 

 

 

 

 

Your scene should start and now you should be able to see the first fruits of your labor.

Try using the arrows keys or the WASD keys to move around. Your player should move around the screen!

One last thing for fun!

OK stop your game by pressing the Play button again.

Now go to your Hierarchy view 

Select your player from the hierarchy window. (Or click on him in the scene)

Look over to the inspector and find the Player Movement (Script) component.

As I mentioned earlier , because we made the speed variable public we can modify it in this view.

Just for fun change it to 44. Hit play again and now try to move.

If everything is working properly then you should run "a bit" faster than you did earlier.

I hope you had fun learning how to build a game in Unity and C#

If you like this series and want to see more head on over to my blog and sign up for my mailing list of leave me a comment.

Oldest comments (0)