Как сделать прыжок от стены в платформере на Unity?
Здраствуйте)
Делаю свою первую игру на Unity. 2d платформер.
При написании кода для прыжка от стены столкнулся с проблемой. Все работает, но прыжок совершается вертикально вверх, хотя должен отталкиваться от стены.
Сперва упраление по Х происходило с помощью Input.GetAxisRaw("Horizontal"), но узнал, что лучше отслеживать движение условием. Вместо velocity применял AddForce, комментировал участки кода, которые теоретически могли конфликтовать. Результатов нет. Правда в некоторых случаях персонажа раз из 10-20 прыжков телепортировало на расстояние от стены.
Заранее извеняюсь за качество кода
public class PlayerController : MonoBehaviour
{
public float maxSpeed;
public float jumpForse;
private Rigidbody2D theRB;
public Transform groundCheckPoint;
public LayerMask whatIsGround;
private bool isGrounded;
private Animator anim;
public SpriteRenderer playerSR;
public float hangTime = .2f;
private float hangCounter;
public float jumpBufferLength = .03f;
private float jumpBufferCount;
private bool isFacingRight = true;
public float hangTimeForWall = .2f;
private float hangCounterForWall;
public float wallJumpBufferLength = .03f;
private float wallJumpBufferCount;
public float wallJumpSpeedX;
public float wallJumpForse;
private float wallJumpFaceDirection = -1;
public bool isTouchingWall;
public Transform wallCheck;
public float wallCheckDistance;
private bool isWallSliding;
public float isWallSlidingSpeed;
void Start()
{
theRB = GetComponent<Rigidbody2D>();
}
void Update()
{
CheckMovementDirection();
//Проверка, на земле ли игрок
isGrounded = Physics2D.OverlapCircle(groundCheckPoint.position, .2f, whatIsGround);
CheckIfWallSliding();
//managehangtime
if (isGrounded)
{
hangCounter = hangTime;
}else
{
hangCounter -= Time.deltaTime;
}
//Буфер прыжков
if(Input.GetButtonDown("Jump"))
{
jumpBufferCount = jumpBufferLength;
}
else
{
jumpBufferCount -= Time.deltaTime;
}
// Прыжок
if(jumpBufferCount >= 0 && hangCounter > 0f && !isWallSliding)
{
theRB.velocity = new Vector2(theRB.velocity.x, jumpForse);
jumpBufferCount = 0;
}
//СКОЛЬЖЕНИЕ ПО СТЕНЕ И ПРЫЖОК ОТ СТЕНЫ
isTouchingWall = Physics2D.Raycast(wallCheck.position, transform.right, wallCheckDistance, whatIsGround);
if (isWallSliding)
{
if (theRB.velocity.y < -isWallSlidingSpeed)
{
theRB.velocity = new Vector2(theRB.velocity.x, -isWallSlidingSpeed);
}
}
if (isWallSliding)
{
hangCounterForWall = hangTimeForWall;
}
else
{
hangCounterForWall -= Time.deltaTime;
}
//Буфер прыжков от стены
if (Input.GetButtonDown("Jump"))
{
wallJumpBufferCount = wallJumpBufferLength;
}
else
{
wallJumpBufferCount -= Time.deltaTime;
}
//!!!!!!!!!!!!!!!!!!ЭТО САМ ПРЫЖОК ОТ СТЕНЫ!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
if (wallJumpBufferCount >= 0 && hangCounterForWall > 0f)
{
// этот способ я попробовал сперва
//theRB.velocity = new Vector2(theRB.velocity.x*wallJumpSpeedX * wallJumpFaceDirection, wallJumpForse);
Vector2 forceToAdd = new Vector2(theRB.velocity.x * wallJumpSpeedX * wallJumpFaceDirection, wallJumpForse);
theRB.AddForce(forceToAdd, ForceMode2D.Impulse);
wallJumpBufferCount = 0;
}
}
private void CheckMovementDirection()
{
if(isFacingRight && Input.GetKey("a"))
{
Flip();
}
else if(!isFacingRight && Input.GetKey("d"))
{
Flip();
}
}
// Разворот
private void Flip()
{
if(!isWallSliding)
{
isFacingRight = !isFacingRight;
transform.Rotate(0.0f, 180.0f, 0.0f);
wallJumpFaceDirection *= -1;
}
}
//Проверка на скольжение по стене
private void CheckIfWallSliding()
{
if(isTouchingWall && !isGrounded && theRB.velocity.y < 0)
{
isWallSliding = true;
}
else
{
isWallSliding = false;
}
}
private void FixedUpdate()
{
//Бег
if(Input.GetKey("d"))
{
theRB.velocity = new Vector2(maxSpeed, theRB.velocity.y);
}
else if(Input.GetKey("a"))
{
theRB.velocity = new Vector2(-maxSpeed, theRB.velocity.y);
}
else
{
theRB.velocity = new Vector2(0, theRB.velocity.y);
}
//Замедление персонажа на пике прыжка
if (!isGrounded && theRB.velocity.y < 10 && theRB.velocity.y > -10)
{
theRB.gravityScale = 6;
}
else
{
theRB.gravityScale = 10;
}
if (!isGrounded)
{
maxSpeed = 10;
}
else
{
maxSpeed = 8;
}
}
}
Ответы (1 шт):
С дебагом я управляться ещё не умею, но коментить все участки кода по очереди додумался. Короче, проблема оказалась в том, что участок кода с бегом конфликтовал с прыжком от стены. Если сделать прыжок от стены и бег с помощью AddForce, то все работает, но движение через AddForce оставлять не хотелось бы. Слишком неуправляемый персонаж получается.