Introduction: COMBAT OF SURVIVAL

"In the mist of war.. where your life is at stake.. With a SELECTIVE range of WEAPONS, you need to FIGHT against an ARMY of OBJECTS that's coming IN YOUR DIRECTION!"

Game Inspiration

As technology advances rapidly in the modern world, it made our life more comfortable and luxurious than ever. But this trade off gave rise to an unhealthy lifestyle where people are obsessed and reliant with the technology, causing them to give up on the most basic and vital healthy activity of exercising. And this can cause all sort of problem and the main obvious one is obesity which can lead to other more serious disease like Cardiovascular disease.

It looks like technology is the root of all evil. And this is where we come in to counter the problem, using technology to fight against the down side of technology. What we will be doing is to create a game that will not only be fun and enjoyable but also keeping the user actively moving physically.

Description & Objective of the Game

Our game will be Augmented Reality(AR) based.

User will be given 2 AR Marker, the 1st we called it the Weapon Maker. The Weapon Marker would display a range of weapons for the user to change. The Weapon would change on taping on the Virtual button that would be displayed on the marker itself located at the bottom of the Marker. The 2nd, we called it the Ninja Marker. This Marker is used after the selecting of a weapon to use from the Weapon marker. The selected Weapon will be displayed and be use to fight off the objects. There would be multiple arsenal of objects that would be appearing and moving towards your direction and you have to use the weapon to slash the objects flying towards you before it hits you. Users will be given three life as indicated on the top right hand side of the screen as three pills. Life will be reduced when a object hits the user. Each object would have different scores and the more scores you claim the better.

Moving on: How to build our project?

Step 1: Download CombatOfSurvival Files & Demo Video

Our Game Files: (include zip folder of our game with apk inside, WeaponMarker, NinjaMarker)

https://drive.google.com/open?id=1hJiyGb4XbkMz0RH22JEe6eKrjtenwOo0

Our Demo Video:

https://youtu.be/Hlpsa1dJbgw

License:


This work is licensed under a Creative Commons Attribution-ShareAlike 4.0 International License.

Step 2: How to Build Our Project?

Hardware requirements:

  • The Printed VR Marker Image (WeaponMarker, NinjaMarker)
  • Smart phone with camera, GPS and flash light
  • AR headset
  • Computer

Software requirements:

Links updated as of 18 November 2018

Step 3: Software Configuration

Preparing Unity for Vuforia

Before we can use vuforia, we have to create a developer account on Vuforia. After that open unity projects and Delete the Camera object in the Hierarchy window. Go to License Manager on Vuforia’s developer portal and create a new license key using your developer account. Insert the license key in Unity. Under Project window, go to Assets > Vuforia > Prefabs > ARCamera. Select ARCamera and drag it to the Hierarchy window.

This would be our basic environment of using vuforia.

Step 4: Building Our Project

After installing the essential programs, click on Unity Hub > Open > CombatOfSurvival (Locate the file you saved).

The objects in Hierarchy panel:

  • AR Camera – The view that the user will look from
  • _GameManager – A object that contains scripts to handle game environment (Spawn, Music, etc)
  • DestroyPoint – End point where the objects will get destroyed
  • SpawnBox – A 3-dimension box that indicates where the objects can be spawned
  • Canvas – User Interface (UI) for “playing”
  • GameOverCanvas – User Interface (UI) for “Game Over”
  • NINJA_ImageTarget – Marker to display default / current weapon
  • WEAPON_ImageTarget – Marker to display range of weapons

Under Assets > Scenes, there are

  1. MainMenu – Contains UI that the user sees when he enters the game
  2. Tutorial – Contains components for game tutorial
  3. ShootCubes (main scene) – Contains everything else that the game needs

Now you are navigate through the folders of CombatOfSurvival!

Step 5: Getting Started

AR CAMERA

To generalize the view and direction the user will be looking at, we need to have a camera in the scene.

  • Click on GameObject > Vuforia > AR Camera

Creating Game Objects

Creating object that will be spawned and interact with the user.

Cube (Game Object)

  • Click on GameObject > 3D Objects > Cube
  • Click on Cube in the Hierarchy panel, add the following components to the object:
    1. Mesh Renderer (by Default, should be there)
    2. Box Collider (Default) – allows object to collide with each other
    3. Add Component > Rigidbody and disable “Use Gravity” – allows object to act under the control of physics when collided with other objects
    4. Add Component > Animator – allows us to add animation to the object (rotation, scaling, etc)

