日々是好日~every day is a good day~

日常の中の非日常の備忘録

【Unity】動くブロックとジャンプするプレーヤー

前回の動くブロックに それを移動するプレーヤーを追加してみました
上のブロックに移動するにはジャンプしないといけませんがそのジャンプ機能が少しややこしいです
まずブロックから コンポーネントやレイヤー プログラムの追加をしていきます
3つのブロックとも同じものを追加するので 説明では真ん中のブロック(CenterObject)を使います
1.オブジェクトのインスペクターからコンポーネントを追加をクリックしてBox Collider 2Dを追加

2.コライダーの編集をクリックするとシーン内のオブジェクトに緑の枠線が表示されるのでポッチをドラッグしてオブジェクトのサイズに合わせる

3.インスペクターのレイヤーをクリックしレイヤーを追加を選択

4.8番目をBlockとしてヒエラルキーのCenterObjectをクリック

5.再びインスペクターのレイヤーをクリックし追加したBlockを選択

6.レイヤー変更の確認が表示されるので はい、子を変更します をクリック

7.スクリプト(CenterObjMove)に処理を追加

using System.Collections;
using UnityEngine;

public class CenterObjMove : MonoBehaviour
{
    [SerializeField] float moveSpeed = 1f;
    private Vector3 rightPosition;
    private Vector3 leftPosition;
    private Vector3 startPosition;
    private bool goRight;
    private bool isMove;
    // Start is called before the first frame update
    void Start()
    {
        startPosition = transform.position;
        leftPosition = new Vector3(startPosition.x - 2f, startPosition.y, startPosition.z);
        rightPosition = new Vector3(startPosition.x + 2f, startPosition.y, startPosition.z);
        goRight = true;
        isMove = true;
    }

    // Update is called once per frame
    void Update()
    {
        if (isMove)
        {
            isMove = false;
            if (goRight)
            {
                StartCoroutine(MoveRight());
            }
            else
            {
                StartCoroutine(MoveLeft());
            }
        } 
    }
    private IEnumerator MoveRight()
    {
        while (rightPosition != transform.position)
        {
            transform.position = Vector3.MoveTowards(transform.position, rightPosition, moveSpeed * Time.deltaTime);
            yield return null;
        }
        goRight = false;
        isMove = true;
    }
    private IEnumerator MoveLeft()
    {
        while (leftPosition != transform.position)
        {
            transform.position = Vector3.MoveTowards(transform.position, leftPosition, moveSpeed * Time.deltaTime);
            yield return null;
        }
        goRight = true;
        isMove = true;
    }
////ここまでは前回と同じ
////これ以降を追加
    private void OnCollisionEnter2D(Collision2D collision)
    {
        if (collision.gameObject.CompareTag("Player"))
        {
            bool isUp = false;
            foreach (ContactPoint2D point in collision.contacts)
            {
                if (transform.position.y < point.point.y)
                {
                    isUp = true;
                }
            }
            if (isUp)
            {
                collision.transform.SetParent(this.transform);
                collision.transform.rotation = GetComponentInParent<Transform>().rotation;
            }
        }
    }

    private void OnCollisionExit2D(Collision2D collision)
    {
        if (collision.gameObject.CompareTag("Player"))
        {
            collision.transform.SetParent(null);
        }
    }
}

これをLeftObject RightObjectにも追加します
次にプレーヤーの追加です
1.左向きの画像をシーン内にドラッグ&ドロップ オブジェクトの名前をPlayerに変更

2.PlayerのインスペクターからタグをクリックしPlayerを選択

3.Playerのインスペクターからコンポーネントを追加をクリックしてRigidbody 2Dを追加
プロジェクトタブのAssetsフォルダーを選択した後+をクリック

4.2D/Physics Material 2Dを選択

5.作成されたものはPlayerに名前を変更 Frictionを0.08にする

6.これをPlayerのRigidbody 2Dのマテリアルにドラッグ&ドロップ

7.Rigidbody 2DのConstraintsの回転を固定Zにチェックをいれる

8.コンポーネントを追加をクリックしてCapsule Collider 2Dを追加
コライダーの編集をクリックし緑の枠線のポッチをドラッグしてオブジェクトのサイズに合わせる

9.プロジェクトタブ内で右クリックし 作成/C#スクリプトを選択してPlayerスクリプトを作成して編集

using UnityEngine;

public class Player : MonoBehaviour
{
    [SerializeField] float moveSpeed = 0.05f;   //移動スピード
    [SerializeField] float jumpPower = 8f;
    public LayerMask layerBlock;
    private bool onBlock;
    private Rigidbody2D rb;

    // Start is called before the first frame update
    void Start()
    {
        rb = this.GetComponent<Rigidbody2D>();
    }

    // Update is called once per frame
    void Update()
    {
        if (Input.GetKey(KeyCode.LeftArrow))   //←キー
        {
            transform.localScale = new Vector2(1f, 1f);
            transform.Translate(-moveSpeed, 0, 0);
        }
        if (Input.GetKey(KeyCode.RightArrow))   //→キー
        {
            transform.localScale = new Vector2(-1f, 1f);
            transform.Translate(moveSpeed, 0, 0);
        }
        //ブロックに接地している時にスペースキーを押されたらジャンプ
        if (Input.GetKeyDown(KeyCode.Space))
        {
            if (Physics2D.CircleCast(transform.position, 0.35f, transform.up * -1f, 0.15f, layerBlock))
            {
                Vector2 jumpUp = new Vector2(0, jumpPower);
                rb.AddForce(jumpUp, ForceMode2D.Impulse);
            }
        }
        
        if (transform.position.y < -5f)
        {
            transform.position = new Vector3(transform.position.x, 5f, 0);
        }
    }
}

10.PlayerスクリプトをPlayerのインスペクターにドラッグ&ドロップ
Layer BlockをクリックしBlockを選択

これで実行すると←キー →キーで移動 スペースキー押下でジャンプします

なかなかのボリュームでしたが急激にレベルが上がった感じがします