CodeLab技術ブログ

プログラミング技術まとめ

[Unity]初めてのUnityを肉付けする その1 クリア時のリスタート

Unityをいじり始めて最初に見るであろう、”はじめてのUnity”のチュートリアルで作成する弾転がし。
すごくわかりやすいチュートリアルなのですが、ゲームのクオリティーはともかく、ゲームとして完結していない部分があるように思います。
例えば、音を出すとか、クリアしたときにスコアが出るとか、他のステージに遷移する etc.

ということで、このチュートリアルの続きとして、実際のゲームを作るときに最低限必要な事柄を肉付けしていきたいと思います。

仕様機材&前提条件
Unity5.5
C#
”はじめてのUnity”の各チュートリアルは理解していること。

第1回目は、クリアした後の処理です。

ゲームクリアしたけど何も起こらないんですが・・・

クリア時の処理はゲームのクリアを追加するの項目で実装されてはいます。
が、”YOU WIN”って出るだけで、何も起こりません。

最低限、
・ゲームの進行を止める
・ゲームをはじめからやり直す
といった処理は必要でしょう。

ということでこの2つを追加します。

ゲーム状態の管理を追加

まずは、ゲームが現在どういった状態かの管理が必要です。
ということで、状態の管理フラグが必要でどこかに置く必要がありますが、とりあえず今回はGameController.csの中に置いておきたいと思います。

以下のようにゲームの進行状態管理用のフラグと、それを取得するためのメソッドを追加しました。

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

using UnityEngine.SceneManagement;

public class GameController : MonoBehaviour {


    public UnityEngine.UI.Text scoreLabel;
    public GameObject winnerLabelObject;

    // Use this for initialization
    void Start () {
        winnerLabelObject.SetActive(false);

    }
    private bool gameClearFlag=false;

    public bool isClear()
    {
        return gameClearFlag;
    }
	
	// Update is called once per frame
	void Update () {
        int count = GameObject.FindGameObjectsWithTag("item").Length;

        scoreLabel.text = count.ToString();

        if (count == 0)
        {
            winnerLabelObject.SetActive(true);
            if (gameClearFlag==false)
            {
                gameClearFlag = true;
            }

            if (Input.GetKey("space"))
            {
                gameClearFlag = false;
                // 現在のシーン番号を取得
                int sceneIndex = SceneManager.GetActiveScene().buildIndex;
                // 現在のシーンを再読込する
                SceneManager.LoadScene(sceneIndex);
            }
        }
    }
}

終了用のテキストを出すところは同じですが、状態管理用の処理と、スペースキーを押したら再始動する処理を追加しました。
ゲームの再開は公式チュートリアルの障害物とリスタートの部分の処理と同じですね。
あとは、winnerLavelをいじって、”Spaceキーを押してください”的なメッセージを入れるとなおよいですね。

これで完成!なのですが、ゲームをクリアした後もプレイヤーが移動しています。
これはちょっと変ですよね…。
ということで、ゲームクリア時にプレイヤーの動きを止める処理を追加します。

プレイヤーの動きを止める

これを実現するには2つのことをする必要があります。
・現在のゲームの状態を取得
・プレイヤーの動きを止める

プレイヤーの操作はPlayerControllerで行っていますので、ここでゲームの状態を取得する必要があるのですが、状態管理についてはGameControllerで行っています。
ですので、PlayerControllerからGameControllerを呼び出す必要がありますが、これはGameObject.Find()とGetComponentを使えば簡単にできます。コードとしてはこんな感じ

GameObject go;
GameController goScript;
go = GameObject.Find("GameController");
goScript = go.GetComponent();

これで、GameControllerのメソッドが呼び出せます。

次に、プレイヤーの動きを止める方法ですが、rigidbody.velocityに対してゼロを設定すればOK.
Rigidbody rigidbody = GetComponent();
rigidbody.velocity = Vector3.zero;

GameControllerから状態を取得して、ゲーム終了状態だったら上記のコードを呼べばOKでしょう。

ちなみに2Dの場合は
rigidbody2D.velocity = Vector2.zero;
という感じでいいらしいです。

具体的なコードは以下です。

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

public class PlayerController : MonoBehaviour {
    private GameObject go;
    GameController goScript;

    // Use this for initialization
    void Start () {
        go = GameObject.Find("GameController");
        goScript = go.GetComponent();
    }

    // Update is called once per frame
    /*
	void Update () {
		
	}*/

    public float speed = 10;

    private bool oldisClear=false;
    void FixedUpdate()
    {
        Rigidbody rigidbody = GetComponent();
        if (goScript.isClear() == true)
        {
            rigidbody.velocity = Vector3.zero;
            return;
        }
        

        float x = Input.GetAxis("Horizontal");
        float z = Input.GetAxis("Vertical");
        rigidbody.AddForce(x*speed, 0, z*speed);
    }

    private void OnTriggerEnter(Collider other)
    {
        if (other.CompareTag("item"))
        {
            audioSource.PlayOneShot(colAudio);
            Debug.Log("COL");
        }
    }
}

コメントは受け付けていません。