Unity 2d 角色用UI 按钮移动和跳转到特定位置

Unity 2d Character moves and jumps to specific positions with UI buttons

在一个简单的 2d 项目中,我的播放器可以在 x 上向右和向左移动,还可以使用其他两个按钮在高度上向右和向左跳。问题是,玩家不应该自由移动。通过按下其中一个按钮,玩家应该只转到下一个特定点,这样玩家总是会停在 x 轴上的六个不同位置(而在 y 轴上他是自由的,并且与他当前站在的平台一样高)。为了能够逼真地跳跃,玩家必须有重力和碰撞器才能降落在平台上(并水平移动单个平台)。 感谢@TEEBQNE 在评论中链接的教程,我终于可以使用 Unitys Rigidbody2D 和以下脚本实现这一点。问题是重力现在表现得很奇怪。玩家只能非常缓慢地向下移动,并在此过程中将游戏对象推到其下方。玩家有一个重力标度为 2 的 Dynamic Rigidbody2D 和一个 2d 胶囊对撞机。这是脚本问题还是玩家检查器中的组件问题?

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

public class movePlayer : MonoBehaviour
{

    public GameObject posChecker1;
    public GameObject posChecker2;
    public GameObject posChecker3;
    public GameObject posChecker4;
    public GameObject posChecker5;
    public GameObject posChecker6;

    public bool go; //Player is allowed to move
    public bool grounded; //Player is allowed to jump
    public string moveDirection;
    public float horizVel = 0; //Movement along x
    public float verticVel = 0; //Jump

    public int laneNum = 3; //Player starts on lane 3!!
    public bool rightButtonMove = false;//
    public bool leftButtonMove = false;//
    public bool rightButtonJump = false;//
    public bool leftButtonJump = false;//



    //Animation
    private SpriteRenderer spriteRenderer;
    private Animator animator;

    private void Awake()
    {
        spriteRenderer = GetComponent<SpriteRenderer>();
        animator = GetComponent<Animator>();
    }



    // Start is called before the first frame update
    void Start()
    {
        posChecker1.SetActive(true);//GameObject.Find("PositionChecker1").SetActive(true);
        posChecker2.SetActive(true);
        posChecker3.SetActive(true); //Player start on lane 3!!
        posChecker4.SetActive(true);
        posChecker5.SetActive(true);
        posChecker6.SetActive(true);

        laneNum = 3;
        go = true;
    }

    // Update is called once per frame
    void Update()
    {
        //Raycast
        int playerMask = LayerMask.GetMask("PositionChecker");// !!!

        Debug.DrawRay(transform.position, transform.TransformDirection(Vector2.up) * 50f, Color.green);
        RaycastHit2D hitCheck = Physics2D.Raycast(transform.position, transform.TransformDirection(Vector2.up), 50f, playerMask);

        //Only the checker objects in the rows next to the player are active
        if (laneNum == 1)
        {
            posChecker1.SetActive(false);
            posChecker2.SetActive(true);
        }
        else if (laneNum == 2)
        {
            posChecker1.SetActive(true);
            posChecker2.SetActive(false);
            posChecker3.SetActive(true);
        }
        else if (laneNum == 3)
        {
            posChecker2.SetActive(true);
            posChecker3.SetActive(false);
            posChecker4.SetActive(true);
        }
        else if (laneNum == 4)
        {
            posChecker3.SetActive(true);
            posChecker4.SetActive(false);
            posChecker5.SetActive(true);
        }
        else if (laneNum == 5)
        {
            posChecker4.SetActive(true);
            posChecker5.SetActive(false);
            posChecker6.SetActive(true);
        }
        else if (laneNum == 6)
        {
            posChecker5.SetActive(true);
            posChecker6.SetActive(false);
        }

        //Movement
        GetComponent<Rigidbody2D>().velocity = new Vector3(horizVel, verticVel, 0);


        //Raycast
        if (hitCheck)
        {
            
            if (moveDirection == "l" && horizVel != 0)
            {
                laneNum -= 1;
            }
            if (moveDirection == "r" && horizVel != 0)
            {
                laneNum += 1;
            }
            go = true;
            horizVel = 0;
            verticVel = 0;
            grounded = true;
        }
        if (horizVel == 0)
            moveDirection = "";


        //Animation
        bool flipSprite = (spriteRenderer.flipX ? (horizVel > 0.01f) : (horizVel < 0.01f));
        if (flipSprite)
        {
            spriteRenderer.flipX = !spriteRenderer.flipX;
        }

        animator.SetBool("grounded", grounded); // -->Jump
        animator.SetFloat("velocityX", Mathf.Abs(horizVel));

    }


    //Button Input
    public void RightButton() //
    {
        if (laneNum < 6 && go)
        {
            moveDirection = "r";
            go = false;
            horizVel = 4;
        }
    }
    public void LeftButton()//
    {
        if (laneNum > 1 && go)
        {
            moveDirection = "l";
            go = false;
            horizVel = -4;
        }
    }
    public void RightJump()//
    {
        if (laneNum < 6 && grounded && go)
        {
            moveDirection = "r";
            horizVel = 4;
            verticVel = 7;
            go = false;
            grounded = false;
        }
    }
    public void LeftJump()//
    {
        if (laneNum > 1 && grounded && go)
        {
            moveDirection = "l";
            horizVel = -4;
            verticVel = 7;
            go = false;
            grounded = false;
        }
    }
}

