Development Blog (Week 4)


Development Blog (Week 4)

I added in lose conditions, scoring and combo systems, as well as visual changes like creating a shader which makes buildings crack!

Published on December 09, 2019 by Amy Elliott

C# Programming Unity Shaders & Technical Art Dev Blog College

20 min READ


Please note: The code and content within this blog post is not representative of my current skills.


Week Number & Date: Week 4 - 09/12/19

List of Tasks planned for this week:

Task List

I started my task 5 early since I felt like I was ready to start it, this is the week where I start properly developing my game, making it FUN to play, since I feel like my game at the moment isn’t fun at all.

Current Position -

What did I do this week?(Screenshots/Videos/Photos & annotations)

Unity - Lose Condition

Task

This one wouldn’t take too long to implement since the code for this is very very simple to plan out.

collision

I started with making a tag named Ground, I need to do this since it’s an easier way to check what the player is colliding with rather then checking the name of the object which they are colliding with etc.

ground tag

I do this for all of the ground objects, since there a 3 which are spread out, and I also put these ground objects into an empty object which I named Ground.

From here, I then made a new script which I’m calling Char Collision, this is so we can keep track of what the player is colliding with.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class _CharCollision : MonoBehaviour
{
    // This is a private bool which tells us if the player is colliding with the ground or not with a true or false statement
    private bool touchingGround = false;

    void Update()
    {
        // This here is an update function which checks if the player is touching the ground or isn't touching the ground
        // and then prints out to the console that they're touching the ground or that they're not touching the ground every frame.
        if (touchingGround)
        {
            Debug.Log("Touching Ground");
        }
        else
        {
            Debug.Log("Not touching ground");
        }
    }

    void OnCollisionEnter(Collision collision)
    {
        // This function here checks if the player is touching the ground, by checking the object which they're colliding with
        // and if the object they're colliding with has the tag "Ground", it sets the touchingGround boolean to True.
        if (collision.gameObject.tag == "Ground")
        {
            touchingGround = true;
        }
    }

    void OnCollisionExit(Collision collision)
    {
        // This function here checks if the player has exited the collision of the game object,
        // if they have, it sets the collision touchingGround boolean to false.
        if (collision.gameObject.tag == "Ground")
        {
            touchingGround = false;
        }
    }
}

I then began implementing the level restarting when the player touches the ground, this was very simple to do, I only had to add these two lines:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement; // This line was added

public class _CharCollision : MonoBehaviour
{
    private bool touchingGround = false;

    void Update()
    {
        if (touchingGround)
        {
            Debug.Log("Touching Ground");
            SceneManager.LoadScene(SceneManager.GetActiveScene().buildIndex); // This line was added
        }
    }
}

What this does is it use UnityEngine.SceneManagement, if we didn’t have that there, the script wouldn’t understand the syntax of ‘SceneManagement’ therefor it would bring up errors when that runs without using the scene management.
The second line simply reloads the current scene.

Result:

via GIPHY

Task Done

Unity - Combo System

Tasks

This was rather simple to do, following along with the flow diagram which I’ve made, I first began by making sure everything worked by printing the condition of the collision to the console, checking if the player is collided with the building or not, at first I had trouble making it so it detects if the player is collided with the building or not since I had it so it checked if the tag is not equal to buildings, and then set the touching buildings to false, but that just didn’t work, so I fixed it by getting rid of that if statement in the OnCollisionExit and just setting the Touching Buildings to false in there.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class _Points : MonoBehaviour
{
    // I began this by making a separate script which deals with the points in the game.
    // I made a bool which returns True or False called TouchingBuildings.
    private bool touchingBuildings;
    private int combo = 0;
    private int score = 0;

    void Start()
    {
        Debug.Log(combo);
        Debug.Log(score);
    }

    void Update()
    {
        // This gives us feedback and tells us if the player is touching the buildings or isn't.
        if (touchingBuildings)
        {
            Debug.Log("Touching Building");
        }
        else
        {
            Debug.Log("Not touching Building");
        }
    }

    void OnCollisionEnter(Collision collision)
    {
        // This detects if the player has collided with something which has the tag of "Buildings,"
        // and if it does, it sets the bool to TRUE.
        if (collision.gameObject.tag == "Buildings")
        {
            touchingBuildings = true;
        }
    }

    void OnCollisionExit(Collision collision)
    {
        // This detects when the collision with the buildings has been exited,
        // and sets the touchingBuildings bool to FALSE.
        touchingBuildings = false;
    }
}

I then began adding my combo system.

public class _Points : MonoBehaviour
{
    private bool touchingBuildings;
    public int combo = 0;
    private int score = 0;

