c# - 在给定力时计算 FixedUpdate 中的未来速度,并计算它是否对当前速度为负
问题描述
我在一个物体上使用相对力。这个想法是
- 如果我应用向上箭头,它将向它移动的方向增加力。
- 当我应用向下箭头时,它会对运动方向施加负力,使物体减速。
我要解决的问题是,当向下箭头按下到足以使对象最终减速时,我需要对象停止并且不改变方向。
简而言之,我需要做的是,FixedUpdate
如果物体的速度(或方向)对运动的方向(或速度)是负的,那么我需要做的是通过计算。这似乎是可能的,但是我不确定正确的计算AddForce
用途。
我的猜测是我需要使用一些计算和Vector3.Dot方法
两个向量的点积。
点积是一个浮点值,等于两个向量的大小相乘,然后乘以它们之间夹角的余弦值。
像这样的东西
var future = (forward) * _body.velocity.magnitude * _body.mass;
但是,我不确定需要什么。
给定
private Rigidbody _body;
public float Speed;
物理计算
private void FixedUpdate()
{
// get the controls
var hAxis = Input.GetAxis("Horizontal");
var vAxis = Input.GetAxis("Vertical");
if (_body.velocity == Vector3.zero)
{
// this is just to give some forward moment when stationary
// this will change at some stage and not my problem
var movement = new Vector3(hAxis, 0.0f, vAxis);
if (vAxis > 0)
_body.AddForce(movement * Speed);
}
else
{
// get the direction we are traveling
var direction = _body.velocity.normalized;
// calculate the vertical force from the controls
var forward = direction * vAxis * Speed;
// Calculate the side force from teh controls
var side = Vector3.Cross(direction, Vector3.up) * hAxis * -1f * Speed;
// This is equation is wrong.
var future = (forward) * _body.velocity.magnitude * _body.mass;
// what I am trying to say, is if the future velocity is negative
// i.e the user has pressed the back arrow so much it will go backwards
// then I want to come to a dead stop, and not apply any backwards force
if (Vector3.Dot(direction, future.normalized) < 0)
{
_body.velocity = Vector3.zero;
return;
}
_body.AddForce(forward + side);
}
}
解决方案
我不是真正的物理专业人士,但我会尽力而为;)
您可以在更新FixedUpdate
后的下一次调用 so时进行钳制_body.velocity
public Rigidbody _body;
public float Speed;
// store the last forward direction
private Vector3 lastForward;
private void FixedUpdate()
{
// Check and clamp the current velocity against the last one
// so after forces from last call have been applied
if (Vector3.Dot(lastForward, _body.velocity.normalized) < 0)
{
Debug.Log("Clamped negative");
_body.velocity = Vector3.zero;
}
lastForward = _body.velocity.normalized;
var hAxis = Input.GetAxis("Horizontal");
var vAxis = Input.GetAxis("Vertical");
// == for Vector3 has only a precision of 0.00001
// to be sure you coul use this instead
if (Mathf.Approximately(_body.velocity.magnitude, 0))
{
if (vAxis > 0) _body.AddForce(new Vector3(hAxis, 0.0f, vAxis) * Speed);
}
else
{
var forwardForce = Speed * vAxis * lastForward;
var sideForce = Speed * hAxis * -1f * Vector3.Cross(lastForward, Vector3.up);
_body.AddForce(forwardForce + sideForce);
}
}
或者我猜你可以用什么沉浸式来代替自己AddForce
直接计算力velocity
public Rigidbody _body;
public float Speed;
private void FixedUpdate()
{
var currentVelocity = _body.velocity;
var currentDirection = currentVelocity.normalized;
var hAxis = Input.GetAxis("Horizontal");
var vAxis = Input.GetAxis("Vertical");
if(Mathf.Approximately(_body.velocity.magnitude, 0))
{
// Directly calculating the velocity as Immersive said:
// newVelocity = currentVelocity + Time.deltaTime * Force / Mass
// where Force = direction * Speed
//
// Ofcourse you could also just use AddForce for this case but
// just for consistency I would use the same method for both cases
if(vAxis>0) _body.velocity += new Vector3(hAxis, 0.0f, vAxis) * (Time.deltaTime * Speed / _body.mass);
}
else
{
var forwardForce = Speed * vAxis * currentDirection;
var sideForce = Speed * hAxis * -1f * Vector3.Cross(currentDirection, Vector3.up);
// calculate the future velocity directly without using AddForce
// (see comment above)
var newVelocity = currentVelocity + (forwardForce + sideForce) * (Time.deltaTime / _body.mass);
// Only use this velocity if the new direction is still forward
// otherwise stop
_body.velocity = Vector3.Dot(currentVelocity, newVelocity) < 0 ? Vector3.zero : newVelocity;
}
}
到达PC并立即对其进行测试;)两者都应该基本上可以工作
AddForce
在下一次通话中使用和钳制
使用计算velocity
推荐阅读
- cloudkit - 使用 CKQueryOperation 和 CKReference 获取大集合
- r - 如何在 ELMR 中使用 predict_elm
- python - 在树莓派的python中导入文件
- c# - 如何在不使用 if 子句的情况下获取所选单选按钮的文本?
- ios - AVQueuePlayer seek(to:) 和 CMTime 的问题
- javascript - 将音乐播放器添加到 Django App
- html - 在不改变现有样式的情况下将搜索图标放在输入的前面
- java - 我有 mAdView.loadAd(adRequest); 错误
- python - Pandas TypeError:转换函数对按组进行最大计算的数据类型无效
- amazon-web-services - 跨账户 S3 存储桶访问