Adding Continuous Animation of Cube

  • Click on Cube in the Hierarchy panel and go to Windows > Animation > Animation
  • In the Animation panel, press “Create” and save the animation in “Animation” Folder under Assets
  • Click on Add Property > Transform > Rotation
  • Click on “1:00” sec, and press the recording mode button (Red Button), and change the rotation of x and y to 360
  • For smooth looping animation, in the Animation panel, go to Curves, press Ctrl + A to select the whole curve, then right click the start of the curve, and select “Auto” – this will provide a linear velocity of the animation

Adding One Time animation to the Cube when it appears

  • Click on Cube in the Hierarchy panel and go to Windows > Animation > Animator
  • Right click in the background of Animator > Create State > Empty
  • Rename it as CubeAppear
  • Right click on CubeAppear in the Animator > Set as Layer Default State – This will ensure that CubeAppear’s Animation will play first before playing other animations
  • Right Click on CubeAppear in the Animator> Make transition > point it to CubeAni
  • Under Animation panel > Create new clip > CubeAppear
  • Set the scale at “0:00” (X,Y,Z) to (0,0,0)
  • Go to CubeAppear > disable Loop Time

Lastly, create a folder “Objects” under assets, and drag the Cube into the folder. Delete the Cube from Hierarchy Panel.

Step 6: Setting Up the Spawn Box & Constructing the Spawner

Spawn Box

Creating Area that Objects will be spawned

  • Right click on the Hierarchy panel > 3D Objects > Cube
  • Rename Cube (1) to SpawnBox
  • Disable the Mesh Renderer & Box Collider – This box is only to define the spawn area.
  • Change the Position (X,Y,Z) to (0,0,30) – This will indicates the distance of spawn area to camera
  • Change the Scale(X,Y,Z) to (20,10,10) – This will indicates the size of the spawn area

Spawner

Writing a script to spawn a Game Object at different time interval

  • Click on SpawnBox > Add Component > new script > Name it “Spawner” > Create and add
  • Right Click on the Script > Edit Script
  • Insert the following codes (Refer to the comments in the codes for explanation)
using System.Collections;
using UnityEngine;

public class Spawner : MonoBehaviour {

   //GameObjects Variabes
    public GameObject Object1; // Insert cube here
    public Transform spawnBox; //gives us position, rotation,scale of spawnbox

    //Changing Variables
    public float SpawnTime = 1f;
    public int MaxNoOfObjects = 5;
    public static bool objectDestroyed = false; //global Variable

    void Start() {
        //Start Spawning objects
        StartCoroutine(spawnLoop());
    }
    
    void Update() {
        if (objectDestroyed) {
            objectDestroyed = false;
            createObj();
        }
    }

   public GameObject createObj() {
            //This function will spawn an obj

            //get random position within a space
            Vector3 randomPos = getRandomPos();

            //Instantiate(object, position, rotation, parent, instantiateInWorldSpace
            //this will spawn an object
            GameObject newObj = Instantiate(Object1, randomPos, Quaternion.identity) as GameObject;

            return newObj;
    }

   public Vector3 getRandomPos() {
        //get random position within the spawnBox</p><p>        //Spawnbox area
        float MIN_X = -spawnBox.localScale.x / 2, MAX_X = spawnBox.localScale.x / 2;
        float MIN_Y = -spawnBox.localScale.y / 2, MAX_Y = spawnBox.localScale.y / 2;
        float MIN_Z = spawnBox.position.z - (spawnBox.localScale.z / 2), MAX_Z = spawnBox.position.z + (spawnBox.localScale.z / 2);

        float x = UnityEngine.Random.Range(MIN_X, MAX_X);
        float y = UnityEngine.Random.Range(MIN_Y, MAX_Y);
        float z = UnityEngine.Random.Range(MIN_Z, MAX_Z);
        Vector3 pos = new Vector3(x, y, z);

        return pos;
    }

    private IEnumerator spawnLoop() {
        yield return new WaitForSeconds(2); //Wait for 5 seconds
        int i = 0;
        while (i < MaxNoOfObjects) {
            createObj();
            i++;

           //Wait for awhile before spawning the next object
            float randomSpawnTime = Random.Range(SpawnTime, SpawnTime * 2);
            yield return new WaitForSeconds(randomSpawnTime);
        }
    }
}

