Unity3Dゲームエンジンを使用してAndroid向けのスペースシューティングゲームを開発する







良い一日! この記事では、Unityゲームエンジンを使用してゲームを開発した経験を共有したいと思います。



ゲームのコンセプトは、宇宙船を制御し、できるだけ多くの流星を破壊する必要があるということです。 敵の宇宙船があなたの道に現れ、それがあなたに干渉し、破壊後、新しいタイプの武器が利用可能になることを選択した後、「カプセル」が現れます。 このゲームはGalaxy Desteroidと呼ばれます。



開発



ゲームのグラフィックは、次のテクスチャで構成されています。







これらのテクスチャに基づいて、次のプレハブが作成されました







ここで:



小惑星回転-破壊されるmet石



敵-敵の宇宙船



explosionasteroid、explosionenemy、explosionplayerは、パーティクルシステムを使用して作成された爆発アニメーションです。



gunactivator(s)は、ゲーム内のさまざまな種類の武器をアクティブにするカプセルです



それ以外はすべてレーザーなどです。 これが武器です。



ゲームには、メインメニューとゲームシーンの2つのシーンが含まれます。



メインメニュー







ここで、「メニュー」はメインメニュー、「1」はゲームシーンです。











背景として、「space」という名前のスプライトを使用し、その上にスペースが描かれています。







次に、スクリプト「menu.cs」を作成し(右クリック→[作成]→[C#スクリプト]を選択)、バックグラウンドで「ハング」します。 backgroundは、メインコントロール(START / EXIT)が作成される100%の透明度を持つスプライトであり、スペースは装飾用です。



スクリプトの内容:



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();//   } } }
      
      





activemenuスクリプトを「スペース」に掛けることを忘れないでください。 メニューの背景の動きのアニメーションを作成するのに役立ちます。 次に、「スペース」のコピーを作成し、それを少し高くします。



Activemenuスクリプトの内容:



 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); } } }
      
      





次のようになります。











ゲームシーンを作成する







ゲームシーンは、次の主要なオブジェクトで構成されています。



スペース(スプライト「スペース」)

プレイヤー

met石

敵船

その他(レーザーと爆発)。



スペースはメインメニューのように整理されます。 ここでは何も触れられません。



次に、ゲームではin石、ショット、敵などのオブジェクトから常に生成されることに注意する必要があります。 また、プレーヤーが見逃したオブジェクトは、もう一度メモリをロードしないように削除する必要があります。



これは次のように実行できます。 ステージ上に新しいゲームオブジェクトを作成し(「controlcountobjects」があります)、それにboxcolliderコンポーネントを追加し、ゲームゾーンの周りに引き伸ばします。







次に、次の内容のスクリプトを追加します。



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





このスクリプトでは、controlcountobjectがボックスコライダーを終了すると、要素が削除されます。 したがって、オブジェクトが削除される特定のゾーンが終了時に取得されます。



Me石の生成



このスクリプトをカメラに追加します。



 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)   //     " ".           .     } } }
      
      









Me石



上記のように、ステージ上にさまざまなサイズで表示されるmet石と、それらも回転していることがわかります。 これは、met石が2つのGameObjectを使用して実装されているためです。











外部オブジェクト「asteroidrotate」はmet石の動きを表し、サークルコライダーを含み、衝突の際に爆発効果をトリガーします。一方、「aster」は作成時に回転速度とサイズをランダムに設定します。



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);//  } } }
      
      





アスターのスクリプト:



 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));// } }
      
      





プレイヤー



宇宙船のあるスプライトをゲームシーンに投げ、ボックスコライダーを追加し(「Is Triger」をマークすることを忘れないでください)、リジボディを追加します(Y座標をフリーズする必要があります)。 これはすべて、プレーヤーが他のゲームオブジェクトと対話するために必要です。







また、パーティクルシステムコンポーネントを追加して、エンジンからのジェットを描写することもできます。







プレーヤーのスクリプトでは、explosionplayer、laser、laser3x、laser3xhorなどのプレハブとの「接続」が確立されます。 同様に、管理の組織と他の武器の活性化のための「カプセル」の選択。 このコントロールは、ゲームオブジェクトがユーザーの指の後ろに移動し、同時に発砲するように配置されています。



スクリプトの内容:



 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);//     } }
      
      









武器アクティベーター。







スクリプトの結果。



プレーヤーが削除され、破壊されたmet石の新しいレコードがファイルに記録されたら、メインメニューに移動する必要があります。



次の内容のスクリプトを作成し、カメラに接続します。



 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); } } } }
      
      





このスクリプトは、プレーヤーのステータスを監視します。



爆発



爆発効果は、パーティクルシステムを使用して作成できます。 しかし、それはループされ、永遠に繰り返されます。 これを防ぐには、爆発プレハブに次のスクリプトを追加します。



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









ショット数



ショットは、プレイヤーの移動中にプレイヤーの位置から生成されます。







ショットのスクリプトでは、速度と方向のみを設定する必要があります。



 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)); } }
      
      





相手の世代



敵の世代はmet石の世代に似ています。







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; } } }
      
      









敵の論理



敵の行動は、単純に直線で飛行し、発砲し、敗北した場合、プレイヤーが新しい武器を起動するためにカプセルを残すことができるように編成されています



次のようになります。











 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); } } }
      
      





武器を備えた「カプセル」の各プレハブは、プレイヤーに向かって移動するだけで、交差した場合には破壊されます。







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





まとめ







転記



Google Playでのゲームのリリースは特に成功しませんでした。 市場での滞在期間全体で、500件をわずかに超えるダウンロードが蓄積されました。

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










All Articles