Мой 2D персонаж не прыгает вообще

У меня проблема с моим персонажем, который вообще не прыгает. Я новичок в Unity, но я позаботился о том, чтобы применить скрипт к плееру и отрегулировать скорость, я не трогал Rigidbody 2D. Если кто-нибудь и поможет мне разобраться в нашей проблеме, это будет высоко оценено.

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

public class PlayerController : MonoBehaviour {

public float moveSpeed;
public float jumpSpeed;
public bool grounded = false;
private Rigidbody2D rb;

void Start() {
    rb = GetComponent<Rigidbody2D>();
}

void Update () {

    transform.Translate (Input.GetAxisRaw ("Horizontal") * moveSpeed * Time.deltaTime, 0, 0);

    if (grounded) 
    {
        if (Input.GetButtonDown ("Jump"))
        {
            rb.AddForce (Vector2.up * jumpSpeed);
            grounded = false;
        }
    }
}


void OnCollisionEnter2D (Collision2D coll){
    if (coll.transform.tag == "Ground") 
    {
        grounded = true;
    }
}

}

Окно инспектора игрока GameObject

игрок

Окно инспектора наземного GameObject

Основание / куб

2 ответа

Решение

Ваша проблема в том, что вы не пометили наземный игровой объект как таковой. Так что в OnCollisionEnter2D персонаж обнаруживает столкновение, но if (coll.transform.tag == "Ground") никогда не будет правдой. Значит, персонаж не может быть grounded

Поскольку заземление - это первое условие, чтобы проверить, нажал ли игрок клавишу Jump. Это невозможно, он когда-нибудь прыгнет

if (grounded) 
    {
        if (Input.GetButtonDown ("Jump"))
        {
            rb.AddForce (Vector2.up * jumpSpeed);
            grounded = false;
        }
    }

Чтобы решить эту проблему: Вам нужно пометить наземный GameObject так. Если вы не уверены, как это сделать, в меню "Тег" создайте (если он еще не существует) новый тег "Земля". Затем в том же меню назначьте наземный тег наземному игровому объекту. Здесь вы можете узнать, как в случае, если вам нужна визуальная справка:

https://docs.unity3d.com/Manual/Tags.html

Изменить: вы можете попробовать этот скрипт, если все не удается. Он должен работать. Я использовал себя некоторое время назад, я очистил код, чтобы оставить только то, что вам нужно, чтобы переместить символ по осям X и Y. Надеюсь, что включены все, что вам нужно:

public class CharacterController2D : MonoBehaviour {

    // LayerMask to determine what is considered ground for the player
    public LayerMask whatIsGround;

    // Transform just below feet for checking if player is grounded
    public Transform groundCheck;

    // store references to components on the gameObject
    Transform transform;
    Rigidbody2D rigidbody;

    bool isGrounded = false;

    float vy;
    float vx;

    public float jumpForce = 600f;

    void Awake () {
        transform = GetComponent<Transform> ();
        rigidbody = GetComponent<Rigidbody2D> ();
    }


    void Update()
    {

        // determine horizontal velocity change based on the horizontal input
        vx = Input.GetAxisRaw ("Horizontal");
        vy = rigidbody.velocity.y;

        // Check to see if character is grounded by raycasting from the middle of the player
        // down to the groundCheck position and see if collected with gameobjects on the
        // whatIsGround layer
        isGrounded = Physics2D.Linecast(transform.position, groundCheck.position, whatIsGround);

        if(isGrounded && Input.GetButtonDown("Jump")) // If grounded AND jump button pressed, then allow the player to jump
        {
            DoJump();
        }

        // Change the actual velocity on the rigidbody
        rigidbody.velocity = new Vector2(_vx * MoveSpeed, _vy);

    }

    //Make the player jump
    void DoJump()
    {
        // reset current vertical motion to 0 prior to jump
        vy = 0f;
        // add a force in the up direction
        rigidbody.AddForce (new Vector2 (0, jumpForce));

    }
}

Итак, что нужно учитывать:

  • Вместо того, чтобы отмечать землю, вы создаете слой со всем, что считаете земным. Это будет включать возможные платформы, через которые персонаж может перепрыгнуть. Передать в качестве параметра этот слой в скрипт в инспекторе

  • Вам нужно поместить пустой GameObject в ноги персонажа. Вы перетащите этот GameObject в редакторе в публичную переменную groundCheck.

  • Вместо OnTriggerEnter вы будете использовать Physics2D.Linecast которая пройдет линию от положения персонажа до его под ног (где вы должны были разместить преобразование, упомянутое на предыдущем шаге), и если в середине есть элемент GroundLayer, это означает, что персонаж будет заземлен.

Дайте мне знать, если что-то не понятно или если вы найдете какую-то ошибку.

Как уже упоминалось, ваша проблема заключается в том, что вам не хватает метки вашего наземного объекта:)

Совет: что мне нравится делать, когда у меня возникают подобные проблемы, - это использовать Unity Debug.Log(), чтобы определить, в чем проблема. Это позволит вам легко узнать в консоли, какой код запущен, а какой нет. Попробуйте сделать следующее:

void Update () {

transform.Translate (Input.GetAxisRaw ("Horizontal") * moveSpeed * Time.deltaTime, 0, 0);

if (grounded) 
{
    Debug.Log("Is grounded");

    if (Input.GetButtonDown ("Jump"))
    {
        Debug.Log("Jump clicked");
        rb.AddForce (Vector2.up * jumpSpeed);
        grounded = false;
    }
}

}

Другие вопросы по тегам