Unity в движении в воздухе с изменением скорости - PullRequest
0 голосов
/ 08 мая 2020

Я сделал скрипт для движения игрока в 3D-игре в Unity. Мне нравится, как работает движение, но когда я прыгаю во время движения, игрок продолжает двигаться в том же направлении с той же скоростью, пока не упадет на землю, что является ожидаемым поведением для этого скрипта. Но я хочу иметь возможность немного перемещать игрока в воздухе (не полностью управляемый). Я представляю себе движение, похожее на майнкрафт, если быть точным.

Любые советы по улучшению этого кода будут очень приняты .

Это мой код.


using System.IO;
using UnityEngine;

public class VelocityMovement : MonoBehaviour
{

    #region Variables

    public float speed;
    public float gravity;
    public float maxVelocityChange;
    public float jumpHeight;
    public float raycastDistance;
    public Rigidbody rb;

    #endregion

    private void Awake()
    {
        //gets rigidbody, freezes rotation of the rigidbody, disables unity's built in gravity system on rigidbody.
        rb = GetComponent<Rigidbody>();
        rb.freezeRotation = true;
        rb.useGravity = false;
    }

    private void Update()
    {
        //Jump system 
        if(Grounded())
        {
            if (Input.GetKeyDown(KeyCode.Space))
            {
                rb.velocity = new Vector3(rb.velocity.x, CalculateJumpSpeed(), rb.velocity.z);
            }
        }
    }

    private void FixedUpdate()
    {

        //Moves the player when on the ground.
        if (Grounded())
        {
            //Calculate how fast the player should be moving.
            Vector3 targetVelocity = new Vector3(playerInputs.hAxis, 0, playerInputs.vAxis); 
            targetVelocity = transform.TransformDirection(targetVelocity);
            targetVelocity *= speed ;

            //Calculate what the velocity change should be
            Vector3 velocity = rb.velocity;
            Vector3 velocityChange = (targetVelocity - velocity);
            velocityChange.x = Mathf.Clamp(velocityChange.x, -maxVelocityChange, maxVelocityChange);
            velocityChange.z = Mathf.Clamp(velocityChange.z, -maxVelocityChange, maxVelocityChange);
            velocityChange.y = 0f;

            //applies a force equal to the needed velocity change
            rb.AddForce(velocityChange, ForceMode.VelocityChange);

        }

        //Adds gravity to the rigidbody
        rb.AddForce(new Vector3(0, -gravity * rb.mass, 0));
    }

    //Checks if player is on the ground
    private bool Grounded()
    {
        return Physics.Raycast(transform.position, Vector3.down, raycastDistance);
    }

    //calculates how high the player should be jumping
    private float CalculateJumpSpeed()
    {
        return Mathf.Sqrt(2 * jumpHeight * gravity);
    }
}

Ответы [ 2 ]

0 голосов
/ 08 мая 2020
private void FixedUpdate()
{
    //check how big the movement is. Swap SomeSmallValue with a float like 0.1f
    float actualSpeed;
    Vector3 velocity;
    if(Grounded())
    {
         actualSpeed = speed;
         //HERE IT IS NOT, THIS DOESN'T MATTER
         velocity = rb.velocity
    }
    else{
         actualSpeed = speed * SomeSmallValue;
         //WITH THIS rb KEEPS THE SPEED IF ANY BUTTON IS PRESSED
         velocity = 0;
    }

    //Moves the player ALWAYS.
        //Calculate how fast the player should be moving.
        Vector3 targetVelocity = new Vector3(playerInputs.hAxis, 0, playerInputs.vAxis); 
        targetVelocity = transform.TransformDirection(targetVelocity);
        //if Grounded == true the movement is exactly the same than before, because actualSpeed = speed. 
        //If Grounded == false, the movement is so light
        targetVelocity *= actualSpeed;

        //Calculate what the velocity change should be
        //I'VE PLACED THIS UP IN ORDER TO CALL Grounded() ONLY ONE TIME
        //Vector3 velocity = rb.velocity;
        Vector3 velocityChange = (targetVelocity - velocity);
        velocityChange.x = Mathf.Clamp(velocityChange.x, -maxVelocityChange, maxVelocityChange);
        velocityChange.z = Mathf.Clamp(velocityChange.z, -maxVelocityChange, maxVelocityChange);
        velocityChange.y = 0f;

        //applies a force equal to the needed velocity change
        rb.AddForce(velocityChange, ForceMode.VelocityChange);



    //Adds gravity to the rigidbody
    rb.AddForce(new Vector3(0, -gravity * rb.mass, 0));
}

Если ваш код работает нормально, попробуйте что-нибудь вроде этого. Просто переехал в заземленное состояние. Теперь движение работает и в эфирное время. Мы проверяем с помощью этого заземленного bool, насколько велик механизм.

0 голосов
/ 08 мая 2020

Если я вас правильно понял, вы хотите замедлить то, что ваши движения делают в воздухе. по крайней мере, так обстоит дело с левым и правым. Если бы я правильно понял вас, вы бы создали else {} после if (Gounded ()) и go оттуда, может сделать некоторую переменную с плавающей запятой, которая действует как множитель для вашего левого / правого управления в воздухе, а также как еще одна переменная с плавающей запятой для прямого и обратного направления. Внутри этого еще вы можете просто умножить вашу скорость на переменные (в зависимости от оси), и вы должны получить там некоторую форму более медленного движения.

Надеюсь, это помогло вам хотя бы немного.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...