A day of great progress

Some days things just seem to click and then you get on a roll and just work for 15 hours straight. Yesterday was one of those days. While I’ve been working on FYP in the time between yesterday and this post I’ve previously found myself in a bit of a rut when it comes to prioritising which projects to work on at any given time. Yesterday a lot of things just fell into place and I hit that right groove of motivation.

 

4a08a2c179e8d59aab3c89c861120e58.thumb.png.8242d3966b570460e1538d159c9c168a.png

The most immediate improvements were made in the addition of a title (I never came up with a better one, but I find this has a certain cynical charm) and a background, the background simply being a royalty free cartoon-styled wood texture to fit the book and the general aesthetic.

I also put together 5 separate stages to go alongside the basic “Battlefield” layout from before.
Levels:
Ball (pictured below) features this curved platform, actually the top of a much larger position locked ball. This ball, while position locked, is not rotation locked and therefore is affected by the movements of the 4 players who fight upon it.

d6cf7acb0e9edb3c0c614a2b31cc59a0.png.8dda42331680a2d375633b97e6d4f206.png

Sway (pictured below) looks humble. However, this single platform can move freely from side to side and, like the ball, is fully under the influence of the game’s physics. This means that swinging too wildly in one direction, or even having multiple people run, can plummet players to the killplane at the bottom of the stage.

5201344301dc1a9d896bdcfac15b9ef5.png.aab585a7732ab43a26c8c8a1ad5d835d.png

Slant (pictured below) is a fairly simple stage with no gimmicks beyond platforms being slanted.

ab2777952199e26dc7db1ca181186306.png.21758cbfd060649388ea4306ef3ed5de.png

Spin (pictured below) is a group of smaller platforms making up one floor, each platform is position locked but not rotation locked, allowing them to spin around their central axes. This can either cause a cascade effect or cause what was once floor to become, for all intents and purposes, a trapdoor to the killplane.

be8a7e919b680ee33640933f43d79bcd.png.212b29800ef6541d066f9af6d2b6780c.png

and last but by no means least, Box. Box is my favourite stage because of the sheer chaos it provides. The box, like many other obstacles, is position locked but not rotation locked, allowing it to spin. The chaos, however, is that all four players and any weapons that spawn are in the middle of the box, with its sides walling them in. The box also has a rather low mass, meaning it’s spin can get rather wild at times.

f4cbf9b5738d4ceea0806a118bd9d9ef.png.2d8cc397893c2ab06e426fedda84299a.png

These stages are selected at random whenever a match is finished.

 

 

Weapons also got some additions, there are now 3 types: The sword, the spear and the knife. Weapons also clash with eachother now, meaning that it’s harder to simply run through an aware opponent; if you collide weapons you now both get blown back. This not only affords a defender some relief from simply being run at but also allows a clever attacker to force people off of platforms with weapon knockback. There is stil a persistent bug which has vexed me since I first implemented weapon pickups though:

 

This is how a sword is meant to be held. Or, at least here it is.

07844a4fe171854660111b0876f381d4.png.e662e98e7b949fc06ca905daeab303a4.png

However if you approach a pickup from certain angles this is what you get:

635ae03daced10a948b6fe98b951260a.png.d3e1e2fc65478de4b31947c444614b7e.png

Neither lecturers nor myself have been able to figure out a fix that has stuck yet, but it seems intermittent enough that it doesn’t break the fun of the base game, it’s just a time-to-time annoyance.

 

Controller support has also been fully added. While not completely drop-in, drop-out it allows for 2 to 4 players, adding more characters the more controllers are connected and if 4 are connected replacing the keyboard, allowing for full 4 person local multiplayer without needing the keyboard. The only constraint to this system is for unity to update the gamepads the game needs to be relaunched. It also only supports XInput, I couldn’t figure out how to get DInput working with Luminosity.

