Как сделать адаптивное направление импульса прыжка, в зависимости от поворота спрайта Unity2D?
Начал изучать C# и Unity2D. Решил сделать небольшой платформер, где передвижение осуществляется только прыжками.Проблемы в том,что я не могу понять как сделать так, чтобы импульс прыжка прикладывался в направлении оси Y персонажа, даже при его наклоне. На данный момент,при наклоне влево или вправо, вектор прыжка направлен по глобальной оси Y вверх, получается что персонаж прыгает вверх боком/под наклоном, а необходимо чтобы он прыгал в направлении головы. Прошу помочь разобраться, буду очень благодарен.
Вот мой код:
public class Player : MonoBehaviour
{
public float hzSpeed;
public float rotateSpeed;
float speedX;
float rotateZ;
public float verImpulse;
Rigidbody2D rb;
bool onGround = false;
void Start()
{
rb = GetComponent<Rigidbody2D>();
}
void FixedUpdate() {
if(Input.GetKey(KeyCode.A)){
speedX = -hzSpeed;
rotateZ = rotateSpeed;
}
if(Input.GetKey(KeyCode.D)){
speedX = hzSpeed;
rotateZ = -rotateSpeed;
}
if(Input.GetKey(KeyCode.Space)&&onGround){
rb.AddForce(new Vector2(speedX,verImpulse),ForceMode2D.Impulse);
}
transform.Rotate(0,0,rotateZ);
speedX = 0;
rotateZ = 0;
}
void Update()
{
}
private void OnCollisionEnter2D(Collision2D collision) {
if(collision.gameObject.tag == "Ground"){
onGround = true;
}
}
private void OnCollisionExit2D(Collision2D collision) {
if(collision.gameObject.tag == "Ground"){
onGround = false;
}
}
}
Ответы (1 шт):
Автор решения: Yaroslav
→ Ссылка
[DisallowMultipleComponent]
// обязательный компонент
[RequireComponent(typeof(Rigidbody2D))]
public class Player : MonoBehaviour {
// эти поля не должны быть public, SerializeField
[SerializeField] private float _speed = 5f;
[SerializeField] private float _jumpPower = 10f;
[Space]
// пустой прикрепленный GameObject у основания ног персонажа
// иначе _onGround можно получать от столкновения боком или головой
[SerializeField] private Transform _groundCheck;
// определять землю не через tag, а через layer
[SerializeField] private LayerMask _groundLayer;
[SerializeField] private float _groundCheckRadius = 1;
private Transform _transform;
private Rigidbody2D _body;
private float _direction = -1;
private bool _onGround = false;
private void Awake () {
_transform = transform;
_body = GetComponent<Rigidbody2D>();
}
// каждый Update кадра
private void Updata () {
if (Input.GetKey(KeyCode.A))
SetDirection(-1);
if (Input.GetKey(KeyCode.D))
SetDirection(1);
if (Input.GetKey(KeyCode.Space))
Jump();
}
// каждый Update физики
private void FixedUpdate () {
if (_onGround == false && _body.velocity.y < 0 && CheckGroundCollide())
Lending();
}
private void SetDirection (float direction) {
_direction = direction;
// направление персонажа в разные стороны делается не через поворот, а зеркальный скеил
// поворот персонажа фризится в свойствах тела
_transform.localScale = new Vector3(_direction, 1, 1);
}
private void Jump () {
if (_onGround) {
_body.AddForce(new Vector2(_speed*_direction, _jumpPower), ForceMode2D.Impulse);
_onGround = false;
}
}
private void Lending () {
_onGround = true;
// обнуляем вектор тело, что бы не было инерции
_body.velocity = Vector2.zero;
}
private bool CheckGroundCollide () {
return Physics2D.OverlapCircle(_groundCheck.position, _groundCheckRadius, _groundLayer);
}
}