Мой игрок не всегда прыгает, когда я нажимаю кнопку прыжка

В моем проекте 2D Unity мой игрок не всегда прыгает при нажатии кнопки «прыжок». Он не прыгает, как только я приземляюсь на землю, но после секунды «приземления» он может снова прыгать. Что это может быть за проблема?

using UnityEngine;
    using System.Collections;
    using UnityEngine.UI;

    public class player : MonoBehaviour {

        private static player instance;

        public static player Instance
        {
            get
            {
                if (instance == null)
                {
                    instance = GameObject.FindObjectOfType<player>();
                }
                return instance;
            }

        }


        private Animator myAnimator;

        [SerializeField]
        public static float movementSpeed;

        private bool facingRight = true;

        [SerializeField]
        private Transform[] groundPoints;

        [SerializeField]
        private float groundRadius;

        [SerializeField]
        private LayerMask whatIsGround;

        [SerializeField]
        private bool airControl;

        [SerializeField]
        private float jumpForce;

        public bool canMove;

        public AudioClip jump001;
        public AudioClip jump002;

        private float direction;
        private bool move;
        private float btnHorizontal;

        public Rigidbody2D MyRigidbody { get; set; }

        public bool Attack { get; set; }

        public bool Jump { get; set; }

        public bool OnGround { get; set; }





        // Use this for initialization
        void Start() {

            facingRight = true;
            MyRigidbody = GetComponent<Rigidbody2D>();
            myAnimator = GetComponent<Animator>();




        }
       void Update()
       {

            HandleInput();

        }
        // Update is called once per frame
        void FixedUpdate()
        {

            OnGround = IsGrounded();

            float horizontal = Input.GetAxis("Horizontal");

            if (move)
            {
                this.btnHorizontal = Mathf.Lerp(btnHorizontal, direction, Time.deltaTime * 5);
                HandleMovement(btnHorizontal);
                Flip(direction);
            }
            else
            {

                HandleMovement(horizontal);

                Flip(horizontal);
            }

            if (!canMove)
            {
                GetComponent<Rigidbody2D>().velocity = new Vector2(0, GetComponent<Rigidbody2D>().velocity.y);
                myAnimator.SetFloat("speed", 0);
                return;
            }




            HandleLayers();
        }


        private void HandleMovement(float horizontal)
        {
            if (MyRigidbody.velocity.y < 0)
            {
                myAnimator.SetBool("land", true);
            }
            if (!Attack && (OnGround || airControl))
            {
                MyRigidbody.velocity = new Vector2(horizontal * movementSpeed, MyRigidbody.velocity.y);
            }
            if (Jump && MyRigidbody.velocity.y == 0)
            {
                SoundManager.instance.RandomizeSfx(jump001, jump002);
                MyRigidbody.AddForce(new Vector2(0, jumpForce));
            }

            myAnimator.SetFloat("speed", Mathf.Abs(horizontal));
        }


        private void HandleInput()
        {
            if (canMove)
            {

                //Input.GetKeyDown(KeyCode.Space) || Input.GetKeyDown(KeyCode.UpArrow) || Input.GetKeyDown(KeyCode.W) ||
                if (Input.GetButtonDown("Jump"))
                {
                    myAnimator.SetTrigger("jump");

                }
                if (Input.GetKeyDown(KeyCode.Z) || Input.GetButton("Fight") && OnGround && !Jump)
                {
                    myAnimator.SetTrigger("attack");
                }
            }
        }

        private void Flip(float horizontal)
        {
            if (horizontal > 0 && !facingRight || horizontal < 0 && facingRight && canMove)
            {
                facingRight = !facingRight;

                Vector3 theScale = transform.localScale;

                theScale.x *= -1;

                transform.localScale = theScale;
            }

        }


        private bool IsGrounded()
        {
            {

            }
            if (MyRigidbody.velocity.y <= 0)
            {
                foreach (Transform point in groundPoints)
                {
                    Collider2D[] colliders = Physics2D.OverlapCircleAll(point.position, groundRadius, whatIsGround);

                    for (int i = 0; i < colliders.Length; i++)
                    {
                        if (colliders[i].gameObject != gameObject)
                        {
                            return true;
                        }
                    }
                }
            }
            return false;
        }

        private void HandleLayers()
        {
            if (!OnGround)
            {
                myAnimator.SetLayerWeight(1, 1);
            }
            else
            {

                myAnimator.SetLayerWeight(1, 0);
            }

        }

        //TouchKnappar

        public void BtnJump()
        {
            if (canMove)
            {


                myAnimator.SetTrigger("jump");
                Jump = true;
            }
        }
        public void BtnAttack()
        {

                myAnimator.SetTrigger("attack");
                Attack = true;

        }
        public void BtnMove(float direction)
        {

                this.direction = direction;
                this.move = true;

        }
        public void BtnStopMove()
        {

                this.direction = 0;
                this.btnHorizontal = 0;
                this.move = false;

        }
        public void BtnStopJump()
        {

                Jump = false;


    }


    }

