首页 > 解决方案 > 统一空中运动与速度变化

问题描述

我在 Unity 的 3D 游戏中为玩家移动制作了一个脚本。我喜欢移动的工作原理,但是当我在移动时跳跃时,玩家会以相同的速度继续朝那个方向移动,直到它掉到地上,这是这个脚本的预期行为。但我希望能够在空中稍微移动玩家(不是完全可控的)。确切地说,我想象有点像我的世界一样的运动。

任何改进此代码的建议将不胜感激。

这是我的代码。


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);
    }
}

标签: c#unity3d3d

解决方案


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));
}

如果您的代码运行良好,请尝试这样的操作。只是移动了接地条件。现在,该运动也可以在播出时间进行。我们用那个接地的布尔值检查运动有多大。


推荐阅读