Tuesday, October 23, 2018

2D Platformer Character 1 / 4 - Basic Movement

Lets make a character for simple 2D platformer type game. I prepared archive with all needed bitmaps here, but feel free to use your own. I used sprite sheet for a cat from opengameart.org, while platform graphics was made by one of super talented participants of our workshop.
Create new 2D project and put all bitmaps in Assets folder. Lets start with making some ground for our character to walk on. Since we want our block to be tiled, we need to change 'Mesh Type' in its import settings to Full Rect. Additionally, change 'Filter Mode' to point if you are going for pixelated look. Once its done, you can put your ground in the scene. Change 'Draw Mode' to Tiled, which will enable you to extend ground as much as you want (with the marked tool in upper left corner), and bitmap will just tile automatically. Also, add Box Collider 2D and check it's 'Auto Tiling' property, so our player wont fall through the ground.
Now we can prepare player character sprite by slicing it. Select cat_idle bitmap, change 'Sprite Mode' to Multiple, and click on the 'Sprite Editor' button. You can also change 'Filter Mode' to Point too if you prefer pixelated look. Within Sprite Editor, open Slice menu and set slicing parameters. We know that each frame in our sprite sheet has size of 64x64 pixels, so it's easiest to pick 'Grid By Cell Size' and set cell size to 64x64. Press Slice when you are done and you can close Sprite Editor. Now we can finally add sprite of our player character to the scene. Select all 4 frames of our 'cat_idle' animation (with SHIFT key) and just drag them into the scene. Unity will ask you for name of new animation, name it cat_idle. If you now enter play mode, you should see your character playing 'idle' animation. However, it might look a bit too small, because most likely camera has incorrect size. Unfortunately, correct size will vary depend on game's window size. On the bright side, we can make script that will update camera automatically. Create and add following script PixelCamera.cs to your Main Camera in the scene.
using UnityEngine;
 
[ExecuteInEditMode]
public class PixelCamera : MonoBehaviour
{
    void Update()
    {
        var c = GetComponent<Camera>();
        if (c != null && c.orthographic)
        {
            c.orthographicSize = Screen.height / 200.0f;
        }
    }
}
Now our game should look nice and crisp. It's time to make our player move around. First, create script PlayerCat.cs
using UnityEngine;
 
public class PlayerCat : MonoBehaviour
{
    public float movementForce = 15;
 
    // References for various components to use later
    private SpriteRenderer sr;
    private Rigidbody2D rb;
 
    // Use this for initialization
    void Start()
    {
        // Find our components
        sr = GetComponent<SpriteRenderer>();
        rb = GetComponent<Rigidbody2D>();
    }
 
    // Update is called once per frame
    void Update()
    {
    }
 
    // FixedUpdate is called every Time.fixedDeltaTime
    void FixedUpdate()
    {
        // Get value of horizontal axis (left/right arrow or a/d keys),
        // returns value in range [-1.0f, 1.0f]
        var h = Input.GetAxis("Horizontal");
 
        // Flip sprite depending on horizontal input
        if (h < 0.0f)
            sr.flipX = true;
        if (h > 0.0f)
            sr.flipX = false;
 
        // Move player according to horizontal axis
        rb.AddForce(Vector2.right * h * movementForce, ForceMode2D.Force);
    }
}
Select our player GameObject (it's probably still called 'cat_idle_0') and change its name to something sensible, like 'cat'. Then, add 'Rigidbody 2D', 'Capsule Collider 2D' and our new PlayerCat.cs script to it. Make sure to set marked parameters accordingly, although feel free to experiment with them, especially with 'Linear Drag' and 'Movement Force'. If all went good, you should be able to move your character around with arrow or a/d keys. Currently, our cat just slides around instead of walking, let's make them walk. Prepare cat_walk animation in exactly the same way like you did with cat_idle, by slicing it and then dragging all frames into the scene, and calling new animation 'cat_walk'. You can delete 'cat_walk_0' GameObject from the scene and 'cat_walk_0' Animator from the assets afterwards, since these wont be needed. Now we have to add 'cat_walk' to our animator. If it's still called 'cat_idle_0', rename it to 'cat' and then double click on our animator to open Animator window. Add parameter 'Speed' of type float Drag 'cat_walk' animation into Animator to create new animation state and set it's Speed multiplier to our 'Speed' parameter. Now we need to tell Animator when to change from cat_idle state to cat_walk. Right click on 'cat_idle' select 'Make Transition' and click on the 'cat_walk' to make transition. With new transition selected, uncheck 'Has Exit Time', change 'Transition Duration' to 0, and add new condition, 'Speed > 0.01' to it. Now make opposite transition, just with condition 'Speed < 0.01'. Finally, lets modify PlayerCat.cs script to set Speed parameter in Animator according to character's horizontal velocity.
using UnityEngine;
 
public class PlayerCat : MonoBehaviour
{
    public float movementForce = 15;
 
    // References for various components to use later
    private SpriteRenderer sr;
    private Rigidbody2D rb;
    private Animator anim;
 
    // Use this for initialization
    void Start()
    {
        // Find our components
        sr = GetComponent<SpriteRenderer>();
        rb = GetComponent<Rigidbody2D>();
        anim = GetComponent<Animator>();
    }
 
    // Update is called once per frame
    void Update()
    {
        // Set Speed parameter to absolute value of our horizontal speed
        anim.SetFloat("Speed"Mathf.Abs(rb.velocity.x));
    }
 
    // FixedUpdate is called every Time.fixedDeltaTime
    void FixedUpdate()
    {
        // Get value of horizontal axis (left/right arrow or a/d keys),
        // returns value in range [-1.0f, 1.0f]
        var h = Input.GetAxis("Horizontal");
 
        // Flip sprite depending on horizontal input
        if (h < 0.0f)
            sr.flipX = true;
        if (h > 0.0f)
            sr.flipX = false;
 
        // Move player according to horizontal axis
        rb.AddForce(Vector2.right * h * movementForce, ForceMode2D.Force);
    }
}
Congratulations, you now have animated 2D character. In next part, we will teach our cat how to jump :3

No comments:

Post a Comment