Lastly, drag Cube under Assets > Objects and SpawnBox in Hierarchy panel to the Spawner script input boxes. Now, you should see objects spawning at different pace. Basically, what this script does is it will spawn a given Game Object(a Cube in this case) at a random position in SpawnBox at a given interval of seconds. You can also refer to the attached file for this script.

Step 7: Setting Up End Point / Destroy Point for Objects

DestroyPoint

Creating a wall that the objects will be flying to and getting destroyed

  • Right click on the Hierarchy panel > 3D Objects > Cube
  • Rename it as “DestroyPoint”
  • Disable Mesh Renderer and ENABLE Box Collider
  • Change the Position (X,Y,Z) to (0,0,0)
  • Change the Scale (X,Y,Z) to (10,10,10)

ObjectBehaviour

Flying the cubes from SpawnBox to Camera and Exploding it when it collide with DestroyPoint

  • Click on Cube under Assets > Objects, Add Component > new script > Name it “ObjectBehaviour” > Create and add
  • Insert the following codes into the script (Refer to the comments in the codes for explanation)
using System.Collections;
using UnityEngine;

public class ObjectBehaviour : MonoBehaviour {

    //Variables
    Vector3 DestroyPtPos;
    Rigidbody rb;
    GameObject[] pieceList; //array of debris after explode
    Renderer rd;

    //public variables
    public float speed = 2f; // Speed
    public float cubeSize = 0.15f; //size of debris after explode
    public int noOfPieces = 30; //no of debris

    void Start() {
        //get Destroy position
        GameObject destroyPt = GameObject.Find("DestroyPoint");
        DestroyPtPos = destroyPt.transform.position;

        //get rigidbody
        rb = GetComponent<rigidbody>();

        //get renderer
        rd = GetComponent<renderer>();
    }

    // Update is called once per frame
    void Update () {
        //make objects fly to camera
        // takes 5 sec for it to reach the camera
        transform.position = Vector3.MoveTowards(transform.position, DestroyPtPos, speed * Time.deltaTime);
    }

    private void OnTriggerEnter(Collider other) {
        //if object collide DestroyPoint
        if (other.gameObject.name == "DestroyPoint") {
            //to make object untouchable
            rb.isKinematic = false;
            rb.detectCollisions = false;

            //make object disappear
            rd.enabled = false;

            //explode after it touches DestroyPoint
            explode();
            //clear debris after 1 sec of explode
            StartCoroutine(delPieces());

          //decrease totalobjects count since 1 is destroyed
            Spawner.objectDestroyed = true;
        }
    }

    void explode() {
        //For loop to create 30 pieces as debris after explode
        int x = 50;
        pieceList = new GameObject[noOfPieces];
        for (int i = 0; i < noOfPieces; i++) {
            pieceList[i] = createPiece(x);
            x *= -1;
        }
    }

    public GameObject createPiece(int x) {
        //create piece
        GameObject piece;
        piece = GameObject.CreatePrimitive(PrimitiveType.Cube);

        //set piece position and scale and rotation
        piece.name = "Debris";
        piece.transform.position = transform.position + new Vector3(cubeSize, cubeSize, cubeSize);
        piece.transform.localScale = new Vector3(cubeSize, cubeSize, cubeSize);
        piece.transform.localEulerAngles = new Vector3(cubeSize * x, cubeSize * x, cubeSize * x);
        //add rigidbody and set mass
        piece.AddComponent<rigidbody>();
        piece.GetComponent<rigidbody>().mass = 0.05f;
        //add color
        piece.GetComponent<renderer>().material.color = new Color(1, 1, 1, 1);

        return piece;
    }

    private IEnumerator delPieces() {
        //Clear debris after 1 seconds
        yield return new WaitForSeconds(1);
        foreach (GameObject item in pieceList) {
            Destroy(item);
        }
        pieceList = new GameObject[0];
        yield return new WaitForSeconds(5);
        Destroy(gameObject);
    }
}

Basically, what this script does is making the cubes fly towards the DestroyPoint, and when it collides with the wall of the DestroyPoint, it will "explode" and taken out from the scene. After which, it will trigger a call to the Spawner to spawn another object in the SpawnBox. You can refer to the attached file for the script.

Moving on: Creating weapon using AR Marker & Game User Interface (UI)

Step 8: Creating the Marker and the Virtual Button

To use our personal marker, we have to go to
vuforia portal login and add tracker database. At there we can add any image tracker we want vuforia to track in there. When done, select all the image we want and export it to unity package. Download the package.

