Мой 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;
}
}
}