Unity2Dでアクションゲームを作る(願望)その3

始めに

はい、どうもこんにちは。黒夢です。まさかの三日目です。うせやん…お前、こんなに連続でブログ書けたんか…
それはともかく、今日も今日とてアクションゲームを作っていきましょう!今日の目標何でしたっけ…

プレイヤーを移動させる

それでは、早速黒夢君を動かしていきましょう!
今回は、前回追加した「RigidBody 2D」に力を加える形で動かしてみようと思います。コードはこんな感じ。

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

public class player_animation : MonoBehaviour
{
    private Animator anim = null;
    public Vector2 Speed;
    public Vector2 Acceleration;

    void Start()
    {
        anim = GetComponent<Animator>();
        Speed = new Vector2(0, 0);
        Acceleration = new Vector2(0, 0);
    }

    void Update()
    {
        float horizontalKey = Input.GetAxis("Horizontal");
        Rigidbody2D PComponent = GetComponent<Rigidbody2D>();

        if (horizontalKey > 0)
        {
            if (!anim.GetBool("RorL"))
                anim.SetBool("RorL", true);
            anim.SetInteger("Action", 1);
            Acceleration.Set(0.3f, 0);
        }
        else if (horizontalKey < 0)
        {
            if (anim.GetBool("RorL"))
                anim.SetBool("RorL", false);
            anim.SetInteger("Action", 1);
            Acceleration.Set(-0.3f, 0);
        }
        else
        {
            anim.SetInteger("Action", 0);
            Speed *= new Vector2(0, 1);
            Acceleration.Set(0, 0);
        }

        Speed += Acceleration;
        PComponent.velocity = Speed;
    }
}

ということでとりあえず動かしてみよ…あれ?動かない?
と思ったら、なんかエラーを吐かれてました…。

f:id:V-hero-aid:20200305190121p:plain
わからなかったらとりあえずググる

ググってみたら、原因がわかりました。どうやら、スクリプトのファイル名を変更していたのが不味かったようです。Unity側で「rename」しても、スクリプト側のクラス名が変更されないみたいです。ということで、コードのクラス名を変更して…再実行!
…あれ?
無駄に回転してしまってる…。ちなみに、これは「Rigid Body」の中の「Constraints」の「Freeze Rotation」でZ軸の回転を無効にすることで解決できます。
これで横移動が出来ましたが、何故か落下速度が遅い…。ということで、次は上下移動について弄っていきます。

プレイヤーを落下させる

とりあえず、設置判定を追加していきます。まずは、設置判定用のコライダーを追加。足元に、極薄の「Box Collider 2D」を設置します。ついでに「is Trigger」にチェックを入れて、当たり判定を消去、トリガーとしてのみ使用できるようにします。
続いて、「Grid」内の「Tilemap」のタグを「Field」に。フィールドとそれ以外の判定ができるようにします。

f:id:V-hero-aid:20200305230720p:plain
タグ付け

フィールドの上に乗っているかどうかの判定を見るコードを雑に書いて…

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

public class player_ground_contact : MonoBehaviour
{
    private string Tag = "Field";
    bool isField = false;
    bool isFieldEnter, isFieldStay, isFieldExit;
    void Start()
    {
        isFieldEnter = false;
        isFieldStay = false;
        isFieldExit = false;
    }

    public bool IsField()
    {
        if (isFieldEnter || isFieldStay)
            isField = true;
        else if (isFieldExit)
            isField = false;

        isFieldEnter = false;
        isFieldStay = false;
        isFieldExit = false;

        return isField;
    }

    private void OnTriggerEnter2D(Collider2D collision)
    {
        if(collision.tag == Tag)
            isFieldEnter = true;
    }

    private void OnTriggerStay2D(Collider2D collision)
    {
        if (collision.tag == Tag)
            isFieldStay = true;
    }

    private void OnTriggerExit2D(Collider2D collision)
    {
        isFieldExit = true;
    }
}

プレイヤー側でも、フィールドにいない時のみ重力が作用するようにコードを書きます。

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

public class player_script : MonoBehaviour
{
    private Animator anim = null;
    public Vector2 Speed;
    public Vector2 Acceleration;
    public float Gravity;
    public player_ground_contact GroundContact;

    void Start()
    {
        anim = GetComponent<Animator>();
        Gravity = -0.3f;
        Speed = new Vector2(0, 0);
        Acceleration = new Vector2(0, Gravity);
    }

    void Update()
    {
    }

    void FixedUpdate()
    {
        float horizontalKey = Input.GetAxis("Horizontal");
        Rigidbody2D PComponent = GetComponent<Rigidbody2D>();

        if (horizontalKey > 0)
        {
            if (!anim.GetBool("RorL"))
                anim.SetBool("RorL", true);
            anim.SetInteger("Action", 1);
            Acceleration.x = 0.2f;
        }
        else if (horizontalKey < 0)
        {
            if (anim.GetBool("RorL"))
                anim.SetBool("RorL", false);
            anim.SetInteger("Action", 1);
            Acceleration.x = -0.2f;
        }
        else
        {
            anim.SetInteger("Action", 0);
            Speed.x = 0;
            Acceleration.x = 0;
        }

        if (GroundContact.IsField())
        {
            Speed.y = 0;
            Acceleration.y = 0;
        }
        else
            Acceleration.y = Gravity;

        Speed += Acceleration;
        PComponent.velocity = Speed;
    }
}


こんな感じですね。良い感じに落下出来ました。

終わりに

今日は、黒夢君を移動+落下させることが出来ました。次回は、ジャンプとアニメーションのトリガーの実装をしてみようと思います。それでは、良い黒の夢が見れますように。