WarioWare Project

Project Summary (Fast)

Project Brief:
For this Project I will be working in a group of 4 alongside Jordan Robson, Owen Bates and Marcus Eley. This game can be anything the team thinks of however the only constraint is it must have a game loop of under 30 seconds. The themes for the challenge are “Take one, leave the rest” “Always Moving” and “Death makes you stronger”. There are also some design challenges which are not required like the themes however are used as a guide to help improve you game and give you ideas. The Design challenges include multiplayer, one button input and controller input.
The deadline for this project was the 1st November so we believed we would be able to make a very polished and advanced game as we had lots of time to work on it.

Idea Phase:

We began this project with the creation of a trello board we all had access too, this allowed for a fast paced start where we were able to start efficiently thinking of ideas and deciding on a solid plan for the game. We spent the entirety of the first lesson deciding on the games main loop process, the different mechanics, assets, music and even art styles.
Our final idea was a 2 player fighting / parkour game which lasted around 30 seconds. The idea was inspired by hot potato which is a popular game played by children and at parties, this involves an object which you have to pass around among a group of people and the person who ends with the object when the timer runs out either loses or wins. Our game would involve 2 players fighting over a steel bar, the person who has the steel bar when the timer runs out wins. This meant 2 players would be chasing each other around a mineshaft which we really liked the idea of and we all believed that we could do it.

Game Design Document (GDD):

The GDD was created to keep track of the games progress and to see all of the info about the game at all times. It really helped to keep an overview of the game and made it easy if we ever forgot a certain aspect of the game as we could just look back at the document.

Technical Considerations Overview 3D:
The game engine I will be using is unity, we will be using certain packages while working on unity to make the creation of the game more efficient. We will be using packages like Pro builder, Pro grids and unity teams so we can link the project between us and make changes from our houses. This will allow us to make much cleaner levels in unity and also allow us to work on the project from 3 different computers.

We will be using post processing in our game as it will make the lighting stand out more and since the game is set in a mine there needs to be many different light sources like lamps and torches. We will use different elements of post processing like bloom and motion blur as it will make the game look much more polished and clean.

Photoshop will be a large part of this project for me as I will be making lots of the UI elements like Menu Buttons and Text which will require me to use a lot of photoshop.
Sony Vegas / Premiere Pro / After Effects will all be used to create a trailer for the game.
I will use Maya to 3D model as I have more experience using it and am more familiar with the application so I will be able to make models more efficiently.

Burndown Chart:
We will use this burndown chart to review and track our progress through out the project as it allows us to see the different tasks each member has completed. It is a very useful tool as we can stay on top of all of the tasks we need to work on.

Asset List:
We will use an asset list to track the different assets we will use in the project, this includes things like 3D assets, Scripts, Scenes, 2D art and different pieces of software we will use. Similarly to a Trello board we are able to complete certain tasks and log it on the asset list to keep track of progress. You can set a specific priority for each task to show us what tasks need to be completed first.

The first thing we started working on was the character controls so we made a simple layout of a map so we could test moving around and we also created 2 cubes and assigned the inputs to different parts of the keyboard so we could test our movement script while we created it and see how well it worked with other characters.

I began coding the movement script with Jordan while Owen worked on particle effects for the character. we created simple movements with WASD and ARROW KEY inputs to move the cube around, it wasn’t perfect however it was great to use for now. For some odd reason the jumping wasn’t working, unity could not recognize that we were colliding the character with the ground so it thought the player was still in the air, to fix this we added a head collider and a foot collider to check if the head and foot were colliding with any other parts of the map. We started working on other aspects of the game once the movement of the players was working.

This image has an empty alt attribute; its file name is image-3.png

Owen now began working on the level designs by using pro builder and pro grids to Crete some test maps for us to try using the characters on, me and Jordan began working on the steel bar and coins. The coins were simple to code as all we wanted to happen was for the coin to disappear on pickup and to add 10 points to the player. The steel bar on the other hand was harder to code as it was going to be a robbable item from the other player by jumping on his head. This meant we had to be checking if the player had the bar and if the other player who did not have the bar was connecting his foot collider to the player with the bars head collider then the bar transfers across players so now the other player has the steel bar.

FINAL MAP LAYOUT

This was the final map design we decided to use as while testing it we found it to be the most fun and it had the most possibilities to escape and outmaneuver the person trying to steal the bar from you. We placed the steel bar and all of the coins into the scene so we now had a points system in place. We still needed to add the UI to the main game however we had now implemented a way to win.

We then began experimenting with lighting to see the best type of light to use in the game. We decided to use a mixture of all lights, Point lights to make the scene brighter, Spot and Directional lights on the minecart and lanterns around the scene to create a diverse look and make the game have a more realistic feel.

