C# 我如何通过使用附加力来增加速度?

C# 我如何通过使用附加力来增加速度?,c#,unity3d,C#,Unity3d,我让bean尝试创建一个脚本,用Rigidbody.AddForce移动一个对象 我的目标是通过增加力来达到指定的速度 我有一些if语句,允许三种情况: 如果玩家在加力后没有达到期望的速度:加力 如果玩家在减去力后没有达到期望的速度:减去力 如果玩家比加力跳跃更近:加力以保持速度 然而,我没能创造出想要的结果 目前,一旦接近所需速度,它就会在所需速度的上方和下方快速跳跃 我想这是因为我预测下一个速度的计算不准确 我试着用多种方法来调整它,但我就是不知道如何才能正确 我的问题可能有不同的原因,

我让bean尝试创建一个脚本,用
Rigidbody.AddForce
移动一个对象

我的目标是通过增加力来达到指定的速度

我有一些if语句
,允许三种情况:

  • 如果玩家在加力后没有达到期望的速度:加力
  • 如果玩家在减去力后没有达到期望的速度:减去力
  • 如果玩家比加力跳跃更近:加力以保持速度
然而,我没能创造出想要的结果

目前,一旦接近所需速度,它就会在所需速度的上方和下方快速跳跃

我想这是因为我预测下一个速度的计算不准确

我试着用多种方法来调整它,但我就是不知道如何才能正确

我的问题可能有不同的原因,但如果有,我找不到

无论如何,我把我的代码放在下面

using System.Collections.Generic;
using UnityEngine;

public partial class PlayerController : MonoBehaviour
{
    //*Public
    //Targeted Objects
    /// <summary>The camera stand/parent/folder that is used for left and right 
    /// rotations</summary>
    public GameObject cameraPivotRL;

    /// <summary>The camera stand/parent/folder that is used for gravity related 
    /// rotations</summary>
    public GameObject cameraGravityPivot;

    //Target scripts
    /// <summary>A script that reads inputs</summary>
    public PlayerInputs playerInputs;

    //User settings
    //speed settings
    /// <summary>The amount the player accelerates</summary>
    public float accelerationForce;

    /// <summary>The amount the player decelerates</summary>
    public float decelerationForce;

    /// <summary>The players desired velocity</summary>
    public float desiredVelocity;

    /// <summary>How fast the velocity will reach the desired velocity after  
    /// accelerating or decelerating</summary>
    public float approximationSpeed;


    //*Private
    //Inputs
    /// <summary>Directional inputs used for Moving the character</summary>
    private Vector2 moveInput;
    /// <summary>Magnitude/lengt of the moveInput Vector</summary>
    private float moveInputMagni;

    //Camera pivot R/L Vectors (I use the camera stand so it's not influenced by 
    //up/down rotations)
    /// <summary>The forward vector of the camera</summary>
    private Vector3 camF;
    /// <summary>The right vector of the camera</summary>
    private Vector3 camR;

    //Gravity pivot Vector
    /// <summary>The vector opposed to the gravity direction</summary>
    private Vector3 gravityPivot;

    //Physics
    /// <summary>The Unity component which stores and processes the players 
    /// physics</summary>
    private Rigidbody body;
    /// <summary>The players current velocity</summary>
    private float bodyVelocityMagnitude;

    /// <summary>The portion of the players velocity that is going in the desired 
    /// direction</summary>
    private float veloInDesiredDirectionMagni;

    /// <summary>The velocity the player is predicted to have after applying the 
    /// acceleration force</summary>
    private float predictedVelocity;

    //Debug bools
    private bool isAccelerating = false;
    private float isAcceleratingForce;
    private bool isDecelerating = false;
    private float isDeceleratingForce;
    private bool isMaximizing = false;
    private float isMaximizingForce;

    /// <summary>The force that will be applied</summary>
    private float desiredForceMagni;
    /// <summary>The amount of velocity that will be added after force is 
    /// applied</summary>
    private float addedVeloMagni;
    /// <summary>The velocity from the previous step</summary>
    private float velocityMagniMem;
    /// <summary>The difference betwean the current velocity and the previous 
    /// velocity</summary>
    private float velocityChange;

    /// <summary>a simple bool to keep track of when this code is ran</summary>
    private bool stepCheck = false;

    //#### Unity Functions ####
    //## Awake is called when this object is spawned
    private void Awake()
    {
        //Get rigidbody
        body = transform.GetComponent<Rigidbody>();

        //Get input script
        playerInputs = GetComponent<PlayerInputs>();
    }