public void AddPlayers()
    {
        Luminosity.IO.InputManager.Reinitialize();
        string[] names = Input.GetJoystickNames();
        foreach(string name in names)
        {
            print(name);
        }
        
        
        Luminosity.IO.ControlScheme scheme = null;
        for(int i = 0; i < 4; i++)
        {
            switch (i)
            {
                case 0:
                    if(names.Length >= 4)
                    {
                        Luminosity.IO.InputManager.SetControlScheme("Gamepad 04", Luminosity.IO.PlayerID.One);
                    }
                    else
                    {
                        Luminosity.IO.InputManager.SetControlScheme("Keyboard", Luminosity.IO.PlayerID.One);
                    }
                    
                    scheme = Luminosity.IO.InputManager.PlayerOneControlScheme;
                    
                    break;
                case 1:
                    if (names.Length >= 1)
                    {
                        Luminosity.IO.InputManager.SetControlScheme("Gamepad 01", Luminosity.IO.PlayerID.Two);
                    }
                    else
                    {
                        players[i] = false;
                    }
                    scheme = Luminosity.IO.InputManager.PlayerTwoControlScheme;
                    break;
                case 2:
                    if (names.Length >= 2)
                    {
                        Luminosity.IO.InputManager.SetControlScheme("Gamepad 02", Luminosity.IO.PlayerID.Three);
                        
                    }
                    else
                    {
                        players[i] = false;
                    }
                    scheme = Luminosity.IO.InputManager.PlayerThreeControlScheme;
                    break;
                case 3:
                    if (names.Length >= 3)
                    {
                        Luminosity.IO.InputManager.SetControlScheme("Gamepad 03", Luminosity.IO.PlayerID.Four);
                    }
                    else
                    {
                        players[i] = false;
                    }
                    scheme = Luminosity.IO.InputManager.PlayerFourControlScheme;
                    break;
                default:
                    scheme = null;
                    break;
            }

            if (scheme != null && scheme.Name != "None")
            {
                print(scheme.Name);
                players[i] = true;
            }
            else
            {
                players[i] = false;
            }

        }

        
    }

This is the player handling code. As you can see most of it is being taken care of by the incredibly useful InputManager addon by Daemon3000.

 

 

The placement of weapons in levels is now also implemented properly. I have created a weaponSpawner script which gets a pool of all of the weapons in the game and then creates Instances of them at all of the child locations of it. This allows me to infinitely scale how many items I put in a level without having to rely on random drops or moving a bunch of classes around. I feel this is the most lightweight solution.

public List<GameObject> weapons;

    void Awake () {
        weapons.AddRange(Resources.LoadAll<GameObject>("Weapons"));

        for(int i = 0; i<transform.childCount;i++)
        {
            GameObject weapon = weapons[Random.Range(0, weapons.Count)];
            GameObject newWeapon = Instantiate(weapon, transform.GetChild(i).position, Quaternion.identity) as GameObject;
        }
    }

A rather simple solution, but works very well in my experience.

 

Similarly, level switching is now done via index rather than a list. This means I can add new levels without worrying about updating a stagelist in the level manager; I only need to make sure the build settings are updated.

238fcabaa167a14169a75f70697929a0.png.932a533597c111e8c156e4a512745e00.png9a50660ca8054b2d26bb363b59fccb18.png.201c5b6907f5def825400dbf58e193d1.png

As a final touch of polish and readability (above) I added weapon trails to the weapons that change colour depending on the player that’s using them. The purpose of these, besides looking nice, is that they clearly display exactly where the hitbox of each weapon is, meaning players can easily read their effective ranges.

Inverse Kinematics – Progress

So I’ve been making decent progress in my studies of Inverse Kinematics. I’ve switched from using Unity’s WIP system to Anima2D, which while not technically supported in this version of Unity works just fine.

I got animating this version working fairly quickly¬†and am still rather proud with how fast I’ve learned this system.

Making it play ball with the physics system, however, presented it’s own challenge.

I actually contacted LandFall games for help here, but upon receiving nothing I can work with I eventually toughed it out and figured the system out on my own.

Now we’re getting somewhere. The arms are stiff and the weapon physics are wonky, but it is something.

Inverse Kinematics

So my prototype has required learning an entirely new field of animation I wasn’t really versed in: Inverse Kinematics and Procedural Animation.

The best part of this is that the feature isn’t even properly in the current build of Unity; Inverse Kinematics is in beta. However I need it, but the current implementation is lacking in a key feature; it doesn’t support objects made of multiple other objects. This presents a notable blockade in my way if I want to retain my stickman dismemberment.
Nonetheless today has proved a useful step in understanding Inverse Kinematics and this step will definitely get me to my goal quicker than I would have before. Even if I have to take a step or two backwards first.

Beginning a new Project

Today I start work on my Final Year Project. I know I haven’t posted particularly much on the blog side of this since I started, or at all, but I want to change that to have a real chronicle of my improvements and findings throughout making this.

I’ll post my initial designs when they are properly formulated.