Возникает ли конфликт между функциями Move и Velocity в Unity?

Я разработал систему управления персонажем в Unity, и всё работает без проблем, кроме прыжка. Проблема заключается в том, что прыжок возможен только во время перемещения персонажа. У меня есть две функции: одна для перемещения (Movement), а вторая – для обработки прыжка (Velocity). Я понял, что они конфликтуют между собой. Как можно решить эту проблему, чтобы прыжок работал независимо от перемещения?

```csharp
using Unity.VisualScripting;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.InputSystem;

public class PlayerContoller : MonoBehaviour
{
    [SerializeField] private CharacterController _characterController;
    [SerializeField] private Transform _cameraTransform;

    [Header("Settings")]
   
    [SerializeField] private float _gravity = -14f;
    [SerializeField] private float _speed = 4f;
    [SerializeField] private float _jumpHeight = 1f;

    [Range(1, 100)]
    [SerializeField] private float _sensitivity = 50f;

    float rotationX;

    Vector3 velocity;
    Vector3 move;
    void Start()
    {
        Cursor.lockState = CursorLockMode.Locked;
        Cursor.visible = false;
    }

    void Update()
    {
        Rotate();
        Movement();
        Velocity();
    }
    
    private void Rotate()
    {
        float mouseX = Input.GetAxis("Mouse X") * _sensitivity * Time.deltaTime;
        float mouseY = Input.GetAxis("Mouse Y") * _sensitivity * Time.deltaTime;

        rotationX -= mouseY;
        rotationX = Mathf.Clamp(rotationX, -90f, 90f);
        _cameraTransform.localRotation = Quaternion.Euler(rotationX, 0, 0);
        transform.Rotate(Vector3.up * mouseX);
    }

    private void Velocity()
    {
        if (_characterController.isGrounded && velocity.y < 0)
            velocity.y = -2f;
```
  • 4 ноября 2024 г. 0:03
Ответы на вопрос 2
Да, в вашем коде может возникнуть конфликт между функциями движения (Movement) и управления вертикальной скоростью (Velocity), особенно в части, где вы обрабатываете прыжок и гравитацию. Чтобы корректно реализовать прыжок, вам нужно убедиться, что значение вертикальной скорости (составляющая `y` в `velocity`) обновляется независимо от горизонтального движения.

Вот несколько шагов, которые могут помочь вам реорганизовать код:

1. **Объедините логику движения**: Вместо того, чтобы рассчитывать вертикальную скорость и движение отдельно, объедините их. Это даст вам возможность управлять движением и прыгать независимо друг от друга.

2. **Расчет прыжка**: Проверяйте, была ли нажата клавиша для прыжка и добавляйте вертикальную составляющую к `velocity` только в этом случае.

Вот пример того, как можно переработать ваш код:

```csharp
private void Update()
{
    Rotate();
    Movement();
    ApplyGravity();
    _characterController.Move(velocity * Time.deltaTime); // Применение полной скорости
}

private void Movement() 
{
    float horizontal = Input.GetAxis("Horizontal");
    float vertical = Input.GetAxis("Vertical");

    Vector3 moveDirection = transform.right * horizontal + transform.forward * vertical;
    moveDirection.Normalize(); // Нормализация направления движения
    moveDirection *= _speed; // Применение скорости

    velocity.x = moveDirection.x;
    velocity.z = moveDirection.z;
}

private void ApplyGravity()
{
    if (_characterController.isGrounded) 
    {
        // Если персонаж на земле и движение вниз
        if (velocity.y < 0) 
            velocity.y = -2f;

        if (Input.GetButtonDown("Jump")) // Проверка нажатия кнопки прыжка
        {
            velocity.y = Mathf.Sqrt(_jumpHeight * -2f * _gravity); // Применение силы прыжка
        }
    } 
    else 
    {
        // Применение гравитации, если персонаж в воздухе
        velocity.y += _gravity * Time.deltaTime;
    }
}
```

### Объяснение изменений:

1. **Обновление логики движения**: Функция `Movement()` теперь просто обновляет горизонтальные компоненты `velocity` на основании пользовательского ввода.

2. **Гравитация и прыжок**: В функции `ApplyGravity()` вы проверяете, приземлён ли персонаж. Если да, то сбрасываете значение вертикальной скорости (вы просто устанавливаете `velocity.y` на -2f, чтобы персонаж "прилипал" к земле). Также вы проверяете, нажата ли кнопка "Jump" (например, пробел), и если да, то используете формулу для вычисления силы прыжка.

3. **Полное применение скорости**: В `Update()` теперь вызывается метод `Move` CharacterController, который применяет комбинированную скорость (горизонтальные и вертикальные составляющие).

Теперь ваша система управления персонажем должна работать корректно, позволяя персонажу прыгать независимо от горизонтального движения.
у вас 2 раза вызывает  _characterController.Move 
в Velocity() сделайте расчет float verticalMover(это будет velocity.y)
private void Movement() ....
_characterController.Move(move * _speed * Time.deltaTime+transform.up*verticalMover*Time.deltaTime );
....
Похожие вопросы