Control and Intro Screen

I decided to create an intro screen to give players a chance to become familiarized with the controls and for them to confirm they are ready before the game starts, after all the assets are loaded.

JpegScreenShot6

Intro screen (Appears after main scene has loaded)

By pressing the spacebar, the following image is loaded to inform the player of the controls:

Controls

Upon pressing enter on either of these screens, the screen moves forward into 3D space and fades out, creating a sense of diving into a  computer screen.

Feedback and changes

We received feedback from Supermassive Games’ Director of Design Steve Goss as well as our tutors.

This is a summary of the main points we gained from this feedback:

  • We already have the elements we need in the game, just need to work on refining them.
  • The green ‘mountains’ don’t look appealing and are better removed.
  • The broken moon with the debris is a nice touch and adds depth to the scene.
  • The shooting needs to be refined, it doesn’t feel as if the player is receiving any visual cue that they have missed the enemy because no bullet is fired.

Following up on this feedback we made the following changes to the game.

particleFXplusmoon

Removed the green mountains

They didn’t fit well in the scene and were causing lag, so it was for the best that we removed them.

 

Let the player shoot when they aren’t hovering over an enemy

By restricting the player’s bullets to only shoot when the player clicks on an enemy, we were lacking visual feedback for the player. The average ratio of mouse clicks to bullets fired was heavily imbalanced and this proved to be an issue.

 

Faded reticle

The reticle is now set to 20% opacity when not hovering over an enemy, and 100% opacity when over an enemy. This is a subtle cue for the player to shoot when hovering over the enemy, and keeps it from being overbearing otherwise.

 

Increase the amount of debris over time

Steve Goss recommended that we start with a large amount of debris on screen on the first stage, then make them gradually spawn in the center of the screen more commonly as it gets closer to stage 5.

 

Reworked particle effects

I reworked the particles to fit the theme of our game more. Previously, we were using an elemental effects pack to trigger an explosive effect on destroyed enemies, but it felt too dramatic. Since our theme is meant to be very digital I created a custom pixel-inspired explosion using the particle renderer and a plain square texture. It was subtle and fit our game more, and also didn’t lag at all in comparison to the previous effect, which would lag if too many enemies were destroyed at once.

A similar effect was put on a loop in our scene, with particles flying past the player. These particles also look like pixels but are much more translucent, so they look like air particles and gives the illusion of forward movement.

 

Added pickups

We felt we were lacking something and we already had experimented with a time slowdown function, so we decided to let this be accessed through a pickup that adds to a gauge. This let onto us experimenting with other ideas such as invincibility and health. I also implemented a magnet mechanic that attracts pickups to the player if they go within a certain radius of them, as I had noticed during playtesting that at times it was hard to actually collide with the pickups due to their small size. Details on individual pickups can be found here.

Pickups

Above are the four pickups I designed for the game.

Glitch Time

This pickup fills up a gauge next to the current life mugshot. If the player has at least one section of the gauge stocked up, they can activate Glitch Time at any point to consume one bar to slow down the game time temporarily.

 

MedKit

This pickup only spawns after the player has been damaged. It restores one of the player’s lives.

 

Nuke

This pickup destroys all enemies on screen. It will only drop rarely. This is a work-in-progress idea so we haven’t actually implemented it into the game yet, it depends on our progress in other aspects of the game as it is not essential, though it will help during later stages of the game.

 

Phase Mode

This pickup makes the player invincible for a limited amount of time, making them unable to take any damage. The player model also flickers giving it a digital, ghost-like effect.

 

 

 

 

Character animation -FINAL

I was able to rig the character again, this time using HumanIK and weight-painting the joints respectively.

paintweighttoolrig1

 

I recreated the previous animations and ended up with:

  • Float (idle) animation
  • Strafe animation (left)
  • Strafe animation (right)
  • Hurt animation
  • Shoot animation

 

Float animation

https://sketchfab.com/models/ae9986316f814304a8f43217c863917c/embed