    // A value I use for how long the player can be in the air before their combo gets lost.
    private float airTime = 1.5f;

    // The timer for this combo.
    private float timer = 0.0f;

    void Start()
    {
        // Initialization or debugging can be done here.
    }

    void Update()
    {
        if (touchingBuildings)
        {
            // Sets the timer back to 0 once the player hits a building,
            // since the timer only increments when the player is in the air.
            timer = 0;
        }
        else
        {
            // Here, the player isn't touching the building, so this means they're in the air,
            // so the timer float increments.
            timer += Time.deltaTime;

            // So then if the player is in the air for longer than airTime, they lose their combo
            // and the timer gets reset to 0.
            if (timer > airTime)
            {
                Debug.Log("LOST COMBO");
                timer = 0;
                combo = 0;
            }
        }
    }

    void OnCollisionEnter(Collision collision)
    {
        if (collision.gameObject.tag == "Buildings")
        {
            touchingBuildings = true;

            // Increments the combo by one.
            combo++;
        }
    }

    void OnCollisionExit(Collision collision)
    {
        touchingBuildings = false;
    }
}

Task

Unity - Score system

Score

This was easy to get working, I just needed to add this into my script.

// Increments the value of the score by - CURRENT Score value + 100 (ScoreMultiplier)
// then this is all multiplied by the current combo which the player holds.
score = score + scoreMultiplier * (combo);
Debug.Log(score);

This is the result:

via GIPHY

Logs

And you can see that this works because in my debug log, it goes from 300, to 600, and then from 600 to 1000, and then when I hit 1000, I lost my combo, which meant my score only went up from 1000 to 1100, since my combo must’ve been 1 at that point, and then from there you can see it gradually increasing in value but not as much as it previously did.

Task

Unity - Buildings change on impact

Task

To do this I began by making a shader graph.
I wanted to make it look like the object is dissolving/cracking.

ShaderGraph

This is the shader graph.
From here I had to change a few things.
I applied the shader to each building object, after making it a material, I quickly found out a problem with the material, since the crack/dissolve amount of the material wasn’t an instance and was applying to everything once it was changed, and this took quite a while to figure out how to get it working, I got Ashley’s help 282with this but the solution was very long.
We started in a new scene, to test everything out, and in the shader graph we changed the name of the reference, which made the text bold, which makes it into an actual variable that we are able to edit in the script.
We then made a separate scene, to test everything in, making 2 cubes and putting them aside each other, and then applying the materials to the cube, and then we made a MaterialTest script for both the cubes.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class MaterialTest : MonoBehaviour
{
    // This is a public string variable which is named crackParameter
    // which makes it easier to reference the string in the code without having to type the string all the time.
    public string crackParameter = "_crackAmount";

    // This is the amount of damage that is dealt.
    Renderer buildingRenderer;
    float damage = .1f;

    // Start is called before the first frame update
    void Start()
    {
        // This here gets the object's Renderer when the game is run.
        buildingRenderer = GetComponent<Renderer>();
    }

    // Update is called once per frame
    void Update()
    {
        if (Input.GetKeyDown(KeyCode.Space))
        {
            // This is a float variable which makes it easier to reference in the script.
            float crackAmount = buildingRenderer.material.GetFloat(crackParameter);

            // This sets the float of the crack to the current crack amount + the value of the damage,
            // which is 0.1. This is clamped between -1 and 1 so you can't go higher or lower.
            buildingRenderer.material.SetFloat(crackParameter, Mathf.Clamp(crackAmount += damage, -1, 1));
        }

        if (Input.GetKeyDown(KeyCode.LeftControl))
        {
            float crackAmount = buildingRenderer.material.GetFloat(crackParameter);

            // This sets the float of the crack to the current crack amount - the value of the damage.
            buildingRenderer.material.SetFloat(crackParameter, Mathf.Clamp(crackAmount -= damage, -1, 1));
        }
    }

    private void OnCollisionEnter(Collision collision)
    {
        // This is just to test if it works on collision but works exactly the same as above.
        float crackAmount = buildingRenderer.material.GetFloat(crackParameter);
        buildingRenderer.material.SetFloat(crackParameter, Mathf.Clamp(crackAmount += damage, -1, 1));
    }
}

I tested this and it all seemed to work just fine, cracking by the amount of damage which I’ve set.
I didn’t like how the shader looked, so I found a picture of a crack and added it into unity, making it so the block cracks more each time the crack amount increases.

Shader Graph

I applied the crack script to the collision detect script on the buildings on my main scene, and this is the result:

