简体   繁体   中英

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

In a simple 2d project in which my player can move to the right and left on x and can also jump to the right and left in height with two other buttons. The problem is, that the player is not supposed to move freely. By pressing one of the buttons the player should only go to the next specific point, so that the player always stops at six different positions on x (while on y he is free and as high as the platform he is currently standing on). To be able to jump realistically, the player must have gravity and a collider to be able to land on the platforms (and move single platforms horizontal). Thanks to the tutorial which @TEEBQNE linked in the comments I could finally realise this with Unitys Rigidbody2D and the following script. The problem is that the gravity is now behaving strangely. The player only moves down very slowly and in the process pushes Gameobjects underneath it through others. The player has a Dynamic Rigidbody2D with a gravity scale of 2 and a capsule collider 2d. Is that a problem with the script or with the components in the players inspector?

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;
        }
    }
}

Glad I was able to help in some way and that you figured out your issue!

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);
            //
        }
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM