Unity Junior Programmer Mission Create With code Unit 4 – Gameplay Mechanics

Unity Development Environment

In this Unit, the goal was to program an arcade-style Sumo battle with the objective of knocking increasingly difficult waves of enemies off of a floating island, using power ups to help defeat them. In creating this prototype, I practiced implementing new gameplay mechanics, which are new rules or systems that make the game more interesting to play. The project scope included programming a powerup, which give the player a temporary advantage. Also included was the requirement to program increasingly difficult enemy waves, which make survival more challenging for the player. I learned how a good balance of powerups and increasing difficulty make for a much more interesting gameplay experience.

The prototype deployed to the web as an HTML 5 application

https://meta.dwdenney.com/unit4/

Project Outcomes:

The camera will evenly rotate around a focal point in the center of the island, provided a horizontal input from the player. The player will control a textured sphere, and move them forwards or backwards in the direction of the aforementioned focal point.

A textured and spherical enemy will spawn on the island at start, in a random location determined by a custom function. It will chase the player around the island, bouncing them off the edge if they get too close.

A powerup will spawn in a random position on the map, eagerly awaiting the player. Once the player collides with this powerup, the powerup will disappear and the player will be highlighted by an indicator. The powerup will last for 5 seconds after pickup, granting the player super strength that blasts away enemies!

The Spawn Manager will operate in waves, spawning multiple enemies and a new powerup with each iteration. Every time the enemies drop to zero, a new wave is spawned and the enemy count increases.

C# Code Samples

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

public class RotateCamera : MonoBehaviour
{
    //speed that camera will rotate
    public float rotationSpeed; // set to 100 in ui after testingP
    
    // Start is called before the first frame update
    void Start()
    {
        
    }

    // Update is called once per frame
    void Update()
    {
        float horizontalInput = Input.GetAxis("Horizontal");
        transform.Rotate(Vector3.up, horizontalInput * rotationSpeed * Time.deltaTime);
    }
}




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

public class PlayerController : MonoBehaviour
{
    
    private Rigidbody playerRb;
    public float speed = 5.0f;
    private GameObject focalPoint;

    public bool hasPowerup;
    public GameObject powerupIndicator;
    public int powerUpDuration = 7;

    private float normalStrength = 5;
    private float powerupStrength = 15.0f;
    
    
    

    // Start is called before the first frame update
    void Start()
    {
        playerRb = GetComponent<Rigidbody>();
        focalPoint = GameObject.Find("Focal Point");
    }

    // Update is called once per frame
    void Update()
    {
        // Add force to the player in direction of  focal point / camera
        float forwardInput = Input.GetAxis("Vertical");
        playerRb.AddForce(focalPoint.transform.forward * speed * forwardInput);

        // set power up indicator to a position beneath the player
        powerupIndicator.transform.position = transform.position + new Vector3(0, -0.5f, 0);
    }

    private void OnTriggerEnter(Collider other)
    {
        if (other.CompareTag("Powerup"))
        {
            hasPowerup = true;
            Destroy(other.gameObject);
            StartCoroutine(PowerupCountdownRoutine());
            powerupIndicator.gameObject.SetActive(true);
        }
    }

    private void OnCollisionEnter(Collision collision)
    {
        if(collision.gameObject.CompareTag("Enemy") && hasPowerup)
        {
            Debug.Log("collided with " + collision.gameObject.name + " with power up set to " + hasPowerup);

            Rigidbody enemyRigidbody = collision.gameObject.GetComponent<Rigidbody>();
            Vector3 awayFromPlayer = (collision.gameObject.transform.position - transform.position);

            if (hasPowerup) // if have powerup, then hit enemy with powerup strength
            {
                enemyRigidbody.AddForce(awayFromPlayer * powerupStrength, ForceMode.Impulse);
            } else // else has no powerup, use normal strength
            {
                enemyRigidbody.AddForce(awayFromPlayer * normalStrength, ForceMode.Impulse);
            }
            
        }
    }

    //coroutine to count down the powerup duration
    IEnumerator PowerupCountdownRoutine()
    {
        yield return new WaitForSeconds(powerUpDuration);
        hasPowerup = false;
        powerupIndicator.gameObject.SetActive(false);
    }
}





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

public class EnemyFollowPlayer : MonoBehaviour
{

    public float speed;
    private Rigidbody enemyRB;
    private GameObject player;
    
    // Start is called before the first frame update
    void Start()
    {
        enemyRB = GetComponent<Rigidbody>();
        player = GameObject.Find("Player");
    }

    // Update is called once per frame
    void Update()
    {
        //get the direction to player
        Vector3 lookDirection = (player.transform.position - transform.position).normalized;
        //move in the direction of the player if player is still alive
        if(player.transform.position.y > -2)
        {
            enemyRB.AddForce(lookDirection * speed);
        } else
        {
            enemyRB.velocity = Vector3.zero;
        }
        
        // destroy me if I fall off the platform
        if(transform.position.y < -10) Destroy(gameObject);
    }
}




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

public class SpawnManager : MonoBehaviour
{
    public GameObject enemyPrefab;
    private float spawnRange = 9;
    public int enemyCount = 0;
    public int waveNumber = 1;
    public GameObject powerupPrefab;



    // Update is called once per frame
    void Update()
    {
        enemyCount = FindObjectsOfType<EnemyFollowPlayer>().Length;
        if (enemyCount == 0)
        {
            waveNumber++; 
            SpawnEnemyWave(waveNumber);
            SpawnPowerup(waveNumber);
            
        }
    }

    private Vector3 GenerateSpawnPosition()
    {
        float spawnPosX = Random.Range(-spawnRange, spawnRange);
        float spawnPosZ = Random.Range(-spawnRange, spawnRange);
        Vector3 randomPos = new Vector3(spawnPosX, 0, spawnPosZ);
        return randomPos;
    }

    void SpawnEnemyWave(int enemiesToSpawn)
    {
        for(int i = 0; i < enemiesToSpawn; i++)
        {
            Instantiate(enemyPrefab, GenerateSpawnPosition(), enemyPrefab.transform.rotation);
            
        }
        
    }

    void SpawnPowerup(int waveNumber)
    {
        Instantiate(powerupPrefab, GenerateSpawnPosition(), enemyPrefab.transform.rotation);
    }
}





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

public class Rotator : MonoBehaviour
{
    // Start is called before the first frame update
    void Start()
    {
        
    }

    // Update is called once per frame
    void Update()
    {
        // Rotate the game object that this script is attached to by 15 in the X axis,
        // 30 in the Y axis and 45 in the Z axis, multiplied by deltaTime in order to make it per second
        // rather than per frame.
        transform.Rotate(new Vector3(15, 30, 45) * Time.deltaTime);
    }
}





Leave a Reply