很高兴我能够以某种方式提供帮助,并且您已经解决了您的问题!

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

public class movePlayer : MonoBehaviour
{
    //Player Position x
    public GameObject posChecker1;
    public GameObject posChecker2;
    public GameObject posChecker3;
    public GameObject posChecker4;
    public GameObject posChecker5;
    public GameObject posChecker6;
    public int laneNum = 3; //Player starts on lane 3!!

    //Player Position y
    public float yPos1;
    public float yPos2;
    public Transform player;

    //Movement Variables
    public bool go; //Player is allowed to move
    public bool grounded; //Player is allowed to jump
    public string moveDirection;
    public float horizVel = 0; //Movement along x
    public float verticVel = 0; //Jump

    //Animation
    private SpriteRenderer spriteRenderer;
    private Animator animator;

    private void Awake()
    {
        spriteRenderer = GetComponent<SpriteRenderer>();
        animator = GetComponent<Animator>();
    }



    // Start is called before the first frame update
    void Start()
    {
        posChecker1.SetActive(true);//GameObject.Find("PositionChecker1").SetActive(true);
        posChecker2.SetActive(true);
        posChecker3.SetActive(true); //Player start on lane 3!!
        posChecker4.SetActive(true);
        posChecker5.SetActive(true);
        posChecker6.SetActive(true);

        laneNum = 3;
        go = true;
    }

    // Update is called once per frame
    void Update()
    {
        //Raycast
        int playerMask = LayerMask.GetMask("PositionChecker");// !!!

        Debug.DrawRay(transform.position, transform.TransformDirection(Vector2.up) * 50f, Color.green);
        RaycastHit2D hitCheck = Physics2D.Raycast(transform.position, transform.TransformDirection(Vector2.up), 50f, playerMask);

        //Only the checker objects in the rows next to the player are active
        if (laneNum == 1)
        {
            posChecker1.SetActive(false);
            posChecker2.SetActive(true);
        }
        else if (laneNum == 2)
        {
            posChecker1.SetActive(true);
            posChecker2.SetActive(false);
            posChecker3.SetActive(true);
        }
        else if (laneNum == 3)
        {
            posChecker2.SetActive(true);
            posChecker3.SetActive(false);
            posChecker4.SetActive(true);
        }
        else if (laneNum == 4)
        {
            posChecker3.SetActive(true);
            posChecker4.SetActive(false);
            posChecker5.SetActive(true);
        }
        else if (laneNum == 5)
        {
            posChecker4.SetActive(true);
            posChecker5.SetActive(false);
            posChecker6.SetActive(true);
        }
        else if (laneNum == 6)
        {
            posChecker5.SetActive(true);
            posChecker6.SetActive(false);
        }

        //Movement
        if (grounded)
        {
            verticVel = GetComponent<Rigidbody2D>().velocity.y;
        }
        GetComponent<Rigidbody2D>().velocity = new Vector3(horizVel, /*GetComponent<Rigidbody2D>().velocity.y*/verticVel, 0);
        //Jump
        yPos2 = player.transform.position.y;
        if ((yPos2 - 2) >= yPos1 && !grounded)
        {
            if (moveDirection == "l")
                horizVel = -4;
            if (moveDirection == "r")
                horizVel = 4;
            verticVel = verticVel * 0.95f;
        }

        //Raycast
        if (hitCheck)
        {
            if (moveDirection == "l" && horizVel != 0)
            {
                laneNum -= 1;
            }
            if (moveDirection == "r" && horizVel != 0)
            {
                laneNum += 1;
            }
            go = true;
            horizVel = 0;
            verticVel = 0;
            grounded = true;
        }
        if (horizVel == 0 && grounded)
            moveDirection = "";


        //Animation
        bool flipSprite = (spriteRenderer.flipX ? (horizVel > 0.01f) : (horizVel < 0.01f));
        if (flipSprite)
        {
            spriteRenderer.flipX = !spriteRenderer.flipX;
        }

        animator.SetBool("grounded", grounded); // -->Jump
        animator.SetFloat("velocityX", Mathf.Abs(horizVel));

    }


    //Button Input
    public void RightButton() //
    {
        if (laneNum < 6 && go)
        {
            moveDirection = "r";
            go = false;
            horizVel = 4;
        }
    }
    public void LeftButton()//
    {
        if (laneNum > 1 && go)
        {
            moveDirection = "l";
            go = false;
            horizVel = -4;
        }
    }
    public void RightJump()//
    {
        if (laneNum < 6 && grounded && go)
        {
            moveDirection = "r";
            verticVel = 5;
            go = false;
            grounded = false;
            //
            yPos1 = player.transform.position.y;
            Debug.Log(yPos1);
            //
        }
    }
    public void LeftJump()//
    {
        if (laneNum > 1 && grounded && go)
        {
            moveDirection = "l";
            verticVel = 5;
            go = false;
            grounded = false;
            //
            yPos1 = player.transform.position.y;
            Debug.Log(yPos1);
            //
        }
    }
}