Ikarus idle float animation
by Boma
on Sketchfab

animnew1

animnew2

 

Shooting animation

https://sketchfab.com/models/105e7f0553a043d6bacaeaa589935433/embed

Ikarus shooting animation
by Boma
on Sketchfab

animnew3

Hurt animation

https://sketchfab.com/models/17ed0d8730114a2785bfc5d5d1b3c4c3/embed

Ikarus hurt animation
by Boma
on Sketchfab

I was able to import these animations into the game via the Game Manager in Maya.

Character animation draft

I experimented with rigging and animations with our current character model. In doing this I was fully prepared to recreate each animation in case something went wrong with the rig, so there were essentially a draft.

I created a custom rig and animated the following:

 

An idle ‘float’ animation to use as a base for other animations

anim2  anim4_1

A hurt pose (returns to the default float animation after duration)

anim3

A shooting animation

anim1

A strafe animation

anim4_2

 

Doing these tests brought some issues to light and gave me some knowledge the was useful for the final product.

anim5_shoulderandelbowmovementdocumentthissss

  • HumanIK is a more efficient way of rigging human models
  • Without using weight painting the model deforms and bends in places it shouldn’t.
  • The model should be textured before advancing with rigging and animation
  • Something is wrong with the import method that was used, as these were some of the final imported results:

why imsofuckingdone

Knowing that I needed to start from scratch, I started by seeing if I could use the transform attribute tool to transfer the vertex values of the fully UV mapped model.

transfer_attributes

After an unsuccessful attempt I decided it would be best to just start again with newly obtained knowledge and some good practice.

 

 

07/03/16 Update: Debug mode + Gameplay

Over the past couple of weeks I was able to implement these features:

 

Heads Up Display

I made some HUD components to make the game information clearer to see.

HUD_L

Score + multiplier component

HUD_R

Lives component

HUD_vign

Visor component

We were on the fence about keeping the visor component in as it implies that the player is in first person when they are actually playing in third-person, but it had good synergy with the chromatic aberration effect so we decided to keep it in.

First person HUD GUI_scoreGameShot

Chromatic Aberration impact effect

I took the chromatic aberration effect further and made it so the amount of chromatic aberration spikes briefly when the player is hit, then decreases back to the value I previously set, which when used in conjunction with the visor HUD component creates a burst/pulse effect on the edge of the screen similar to a screen shake. This is useful for giving visual feedback on the player’s current status and it gives the illusion of an impact.

hurt gif.gif

(Hard to see blinking hurt animation because of GIF framerate)

Bullet system rework

My previous solution to our shooting problem was to spawn the bullets inside of enemies, causing them to die when clicked. I’ve been able to code a way for bullets to fly directly towards individual enemies allowing for  a cleaner looking shooting system. The major issue that seems to have popped up through feedback is that it gets harder to click directly on the enemies as time progresses due to it being such a specific thing. I think a lock-on mechanic would fix this problem easily, however  we may not have enough time to implement a thorough system.

shooting gif

 

Stage system

I have implemented a stage system that increases the stage in intervals of 8000 points. This is a temporary interval as our score acquisition rate increases with time meaning that jump from stage 1 to stage 2 is much longer than the jump from stage 4 to stage 5. It will take a lot of trial and error and testing to get more accurate numbers or it might even require an alternate stage progression method. The current stage is displayed at the top of the screen.

stage switch gif

Global Speed

There is now a global speed variable that is applied to all moving assets of the game such as enemies and obstacles, making the game feel faster depending on the current stage number.

Enemies increase in frequency as stage progresses

As the stage number increases so does the enemy spawn rate, making it harder as the player progresses. I intend on changing this from simply spawning more of the same enemy to spawning more difficult variations of our enemies or even new ones.

Debug Mode

Pressing escape in-game brings up the debug menu on the top of the screen.