We were discussing different modes of transport in the game however due to such a small map we were unable to add any fast vehicles. This then led to us thinking of other methods of movement in the game, we all decided on elevators as we thought it would fit well into the game and would create a very fun experience for the user.

The elevators were inspired by Super Mario 64 and we felt like our game would feel much more fun if there were other methods of transport like elevators. the elevators were very simple to add as we just created animations however the players would slide off the platforms as they moved which was not what we wanted, this meant we had to create a script that set the player as a child object of the specific elevator they were standing on when

Elevator Tour in the Volcano - Super Mario 64 HD (Super Mario 3D All Stars)  - YouTube

We created multiple particle effects as it made the game feel more interactive and alive, ass we added more sound effects and particles the game became so much more alive.

As our game is very minimal on the level design we did not require many 3D assets however everyone in the group created 3D assets to help. (Barrell: Owen Bates) (Steel Bar + Rails: Jordan Robson) (Lantern: Devon Hunt) (Minecart + Beams + Crates: Marcus Eley). Marcus was the lead 3D artist and he worked very well to create great textures and models for the game.

We decided to add Post Processing to the game to make it look 10x better and include different graphic settings like Bloom, Anti-Aliasing and Ambient Occlusion. These will all make the game look more aesthetically pleasing, they do things like make the lighting effect the camera, soften the edges of different objects in the scene and make darker areas of the scene appear more dark.

This is the Trello board currently as we have finished the project. It has almost no bugs to fix as we know of and the items in the to do list are just potential improvements however the core game is complete. We are all going to continue working on the game as it is very well made and if we keep improving it we could potentially market the game on a digital storefront.

———SCRIPTS———

Menu Script –

Movement manager –

Camera Controller –

Game Over Script –

Minecart Script –

Head Controller –

Foot Controller –

Score Manager –

public class ScoreManager : MonoBehaviour
{
    public Text scoreP1;
    public Text scoreP2;
    public Text timer;

    public float timeRemaining;

    public bool timerIsRunning = false;
    public bool testMode;

    public GameObject[] coins;

    public GameObject hotSteel;
    public Camera cam;
    public Camera flythrough;


    public RawImage bar1;
    public RawImage bar2;

    public MovementP1 mp1;
    public MovementP2 mp2;
    

    // Start is called before the first frame update
    void Start()
    {
        // Start Timer
        timerIsRunning = false;
        timeRemaining = 20f;

        cam.gameObject.SetActive(false);
        flythrough.gameObject.SetActive(true);

        mp1 = GameObject.FindGameObjectWithTag("Player1").GetComponent<MovementP1>();
        mp2 = GameObject.FindGameObjectWithTag("Player2").GetComponent<MovementP2>();

        StartCoroutine(CoinSpawn());
        StartCoroutine(CameraChange());
    }

    // Update is called once per frame
    void Update()
    {
        if(hotSteel.activeInHierarchy == false)
        {
            timerIsRunning = true;
            //StartCoroutine(CoinSpawn());
        }

        scoreP1.text = PlayerPrefs.GetInt("ScoreP1").ToString();
        scoreP2.text = PlayerPrefs.GetInt("ScoreP2").ToString();

        if(timerIsRunning)
        {
            if (timeRemaining > 0)
            {
                timer.text = Mathf.RoundToInt(timeRemaining -= Time.smoothDeltaTime).ToString();
            }
            else
            {
                Debug.Log("Time's Up!");
                timeRemaining = 0;
                timerIsRunning = false;
            }
        }

        if(testMode == false)
        {
            if (timeRemaining == 0)
            {
                SceneManager.LoadScene("DeathScreen");
            }

            if(PlayerPrefs.GetInt("P1 Lava") == 1 && PlayerPrefs.GetInt("P2 Lava") == 1)
            {
                SceneManager.LoadScene("DeathScreen");
            }

            if(PlayerPrefs.GetInt("P1 Exit") == 1 || PlayerPrefs.GetInt("P2 Exit") == 1)
            {
                SceneManager.LoadScene("DeathScreen");
            }
        }

        if (mp1.steelBar == true)
        {
            bar1.enabled = true;
        } else
        {
            bar1.enabled = false;
        }

        if (mp2.steelBar == true)
        {
            bar2.enabled = true;
        }
        else
        {
            bar2.enabled = false;
        }
    }

    public void SpawnRandomCoin()
    {
        int i = Random.Range(0, coins.Length);
        coins[i].SetActive(true);
    }

    IEnumerator CoinSpawn()
    {
        yield return new WaitForSeconds(Random.Range(1f, 3f));
        SpawnRandomCoin();

        StartCoroutine(CoinSpawn());
    }