Go to unity and add the downloaded package in. (Go to Assets > Import package > Custom package > select the vuforia package then import everything in)

After all that is done we are now set and ready to use our personalized Marker!

Eg. Sphere (Game Object) creation

  • Click on GameObject > 3D Objects > Sphere
  • Click on Sphere in the Hierarchy panel, add the following components to the object:
  1. Mesh Renderer (by Default, should be there)Box Collider (Default) – allows object to collide with each other
  2. Add Component > Rigidbody and disable “Use Gravity” – allows object to act under the control of physics when collided with other objects
  3. Add Component > Animator – allows us to add animation to the object (rotation, scaling, etc)

Making the Marker track the virtual object

  • Click on Game Object > vuforia > Image
  • Click on the ImageTarget and Go to Inspector > Image Target Behavious (Script).

In here there would be three settings we have to set to use our personalized marker.

  1. Type: choose predefined.
  2. Database: choose the database name that you use to add the marker tracker in the vuforia portal.
  3. Image Target: choose the image you want to use.
  • Drag the game object you want to display when the marker is displayed in to the ImageTarget.
  • Go to the Scene View and Move and scale the Game object (Sphere) to the position you want to display at, with respect to the marker object.
  • With this set up, when built and run, you can see the game object being displayed whenever the marker is in view.

Adding the Virtual Button

  • Click on the ImageTarget and Go to Inspector > Image Target Behavious (Script).
  • Click on the Advanced > Add Virtual Button.
  • By doing this, a Virtual Button object will be created and stored in the ImageTarget hierarchy.
  • Click on the Virtual Button and go to the Inspector > Virtual Button Behaviour (Script)

In here there would be two settings:

  1. Name: choose a name for your virtual button.
  2. Sensitivity Setting: choice of high, medium low. (High meaning extremely sensitive detection of movement near the Virtual button, eg. even a shadow would cause the Virtual button to trigger. And the rest respectively.)

Step 9: ​Making the Game Object Change Whenever the Virtual Button Is Pressed & Tracking of the Marker (Script)

Hooking things up

  • Click on the ImageTarget and Go to Inspector > Add a component > Script.
  • Right Click on the Script > Edit Script
  • Insert the following codes (Refer to the comments in the codes for explanation)
