Learning Unity 2D

by re-creating Mega Man

Well, before I can re-create Mega Man, I need some sprites. Some searching led me to this site, which has sprites for almost every game in the series! Very cool.

However, the resolution is teeny tiny, made for the NES. While I installed GIMP, I was curious if there were any superior pixel art re-sizing tools. I learned about MMPX which does some interpolation rather than just enlarging, and it seemed pretty cool. This web tool is simple enough to use: just drag the image over. I ended up liking “nearest” (which is just enlarging) anyway, though I may switch to MMPX later.

I created a new Unity 2D project, created a background 2D square, created a player GameObject, and I was on my way. Unity automatically slices the sprite sheet into sprites, which is nice, so I just started tossing spritesheets into a “Spritesheets” folder. I renamed some of the ones that I planned on using, and will probably rename others as I need them.

So, now I have Mega Man just flying through the air with his jump animation:

My next goal for today: using WASD to move him around. Equipped with my incredible tutorial-given know-how, I added a Rigidbody 2D to him and looked at some of the scripts that were provided by the tutorial to figure out how to move him around. I created a script, ran the game, and… he didn’t move. I got an error at the bottom about the input system not matching my script. Specifically, these lines:

float horizontalInput = Input.GetAxisRaw("Horizontal");
float verticalInput = Input.GetAxisRaw("Vertical");

A little later, I discovered the tutorial from Unity was using the old “Input Manager,” and my new project was set to use “Input System Package.” Well, as a software developer, I prefer using the latest tools whenever possible, so now I needed to figure out how to do so. Luckily, I stumbled upon this amazing video from a YouTuber named samyam, which got me all set up.

Basically, it seems Unity can auto-generate the controls with the new input system, which allows you to utilize events for different actions, rather than checking with each call to Update(). This seems more efficient to me, and definitely more clear and easier to manage. Other benefits include the coalescing of control schemes between keyboard, controller, etc. It seems a lot better in the long run.

Eventually, I had a controls assets:

So, now my controller script is using the PlayerInput and InputAction to move around, instead of whatever the Unity tutorial was using. Nice.

public float moveSpeed = 7f;
private InputAction _moveAction;
private Rigidbody2D _body;
private PlayerInput _playerInput;
private Vector2 _movement;

private void Awake()
{
    _body = GetComponent<Rigidbody2D>();
    _playerInput = GetComponent<PlayerInput>();
    
    _moveAction = _playerInput.actions["Move"];
    _moveAction.started += Move;
    _moveAction.performed += Move;
    _moveAction.canceled += Move;
}

private void OnDestroy()
{
    _moveAction.started -= Move;
    _moveAction.performed -= Move;
    _moveAction.canceled -= Move;
}

private void FixedUpdate()
{
    _body.linearVelocity = _movement * moveSpeed;
}

private void Move(InputAction.CallbackContext context)
{
    _movement = context.ReadValue<Vector2>();
}

Cool, cool, cool. Is this the best way of doing it? Who knows, but it works.

My next goal will be shooting bullets. My guess is that I’ll use the SpriteRenderer to change Mega Man’s sprite whenever the shoot button is pressed, and I’ll need to instantiate a projectile GameObject with a certain vector and velocity. I’ve seen whispers of a Animator component as well, so I may investigate using that. What’s the best solution? No idea, but hopefully I can arrive at something reasonable.

Posted in

Leave a comment