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