微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

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

如何解决Unity 2d 角色使用 UI 按钮移动并跳转到特定位置

一个简单的 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);
            //
        }
    }
}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。