    IEnumerator CameraChange()
    {
        yield return new WaitForSeconds(7f);

        cam.gameObject.SetActive(true);
        flythrough.gameObject.SetActive(false);
    }
}

Movement Player 1 –

public class MovementP1 : MonoBehaviour
{
    public float moveSpeed;
    public float jumpHeight;

    public int scoreToAdd;
    public int score;
    public int steelBarValue;

    Rigidbody rb;

    Vector3 velocityP1 = Vector3.zero;
    Vector3 jumpVelocity;


    public FootControllerP1 fc;
    public ScoreManager sm;

    //Determine the player for controls in game
    public bool Player1;
    public bool jump1;
    public bool isJumping;
    public bool steelBar;

    public Transform warpR;
    public Transform warpL;

    public AudioClip coinCollect;
    public AudioClip jumpSound;
    public AudioClip barSound;

    public AudioSource audioSource;
    public AudioSource barAudioSource;


    void Start()
    {
        rb = GetComponent();
        //jumpVelocity = new Vector3(transform.position.x, jumpHeight, transform.position.z);
        jumpVelocity = new Vector3(transform.position.x, jumpHeight, transform.position.z);

        PlayerPrefs.SetInt("ScoreP1", 0);
        PlayerPrefs.SetInt("P1 Exit", 0);
        PlayerPrefs.SetInt("P1 Lava", 0);


        fc = GetComponentInChildren();
        sm = FindObjectOfType();

        if(PlayerPrefs.GetInt("GameMode") == 1)
        {
            audioSource = GetComponent();
        }

        if(PlayerPrefs.GetInt("GameMode") == 2)
        {
            audioSource = GameObject.FindGameObjectWithTag("SoundEffect").GetComponent();
        }
        
    }

    void Update()
    {
        if (sm.timerIsRunning == false)
        {
            rb.isKinematic = true;
        } else
        {
            rb.isKinematic = false;
        }

        if (fc.isGrounded)
        {
            Jump();
            isJumping = false;
        }

        if (Player1)
        {
            velocityP1.x = Input.GetAxis("MoveP1") * moveSpeed * Time.deltaTime;

            //rb.velocity = velocityP1 * moveSpeed * Time.deltaTime;
            rb.AddForce(velocityP1);
        }

        if(steelBar == true)
        {
            moveSpeed = 3200f;
            audioSource.PlayOneShot(barSound);
        } else
        {
            moveSpeed = 3800f;
        }

        if (score < 0)
        {
            score = 0;
        }

        PlayerPrefs.SetInt("ScoreP1", score);
    }

    private void OnTriggerEnter(Collider other)
    {
        if (other.gameObject.tag == "Coin")
        {
            score = score + scoreToAdd;
            audioSource.PlayOneShot(coinCollect);
            Destroy(other.gameObject);
        }

        if (other.gameObject.tag == "Bar")
        {
            //score = score + steelBarValue;
            barAudioSource.PlayOneShot(barSound);
            other.gameObject.transform.parent = this.gameObject.transform;
            steelBar = true;
            Destroy(other.gameObject);
            barCheck();
        }

        if (other.gameObject.tag == "Exit")
        {
            PlayerPrefs.SetInt("P1 Exit", 1);
        }
    }

    private void OnCollisionEnter(Collision collision)
    {
        /*
        if (collision.gameObject.tag == "Ground")
        {
            isGrounded = true;
            isJumping = false;
        }
        */



        if(collision.gameObject.tag == "DoorL")
        {
            transform.position = warpR.position;
        }

        if (collision.gameObject.tag == "DoorR")
        {
            transform.position = warpL.position;
        }

        if (collision.gameObject.tag == "Platform")
        {
            this.gameObject.transform.parent = collision.gameObject.transform;
        }

        if (collision.gameObject.tag == "Lava")
        {
            PlayerPrefs.SetInt("P1 Lava", 1);
            rb.isKinematic = true;
            GetComponent().enabled = false;
            
        }
    }

    private void OnCollisionExit(Collision collision)
    {
        this.transform.parent = null;
    }

    void Jump()
    {
        if (Input.GetButtonDown("JumpP1") && isJumping == false)
        {
            audioSource.PlayOneShot(jumpSound);
            isJumping = true;
            fc.isGrounded = false;

            Debug.Log("Jumping1");
            rb.AddForce(Vector3.up * jumpHeight, ForceMode.Impulse);
        }

    }

    void barCheck()
    {
            score = score + steelBarValue;
    }

}

Movement Player 2 –

public class MovementP2 : MonoBehaviour
{
    public float moveSpeed;
    public float jumpHeight;

