Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / game / Unity

Day 100 of 100 Days of VR: Endless Flyer – Adding the Power-Up Upgrade Into the Game

1.00/5 (1 vote)
6 Feb 2019CPOL5 min read 2.3K  
How to add power-up upgrade into the game

Introduction

We did it! We just reached the 100th article in the 100 day challenge! Wow, I cannot believe how far I’ve come since! For those of you who have read up to this point, THANK YOU! I would have never made it as far as I have today (at the time I did now) without your support.

Reflecting on it, in the past 10-20 articles, there really hasn’t been much talk about VR and motivation was also at an all-time low, but I promised myself that I would pull through this and here, we are at the last one!

There’s been so much I learned in the past year with Unity and typing everything out was a great outlet for me to really learn the materials. As the saying goes, you don’t really know something until you teach it!

In the beginning, it was a great boon for me in terms of learning, however as I continued, I realized that thing was getting repetitive and it was slowing me down, but I couldn’t fail my personal challenge to myself and here we are!

Anyways, enough celebration, let’s get the final day finished!

——————————–End Writer's note——————————–

In the previous post, we were able to write the code needed to be able to purchase our power-up upgrades, however as it stands now, it’s just data that hasn’t been used.

Today we’re going to be putting the finishing touches to the power-up upgrades by changing our existing power-up behaviors based on its level.

The changes today aren’t going to be too complex, but nonetheless, let’s get to it!

Step 1: Adding the Power-Up Upgrades into our Gameplay

Step 1.1: Adding the Magnet Upgrades

As you might recall in the previous day, we made a PowerUpsDatabase class that held an array of PowerUpModel that define different upgrade levels and their effects for each level.

Here’s what the power-up upgrades for magnet look like:

C#
public static PowerUpModel[] MagnetPowerUps = {
    new PowerUpModel(0, 15, 50),
    new PowerUpModel(1, 20, 100),
    new PowerUpModel(2, 25, 200),
    new PowerUpModel(3, 30, 400),
    new PowerUpModel(4, 35, -1)
};

I intend to use the effect values (15, 20, 25, etc.) to change the radius of our Magnet Collider so we can collect coins further away.

The change will be relatively straightforward. As you might recall, when we collide against our Magnet power-up, we add a Magnet Collider to our plane that moves any coins that it touches to our plane to collect.

With our upgrade, we’re going to change the Radius of the Sphere Collider to be the radius of our upgrade.

Here’s what our Magnet Collider script looks like:

C#
using UnityEngine;

public class MagnetCollider : MonoBehaviour {

    void Start()
    {
        SphereCollider sphereCollider = GetComponent<SphereCollider>();
        if (sphereCollider != null)
        {
            sphereCollider.radius = PowerUpsDatabase.MagnetPowerUps
                                    [DataManager.LoadMagnetLevel()].Effect;
        }
    }

    void OnTriggerEnter(Collider other)
    {
        print("magnet collider hit " + other.tag);
        switch (other.tag)
        {
            case "Coin":
                Coin coin = other.GetComponent<Coin>();
                coin.Follow(gameObject.transform.parent.gameObject);
                break;
        }
    }
}

Walking Through the Code

In Start(), when we first create our Magnet Collider, we grab our SphereCollider component and if it exists, we’re going to set its’ radius to be the Effect value of the upgrade level we currently have for our Magnet upgrade.

If we play the game with a max range magnet upgrade, our range will be something like this:

Image 1

Step 1.2: Adding the Multiplier Upgrades

Next up is the multiplier effect. Here’s what we defined for it in our PowerUpsDatabase:

C#
public static PowerUpModel[] MultiplierPowerUps =
{
    new PowerUpModel(0, 2, 50),
    new PowerUpModel(1, 3, 100),
    new PowerUpModel(2, 4, 200),
    new PowerUpModel(3, 5, 400),
    new PowerUpModel(4, 6, -1)
};

We 2x our coin and score at level 0 and bring that up to 6x at level 4. Is this a bit OP? Probably, but it’s okay, this is just an example!

We change our score and coin in ScoreManager and GameManager.

Here are the changes:

GameManager:

C#
using UnityEngine;

public class GameManager : MonoBehaviour
{
    public static GameManager Instance;

    private int _coin = 0;

    void Start ()
	{
	    if (Instance != null)
	    {
	        // If Instance already exists, we should get rid of this game object
	        // and use the original game object that set Instance   
	        Destroy(gameObject);
	        return;
	    }

	    // If Instance doesn't exist, we initialize the Player Manager
	    Init();
	}

    private void Init() {
        Instance = this;
        _coin = 0;
    }

    // Called from outside function for when the player collects a coin.
    public void CollectCoin()
    {
        int scoreIncrease = 1;
        if (PlayerManager.Instance.ContainsPowerUp(PlayerManager.PowerUpType.Score))
        {
            scoreIncrease *= (int) PowerUpsDatabase.MultiplierPowerUps
                                     [DataManager.LoadMultiplierLevel()].Effect;
        }
        _coin += scoreIncrease;
        GameUIManager.Instance.SetCoinText(_coin);
    }

    // Return the number of coins that we have collected.
    public int GetCoin() 
    {
        return _coin;
    }

    public void GameOver()
    {
        DataManager.AddCoin(_coin);
        DataManager.AddNewScore(ScoreManager.Instance.GetScore());
    }
}

ScoreManager:

C#
using UnityEngine;

public class ScoreManager : MonoBehaviour {

    public static ScoreManager Instance;

    private float _score = 0;

