⬆️ ⬇️

Development of space shooter for android using the Unity3D game engine



Good day! In this article, I want to share the experience of developing my game using the Unity game engine.



The concept of the game is that you need to take control of the starship and destroy as many meteorites as possible. On your way will appear enemy spaceships that will disturb you and after their destruction there will appear “capsules” after selecting which a new type of weapon will be available. The game will be called Galaxy Desteroid.



Development



The graphics of the game consists of the following textures:





')

Based on these textures, the following prefabs were created.







Where:



asteroidrotate - meteorite to be destroyed



enemy - enemy spaceship



explosionasteroid, explosionenemy, explosionplayer - this is an explosion animation created using particle system



gunactivator (s) - these are capsules that will activate a different type of weapon in the game.



Everything else like laser, etc. this is a weapon.



The game will include 2 scenes: the main menu and the game scene.



Main menu







Where “menu” is the main menu and “1” is a game scene.











I used a sprite with the name “space” as a background, a space was drawn on it.







Next, create the menu.cs script (right click → select Create → C # Script) and “hang” it on the background. background is a sprite with 100% transparency on which the main controls (START / EXIT) are created and the space is just for decoration.



Script content:



using UnityEngine; using System.Collections; using System.Collections.Generic; using System.Runtime.Serialization.Formatters.Binary; using System.IO; using UnityEngine.SceneManagement; public class menu : MonoBehaviour { public GUIStyle mystyle;//      GUI (,  ...) string score; void Start () { StreamReader scoredata = new StreamReader (Application.persistentDataPath + "/score1.gd");//   score = scoredata.ReadLine ();//  scoredata.Close ();//   } // Update is called once per frame void Update () { } void OnGUI(){ GUI.Box (new Rect (Screen.width*0.15f, Screen.height*0.8f, Screen.width*0.7f, Screen.height*0.1f), "MAX DESTROYED:"+score,mystyle); if (GUI.Button (new Rect (Screen.width*0.15f, Screen.height*0.25f, Screen.width*0.7f, Screen.height*0.1f), "START",mystyle)) { SceneManager.LoadScene (1);//   } if (GUI.Button (new Rect (Screen.width*0.15f, Screen.height*0.4f, Screen.width*0.7f, Screen.height*0.1f), "EXIT",mystyle)) { Application.Quit();//   } } } 


Do not forget to hang the activemenu script on the “space”. It serves to create a motion animation for the menu background. Then create a copy of “space” and put it a little higher.



The contents of the activemenu script:



 using UnityEngine; using System.Collections; public class activemenu : MonoBehaviour { float speed=-0.1f; void Start () { } // Update is called once per frame void Update () { transform.Translate (new Vector3 (0f,speed,0f)); if (transform.position.y < -12f) { transform.position=new Vector3(0f,13f,0f); } } } 


It should look like this:











Creating a game scene







The game scene consists of the following key objects:



space (sprite "space")

player

meteorites

enemy ships

other (lasers and explosions).



Space is also organized in the main menu. Here you can not touch anything.



Next, you need to pay attention to the fact that the game will be constantly generated from prefabs, such objects as meteorites, shots and enemies. And those objects that the player missed need to be deleted so as not to burden the memory once again.



This can be done as follows. We create a new game object on the scene (I have this “controlcountobjects”), add the boxcollider component to it and stretch it around the gaming zone.







Next, add a script to it with the following contents:



 using UnityEngine; using System.Collections; public class systemcontrolobjects : MonoBehaviour { void Start () { } void Update () { } void OnTriggerExit2D(Collider2D col) { Destroy(col.gameObject); } } 


In this script, the elements are deleted when exiting the box control of the controlcountobject object. Thus, a certain zone is obtained when exiting from which objects are deleted.



Meteorite generation



Add this script to the camera:



 using UnityEngine; using System.Collections; using System.Runtime.Serialization.Formatters.Binary; using System.IO; public class blockgenerator : MonoBehaviour { public GameObject asteroid;//     float x,y,timer; float timerespawn=0.25f;//  .         . bool trigtime=false;//   .    true        . public int score;//                     .       .      ,       . public float data; void Start () { score = 0;// timer = timerespawn; StreamReader scoredata = new StreamReader (Application.persistentDataPath + "/score1.gd"); data = float.Parse(scoredata.ReadLine ()); scoredata.Close (); } void Update () { if (timer==timerespawn)//       : { x = Random.Range (-2.5f, 2.5f);//1)         . Instantiate(asteroid, new Vector3(x,5.5f,-2.17f),transform.rotation);//2)   . x      . trigtime = true;//3)    .         timerrespawn    . } if (trigtime==true)//  { timer = timer-Time.deltaTime;//     . } if (timer < 0)//     : { timer = timerespawn;//1)      timerespawn trigtime = false;//2)   //     " ".           .     } } } 






Meteorite



Above you can see, the fact that the meteorites that appear on the scene of different sizes and still they rotate. This is all because the meteorite is implemented using two GameObjects, where one is inside the other (the Russian doll).











The external object “asteroidrotate” describes the motion of a meteorite, contains a circle collider and triggers an explosion effect in the event of a collision, and “aster” randomly creates a direction of rotation and size when created.



Script for asteroidrotate:



 using UnityEngine; using System.Collections; public class asteroidlogic : MonoBehaviour { public GameObject explosion;//     float speedasteroid=-0.1f;//   void Start () { } void Update () { transform.Translate (new Vector3 (0, speedasteroid, 0f));//         } void OnTriggerEnter2D(Collider2D col) { if (col.tag == "systemcontrol") { return;//       controlcountobjects } if (col.tag == "laser") //       { Destroy (col.gameObject);//   GameObject.Find ("Main Camera").GetComponent<blockgenerator> ().score++;//       Instantiate(explosion, transform.position,transform.rotation);//    Destroy (this.gameObject);//  } } } 


Script for aster:



 using UnityEngine; using System.Collections; public class rotator : MonoBehaviour { int f; float sc; void Start () { f = Random.Range (-5, 5); sc = Random.Range (0.1f,0.2f); transform.localScale = new Vector3 (sc,sc,sc);// } void Update () { transform.rotation *= Quaternion.AngleAxis (f,new Vector3(0,0,1));// } } 


Player



We throw a sprite with a starship on the game scene, add a box collider to it (do not forget to mark “Is Triger”), add a rigibody (we need to freeze the Y coordinate). All this is necessary so that the player can interact with other game objects.







You can also add the particle system component, which will represent the jet from the engine.







In the script for the player, a “connection” is established with prefabs such as explosionplayer, laser, laser3x, laser3xhor, etc. as well as the organization of control and selection of "capsules" for the activation of other types of weapons. Management is arranged so that the game object simply moves after the user's finger and in the process fires.



Script content:



 using UnityEngine; using System.Collections; using UnityEngine.SceneManagement; using System.Runtime.Serialization.Formatters.Binary; using System.IO; public class carconroller : MonoBehaviour { public GameObject laser;//      laser public GameObject laser3x;//      laser3x public GameObject laserhor;//      laserhor public GameObject laser3xhor;//      laser3xhor public GameObject sphere;//      sphere public GameObject sphere3x;//      sphere3x public GameObject explosionplayer;//      explosionplayer float x,y,z,x1,y1; bool trigtime=false; public float speedreset=0.25f;//     float timer; Vector2 startpos; Vector2 startcar; // laser...sphere3x          public bool gun1 = true;//   1 (laser),       ,     (laser3x...) public bool gun2 = false; public bool gun3 = false; public bool gun4 = false; public bool gun5 = false; public bool gun6 = false; //        .        . int guncount=0;//   ,    .          . void Start () { timer = speedreset; y = laser.transform.position.y; z = laser.transform.position.z; } public void Update () { if (timer < 0) { timer = speedreset; trigtime = false; } if (Input.GetMouseButton(0))//    { Vector2 pos = Camera.main.ScreenToWorldPoint (Input.mousePosition);//   pos  ,    . transform.position = pos;//       pos transform.position = new Vector2 (transform.position.x,transform.position.y+1f);//  () if (timer==speedreset)//  ( ) { if (gun1 == true)//   { Instantiate (laser, new Vector2(transform.position.x,transform.position.y+1.1f), transform.rotation);//    laser     (  ) trigtime = true; } if (gun2 == true && guncount > 0)//   2-        { guncount--;//   if (guncount == 0) //       1     { gun1 = true; gun2 = false; gun3 = false; gun4 = false; gun5 = false; gun6 = false; } Instantiate (laser3x, new Vector2(transform.position.x,transform.position.y+1.1f), transform.rotation);//    laser3x trigtime = true; } //    ""    if (gun3 == true && guncount > 0) { guncount--; if (guncount == 0) { gun1 = true; gun2 = false; gun3 = false; gun4 = false; gun5 = false; gun6 = false; } Instantiate (laserhor, new Vector2(transform.position.x,transform.position.y+1.1f), transform.rotation); trigtime = true; } if (gun4 == true && guncount > 0) { guncount--; if (guncount == 0) { gun1 = true; gun2 = false; gun3 = false; gun4 = false; gun5 = false; gun6 = false; } Instantiate (laser3xhor, new Vector2(transform.position.x,transform.position.y+2f), transform.rotation); trigtime = true; } if (gun5 == true && guncount > 0) { guncount--; if (guncount == 0) { gun1 = true; gun2 = false; gun3 = false; gun4 = false; gun5 = false; gun6 = false; } Instantiate (sphere, new Vector2(transform.position.x,transform.position.y+1.1f), transform.rotation); trigtime = true; } if (gun6 == true && guncount > 0) { guncount--; if (guncount == 0) { gun1 = true; gun2 = false; gun3 = false; gun4 = false; gun5 = false; gun6 = false; } Instantiate (sphere3x, new Vector2(transform.position.x,transform.position.y+2f), transform.rotation); trigtime = true; } } if (trigtime == true) { timer = timer - Time.deltaTime;//    } } } void OnTriggerEnter2D(Collider2D col) { if (col.tag == "systemcontrol") { return;//       controlcountobject } if (col.tag == "gunactivator2")//    ""  gunactivator2 { gun2 = true;//   guncount = 85;//   gun1 = false;//  "" gun3 = false; gun4 = false; gun5 = false; gun6 = false; Destroy (col.gameObject);// ""     return; } //   if (col.tag == "gunactivator3") { gun3 = true; guncount = 50; gun1 = false; gun2 = false; gun4 = false; gun5 = false; gun6 = false; Destroy (col.gameObject); return; } if (col.tag == "gunactivator4") { gun4 = true; guncount = 15; gun1 = false; gun3 = false; gun2 = false; gun5 = false; gun6 = false; Destroy (col.gameObject); return; } if (col.tag == "gunactivator5") { gun5 = true; guncount = 100; gun1 = false; gun3 = false; gun4 = false; gun2 = false; gun6 = false; Destroy (col.gameObject); return; } if (col.tag == "gunactivator6") { gun6 = true; guncount = 50; gun1 = false; gun3 = false; gun4 = false; gun5 = false; gun2 = false; Destroy (col.gameObject); return; } //   ""           ,     .       Handheld.Vibrate ();// ( ) if (GameObject.Find ("Main Camera").GetComponent<blockgenerator> ().score>GameObject.Find ("Main Camera").GetComponent<blockgenerator> ().data)//              ,        { StreamWriter scoredata=new StreamWriter(Application.persistentDataPath + "/score1.gd"); scoredata.WriteLine(GameObject.Find ("Main Camera").GetComponent<blockgenerator> ().score); scoredata.Close(); } Instantiate (explosionplayer, transform.position, transform.rotation);//    Destroy (col.gameObject);//      Destroy(this.gameObject);//     } } 






Weapon activators.







The result of the script.



When a player is removed and a new record of destroyed meteorites is recorded in the file, then you need to go to the main menu.



Create a script with the following content and connect it to the camera:



 using UnityEngine; using System.Collections; using UnityEngine.SceneManagement; using System.Runtime.Serialization.Formatters.Binary; using System.IO; public class Exit : MonoBehaviour { public GameObject target;//    float timer=3f; void Start () { } void Update () { if (Input.GetKey (KeyCode.Escape))//       , : { if (GameObject.Find ("Main Camera").GetComponent<blockgenerator> ().score>GameObject.Find ("Main Camera").GetComponent<blockgenerator> ().data) { StreamWriter scoredata=new StreamWriter(Application.persistentDataPath + "/score1.gd"); scoredata.WriteLine(GameObject.Find ("Main Camera").GetComponent<blockgenerator> ().score); //     score  "blockgenerator",     scoredata.Close(); } SceneManager.LoadScene (0);//   } if (!GameObject.Find ("playercar"))//       ( )   timer     { timer = timer - Time.deltaTime; if (timer < 0) { SceneManager.LoadScene (0); } } } } 


This script monitors the status of the player.



Explosions



The explosion effect can be created using Particle System. But then he will be looped and forever repeated. To prevent this, add the following script to the prefab explosion.



 using UnityEngine; using System.Collections; public class DestroyAsteroid : MonoBehaviour { void Start () { } void Update () { Destroy (this.gameObject,0.4f);//     .   400 .   . } } 






Shots



Shots are generated from the location of the player during his movement.







In the script for the shot you need to set only the speed and direction.



 using UnityEngine; using System.Collections; using System.Runtime.Serialization.Formatters.Binary; using System.IO; public class laser : MonoBehaviour { float speedlaser=0.5f; void Start () { } void Update () { transform.Translate (new Vector3 (0, speedlaser, 0f)); } } 


Generation of opponents



The generation of opponents is similar to the generation of meteorites.







The contents of the script Enemygenerator:



 using UnityEngine; using System.Collections; public class enemygenerator : MonoBehaviour { public GameObject enemy; bool trigtime=false; float speedreset=2f; float timer,x; void Start () { timer = speedreset; } void Update () { if (timer < 0) { timer = speedreset; trigtime = false; } if (timer == speedreset) { x = Random.Range (-2.5f, 2.5f);//  Instantiate(enemy, new Vector2(x,5.5f),transform.rotation);//    trigtime = true; } if (trigtime == true) { timer = timer - Time.deltaTime; } } } 






Enemy logic



The enemy's behavior is organized in such a way that he just flies in a straight line, firing and in case of defeat he can leave a capsule for the player to activate



It looks like this:











 using UnityEngine; using System.Collections; public class enemylogic : MonoBehaviour { public GameObject explosionenemy;//  public GameObject laserenemy;//  //       public GameObject gunactivator2; public GameObject gunactivator3; public GameObject gunactivator4; public GameObject gunactivator5; public GameObject gunactivator6; // bool trigtime=false; float speedreset=1.5f;//  float timer; float speedenemy = -0.02f;//   float x; void Start () { timer = speedreset; } void Update () { if (timer < 0) { timer = speedreset; trigtime = false; } if (timer == speedreset) { Instantiate (laserenemy, new Vector2(transform.position.x,transform.position.y-0.4f), transform.rotation); trigtime = true; } if (trigtime == true) { timer = timer - Time.deltaTime; } transform.Translate (new Vector3 (0, speedenemy, 0f)); } void OnTriggerEnter2D(Collider2D col) { if (col.tag == "systemcontrol") { return; } if (col.tag == "Player") { Instantiate (explosionenemy, transform.position, transform.rotation); Destroy(this.gameObject); } if (col.tag == "laser") { x = Random.Range (0f, 100f);//    0  100 if (x > 1f && x < 5f) //     1  5    gunactivator2 { Instantiate (gunactivator2, transform.position, transform.rotation); } //   if (x > 20f && x < 25f) { Instantiate (gunactivator3, transform.position, transform.rotation); } if (x > 40f && x < 45f) { Instantiate (gunactivator4, transform.position, transform.rotation); } if (x > 60f && x < 65f) { Instantiate (gunactivator5, transform.position, transform.rotation); } if (x > 80f && x < 85f) { Instantiate (gunactivator6, transform.position, transform.rotation); } Instantiate (explosionenemy, transform.position, transform.rotation); Destroy(this.gameObject); } } } 


Each prefab "capsule" with a weapon just moves towards the player and in the case of crossing is destroyed.







 using UnityEngine; using System.Collections; public class gunactivatorlogic : MonoBehaviour { float speed = -0.025f; void Start () { } void Update () { transform.Translate (new Vector3 (0, speed, 0f)); } } 


Total







Publication



The release of the game on google play was not a big success. For all the time in the market a little more than 500 downloads.

play.google.com/store/apps/details?id=com.WRXM4STER.SpaceStriker



Source: https://habr.com/ru/post/324288/



All Articles