0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

2D動く床 MovePositionを使用

Last updated at Posted at 2025-04-20

Unity6.0 (6000.0.47f1)

使用しているPlayerの移動クラス

public class PlayerMove : MonoBehaviour
{
    #region デバッグ

    public float debugmoveX = 0;

    #endregion


    #region 移動
    Animator m_animator;

    Rigidbody2D m_rb;                   //剛体
    [SerializeField] Vector2 m_movement;
    public float maxMoveSpeed= 3.6f;
    public float moveSpeed= 3.6f;             //移動速度
    [SerializeField] ReactiveProperty<bool> isGround /*{ get; set; }*/ = new ReactiveProperty<bool>(true);
    //public bool IsGround => isGround.Value;
    public bool IsGround
    {
        get => isGround.Value;
        set => isGround.Value = value;
    }

    public bool isLimitMove = false;     //アニメーション中などの移動制限
    [SerializeField] float skyGravity = 22;
    [SerializeField] float groundGravity = 1; //ダッシュ対応のため1

    //ジャンプ
    const float upSpd = 4f;
    public bool isJump = false;
    [SerializeField] float jumpHeight=2f; //1.8
    float keepPosY;


    //ダッシュ
    bool isDash = false;
    bool isSkyDash = false;
    [SerializeField] float dashLen = 10;//10
    [SerializeField] float dashStopTime = 0.3f;//0.3f
    #endregion

    //[SerializeField] GameObject deadKnife;


    //public void PlayerDead()
    //{
    //    GetComponent<PlayerScr2D>().isDead = true;
    //    m_animator.SetBool("dead", true);
    //}

    public bool isNoise = false;

    [SerializeField]PlayerGroundCollider pGroundCol;

    void Start()
    {
        //アニメーションイベントで解除する
        //isLimitMove = true;
        //ダッシュ残像のオフ
        GetComponent<DynamicAfterImageEffect2DPlayer>().SetActive(false);

        moveSpeed = maxMoveSpeed;

        m_rb = GetComponent<Rigidbody2D>();
        m_animator = GetComponent<Animator>();


        isGround.Skip(1).Subscribe(ground =>
        {
            if (ground == false)
                m_rb.gravityScale = skyGravity;
            else
            {
                m_rb.gravityScale = groundGravity;
                isSkyDash = false;
            }
        });

        if (Save.I.isLoad)
        {
            Vector3 loadPos;
            loadPos.x = PlayerPrefs.GetFloat("POSX");
            loadPos.y = PlayerPrefs.GetFloat("POSY");
            loadPos.z = PlayerPrefs.GetFloat("POSZ");
            transform.position = loadPos;
        }
    }

    private void Update()
    {
        if (GetComponent<PlayerScr2D>().isDead) return;
        if (isLimitMove) return;

        MoveControl();
        Dash();

        if (Input.GetKeyDown(KeyCode.Space) && isGround.Value)
        {
            isJump = true;
            isGround.Value = false;
            keepPosY = transform.position.y;

            MyLib.MyPlayOneSound("Sound/SE/wave/パンチ素振り", 1f, gameObject);
        }

        JumpControl();


    }

    void FixedUpdate()
    {

        if (GetComponent<PlayerScr2D>().isDead) return;
        if (isDash) return;

        m_rb.MovePosition((Vector2)transform.position + m_movement * moveSpeed * Time.deltaTime);

    }

    public void RideMove(Vector2 f)
    {
        m_rb.MovePosition(((Vector2)transform.position + m_movement * moveSpeed * Time.deltaTime)+ f);
    }

    void MoveControl()
    {
        //テスト用
        debugmoveX = Input.GetAxis("Horizontal");
        // 入力の取得
        m_movement.x = Input.GetAxis("Horizontal");
        m_movement.y = 0f;//Input.GetAxis("Vertical");


            const float walkAnimSpd = 0.3f;
        if (m_movement.x >= walkAnimSpd&&!isNoise)
            GetComponent<SpriteRenderer>().flipX = true;
        if (m_movement.x <= -walkAnimSpd)
            GetComponent<SpriteRenderer>().flipX = false;

        var absX = Mathf.Abs(m_movement.x);
        //速度が一定を超えたら アニメーションの設定
        if (absX > walkAnimSpd)
            m_animator.SetBool("walk", true);
        else
            m_animator.SetBool("walk", false);
    }