person SafeSailor    schedule 14.10.2016    source источник
comment
Возможно ли, что ваш персонаж немного подпрыгивает, когда приземляется, что приводит к провалу проверки MyRigidbody.velocity.y <= 0? Попробуйте использовать Debug.Log(), чтобы проверить это.   -  person Serlite    schedule 14.10.2016
comment
Я предполагаю, что скорость.у немного отличается от 0, когда на земле и требуется несколько секунд, чтобы стать ровно 0. И скорость.у может быть даже немного отрицательной. Так что, возможно, сработает изменение (Jump && MyRigidbody.velocity.y == 0) на (Jump && MyRigidbody.velocity.y ›= 0). Но, честно говоря, весь код надо переработать...   -  person Alox    schedule 14.10.2016
comment
Хорошо, спасибо, я посмотрю на это. Это моя первая игра, и я следил за парнем на YouTube и сам внес некоторые изменения. я не понимаю весь код полностью.   -  person SafeSailor    schedule 14.10.2016
comment
@ Serlite, да, я думал о том же. Маркус Лённквист Попробуйте также проверить с помощью точек останова, когда он действительно достигает этих определенных условий.   -  person Alox    schedule 14.10.2016
comment
Я вижу, что персонаж немного подпрыгивает, что может вызвать проблему. есть ли способ исправить это?   -  person SafeSailor    schedule 14.10.2016
comment
@MarcusLönnqvist На ум приходит пара идей: вы можете обнулить y-составляющую скорости, когда игрок сталкивается с землей. Но сначала убедитесь, что это реальная проблема, сняв галочку — если она по-прежнему не работает, возможно, вам нужно поискать в другом месте.   -  person Serlite    schedule 14.10.2016
comment
@Serlite Когда я добавил эту отладочную вещь в код, она предупредила меня только тогда, когда персонаж перестал подпрыгивать (мы говорим о 1/4 секунды). Что тогда должно означать, что персонаж не считается заземленным, пока он не перестанет подпрыгивать, я думаю.   -  person SafeSailor    schedule 14.10.2016


Ответы (1)


У меня была такая же проблема, и это исправило ее для меня.

Этот код определяет, привязан ли символ к FixedUpdate().

Collider2D groundCol = Physics2D.OverlapBox(groundCheck.position, groundBoxRadius, 0f, whatIsGround);
this.grounded = (groundCol != null && !groundCol.isTrigger && this.rigbody2d.velocity.y > -0.01f && this.rigbody2d.velocity.y < 0.01f);

Некоторое объяснение:

  • GroundCheck — пустой объект у ног персонажа
  • В условии я проверяю, столкнулся ли блок Overlay с чем-то, и если это что-то не является триггером
  • Наконец, скорость скорости иногда может быть не совсем равной 0, поэтому +-0.01f у меня сработало.
person Hrusilov    schedule 18.10.2016