    void Start()
    {
        if (Instance != null)
        {
            // If Instance already exists, we should get rid of this game object
            // and use the original game object that set Instance   
            Destroy(gameObject);
            return;
        }

        // If Instance doesn't exist, we initialize the Player Manager
        Init();
    }

    private void Init()
    {
        Instance = this;
        _score = 0;
    }

    void Update()
    {
        // increase our score and then update our ScoreText UI.
        float increaseTime = Time.deltaTime * 10;
        if (PlayerManager.Instance.ContainsPowerUp(PlayerManager.PowerUpType.Score))
        {
            increaseTime *= PowerUpsDatabase.MultiplierPowerUps
                               [DataManager.LoadMultiplierLevel()].Effect;
        }
        _score += increaseTime;
        GameUIManager.Instance.SetScoreText((int)_score);
    }

    public int GetScore()
    {
        return (int) _score;
    }
}

Walking Through the Code

The change is very straightforward and identical to both of these scripts.

Whenever we increase our coin or score amount, we originally 2x everything when our power-up is active. In this case, the change instead of multiplying by 2, I multiply our coin/score by the Effect value that we set.

I would add a screenshot, but there’s nothing interesting I can show.

Step 1.3: Adding the Invincible Upgrades

Finally, we move on to our final upgrade. For our invincible upgrade, I decided to play with the speed that we can travel.

Here are the values we set for it:

C#
public static PowerUpModel[] InvinciblePowerUps =
{
    new PowerUpModel(0, 2, 50),
    new PowerUpModel(1, 2.25f, 100),
    new PowerUpModel(2, 2.5f, 200),
    new PowerUpModel(3, 2.75f, 400),
    new PowerUpModel(4, 3, -1)
};

As you can see from level 0, we will go for 2X speed and when at level 4, we will be going at 3x speed.

We fiddle with our player movement speed inside the PlaneController script, the change will be very similar to what we have done already for the multiplier power-up.

Here are our changes to PlaneController:

C#
using System;
using UnityEngine;

public class PlaneController : MonoBehaviour
{
    private Camera _mainCamera;

	void Start () {
        _mainCamera = Camera.main;
	}
	
	void Update ()
	{
	    switch (PlayerManager.Instance.CurrentState)
	    {
            case PlayerManager.PlayerState.Alive:
                MovePlayer();
                break;
	    }
	}

    /// <summary>
    /// Moves the player forward and to the side based off of where 
    /// they're looking at with the cardboard.
    /// </summary>
    private void MovePlayer()
    {
        Vector3 movement = 
           GetMoveSpeed(_mainCamera.transform.rotation.x, _mainCamera.transform.rotation.y);
        Vector3 forward = transform.forward;
        if (PlayerManager.Instance.ContainsPowerUp(PlayerManager.PowerUpType.Invincible))
        {
            forward *= (int)PowerUpsDatabase.InvinciblePowerUps
                            [DataManager.LoadInvincibleLevel()].Effect;
        }
        transform.position += (forward + movement) / 2;
    }

    /// <summary>
    /// Creates and returns a Vector3 using rotation values from the camera 
    /// that will be used for this game objects 
    /// vertical/horizontal movement
    /// </summary>
    /// <param name="x">The X rotation value of our camera, 
    /// used to calculate our vertical movement (up and down)</param>
    /// <param name="y">The Y rotation value of our camera, 
    /// used to calculate our horizontal movement (left and right)</param>
    /// <returns>A Vector3 that has the horizontal and vertical direction 
    /// the plane should be moving to</returns>
    private Vector3 GetMoveSpeed(float x, float y)
    {
        // create our movement vector value based off of where we're looking at with a cap 
        float xMove = Mathf.Min(Mathf.Abs(y * 10), 3);
        float yMove = Mathf.Min(Mathf.Abs(x * 10), 3);

        // Figure out which direction our plane should be turning to
        if (x >= 0)
           yMove *= -1;
        if (y < 0)
            xMove *= -1;

        return new Vector3(xMove, yMove, 0f);
    }
}

Walking Through the Code

As mentioned above, the change here is very similar to what we have done before. Instead of hardcoding 2 as our multiplier effect, we are now using the Effects value from our upgrade.

End of Day 100!!!!!!!!

There you have it! The last article of the series, there’s still tons more that needs to be done, but as a throwaway project, we did some good work and we learned a lot.

Here’s a gif of some of our final playthrough. We pick up a power-up play through some of the game, crash, visit the item store, and restart the game all over again! Not bad, not bad at all!

It’s been a long journey, especially over a year. I’m not going to be doing something as outrageous as this again. I think it’s obvious that this series dragged on longer than it should have, but I’m glad that I finally pulled through!

What’s next? Well, I’ll tell you what! I became acquainted with a friend who was working on a VR project dealing and I think that will be my next big adventure (among many other things!)

I’ll post the new interesting content/tutorial to the site, but never again will I do something like a 100-day challenge. I’m sick of writing it and for my readers who have made it this far, I’m sure you’re sick of reading it!

Any future work from me will be on one topic where we can dive deeper into it. It’ll be more interesting for me and it’ll be more informative for you, the readers!

Once again, thank you, my readers, for following me through this 1+ year of my “100” days of VR challenge, I’ve finally accomplished it and now I’m going to move on to bigger and better! You can see the full project at my Github repo: Cube Flyer. I’ll see you guys around!

Day 99 | 100 Days of VR

Home

The post Day 100 of 100 Days of VR: Endless Flyer – Adding the Power-Up Upgrade Into the Game appeared first on Coding Chronicles.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)