    void Dash()
    {
        //g = m_rb.gravityScale;
        if (isDash) return;
        if (isSkyDash) return;
        if (!Input.GetKeyDown(KeyCode.LeftShift)) return;

        //Debug.Log("ダッシュ");

        isDash = true;
        GetComponent<DynamicAfterImageEffect2DPlayer>().SetActive(true);

        if (!IsGround)
        {
            m_rb.gravityScale = 0;
            isSkyDash = true;

            isJump = false;
            //m_movement.y = 0f;
        }


        if (GetComponent<SpriteRenderer>().flipX)
            m_rb.AddForce(((Vector2.right * dashLen)), ForceMode2D.Impulse);
        else
            m_rb.AddForce(((-Vector2.right) * dashLen), ForceMode2D.Impulse);


        StartCoroutine(MyLib.DelayCoroutine(dashStopTime, () =>
        {
            GetComponent<DynamicAfterImageEffect2DPlayer>().SetActive(false);
            if (IsGround)
            {
                isSkyDash = false;
                m_rb.gravityScale = groundGravity;

            }
            else
            {
                m_rb.gravityScale = skyGravity;
            }

            m_rb.linearVelocity = Vector2.zero;
            //Debug.Log("DASHOFF");
            isDash = false;
        }));

    }

    void JumpControl()
    {
        if (!isJump) return;
        m_movement.y += upSpd;

        //現在の高さからジャンプ高度へ到達したら終了
        if (transform.position.y > keepPosY + jumpHeight)
        {
            isJump = false;
        }

        //地面にいるとき 真上にオブジェクトがあるときのジャンプ対策 両方がtrueの時
        //if (IsGround)
        //    isJump = false;
    }


    #region アニメーションイベント プレイヤー

    public void StartAnimEnd()
    {
        //フラグをオフ
        isLimitMove = false;
        //Debug.Log("isLimitMove = false;");
    }


    #endregion

}




移動床のクラス
public class MoveFloor2D : MonoBehaviour
{
    [SerializeField] Transform[] moveTrans;
    [SerializeField] int targetNo;
    [SerializeField] float SPEED = 3f;
    [SerializeField] bool isMoveBack = false;

    Rigidbody2D rb2;

    Vector3 moveDir = Vector3.zero;

    Vector2 floorVelocity = Vector2.zero;

    PlayerMove pMove;
    bool isRide = false;

    void Start()
    {
        pMove = GameObject.FindGameObjectWithTag(TagName.Player).GetComponent<PlayerMove>();
        rb2 = GetComponent<Rigidbody2D>();

        moveDir = moveTrans[targetNo].position - transform.position;
    }

    private void FixedUpdate()
    {

        float len = Vector2.Distance(transform.position, moveTrans[targetNo].position);
        const float ENDMOVELEN = 0.3f;

        //移動地点に近づいたら移動地点の再設定
        if (len < ENDMOVELEN)
        {
            //移動地点の再設定
            if (!isMoveBack)
                targetNo++;
            else
                targetNo--;

            if (targetNo > moveTrans.Length - 1)
            {
                //Debug.Log("RETURN 00");
                isMoveBack = true;
                targetNo--;

            }
            else if (targetNo < 0)
            {
                //Debug.Log("RETURN 11");
                targetNo++;
                isMoveBack = false;

            }
            moveDir = moveTrans[targetNo].position - transform.position;




        }

        floorVelocity = moveDir.normalized * SPEED * Time.deltaTime;


        rb2.MovePosition((Vector2)transform.position + floorVelocity);


        //プレイヤーが乗っている時の処理
        if (isRide)
        {
            pMove.RideMove(floorVelocity);
        }

    }

    private void OnTriggerEnter2D(Collider2D collision)
    {
        if (collision.gameObject.CompareTag(TagName.Player))
        {
            isRide = true;
        }


    }

    private void OnTriggerExit2D(Collider2D collision)
    {

        if (collision.gameObject.CompareTag(TagName.Player))
        {
            isRide = false;
        }
    }

}

・この関数を移動床のクラスのほうで呼び出して移動を合わしている
たぶんPlayerのMovePositionが1フレームで2回呼び出されることになるので上書き
されてるんじゃないかと思います

public void RideMove(Vector2 f)
{
    m_rb.MovePosition(((Vector2)transform.position + m_movement * moveSpeed * Time.deltaTime)+ f);
}

元々はこちらのサイトを参考にしていたのですが
移動床がうまくいかなかったプレイヤーの移動などのコードが難しかったのでこちらの方法で行っています
移動床の移動後にプレイヤーのMovePositionに移動床の移動加算したものを
呼び出すだけで動いたので
下からすり抜けたりも追加できます

Rigidbodey2Dの設定など

・注意点

・実行順序の影響で動作しなくなる
↓順番をPlayerのスクリプトの後に移動床のスクリプトを設定することで解決

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?