【问题标题】:Unity 2D - Jump Function Doesn't Work ProperlyUnity 2D - 跳转功能无法正常工作
【发布时间】:2021-06-06 00:43:57
【问题描述】:

我是编码和 Unity2D 的新手,所以请多多包涵。

我创建了一个角色控制器,它是通过针对 UI 按钮对象设置的 EventTriggers 调用的。控制器工作正常(虽然可能是矫枉过正),但以下是我遇到的跳跃功能的挑战。非常感谢您对此的任何帮助。

非常感谢!

挑战

  • 玩家即使从静止状态也能朝着正确的方向跳跃。
  • 玩家即使在空中也可以继续跳跃。

这是脚本:

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    
    public class GameController : MonoBehaviour
    {
        Rigidbody2D rb2d;
        SpriteRenderer spriteRenderer;
        Animator animator;
        public Transform groundCheck;
        private LayerMask groundLayer = 1 << LayerMask.NameToLayer ("groundLayer");
        private bool moveLeft;
        private bool moveRight;
        private bool moveJump;
        private bool isGrounded;
        private float horizontalMove;
        private float verticalMove;
        public float playerSpeed = 0f;
        public float jumpForce = 0f;
        public float groundCheckRadius;
    
        public void Start()
        {
            rb2d = GetComponent<Rigidbody2D>();
            spriteRenderer = GetComponent<SpriteRenderer>();
            animator = GetComponent<Animator>();
    
            moveLeft = false;
            moveRight = false;
            moveJump = false;
        }
    
        //Function - Left button pressed
        public void MoveLeft()
        {
            moveLeft = true;
            Debug.Log("Function - Move Left");
        }
    
        //Function - Right button pressed
        public void MoveRight()
        {
            moveRight = true;
            Debug.Log("Function - Move Right");
        }
    
        //Function - Jump button pressed
        public void MoveJump()
        {
            moveJump = true;
            Debug.Log("Function - Move Jump");
        }
    
        //Function - Stop player movement
        public void MoveStop()
        {
            rb2d.velocity = Vector3.zero;
            animator.Play("PlayerIdle");
            moveLeft = false;
            moveRight = false;
            moveJump = false;
        }
    
        //Function - Check if player 'GroundCheck' is touching the ground layer
        private void PlayerGrounded()
        {
            isGrounded = Physics2D.OverlapCircle(groundCheck.position, groundCheckRadius, groundLayer);
    
            if (isGrounded == true)
            {
                Debug.Log("Player is touching the ground!");
            }
    
            if (isGrounded == false)
            {
                Debug.Log("Player is not touching the ground!");
            }
    
        }
    
        //Function - Plays once every frame
        private void Update()
        {
            PlayerMovement();
    
            PlayerGrounded();
        }
    
        //Function - Move the player GameObject
        public void PlayerMovement()
        {
    
            //Set the player horizontal right axis
            if (moveRight)
            {
                horizontalMove = playerSpeed;
                Debug.Log("Function - PlayerMovement - Move Right!");
            }
    
            //Set the player horizontal left axis
            if (moveLeft)
            {
                horizontalMove = -playerSpeed;
                Debug.Log("Function - PlayerMovement - Move Left!");
            }
    
            //Set the player vertical axis
            if (moveJump)
            {
                verticalMove = jumpForce;
                Debug.Log("Function - PlayerMovement - Move Jump!");
            }
    
        }
    
        //Function - Plays once every loaded frame
        private void FixedUpdate()
        {
    
            //Move the player right, don't flip, play animation
            if (moveRight)
            {
                rb2d.velocity = new Vector2(horizontalMove, rb2d.velocity.y * playerSpeed * Time.deltaTime);
                spriteRenderer.flipX = false;
                animator.Play("PlayerRun");
                Debug.Log("Function - Player Moving Right!");
            }
    
            //Move the player left, don't flip, play animation
            if (moveLeft)
            {
                rb2d.velocity = new Vector2(horizontalMove, rb2d.velocity.y * playerSpeed * Time.deltaTime);
                spriteRenderer.flipX = true;
                animator.Play("PlayerRun");
                Debug.Log("Function - Player Moving Left!");
            }
    
            //Move the player into the air via a jump
            if (moveJump && (rb2d.velocity.y == 0))
            {
                rb2d.velocity = new Vector2(verticalMove, rb2d.velocity.x * jumpForce);
                animator.Play("PlayerJump");
                Debug.Log("Function - Player Moving Up!");
            }
    
        }
    
    }

【问题讨论】:

    标签: unity3d


    【解决方案1】:

    问题在于固定更新结束。这就是你所拥有的:

    if (moveJump && (rb2d.velocity.y == 0))
    {
        rb2d.velocity = new Vector2(verticalMove, rb2d.velocity.x * jumpForce);
        animator.Play("PlayerJump");
        Debug.Log("Function - Player Moving Up!");
    }
    

    让我们看看开头。它说if (moveJump &amp;&amp; (rb2d.velocity.y == 0)。因此,(我假设您在他们按下跳跃按钮时设置 moveJump)如果您按下跳跃按钮并且 y 速度为 0。但是,这与玩家是否在地面上无关。我们应该把它改成if (moveJump &amp;&amp; isGrounded)。这样,它会在跳转前检查 isGrounded 是否为真。

    当您将速度更改为跳跃时,我注意到几个问题。它是这样说的:

    rb2d.velocity = new Vector2(verticalMove, rb2d.velocity.x * jumpForce);
    

    新建Vector2时,第一个参数为x,第二个参数为y。您正在以相反的顺序进行操作。你做了y,然后x。你应该像这样交换它们:

    rb2d.velocity = new Vector2(rb2d.velocity.x, verticalMove * jumpForce);
    

    由于此交换,您将跳转应用到 x 轴,并将移动应用到 y 轴,但现在它已修复。

    这是所有的变化:

    if (moveJump && (rb2d.velocity.y == 0))
    {
        rb2d.velocity = new Vector2(verticalMove, rb2d.velocity.x * jumpForce);
        animator.Play("PlayerJump");
        Debug.Log("Function - Player Moving Up!");
    }
    

    【讨论】:

    • 非常感谢!这解决了问题!谢谢!
    • 然后请点击复选标记接受答案,向其他开发人员表明这解决了问题(加上它给你 2 声望)
    猜你喜欢
    • 2020-11-03
    • 1970-01-01
    • 2022-11-01
    • 1970-01-01
    • 2019-01-15
    • 1970-01-01
    • 2017-09-23
    • 1970-01-01
    相关资源
    最近更新 更多