This gives us the following options:

  • F1-F5: Skip to stage
  • F6: Have a bad time (Insta-kill player for testing purposes)
  • F7: God mode (Invincibility state. Turned off when debug menu is closed)

debug mode

High score system

The high score is now shown on the pause/game over menu. This is only stored while the game is open, meaning the value is lost once the game is closed. My next goal in this area is to store the high score to a local file allowing it to remain consistent between game loading. As a stretch goal we could have a leader board system implemented.

 

Ikarus 19/2/16 Update: Aesthetics

In the past week I was able to implement these features:

Enemy Fading

Enemies now fade in when they spawn to help them transition into the scene better. I also had to move the spawn point backwards slightly to give the player more of a chance to realise where the enemies are spawning from.

enemy fade spawn gif

Hurt Mode

I implemented a ‘hurt mode’ system, which makes the player flash rapidly when they lose a life upon contact with enemies and gives them invincibility frames. It also stops their movement for a brief duration during this mode. The mode’s duration lasts around a second.

god mode and hurt mode gif

Ikarus Mugshot

I was able to include the character mugshot with visual feedback relative to damage taken.

87616b55bf4b49a06f607d8ab049f640

The portrait shakes and changes depending on how much damage the player has taken.

Sprites:  IkarusMug_1.fw    IkarusMug_2.fw    IkarusMug_3.fw

Code:

	   if (PlayerDamageAndDeath.playerLives == 2)
       {
			myImageComponent.sprite = TwoLivesMug;
			anim.SetInteger("Lives",2);
       }
        
         if (PlayerDamageAndDeath.playerLives == 1)
       {
			myImageComponent.sprite = LastLifeMug;
			anim.SetInteger("Lives",1);
       }

		if (PlayerDamageAndDeath.playerLives == 0)

		{
			myImageComponent.sprite = LastLifeMug;
			anim.SetInteger("Lives",0);
		}

 

Vignette and Chromatic Aberration

I was able to incorporate this into the game and merge it with my ‘PlayerDamageAndDeath’ script, the script that manages the player’s lives.

(Chromatic aberration effect, before taking damage and after taking critical damage)

The more damage the player takes, the more chromatic aberration is added, making it look more distorted. I experimented with camera animation alongside this as I thought it would be a good mix, but it turns out it was a bit disruptive in terms of control and I had some issues due to the use of multiple cameras.

Key code:

		Component dofs = GameObject.Find("Main Camera").GetComponent("VignetteAndChromaticAberration");
		vin = dofs.GetType().GetField("chromaticAberration");
		vin.SetValue( dofs, hitDistort);

 

Chain Bonus

I set up a primitive enemy chaining bonus system that increases the duration of the multiplier as well as the value depending on how many enemies the player has destroyed before a certain time limit. This code can be improved upon in the future as it only checks once how many enemies have been destroyed and then adds that to the remaining time.

scoremultiply

I was also able to use the animator to set up a system that hides the multiplier when it has a value of 1 (inactive) and fades it in when the multiplier activates (anything > 1). The fade out animation can be cancelled by starting another chain.

 

Stage System (early stages)

I laid the foundations for a stage system that I will be making more use of as we form plans for how the stages will work. We are currently aiming for something similar to Tetris, so the stages will get harder the further the player progresses, and we aim to let the player return to later stages once they’ve been completed or gotten to. Currently the stage progression is determined by the player’s score at intervals of 8000.

Code:

