hobby-game-prgrammer
@hobby-game-prgrammer

Are you sure you want to delete the question?

Leaving a resolved question undeleted may help others!

Unity で2D横スクロールゲーム作り。キャラがジャンプしなくて困っています。

解決したいこと

たのしい2Dゲームの作り方という本をもとに、
サンプルコードを入力して、
プログラミングをしようとしています。

横スクロールゲーム(スーパーマリオのような感じのゲーム)
を作る途中で、
キャラクターが左右のアローキーには反応するのですが、
スペースキーを押してもジャンプしないという状態になりました。
本のP108ページのところで止まっています。
キャラクターがスペースキーでジャンプする状態にしたいです。

発生している問題・エラー

エラーメッセージは出ずに、
実行できます。

該当するソースコード

ソースコード
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class PlayerController : MonoBehaviour
{
    Rigidbody2D rbody;              //Rigidbody2D型の変数
    float axisH = 0.0f;             //入力
    public float speed = 3.0f;      //移動速度

    public float jump = 9.0f;       //ジャンプ力
    public LayerMask groundLayer;   //着地できるレイヤー
    bool goJump = false;           //ジャンプ開始フラグ


    // Start is called before the first frame update
    void Start()
    {
        rbody = this.GetComponent<Rigidbody2D>();   //Rigidbody2Dを取ってくる
    }

    // Update is called once per frame
    void Update()
    {
        //水平方向の入力をチェックする
        axisH = Input.GetAxisRaw("Horizontal");


        //向きの調整
        if (axisH > 0.0f)
        {
            Debug.Log("右移動");
            transform.localScale = new Vector2(1, 1);
        }
        else if (axisH < 0.0f)
        {

            transform.localScale = new Vector2(-1, 1);
        }

        //キャラクターをジャンプさせる
        if (Input.GetKeyDown(KeyCode.Space))
        {
            //Debug.Log("スペースキーが押された");
            Jump();
        }
    }

    void FixedUpdate()
    {

        //地上判定
        bool onGround = Physics2D.CircleCast(transform.position,    //発射位置
                                             0.2f,                  //円の半径
                                             Vector2.down,          //発射方向
                                             0.0f,                  //発射距離
                                             groundLayer);          //検出するレイヤー
        if (onGround || axisH != 0)
        {
            //速度を更新する
            rbody.velocity = new Vector2(axisH * speed, rbody.velocity.y);
        }
        if (onGround && goJump)
        {
            Debug.Log("地上でスペースキーが押された");
            //地面の上でジャンプキーが押された
            //ジャンプさせる
            Vector2 jumpPw = new Vector2(0, jump);          //ジャンプさせるベクトルを作る
            rbody.AddForce(jumpPw, ForceMode2D.Impulse);    //瞬間的な力を加える
            goJump = false;
        }

    }
    //ジャンプ
    public void Jump()
    {
        goJump = true;                      //ジャンプフラグを立てる
    }
}

※キャラクターにはRigidbody2DとCapsule Collider 2Dをつけています。
※地面にはBox Collider 2Dをつけています。

敵キャラはまだ出てこなくて、主人公キャラと、地面と、ブロックが出てくる状態です。

### 自分で試したこと
スペースキーが押されたら、DEBULOGで”スペースキーが押された”という文字を表示するようにし、
実行すると、その文字が表示されるので、スペースキーのキー入力は反応しているようです。
0

4Answer

「地上判定」とコメントしているところの、onGround変数がTrueにならないということではないでしょうか?

Unityに詳しく無いので、逆に質問ですが、Physics2D.CircleCastPhysics2D.Linecastの「地上判定」の違いはなんでしょうか?

0Like

Comments

  1. 回答ありがとうございます。

    本に載っている文章を引用すると、
    「CircleCastメソッドは、
    指定点から指定方向に「円」を発射して、
    その「円」がゲームオブジェクトに接触しているかをbool型で返すメソッドです。

    1番目の引数が始点、
    2番目の引数が円の半径、
    3番目の引数が発射する方向、
    4番目の引数が発射距離、
    5番目の引数が対象となるレイヤーの指定です。
    ・・・」

    といろいろ書いてあります。
    LineCastについては本に載っているかどうかは見つけられませんでした。
    CircleCastメソッドをもう少し調べると、何かわかるかもしれません。

    CircleCastメソッドは本に載っているサンプルコードを何も考えずに入力したので、
    理解できていない所です。

    アドバイスありがとうございます。

  2. 半径0.2とは、どのくらいのサイズでしょうか?
    「その半径の円オブジェクトとは接触していない」ということになりますね。

    ちなみに、第何章のコードサンプルでしょうか?
    本は持っていませんが、サンプルコードは公開されているので、見ることができます。

  3. コーディング得意な人って、ネットの情報だけで結構いろいろわかるもんなのかもしれませんね。
    回答ありがとうございます。

    第4章のコードなのですが、
    4章で最終的に作るコードの途中段階が本に載っていて、それを入力したのが上記のコードです。

    ダウンロードリンクから、サンプルコードをダウンロードして、自分の入力したコードとの違いを
    調べていくといいのかもしれませんね。

    あとで、リンク先のコードを確認させていただきます。

    アドバイスありがとうございます。

    半径0.2という記述ですが、本の解説第4章のp111というところにCircleCastの説明が載っていて、
    そこでは、「ゲームオブジェクトの現在位置から半径0.2の円を真下に0飛ばす(結果的にはプレイヤーの足元に半径0.2の円が出現する)」と書いてあります。
    さらに読み進んでいくと
    「この円が5番目の引数に指定したレイヤーが設定されたゲームオブジェクトに触れることでonGroundがtrueになり、触れていなければfalseになります。」
    と書いてあります。

  4. chapter4のサンプルコードダウンロードして実行したところ、ちゃんとジャンプ出来ました。
    C#のコードを開いてみると
    LineCastというものが地上判定として入力されています

    ダウンロードしたサンプルコードを読み込んで、
    自分が入力したコードに何が足りなかったのかとか、
    コードの作りとかを分析してみようと思います。

    @nak435さん
    アドバイスありがとうございます。

  5. 解決したということでしょうか?
    用済みであれば、当Q&Aをクローズしてください。

  6. ありがとうございます。
    この質問に関しては、解決したという事でいいと思います。

    回答してくださった皆様ありがとうございました。
    image.png

あと、気になるところでは、
コードでは
groundLayerとなっていますが、
地面のブロックの登録をGroundとしているので、
大文字小文字で扱いが違う可能性はないのかも気になります。

0Like

一応ソースを参考にして動くようになった?ようですが、
元のソースで動かない理由を知る必要はあると思うのでお聞きしたいのですが、
groundLayerの設定はされてますでしょうか?
この変数はキャラクターが"ジャンプできる床の種類"になります。
Layerというのは全てのGameObjectが持っており、Inspector(Unity上での座標とかいじるところ)のGameObjectの名前の下あたりに設定する箇所があります。
基本はデフォルトのものになっていますが、"ジャンプできる床のGameObject"のLayerをGroundなどに設定し、プレイヤーのInspectorにてgroundLayerという項目があると思いますので、Groundにチェックを入れてあげればジャンプできるようになるのではないかな?と思います。

0Like

groundlayer.png

Ground

groundLayer
が同じとパソコンが認識するかどうかよくわからないのですが、
とりあえずこんな感じになっています。
画面が張り付けられるかどうかわかりませんが投稿してみます。

0Like

Comments

  1. 回答ありがとうございます。
    Layerの設定は自分でも疑問なところです。

  2. image.png
    一応キャラと、地面はこんな感じの画像を使っているようです。

Your answer might help someone💌