    public int scoreToAdd;
    public int score;
    public int steelBarValue;

    Rigidbody rb;

    Vector3 velocityP2 = Vector3.zero;
    Vector3 jumpVelocity;


    //public bool isGrounded;

    public FootControllerP2 fc;
    public ScoreManager sm;

    //Determine the player for controls in game
    public bool Player2;
    public bool jump2;
    public bool isJumping;
    public bool steelBar;

    public Transform warpR;
    public Transform warpL;

    public AudioClip coinCollect;
    public AudioClip jumpSound;
    public AudioClip barSound;

    public AudioSource audioSource;
    public AudioSource barAudioSource;


    void Start()
    {
        rb = GetComponent();
        //jumpVelocity = new Vector3(transform.position.x, jumpHeight, transform.position.z);
        jumpVelocity = new Vector3(0, jumpHeight, 0);

        PlayerPrefs.SetInt("ScoreP2", 0);
        PlayerPrefs.SetInt("P2 Exit", 0);
        PlayerPrefs.SetInt("P2 Lava", 0);

        fc = GetComponentInChildren();
        sm = FindObjectOfType();

        if (PlayerPrefs.GetInt("GameMode") == 1)
        {
            audioSource = GetComponent();
        }

        if (PlayerPrefs.GetInt("GameMode") == 2)
        {
            audioSource = GameObject.FindGameObjectWithTag("SoundEffect").GetComponent();
        }

    }

    void Update()
    {
        if (sm.timerIsRunning == false)
        {
            rb.isKinematic = true;
        }
        else
        {
            rb.isKinematic = false;
        }

        if (fc.isGrounded)
        {
            Jump();
            isJumping = false;
        }

        if (Player2)
        {
            velocityP2.x = Input.GetAxis("MoveP2") * moveSpeed * Time.deltaTime;

            //rb.velocity = velocityP2 * moveSpeed * Time.deltaTime;
            rb.AddForce(velocityP2);
        }

        if (steelBar == true)
        {
            moveSpeed = 3200f;
            audioSource.PlayOneShot(barSound);
        } else
        {
            moveSpeed = 3800f;
        }

        if(score < 0)
        {
            score = 0;
        }

        PlayerPrefs.SetInt("ScoreP2", score);
    }

    private void OnTriggerEnter(Collider other)
    {
        if (other.gameObject.tag == "Coin")
        {
            score = score + scoreToAdd;
            audioSource.PlayOneShot(coinCollect);
            Destroy(other.gameObject);
        }

        if (other.gameObject.tag == "Bar")
        {
            //score = score + steelBarValue;
            barAudioSource.PlayOneShot(barSound);
            other.gameObject.transform.parent = this.gameObject.transform;
            steelBar = true;
            Destroy(other.gameObject);
            barCheck();
        }

        if (other.gameObject.tag == "Exit")
        {
            PlayerPrefs.SetInt("P2 Exit", 1);
        }
    }

    private void OnCollisionEnter(Collision collision)
    {
        /*
        if (collision.gameObject.tag == "Ground")
        {
            isGrounded = true;
            isJumping = false;
        }
        */

        if (collision.gameObject.tag == "DoorL")
        {
            transform.position = warpR.position;
        }

        if (collision.gameObject.tag == "DoorR")
        {
            transform.position = warpL.position;
        }

        if (collision.gameObject.tag == "Platform")
        {
            gameObject.transform.parent = collision.gameObject.transform;
        }

        if (collision.gameObject.tag == "Lava")
        {
            PlayerPrefs.SetInt("P2 Lava", 1);
            Destroy(this.gameObject);
            //rb.isKinematic = true;
            //GetComponent().enabled = false;
            
        }
    }

    private void OnCollisionExit(Collision collision)
    {
        this.transform.parent = null;
    }

    void Jump()
    {
        if (Input.GetButtonDown("JumpP2") && isJumping == false)
        {
            audioSource.PlayOneShot(jumpSound);
            isJumping = true;
            fc.isGrounded = false;

            Debug.Log("Jumping2");
            rb.AddForce(Vector3.up * jumpHeight, ForceMode.Impulse);
        }

    }

    void barCheck()
    {
            score = score + steelBarValue;
    }

}

Post Mortem:
The project went very well because we all worked fantastically as a team, the project ran smoothly and everyone worked very hard to make sure the project was very well made and polished .

There was some bugs with the game that took up a large portion of time as they were extremely difficult to fix, when we first started the project we had an issue with the characters jumping, we tried countless times for days to fix it which took a long time to fix. We managed to fix it but it took almost 2 weeks to complete which did stop us from being able to test the character on different maps.

what went wrobg

final thoughts

Design a site like this with WordPress.com
Get started