using UnityEngine;<br>using Vuforia;
public class Wchange : MonoBehaviour, ITrackableEventHandler, IVirtualButtonEventHandler
{
    private TrackableBehaviour mTrackableBehaviour;
    public GameObject virtualBtn;
    public GameObject lightSaberWeapon;
    public GameObject turretWeapon;
    public GameObject KnifeWeapon;
    [System.NonSerialized]
    public int changingState = 2;
    private Nchange nWc;
    void Awake()
    {
        nWc = GameObject.FindObjectOfType();
    }
    // Use this for initialization
    void Start()
    {
        mTrackableBehaviour = GetComponent
();
        if (mTrackableBehaviour)
        {
            mTrackableBehaviour.RegisterTrackableEventHandler(this);
        }
        virtualBtn = GameObject.Find("VirtualButton");
        virtualBtn.GetComponent().RegisterEventHandler(this);
    }
    //On tracking change do something here.
    public void OnTrackableStateChanged(TrackableBehaviour.Status previousStatus, TrackableBehaviour.Status newStatus)
    {
        if (newStatus == TrackableBehaviour.Status.DETECTED ||
newStatus == TrackableBehaviour.Status.TRACKED 
//|| newStatus == TrackableBehaviour.Status.EXTENDED_TRACKED
)
        {
            Debug.Log(mTrackableBehaviour.TrackableName + "::::: NAME");
            int stateCorrection = changingState - 1;
            if (stateCorrection == 0)
            {
                stateCorrection = 3;
            }
            if (stateCorrection == 1)
            {
                var LightSaberComponents = lightSaberWeapon.GetComponentsInChildren(true);
                foreach (var component in LightSaberComponents)
                    component.enabled = true;
                var TurretComponents = turretWeapon.GetComponentsInChildren(true);
                foreach (var component in TurretComponents)
                    component.enabled = false;
                var KnifeComponents = KnifeWeapon.GetComponentsInChildren(true);
                foreach (var component in KnifeComponents)
                    component.enabled = false;
            }
            else if (stateCorrection == 2)
            {
                var LightSaberComponents = lightSaberWeapon.GetComponentsInChildren(true);
                foreach (var component in LightSaberComponents)
                    component.enabled = false;
                var TurretComponents = turretWeapon.GetComponentsInChildren(true);
                foreach (var component in TurretComponents)
                    component.enabled = false;
                var KnifeComponents = KnifeWeapon.GetComponentsInChildren(true);
                foreach (var component in KnifeComponents)
                    component.enabled = true;
            }
            else if (changingState == 3)
            {
                var LightSaberComponents = lightSaberWeapon.GetComponentsInChildren(true);
                foreach (var component in LightSaberComponents)
                    component.enabled = false;
                var TurretComponents = turretWeapon.GetComponentsInChildren(true);
                foreach (var component in TurretComponents)
                    component.enabled = true;
                var KnifeComponents = KnifeWeapon.GetComponentsInChildren(true);
                foreach (var component in KnifeComponents)
                    component.enabled = false;
            }
            var rendererComponents = virtualBtn.GetComponentsInChildren(true);
            foreach (var component in rendererComponents)
                component.enabled = true;
        }
        else
        {
            var LightSaberComponents = lightSaberWeapon.GetComponentsInChildren(true);
            foreach (var component in LightSaberComponents)
                component.enabled = false;
            var TurretComponents = turretWeapon.GetComponentsInChildren(true);
            foreach (var component in TurretComponents)
                component.enabled = false;
            var KnifeComponents = KnifeWeapon.GetComponentsInChildren(true);
            foreach (var component in KnifeComponents)
                component.enabled = false;
            var rendererComponents = virtualBtn.GetComponentsInChildren(true);
            foreach (var component in rendererComponents)
                component.enabled = false;
            //OnTrackingLost();
        }
    }
    protected virtual void OnTrackingLost()
    {
        var rendererComponents = GetComponentsInChildren(true);
        var colliderComponents = GetComponentsInChildren
(true);
        var canvasComponents = GetComponentsInChildren(true);
        // Disable rendering:
        foreach (var component in rendererComponents)
            component.enabled = false;
        // Disable colliders:
        foreach (var component in colliderComponents)
            component.enabled = false;
        // Disable canvas':
        foreach (var component in canvasComponents)
            component.enabled = false;
    }
    public void OnButtonPressed(VirtualButtonBehaviour vb)
    {
        Debug.Log("Btn_Pressed");
        //pass State to ninja display
        nWc.chgState = changingState;
        if (changingState == 1)
        {
            var LightSaberComponents = lightSaberWeapon.GetComponentsInChildren(true);
            foreach (var component in LightSaberComponents)
                component.enabled = true;
            var TurretComponents = turretWeapon.GetComponentsInChildren(true);
            foreach (var component in TurretComponents)
                component.enabled = false;
            var KnifeComponents = KnifeWeapon.GetComponentsInChildren(true);
            foreach (var component in KnifeComponents)
                component.enabled = false;
        }
        else if (changingState == 2)
        {
            var LightSaberComponents = lightSaberWeapon.GetComponentsInChildren(true);
            foreach (var component in LightSaberComponents)
                component.enabled = false;
            var TurretComponents = turretWeapon.GetComponentsInChildren(true);
            foreach (var component in TurretComponents)
                component.enabled = false;
            var KnifeComponents = KnifeWeapon.GetComponentsInChildren(true);
            foreach (var component in KnifeComponents)
                component.enabled = true;
        }
        else if (changingState == 3)
        {
            var LightSaberComponents = lightSaberWeapon.GetComponentsInChildren(true);
            foreach (var component in LightSaberComponents)
                component.enabled = false;
            var TurretComponents = turretWeapon.GetComponentsInChildren(true);
            foreach (var component in TurretComponents)
                component.enabled = true;
            var KnifeComponents = KnifeWeapon.GetComponentsInChildren(true);
            foreach (var component in KnifeComponents)
                component.enabled = false;
        }
        //change restart loop
        if (changingState == 3)
        {
            changingState = 1;
            return;
        }
        changingState++;
    }
    public void OnButtonReleased(VirtualButtonBehaviour vb)
    {
        Debug.Log("Btn_Released");
    }
}