void OnCollisionEnter(Collision collision)
{
    if (collision.gameObject.name == "Character")
    {
        buildingHealth--;

        if (buildingHealth == 0)
        {
            gameObject.SetActive(false);
        }
        else if (buildingHealth >= 1)
        {
            float crackAmount = buildingRenderer.material.GetFloat(crackParameter);

            buildingRenderer.material.SetFloat(crackParameter, Mathf.Clamp(crackAmount += damage, -1, 1));
        }
    }
}

via GIPHY

With music:

Task

Unity - Improve Collision

Task

After play testing my game for a while, I figured out I need to further improve the collision detection since the player always went through the mesh collider when approaching it at high speed, which the player would be doing a lot so it’s something important which needs to be fixed.
I added this onto my trello board and then found a blog which I find very useful to help me with improving my collision.

That didn’t help at all.
I then went onto Unity Documentation and looked around for everything related to Collision.
I found a post which helped me solve my problem somewhat, not 100% since I don’t think there is a way to improve my collision since both object are moving fast and there is no way to do any raycasting.
I just selected all of the building and the player character and changed the collision mode to Continuious Dynamic which effects your performance a little bit but not much and then it makes my accuracy on the collision slightly better which is what I need since the objects in my game would be moving fast, doing this made me figure out if I change the mass I can make the player jump higher, which makes the game feel completely different, but still fun.

Task

Unity - Stylish Combo

Task

I began this by adding this into my points script, I feel as if it would be much better to give combos and points based on the players Y position since it can be a lot more accurate and fast then a timer, I can tell that this coding is very flawed and needs lots of simplification, but at the moment I’m just testing out everything to see if it works.
I wasn’t able to figure out how to get it to compare if it’s exactly equal to a value, only greater than or equal to, since the == and = operator wasn’t working, so I was getting thousands of the combos since the player would be above the Y axis in the combo for a few seconds, and this is on the update function which runs every once per frame. - This is also because the Y position wouldn’t always be an exact value.

    void Update()
    {
        if (touchingBuildings)
        {
            timer = 0;
        }
        else
        {
            timer += Time.deltaTime;
        }

        if (transform.position.y >= 50)
        {
            Debug.Log("50");
            combo++;
            combo += combo * comboMultiplier;
        }

        if (transform.position.y >= 100)
        {
            Debug.Log("100");
            combo++;
        }

        if (transform.position.y >= 150)
        {
            Debug.Log("150");
            combo++;
            combo += combo * comboMultiplier;
        }

        if (transform.position.y >= 200)
        {
            Debug.Log("200");
            combo++;
            combo += combo * comboMultiplier;
        }
    }

Then I realized that I could just make this fire alongside a bool if I only want it to work once.
And this worked.
This is all I needed to do in the script.

Code

But then I came by another problem, doing this only meant that I could have one combo, I couldn’t run a good, cool, amazing type of combo the higher I go.
So I decided I would need to do a loop of three, with three height values and three booleans, my friend helped me with figuring this out.

bool[] hitBoundry = new bool[] {false, false, false}; 
// This is the hit boundary, which is using an array variable to store 3 boolean values for the hit boundary, 
// so they can activate and deactivate all when they're hit.

float[] boundryHeights = new float[] {100, 150, 200}; 
// This is the float array variable which contains three separate floats representing the Y values 
// the player has to hit in order to get their combo text.

string[] comboText = new string[] {"Good", "Impressive", "AMAZING!"}; 
// This is the combo text, which will be later inserted into the UI interface.

These are the three bool arrays I made for my combos to work.

void Update()
{
    for (int i = 0; i < 3; i++) 
    {
        // This is a loop which will run 3 times.

        if (transform.position.y > boundryHeights[i] && !hitBoundry[i]) 
        {
            // This will check if the Y position is more than the boundaryHeights floats,
            // and it will go through each array of the floats each time the loop goes to the next one.
            // And then it would also check if it hasn't activated the hitBoundry bool.

            combo++;
            Debug.Log(comboText[i]); 
            // This will go through the string array for the different combo text.

            hitBoundry[i] = true; 
            // This will set the hitBoundry as true for whatever bool array it's on.
        }

        if (transform.position.y < boundryHeights[i]) 
        {
            // This will run if the player's Y position is lower than the current boundaryHeight bool.

            hitBoundry[i] = false; 
            // This will set the hitBoundry as false for whatever bool array it's on.
        }
    }
}

And this if my loop which I made to get the combo system properly working.

Result:

Task

Planning for next week -

  • How do I plan to catch up? 

I plan to catch up by doing all my fonts and UI in the next week so my combo system is up to date and ready, but besides from that I am up to date.

  • Do I need to change anything about my work or planning?

No