Player GameObject v1

Version 1 of the PlayerController.cs Script

Animated Player GameObject

Follow directions in the Animator Controller, Animation Steps section to create an animated player and assume that all references to the Player below are using that Animated Player GameObject.

Moving GameObjects: RigidBody2D

Then we need to attach a RigidBody2D component to our Player gameObject. The Unity Manual explains that we need to add a RigidBody2D component so that we can use the Unity Physics Engine to move our Player in the scene. We can update the player's RigidBody.velocity or add a force to the RigidBody2D each frame in response to the user key-presses, to cause the gameObject to move in a realistic way.

RigidBody2D

In the PlayerController code below, we write code to allow the user to move the player using various keyboard input. We're using the UnityEngine Input default mappings so we want to provide access to move the player along the horizontal and vertical axis. We need to use a RigidBody2D component because it allows us to use UnityEngine physics engine to create realistic character movement.

Unity RigidBody Documentation 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. Rigidbody 2D, the difference that in 2D, objects can only move in the XY plane and can only rotate on an axis perpendicular to that plane. Remember to set gravity to 0 if you don't want gravity acting on your gameObject. 1. Add a Rigidbody2D to the Player gameObject. Expand the constraints option and check option to Freeze Rotation: Z as true.

2D-Colliders

Collider interactions Colliders interact with each other differently depending on how the Collider and Rigidbody components are configured. Collider Components define the shape of an object for the purposes of physical collisions. A collider, which is invisible, does not have to be the exact same shape as the object’s mesh. A GameObject that has a Collider but no RigidBody component will act like an immovable object that other objects can run into, the collider gives the gameObject a physical presence in the scene. When isTrigger is selected, then the collider does not show physics-based collision behavior, instead, an event is generated that can be used to execute related actions or behaviors.

2. Add a Collider2D to the Player gameObject. Adjust the boundary to fit the player sprite. I have used a Capsule Collider2D, you can use other types of colliders to fit your sprite.

Constrain Player Movement using Box Collider to create a Floor

If we want to constrain the player, to keep her on the screen, we can create an empty game object and attach a collider2D component to that gameObject. We can use this to create a floor in our scene, this will allow us to have a non-zero value for gravity on our player's Rigidbody2D component. We can also create a leftBorder as an empty gameObject, again, add a BoxCollider2D component. If we don't set this gameObject to be a trigger, then it will act as a physical barrier to our playerGame object so it can't leave the camera view area.

3. Create an empty gameObject: name: Floor, attach a collider2D, add an icon by selecting the leftmost dropdown in the top section of the inspector.

PlayerController Code: v1

Create a C# Script: PlayerController in the Scripts folder of your project's Assets. Double-Click on the script to have it open Visual Studio so you can edit the script. You can copy and paste the code from below into the script. In Visual Studio, build the script to compile the code so it can be used in Unity. Add the PlayerController.cs script as a component to the Player GameObject.

This script requires an Animator Component on the Player GameObject

Create C# Script: PlayerController.cs

In this version of the PlayerController script, we'll add logic for Horizontal movement using the Rigidbody2D component. We'll also add a method: Flip( ) that will use to reverse the sprite if necessary so that it faces the direction of movement. We'll add variables for forceX, the magnitude of horizontal force applied to the gameObject each frame that the player is in the walk state. In this version of the code, we'll zero-out the velocity

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

public class PlayerController : MonoBehaviour
{
    public enum HeroState {idle, walk, jump }    //CONSTANT:  Custom data-type - integer using words

    public HeroState currentHeroState; //instance of a variable using our custom data-type

    private Animator animator;  //object reference variable - null, null reference exception - initialization error
    public bool facingRight;   //default is that this is false, facing left
    private Rigidbody2D rb2D;

    public float forceX; //stores force for movement in horizontal direction

    // Start is called before the first frame update
    void Start()
    {
        currentHeroState = HeroState.idle;  //we can see the current value in inspector
        animator = GetComponent<Animator>(); //initialize by connection to gameObject component
        animator.SetInteger("HeroState", (int)HeroState.idle); //misspelling will give run-time error in Unity
        facingRight = true;
        rb2D = GetComponent< Rigidbody2D >(); //connect with component on same gameObject
        forceX = 100.0f;
    }

    // FixedUpdate is called with constant-time between each execution
    void FixedUpdate()
    {
        float inputX = Input.GetAxis("Horizontal"); //-1, 0, 1 values for L,R arrows, a, d
        bool isWalking = Mathf.Abs(inputX) > 0;  //left or right walking movement

        if (isWalking)
        {
            animator.SetInteger("HeroState", (int)HeroState.walk); //send signal to animator
            currentHeroState = HeroState.walk;

            if ( facingRight && inputX < 0) //facing right, moving left
            {
                Flip(); //flip to make facing left
            }
            if( !facingRight && inputX > 0) //facing left, moving right
            {
                Flip(); //flip to set facingRight
            }
            ////ADD MOVEMENT LOGIC - HORIZONTAL
            rb2D.velocity = new Vector2(0, 0);  //set velocity to 0 x, y
            rb2D.AddForce(new Vector2(forceX * inputX, 0));  //
        }
        else 
        { //set back to Idle, if it was walking,jumping in last frame
            animator.SetInteger("HeroState", (int)HeroState.idle);
            currentHeroState = HeroState.idle;
        }

        //check for spacebar or w, up keys to indicate vertical jump
        bool jumpPressed = Input.GetButtonDown("Jump") || Input.GetAxis("Vertical") > 0;

        if (jumpPressed)
        {
            animator.SetInteger("HeroState", (int)HeroState.jump);
            currentHeroState = HeroState.jump;
            ///ADD VERTICAL MOVEMENT LOGIC
        }

    } //end FixedUpdate

    private void Flip()
    {
        facingRight = !facingRight; //toggle to opposite value 
        //  transform is a variable initialized to refer to the current gameObject's transform component
        //Common pattern when working with vector values in Unity
        Vector3 theScale = transform.localScale; //initialize temp Vector3 with current transform values
        theScale.x *= -1; //multiple current Scale.x by -1
        transform.localScale = theScale;
    }

} //end PlayerController

Last updated