public static int currentStage = 0;
	public int Stage;
	public static bool stage1 = false;
	public static bool stage2 = false;
	public static bool stage3 = false;
	public static bool stage4 = false;
	public static bool stage5 = false;

	void Start () 
	{
		stage1 = true;
	}

	void Update () 
	{
		Stage = currentStage;
	
		if ((ScoreManager.score > 0 && ScoreManager.score < 7999) || stage1 == true) 		{ 			Debug.Log ("STAGE 1 ACTIVE"); 			currentStage = 1; 		} 		if ((ScoreManager.score > 8000 && ScoreManager.score < 15999) || stage2 == true ) 		{ 			Debug.Log ("STAGE 2 ACTIVE"); 			currentStage = 2; 			stage1 = false; 		} 		if ((ScoreManager.score > 16000 && ScoreManager.score < 23999)|| stage3 == true) 		{ 			Debug.Log ("STAGE 3 ACTIVE"); 			currentStage = 3; 			stage2 = false; 		} 			if ((ScoreManager.score > 24000 && ScoreManager.score < 31999)|| stage4 == true) 		{ 			Debug.Log ("STAGE 4 ACTIVE"); 			currentStage = 4; 			stage3 = false; 		} 				if ((ScoreManager.score > 32000) || stage5 == true)
		{
			Debug.Log ("STAGE 5 ACTIVE");
			currentStage = 5;
			stage4 = false;
		}
	}

 

 

 

Life system implementation

I was able to add a life system into the game today. It works by making the player go invisible on enemy collision to imply invincibility frames until the life count has  decremented to the point that the player gets a game over.

Key lines of code:

public int playerLives = 3;

void Start ()
    {
	Debug.Log("Lives:"+playerLives);
        rend = GetComponent();
        rend.enabled = true;
    }

void OnTriggerEnter(Collider col)
	{
		if (col.gameObject.tag == "Enemy" && GodMode == false)
		{   
            if (playerLives <= 1)             {                 Destroy(gameObject);                 PlayerDie.PlayerAlive = false;                 Debug.Log("Death via enemy");             }             if (playerLives >= 2)
            {
                // Health = Health - 100f;
                playerLives--;
                Debug.Log("Player lost a life");
                Debug.Log("Lives:"+playerLives);
                StartCoroutine(blinkTime());
            }

 IEnumerator blinkTime()
    {
        rend.enabled = false;
        yield return new WaitForSeconds(1f);
        rend.enabled = true;
    }

Lives system

I did some research on ways to implement the lives into the HUD and found these examples:

Starfox

Starfox (SNES)

Starfox uses a “Lives x (number of lives)” format which I thought would be quite useful for our game, but decided against it as it implies that the player respawns on the spot which we wanted to avoid. We wanted something that properly showed that the player was getting damaged.

Super street fighter 2

Super Street Fighter 2 – Ryu Portrait

We looked at games that gave feedback of procedural damage to the player and decided that this was a good direction to go in, so I plan to use a similar format for our game. I’ll design a mugshot sprite of the main character with alternative damaged versions.

KHCoM

Kingdom Hearts: Chain of Memories Health HUD

Score multiplier system

Today I was able to implement a score multiplier system. We thought this would be essential for some variation for high scores if we want to include leaderboards.

scoremultiply

Early implementation of HUD multiplier feedback

My next step for this is to set it up so that when the multiplier is not active (when it has a value of 1) it will be hidden.

Code (added to exisiting score manager code):

void Update()
    {
        if (PlayerDie.PlayerAlive == true && pauseGame.paused == false)
        {
            score = score + (scorescale * scoreMultiplier * Time.time); //score growth rate increases over time

            //will add code to make score scale reset to 0 every time damage is taken.

            TextScore = scoreScreen.GetComponent();
            TextScore.text = Mathf.Floor(score).ToString();

            Multiplier = scoreMultiplier;
            //for public inspector feedback on multiplier

            MultiplyScore.text = Mathf.Abs(scoreMultiplier).ToString("0.#");

            ScoreMultiply();
            //run score multiply control system
        }
    }

void ScoreMultiply()
    {
        if (scoreMultiplier > 1f && ResetOK == false)
        {
            ResetOK = true;
            StartCoroutine (MultiplyReset());
        }
    }

    IEnumerator MultiplyReset() //resets the multiplier to 0 after shooting no enemies for a certain amount of time

    {
        yield return new WaitForSeconds(MultiplierResetTime);
        scoreMultiplier = 1f;
        ResetOK = false;
    }