*In the code, make sure you implement two important interface for it. (ITrackableEventHandler,

IVirtualButtonEventHandler.)

  1. ITrackableEventHandler: This interface will provide you an abstract method OnTrackableStateChanged() that will allow you to have control on what you want to do when the marker is being in view and when the marker is out of view.
  2. IVirtualButtonEventHandler: This interface if for the virtual button and it will provide you an abstract method OnButtonPressed() and OnButtonReleased(). This will allow you to control on what you want to do when the virtual button is pressed.
  • One important note:
    • Since we already use the ITrackableEventHandler Interface, this means we are actually accessing more control in the Handler. But Vuforia have its own script that uses ITrackableEventHandler in global scope. So, because we want more control, we have to disable or comment out Vuforia script.
    • Got to Vuforia > Scripts > DefaultTrackableEventHandler
    • At there you can comment out the OnTrackingFound() as we do not need it to help us render our objects as we will be customizing our rendering process our self.
  • Lastly, drag The Virtual Button Object and all the Game object we want to change in the script variable. Located at Image Target > Inspector > Script.

Step 10: Creating the Main Menu

Adding the background image and particle

  • Click on to GameObject tab > UI > Canvas.
  • Right click on the canvas > CreateEmpty.
  • In the Empty GameObject, Click add Component > Sprite Renderer.
  • In the Sprite renderer of the GameObject, there will be a Sprite field. At there you can add whatever image you want. (For us its the SF background)
  • To make small particles floating around, unity have its own in built in component for that that will make our life a lot easier.
  • Add component > Particle System.
  • At that Particle system Field we can than manipulate what we want like how fast the we want the particle move, what color what size etc. (eg. see image above)

Creating the Canvas/Panel

*Canvas and panel will hold all our UI objects.

  • Click on to GameObject tab > UI > Canvas.
  • Click on the Created Canvas, right click > UI > Panel. (Creating the panel)
  • Click on the Created Canvas, right click UI > Button to create a button. (Creating the button)

The result hierarchy as follow:

Canvas > Panel > Button

For the button to change scene, we have to hook up some scripts to it.

Hooking up the script

  • Click on the button, go to the inspector scroll down you will see the click handler for the button. Choose runtime only on the drop-down menu and drag your button object in.
  • Click on the Add component button and add a script, naming it "LoadSceneOnClick" (Or any of your naming choice). Double click it to open up the script on your favorite IDE.

Add the function in, this function would allow us to change scene by index

public void LoadByIndex(int sceneIndex) {<br>        SceneManager.LoadScene(sceneIndex);     
}

When done, go back to the button click handler and choose the script then choose the function. On the empty box below is the parameter we pass, which is the index of the scene we want to load.

Changing the canvas/panel NOT the scene

  • For this, the basic is to hide one canvas when click and display another. This will give the effect of the change.
  • 1st we have to hide the panel we do not want to display.
  • Click on a panel, for us its the IntroPanel, on the inspector tab, there is a check box. Untick the check box, this will setActive of the object to be false. You can write in code GameObject.setActive(false) if you prefer.
  • Click on the button and on the inspector > On click()
  • This On Click() setting will allow us to control what happen when the user click on the button.
  • Drag the panel you want to hide from view when click into the onclick() box. the box on the right will give us control on what function will be called to the GameObject.
  • Click GameObject > setActive.
  • And on the bottom would be the parameter. Since setActive() takes in a boolean, unity gave us a check box display when there is a tick means true else otherwise.
  • So from this setting we can hide one panel and display another giving an illusion of change of screen.

Step 11: BONUS (Shooting Turret)

*We will Assume u follow Everything at the front and know how to use the basic unity.

Basic Setup

  • We have the GameObject of the turret and the DiskProjectile Object so just download it and drag into the hierarchy.
  • Also download the Animation clip for the turret "Bunker" as provide.
  • Create an ImageTarget and add a virtual button as previously taught.
  • Add the Turret object in the the Image Target.
  • *Our main objective is to let the Turret shoot a Projectile Disk when the virtual button is pressed

