GitHub Game Off 2016 - Day 3

Today I started getting basic movement working. Having done this implementation for the Entelect Jam already it was quite quick pulling it in. Unfortunately I did not have time to look at pulling in the calculations for gravity interaction between objects, but that's most likely going to take a few days to tweak so I'm not that worried.

Unfortunately I've also not had time or tools installed to get some concept art into the game yet so I don't have any screenshots yet. I'm most likely going to need some concept art soon as knowing what direction your ship is facing helps out a ton! I do have some code samples of what I implemented today.

Codes or it did not happen!

So I'm trying to build small little components that I can then compose on GameObjects in Unity to build more complex usable features with. I've thus split the movement into two sections. The first section is the thruster:

using UnityEngine;  
using System.Collections;

public class Thruster : MonoBehaviour  
{
    public float Speed = 10.0f;

    private Rigidbody2D body;
    private Vector2 force;

    // Use this for initialization
    void Start()
    {
        this.body = GetComponentInParent<Rigidbody2D>();
    }

    // Update is called once per frame
    void Update()
    {
        var input = Input.GetAxis("Vertical");
        var thrust = input > 0 ? input : 0;

        Vector2 force = new Vector2(0, thrust * Speed);
        var rot = Quaternion.Euler(0, 0, this.body.rotation);
        this.force = rot * this.force;
    }

    void FixedUpdate()
    {
        this.body.AddForce(force);
    }
}

This looks more complex than it really is so I'll quickly explain it a bit. On script startup it will get a hold of the Rigidbody2D component on the main ship object (I'm grouping scripts onto a child object to try and fight some clutter hence the use of GetComponentInParent). Then once per frame the current Vertical axis input is retrieved and sanitized so that we only get the positive input. This positive input is then multiplied by a set amount of thrust and stored in a Vector2 variable. The next step is to then apply the ship's current rotation to the force to ensure that it is applied in the correct direction and store it in the private force variable.

Then in the FixedUpdate method that will be called a set amount of times a second (it's about 60/s) is used to apply this force using the private force Vector2 variable. The reason for splitting the calculation and application of the force is to account for the differences in timing that the Update and FixedUpdate methods produce. We provide input on what we see, hence why input is calculated on Update. Then once we've calculated the input it can be applied as a constant so if it takes 2 FixedUpdate calls for a next frame to render the force will be applied for both calls.

The next piece of movement functionality is the rotation. This was also just a small bit of code:

using UnityEngine;  
using System.Collections;

public class Rotate : MonoBehaviour  
{
    public float Speed = 10.0f;
    private Rigidbody2D body;
    private float torque;

    // Use this for initialization
    void Start()
    {
        this.torque = 0;
        this.body = GetComponentInParent<Rigidbody2D>();
    }

    // Update is called once per frame
    void Update()
    {
        this.torque = -Input.GetAxis("Horizontal") * Speed;
    }

    void FixedUpdate()
    {
        body.AddTorque(torque);
    }
}

Again the rotation is doing the same in using the Rigidbody2D component to apply rotational forces. The basis of this is to use the Horizontal input and multiply it with a rotational speed multiplier to calculate a torque to be applied.

There is some hidden magic in order to get some of this to work, the first being that you have to go and update the project settings for the Physics2D engine to not apply a gravitational force in any direction. We're in space and everything is scaled down enough that one generic gravitational force is not flexible enough to use. The other configuration was to ensure that the ships Rigidbody2d component experiences a generous enough force of friction when rotating.

With initial playtesting of Gravity Fight I found it quite difficult to effectively bleed of rotation, so my answer was to have some friction applied when rotating. This insured that a player can't spin out of control and end up with an uncontrollable experience. There's enough chaos going around just having asteroids exert a gravitational pull on you to have to worry about stabilizing rotation and balancing your thrusting vector.

I do have plans to break these components up even more and to have an easier to control "Domain" within the game, but I first need to hack together some implementation before I start fiddling with making the game system easier to work with. That's it for today!

Sas van der Westhuizen

Intermediate Software Engineer at Entelect; "engineering" since 2015; loves games, rock climbing; been trying my hand at making games, but nothing good yet!

Johannesburg, South Africa