超初心者のゲーム開発記~Unity~

超初心者がUnityでゲーム(目標はAndroidアプリ )を開発していくブログです!

【Unity 2Dローグライク】公式チュートリアルをやってみる part.10~プレイヤーの動かし方

こんにちは!ヤギです!

Unityの2Dローグライクの
公式チュートリアルをやってみる part.10になります!
※前回(part.9)の記事はこちら
www.yagigame.com

記事概要

今回の記事では、プレイヤーの動かし方についてご説明していきます。
※part.10に対応する公式チュートリアルの章は、Writing the Player Scriptです!
unity3d.com
※この記事は、ひよこのたまご様の記事をリスペクトしています。
hiyotama.hatenablog.com

プレイヤーの管理を行うスクリプト作成

まず初めに、プレイヤーの体力や、ターン、ゲームオーバーを管理するためのスクリプトを作成します。
GameManage.csを修正していきます。
※ソースの中に、解説を記載しています。ご参照ください。

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

public class GameManager : MonoBehaviour {

    //クラスに属し、複数のシーンで使われる変数を宣言
    //Staticにすることで、他のスクリプトからも呼び出すことができます
    public static GameManager instance = null;

    //ここから:part.10で追加
    public int playerFoodPoints = 100; //プレイヤーの食料
    //HideInspectorをつけることで、Inspector viewに表示されなくなる
    [HideInInspector] public bool playerTurn; //プレイヤーのターンかの判定フラグ
    //ここまで:part.10で追加

    //BoardManager型の変数を宣言
    public BoardManager boardScript;

    //テストとして、敵が出現するレベルの3とする
    private int level = 3;

	// AwakeはStartよりも前、最初に呼ばれる
	void Awake () {
        //GameManagerが存在しなければ、このオブジェクトを設定する
        if(instance = null){
            instance = this;
        }else{
            //すでに存在する場合、このオブジェクトは不要なため破壊する
            Destroy(this);
        }

        //シーン遷移時に、このオブジェクトは破壊せず引き継ぐ
        DontDestroyOnLoad(gameObject);

        //BoardManagerのコンポーネントを取得
        boardScript = GetComponent<BoardManager>();
        //ステージ生成の関数を呼ぶための、関数を呼ぶ
        InitGame();
	}
	
    void InitGame(){
        //ステージ生成の関数を呼ぶ
        boardScript.SetupScene(level);
    }

    //ここから:part.10で追加
    public void GameOver(){
        //enabledをfalseにすることで、GameManagerが無効になる
        enabled = false;
    }
    //ここまで:part.10で追加
}

プレイヤーを動かすスクリプト作成

ここからは、プレイヤーを動かすためのスクリプトを作成していきます。
1. Player.csを作成します。
※ソースの中に解説を記載しました。ご参照ください。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement; //シーンの読み込みに必要

//MovingObjectクラスを継承する
public class Player : MovingObject {

    public int wallDamage = 1; //壁へのダメージ量
    public int pointsPerFood = 10; //食べ物の回復量
    public int pointsPerSoda = 20; //ソーダの回復量
    public float restartLevelDeray = 1f; //ステージ移動時の時間

    private Animator animator; //アニメーション用変数
    private int food; //食料


	// Use this for initialization
    //MovingObjectクラスのStartを継承する
    protected override void Start () {
        //animatorのコンポーネントを設定
        animator = GetComponent<Animator>();
        //foodをステージ間で引き継げるように、GameManagerから設定
        food = GameManager.instance.playerFoodPoints;
        Debug.Log(food);
        //GameObjectのStartを呼び出す
        base.Start();
	}

    //PlayerのfoodをGameManageに保存する
    public void OnDisable()
    {
        GameManager.instance.playerFoodPoints = food;
    }

    protected override void AttemptMove<T>(int xDir, int yDir)
    {
        //移動するたびに食料が減る
        food--;
        //MovingObjectのAttemptMoveを呼び出す
        base.AttemptMove<T>(xDir, yDir);

        RaycastHit2D hit;

        //ゲームオーバーか確認
        CheckIfGameOver();
        //プレイヤーのターン終了
        GameManager.instance.playerTurn = false;
    }

    //プレイヤーが壁にぶつかった場合、壁をチョップする
    protected override void OnCantMove<T>(T component)
    {
        //Wallスクリプトを使えるように設定
        Wall hitWall = component as Wall;
        //壁にダメージを与える
        hitWall.DamageWall(wallDamage);
        //チョップするアニメーションを呼び出す
        animator.SetTrigger("PlayerChop");
    }

    //プレイヤーが、Exit、Food、Sodaと接触した場合に呼び出す
    private void OnTriggerEnter2D(Collider2D other)
    {
        //Exitと接触した場合
        if(other.tag == "Exit"){
            //ステージ移動の時間分待ってから、次のツテージに移動する
            Invoke("Restart", restartLevelDeray);
        }else if(other.tag == "Food"){ //食料と接触した場合
            //食料を回復
            food += pointsPerFood;
            //食料を削除
            other.gameObject.SetActive(false);
        }else if(other.tag == "Soda"){
            //食料を回復
            food += pointsPerSoda;
            //ソーダを削除
            other.gameObject.SetActive(false);
        }
    }

    //プレイヤーがExitに到達した場合、次のステージを呼び出す
    private void Restart(){
        //シーンを呼び直す
        SceneManager.LoadScene(0);
    }

    //プレイヤーが敵に攻撃された場合、食料を減らす
    private void LoseFood(int loss){
        //攻撃を受けたアニメーションを呼び出す
        animator.SetTrigger("PlayerHit");
        //食料を減らす
        food -= loss;
        //ゲームオーバーか判定
        CheckIfGameOver();
    }

    // Update is called once per frame
    void Update () {
        //プレイヤーのターンではない場合、何も実行しない
        if(!GameManager.instance.playerTurn)
            return;
      
        //左右の移動
        int horizontal = 0;
        //上下の移動
        int vertical = 0;
        //左右の移動量を受け取る
        horizontal = (int)(Input.GetAxisRaw("Horizontal"));
        //上下の移動量を受け取る
        vertical = (int)(Input.GetAxisRaw("Vertical"));

        //上下左右のいずれかに移動を制限する
        if(horizontal != 0){
            vertical = 0;
        }

        //左右上下のいずれかに移動する場合
        if(horizontal != 0 || vertical != 0){
            //プレイヤーの侵攻方向に壁があるか確認
            AttemptMove<Wall>(horizontal, vertical);
        }
	}

    //食料が0いかになった場合、ゲームオーバーにする
    private void CheckIfGameOver(){
        if(food <= 0){
            //GameManagerのGameOverを呼び出す
            GameManager.instance.GameOver();
        }
    }
}

※作成したPlayer.csをPlayer Prefabにアタッチしておきましょう!
※これで、プレイヤーを動かすスクリプトが完成です!
f:id:yagigame:20181104023453p:plain

次回予告

次回の記事では、敵の動かし方について書いていきたいと思います。
※次回の記事はこちら
www.yagigame.com
※Unityのチュートリアルの章としては、次回は(Writing the Enemy Script)となります!

読んでいただきありがとうございました!