The Hook up

  • Go to the turret and Click Add component > Script
  • Insert the following codes (Refer to the comments in the codes for explanation)
    using UnityEngine;
    using UnityEngine.Events;
    public class CannonSystem : MonoBehaviour 
    {
    	[Header("Firing Properties")]
    	public float maxProjectileForce = 18000f;   //Maximum force of a projectile
    	public float cooldown = 1f;
    	[Header("Projectile Properties")]
    	public GameObject projectilePrefab;			//The projectile to be shot
    	Transform projectileSpawnTransform;         //Location where the projectiles should spawn
    	bool canShoot = true;
    	Animator anim;								//Reference to the animator component
    	void Awake()
    	{
    		//Get a reference to the projectile spawn point. By providing the path to the object like this, we are making an 
    		//inefficient method call more efficient
    		projectileSpawnTransform = GameObject.Find("Geometry/Cockpit/Turret Elevation Pivot Point/Projectile Spawn Point").transform;
    		//Get a reference to the animator component
    		anim = GetComponent<animator> ();
    	}</animator>
    	public void FireProjectile()
    	{
    		if (!canShoot)
    			return;
    		GameObject go = (GameObject)Instantiate(projectilePrefab, projectileSpawnTransform.position, projectileSpawnTransform.rotation);
    		Vector3 force = projectileSpawnTransform.transform.forward * maxProjectileForce;
    		go.GetComponent<rigidbody>().AddForce(force) ;
    		anim.SetTrigger ("Fire");</rigidbody>
    		canShoot = false;
    		Invoke("CoolDown", cooldown);
    	}
    
    	void CoolDown()
    	{
    		canShoot = true;
    	}
  • After adding it to the turret, Go to the virtual button so when can execute the script on button pressed.

  • In the Button, add a script as taught previously, and on button pressed, call the function FireProjectile() in the turret script.

  • This will allow the turret to play the animation and fire a Game object which is the projectile Disk which will hook up now.

  • Click the turret > inspector > script

  • Go to the script section (that we added just now), and drag the projectile Disk game object in. In there we can set the cool down time and projectile Force, which is the speed we want the projectile disk game object to fly at when the virtual button is executed.

Step 12: And Off You GO!

You have successfully make a fully working mobile game!

Further features that you can include:

  • Design of the UI
  • Design of the Game Objects and Weapons (Such as creating your own 3D Objects OR downloading 3D Objects from the asset store in Unity)
  • Navigation of the game (from scene to scene)

Have fun!

Step 13: Future Improvement of Our Project

Firstly, in terms of users input, we want to insert a larger variety of actions that can be performed by the users to make the game more interactive. Currently, our user input is marker tracking for the weapon used to destroy objects. The range and speed of motion is very limited since the camera detection is not as robust as we expected it to be. Therefore, other inputs such as using voice recognition to execute an action is plausible.

Secondly, multiplayer mode can be introduced where 1st player will be the one slashing the objects while 2nd player will be the one who is spawning the objects. This can be done with the help of another marker for the 2nd player to initialize the position of where the next object will be spawned. This will increase the participatory of the game and making it more competitive by introducing a competitor.

Thirdly, increasing the scope of scoring points. Instead of slashing objects flying towards the user to score points, objects can appear falling from the sky or appearing at random position in the scene for a certain period of time for the users to slash for bonus points. This will make the game more intensive and ensure the user is always on the ball trying to score more points and at the same time, trying to destroy objects flying towards the user that will reduce his health bar.

Step 14: Other Challenges to Consider

Overall, Combat Of Survival is playable but there are limitations that will affect the user experience of the game which we did not foresee during the creation of the game. We overestimated the robust image detection of the camera. We realized that users cannot move their marker too quickly in front of the camera when playing the game because the camera would not be able to detect the marker. Moreover, lighting of the area is essential for the marker to be visible to the camera. As a temporary solution, we triggered the mobile phone's flash light when the user start the game in order to maximize the lighting in the area. This is effective to only a certain extent.

Another aspect to take note is using of Virtual Buttons that is displayed using the marker. The sensitivity of the button is also highly dependent on the motion of the users' hands and the lighting of the area as mentioned above.

Step 15: Extra: Work Allocation

Jun Bang:

  • Step 1: Download CombatOfSurvival Files & Demo Video
  • Step 2: How to Build Our Project?
  • Step 4: Building Our Project
  • Step 5: Getting Started
  • Step 6: Setting Up the Spawn Box & Constructing the Spawner
  • Step 7: Setting Up End Point / Destroy Point for Objects
  • Step 12: And Off You GO!
  • Step 13: Future Improvement of Our Project

Lester:

  • Introduction
  • Step 3: Software Configuration
  • Step 8: Creating the Marker and the Virtual Button
  • Step 9: Making the Game Object Change Whenever the Virtual Button Is Pressed & Tracking of the Marker (Script)
  • Step 10: Creating the Main Menu
  • Step 11: BONUS (Shooting Turret)
  • Step 14: Other Challenges to Consider