    //## Fixed update is called 50 times per second
    private void FixedUpdate()
    {
        //Reset debug bools
        isAccelerating = false;
        isDecelerating = false;
        isMaximizing = false;

        //Draw current velocity
        Debug.DrawRay(transform.position + new Vector3(0, 0.1f, 0), 
                body.velocity * 0.1f, Color.white);

        //Measure the current velocity
        bodyVelocityMagnitude = body.velocity.magnitude;

        //Get move inputs
        moveInput = playerInputs.moveInput;

        //* Main move script block
        if (moveInput.magnitude > 0)
        {
            //Get camera axis
            camF = cameraPivotRL.transform.forward;
            camR = cameraPivotRL.transform.right;

            //Get the current gravity direction
            gravityPivot = cameraGravityPivot.transform.up;

            //Turn inputs into a direction relative to the camera
            var desiredDirection = (camF * moveInput.y) + (camR * moveInput.x);

            //Determine the dirctional force that will be applied
            var desiredForce = desiredDirection * accelerationForce;

            //Calculate how much velocity will be added after the force is applied
            var addedVelo = desiredForce.normalized * (desiredForce.magnitude 
                    - (body.velocity.magnitude * body.drag)) / body.mass 
                    * Time.fixedDeltaTime;

            //Calculate how much of the current velocity is going in the desired 
            //direction
            var veloInDesiredDirection = body.velocity - (body.velocity 
                    - desiredDirection.normalized * Vector3.Dot(body.velocity, 
                    desiredDirection.normalized));

            //Make the desired velocity shrink/grow based on the move inputs 
            //strengt
            var desiredVelocityTemp = desiredVelocity * moveInput.magnitude;

            //Predict future velocity and add/subtract force accordingly
            //will velocity in the desired direction be greater or ecual to 
            //desired velocity after aplying force?
            if ((addedVelo + veloInDesiredDirection).magnitude 
                    >= desiredVelocityTemp && veloInDesiredDirection.magnitude 
                    >= desiredVelocityTemp && Vector3.Dot(body.velocity, 
                    desiredDirection.normalized) > 0)
            {
                //will velocity in the desired direction still be greater than
                //desired velocity after aplying negative force?
                if (((addedVelo * -1) + veloInDesiredDirection).magnitude 
                        > desiredVelocityTemp)
                {
                    //apply force in oposite direction of desired direction
                    body.AddForce(desiredForce * -1, ForceMode.Acceleration);

                    //a peace of code to measure how much the velocity changed
                    //after 1 step
                    if (stepCheck && velocityMagniMem > 0)
                    {
                        velocityChange = body.velocity.magnitude 
                                - velocityMagniMem;
                        stepCheck = false;
                    }
                    else
                    {
                        velocityMagniMem = body.velocity.magnitude;
                        stepCheck = true;
                    }

                    //Debug
                    //draw ray that represents the negative force that is applied 
                    //to the player
                    Debug.DrawRay(transform.position, desiredForce * -1 * 0.005f, 
                            Color.cyan);

                    //this code is running
                    isDecelerating = true;

                    //measure force
                    isDeceleratingForce = desiredForce.magnitude * -1;
                }
                else
                {
                    //calculate force requered to reach and maintain velocity
                    var requiForce = (desiredVelocityTemp * 1.4056579f 
                        + 20.6009236f) * (((desiredVelocityTemp 
                        - (desiredDirection.normalized * Vector3.Dot(
                        body.velocity, desiredDirection.normalized)).magnitude) 
                        * approximationSpeed) + 1);

                    //apply force needed to reach and maintain desired velocity
                    body.AddForce(desiredForce.normalized * requiForce,
                            ForceMode.Acceleration);

                    //Debug
                    //draw ray that represents the negative force that is applied 
                    //to the player
                    Debug.DrawRay(transform.position, desiredForce.normalized 
                            * requiForce * 0.005f, Color.green);

                    //this code is running
                    isMaximizing = true;

                    //measure force
                    isMaximizingForce = requiForce;
                }
            }
            else
            {
                //apply force in desired direction
                body.AddForce(desiredForce, ForceMode.Acceleration);

                //a peace of code to measure how much the velocity changed after 
                //1 step
                if (stepCheck && velocityMagniMem > 0)
                {
                    velocityChange = body.velocity.magnitude - velocityMagniMem;
                    stepCheck = false;
                }
                else
                {
                    velocityMagniMem = body.velocity.magnitude;
                    stepCheck = true;
                }

                //Debug
                //draw ray that represents the negative force that is applied to 
                //the player
                Debug.DrawRay(transform.position, desiredForce * 0.005f, 
                        Color.red);

                //this code is running
                isAccelerating = true;

                //measure force
                isAcceleratingForce = desiredForce.magnitude;
            }

            //Code to turn player model
            //if velocity is detected use velocity to turn player model
            if(body.velocity.magnitude > 0.01f)
            {
                transform.rotation = Quaternion.LookRotation(camF * Vector3.Dot(
                        camF, body.velocity.normalized) + camR * Vector3.Dot(camR,
                        body.velocity.normalized), gravityPivot);
            }
            //if not use inputs
            else if(moveInput.magnitude > 0)
            {
                transform.rotation = Quaternion.LookRotation((camF * moveInput.y) 
                        + (camR * moveInput.x), gravityPivot);
            }

            //Debug variables
            //the strengt of the applied force
            desiredForceMagni = desiredForce.magnitude;

            //the amount of velocity that is predicted to be added after aplying 
            //force
            addedVeloMagni = addedVelo.magnitude;

            //the current velocity strengt that is in the same direction as the
            //desired direction
            veloInDesiredDirectionMagni = veloInDesiredDirection.magnitude;

            //the velocity streng that is predected player is predicted to have in 
            //the desired direction after force is applied
            predictedVelocity = (addedVelo + veloInDesiredDirection).magnitude;

            //draw predicted velocity
            Debug.DrawRay(transform.position + new Vector3(0, 0.2f, 0), 
                    addedVelo.normalized * predictedVelocity * 0.1f, 
                    Color.magenta);

            //draw the velocity in the desired direction
            Debug.DrawRay(transform.position + new Vector3(0, 0.1f, 0), 
                    veloInDesiredDirection * 0.1f, Color.yellow);

            //draw a line betwean the normal velocity and the velocity in the 
            //desired direction
            Debug.DrawLine(transform.position + new Vector3(0, 0.1f, 0) 
                    + (veloInDesiredDirection * 0.1f), transform.position 
                    + new Vector3(0, 0.1f, 0) + (body.velocity * 0.1f), 
                    Color.gray);
        }
    }
}
使用System.Collections.Generic;
使用UnityEngine;
公共部分类PlayerController:monoBehavior
{
//*公开的
//目标物体
///用于左侧和右侧的相机支架/父/文件夹
///轮换
公共游戏对象cameraPivotRL;
///用于重力相关的相机支架/父/文件夹
///轮换
公共游戏对象摄像机;
//目标脚本
///读取输入的脚本
公开播放者播放者播放者播放者播放者播放;
//用户设置
//速度设置
///玩家加速的量
公众浮力;
///玩家减速的量
公共浮动减速力;
///运动员们要求速度
公众期望速度;
///之后速度达到所需速度的速度
///加速或减速
公共浮动近似速度;
//*私人的
//投入
///用于移动角色的方向输入
私有向量2移动输入;
///移动输入向量的大小/长度
私有浮动moveInputMagni;
//摄影机轴R/L向量(我使用摄影机支架,因此不受
//向上/向下旋转)
///摄像机的前向矢量
私有向量3 camF;
///相机的右向量
私人矢量3;
//重力轴矢量
///与重力方向相反的矢量
私人向量3重力向量;
//物理学
///存储和处理玩家的Unity组件
///物理学
私人刚体;
///运动员的速度
私人浮体速度;
///运动员以期望的速度前进的部分
///方向
专用浮动速度指定方向Magni;
///玩家在应用后预计的速度
///加速力
私人浮动预测速度;
//调试布尔
private bool isAccelerating=错误;
私人浮动是一种加速力量;
私有bool isdecellerating=false;
私人浮动是一种不可容忍的力量;
私有布尔值最大化=假;
私人浮动是最大化的力量;
///将要施加的力
私人浮动要求ForceMagni;
///受力后将添加的速度量
///应用
私有浮动加法器;
///上一步的速度
私人浮动速度;
///当前速度和先前速度之间的差异
///速度
私人浮动速度变化;
///一个跟踪代码运行时间的简单bool
私有bool stepCheck=false;
//####统一功能####
//##生成此对象时将调用唤醒
私人空间
{
//僵硬
body=transform.GetComponent();
//获取输入脚本
playerInputs=GetComponent();
}
//##固定更新每秒调用50次
私有void FixedUpdate()
{
//重置调试布尔
isAccelerating=错误;
IsDecellerating=假;
isMaximizing=false;
//牵引流速
Debug.DrawRay(transform.position+新矢量3(0,0.1f,0),
车身速度*0.1f,颜色为白色);
//测量流速
bodyVelocityMagnitude=body.velocity.magnitude;
//获取移动输入
moveInput=playerInputs.moveInput;
//*主移动脚本块
如果(moveInput.magnitude>0)
{
//获取相机轴
camF=cameraPivotRL.transform.forward;
camR=cameraPivotRL.transform.right;
//获取当前重力方向
gravityPivot=cameraGravityPivot.transform.up;
//将输入转换为相对于相机的方向
var desiredDirection=(camF*moveInput.y)+(camR*moveInput.x);
//确定将应用的方向力
var desiredForce=desiredDirection*加速力;
//计算施加力后将增加多少速度
var addedVelo=desiredForce.normalized*(desiredForce.magnitude
-(body.velocity.magnity*body.drag))/body.mass
*固定时间;
//计算有多少流速以所需的速度移动
//方向
var veloInDesiredDirection=body.velocity-(body.velocity
-desiredDirection.normalized*矢量3.Dot(body.velocity,
期望方向(归一化);
//使所需的速度基于
//Set a target velocity
Vector3 targetVelocity = moveDirection * maxSpeed;

//Find the change of velocity needed to reach target
Vector3 velocityChange = targetVelocity - rb.velocity;

//Convert to acceleration, which is change of velocity over time
Vector3 acceleration = velocityChange / Time.fixedDeltaTime;

//Clamp it to your maximum acceleration magnitude
acceleration = Vector3.ClampMagnitude(acceleration, maxAcceleration);

//Then AddForce
rb.AddForce(acceleration, ForceMode.Acceleration);