シューティングチュートリアルをUnity5で(第12回)

12.1 Waveの作成

  • Import直後はScriptがアタッチされていないので追加されたWaveの各Enemyに手動でEnemyとSpaceshipをアタッチする。

f:id:shady:20150524181021j:plain

  • アタッチしたEnemyにはHpを、SpaceshipにはSpeed、Shot Delay、Can Shot、Bullet、Explosionを設定する(これをしないと敵が出現したきり動かない、弾幕がレーザー、敵が弾を撃ってこない、UnassignedReferenceExceptionなどが起きる)。
Wave 1 2 3 4 5
Can Shot T F T T T
HP 10 4 10 10 100
Speed 1 1 1 1 0.5
  • Animatorは追加済みだがControllerが未設定なのでEnemyを設定する(しないとAnimator has not been initializedが出る)。

スコアの表示

GUITextはHierarchyから作成できないので、CreateEmptyで空GameObjectを二つ作り、それぞれにScoreとHighscoreと名をつけ、Add Component>Rendering>GUITextでチュートリアルと同様の構成を実現する。

HighScoreが表示されないのでTransform.Position.Yを0.05に設定する。 f:id:shady:20150524181150j:plain

スクリプトの作成

  • 特記事項なし。Initializeメソッドにスコアクリア処理があるが、このメソッドは最後の「ハイスコアの保存」まで呼ばれないので今はゲームオーバーになってもスコアクリアされない。
using UnityEngine;
using System.Collections;

public class Score : MonoBehaviour {
    public GUIText scoreGUIText;
    public GUIText highScoreGUIText;
    private int score;
    private int highScore;
    private string highScoreKey = "highScore";

    void Update () {
        if (highScore < score) {
            highScore = score;
        }

        scoreGUIText.text = score.ToString ();
        highScoreGUIText.text = "HighScore : " + highScore.ToString ();
    }

    private void Initialize()
    {
        score = 0;
        highScore = PlayerPrefs.GetInt (highScoreKey, 0);
    }

    public void AddPoint(int point)
    {
        score = score + point;
    }

    public void Save()
    {
        PlayerPrefs.SetInt (highScoreKey, highScore);
        PlayerPrefs.Save ();

        Initialize ();
    }
}

エネミーにポイントを持たせる

  • 特記事項なし
using UnityEngine;
using System.Collections;

public class Enemy : MonoBehaviour {
    public int hp = 1;
    public int point = 100;
    Spaceship spaceship;
    private Transform tran;

    void Start () {
        spaceship = GetComponent<Spaceship> ();
        tran = GetComponent<Transform> ();
        Move (tran.up * -1);

        StartCoroutine ("IE");
    }

    IEnumerator IE() {
        if (spaceship.canShot == false) {
            yield break;
        }

        while (true) {
            for (int i = 0; i < tran.childCount; i++) {
                Transform shotPosition = transform.GetChild (i);
                spaceship.Shot (shotPosition);
            }
            yield return new WaitForSeconds (spaceship.shotDelay);
        }
    }

    public void Move(Vector2 direction)
    {
        Rigidbody2D rb2 = GetComponent<Rigidbody2D> ();
        rb2.velocity = direction * spaceship.speed;
    }

    void OnTriggerEnter2D(Collider2D c)
    {
        string layerName = LayerMask.LayerToName (c.gameObject.layer);

        if (layerName != "Bullet(Player)")
            return;

        Transform playerBulletTransform = c.transform.parent;
        Bullet bullet = playerBulletTransform.GetComponent<Bullet> ();
        hp = hp - bullet.power;

        Destroy (c.gameObject);

        if (hp <= 0) {
            FindObjectOfType<Score> ().AddPoint (point);
            spaceship.Explosion ();
            Destroy (gameObject);
        } else {
            spaceship.GetAnimator ().SetTrigger ("Damage");
        }
    }
}

ハイスコアの保存

  • 特記事項なし。GameOver時に得点クリア処理が実行されるのでハイスコアを出さないと今回のスコアがわからない。
using UnityEngine;

public class Manager : MonoBehaviour {
    public GameObject player;
    private GameObject title;

    void Start () {
        title = GameObject.Find ("Title");
    }
    
    void Update () {
        if (IsPlaying () == false && Input.GetKeyDown (KeyCode.X)) {
            GameStart ();
        }
    }

    void GameStart()
    {
        title.SetActive (false);
        Instantiate (player, player.transform.position, player.transform.rotation);
    }

    public void GameOver()
    {
        FindObjectOfType<Score> ().Save ();
        title.SetActive (true);
    }

    public bool IsPlaying()
    {
        return title.activeSelf == false;
    }
}