我有一架无人机在跟踪一条移动路径。也就是说,它不使用刚体,所以我无法获得速度或大小等。它沿着这条路走得很好,但我想在它向左或向右转弯时添加银行业务。我在无人机前面使用了一个虚拟对象,认为我可以使用这两个对象的变换向量来计算倾斜/倾斜量。
我已经做了好几天了,因为我没有太多的数学技能。基本上,我一直在复制代码片段,试图让事情正常工作。我所做的一切都无法使无人机成为银行。下面的代码设法旋转(而不是银行)。
// Update is called once per frame
void Update () {
Quaternion rotation = Quaternion.identity;
Vector3 dir = (dummyObject.transform.position - this.transform.position).normalized;
float angle = Vector3.Angle( dir, transform.up );
float rollAngle = CalculateRollAngle(angle);
rotation.SetLookRotation(dir, transform.right);// + rollIntensity * smoothRoll * right);
rotation *= Quaternion.Euler(new Vector3(0, 0, rollAngle));
transform.rotation = rotation;
}
/// <summary>
/// Calculates Roll and smoothes it (to compensates for non C2 continuous control points algorithm) /// </summary>
/// <returns>The roll angle.</returns>
/// <param name="rollFactor">Roll factor.</param>
float CalculateRollAngle(float rollFactor)
{
smoothRoll = Mathf.Lerp(smoothRoll, rollFactor, rollSmoothing * Time.deltaTime);
float angle = Mathf.Atan2(1, smoothRoll * rollIntensity);
angle *= Mathf.Rad2Deg;
angle -= 90;
TurnRollAngle = angle;
angle += RollOffset;
return angle;
}
假设你有无人机跟随的航路点,你应该计算出后两者之间的角度(即你的"现在面向"one_answers"将面向"方向)。最简单的方法是使用Vector2.Angle。
我会用这个角度来确定无人机机身的倾斜量:转弯越急,倾斜越困难。我会使用一个比值(最初public,这样我就可以从编辑器中操作它)
接下来,我不做任何数学运算,而是依靠引擎为我做旋转——所以我会选择Transform。旋转功能
如果银行业务可能过高,看起来很傻,我会为此设置一个最大值,并将我计算的银行业务角度限制在零和最大值之间。
在不知道你做什么以及如何做的情况下,给出完美的代码并不容易,但为了更好地理解以上内容,以下是我所设想的解决方案的一些(未经测试的,即伪)代码:
public float turnSpeed = 7.0f; //the drone will "rotate toward the new waypoint" by this speed
//bankSpeed+turnBankRatio must be two times "faster" (and/or smaller degree) than turning, see details in 'EDIT' as of why:
public float bankSpeed = 14.0f; //banking speed
public float turnBankRatio = .5f; //90 degree turn == 45 degree banking
private float turnAngle = 0.0f; //this is the 'x' degree turning angle we'll "Lerp"
private float turnAngleABS = 0.0f; //same as turnAngle but it's an absolute value. Storing to avoid Mathf.Abs() in Update()!
private float bankAngle = 0.0f; //banking degree
private bool isTurning = false; //are we turning right now?
//when the action is fired for the drone it should go for the next waypoint, call this guy
private void TurningTrigger() {
//remove this line after testing, it's some extra safety
if (isTurning) { Debug.LogError("oups! must not be possible!"); return; }
Vector2 droneOLD2DAngle = GetGO2DPos(transform.position);
//do the code you do for the turning/rotation of drone here!
//or use the next waypoint's .position as the new angle if you are OK
//with the snippet doing the turning for you along with banking. then:
Vector2 droneNEW2DAngle = GetGO2DPos(transform.position);
turnAngle = Vector2.Angle(droneOLD2DAngle, droneNEW2DAngle); //turn degree
turnAngleABS = Mathf.Abs(turnAngle); //avoiding Mathf.Abs() in Update()
bankAngle = turnAngle * turnBankRatio; //bank angle
//you can remove this after testing. This is to make sure banking can
//do a full run before the drone hits the next waypoint!
if ((turnAngle * turnSpeed) < (bankAngle * bankSpeed)) {
Debug.LogError("Banking degree too high, or banking speed too low to complete maneuver!");
}
//you can clamp or set turnAngle based on a min/max here
isTurning = true; //all values were set, turning and banking can start!
}
//get 2D position of a GO (simplified)
private Vector2 GetGO2DPos(Vector3 worldPos) {
return new Vector2(worldPos.x, worldPos.z);
}
private void Update() {
if (isTurning) {
//assuming the drone is banking to the "side" and "side" only
transform.Rotate(0, 0, bankAngle * time.deltaTime * bankSpeed, Space.Self); //banking
//if the drone is facing the next waypoint already, set
//isTurning to false
} else if (turnAngleABS > 0.0f) {
//reset back to original position (with same speed as above)
//at least "normal speed" is a must, otherwise drone might hit the
//next waypoint before the banking reset can finish!
float bankAngle_delta = bankAngle * time.deltaTime * bankSpeed;
transform.Rotate(0, 0, -1 * bankAngle_delta, Space.Self);
turnAngleABS -= (bankAngle_delta >0.0f) ? bankAngle_delta : -1 * bankAngle_delta;
}
//the banking was probably not set back to exactly 0, as time.deltaTime
//is not a fixed value. if this happened and looks ugly, reset
//drone's "z" to Quaternion.identity.z. if it also looks ugly,
//you need to test if you don't """over bank""" in the above code
//by comparing bankAngle_delta + 'calculated banking angle' against
//the identity.z value, and reset bankAngle_delta if it's too high/low.
//when you are done, your turning animation is over, so:
}
同样,这段代码可能不完全符合您的需求(或compile:p),所以请关注想法和方法,而不是代码本身。很抱歉现在没能整理一些东西来测试自己,但我希望我能帮上忙。干杯
编辑:我试着用代码回答你的问题,而不是用一堵文字墙(仍然不完美,但目标不是完成任务,而是提供一些片段和想法:)
所以。基本上,你所拥有的是两个航路点之间的距离和"角度"。这个距离和你的无人机的飞行/行走/任何速度(我不知道)是最大可用时间:
1.转向,这样无人机将面向新的方向
2。银行向一侧倾斜,然后回到零/"正常">
由于银行方面的行动要多出两倍,要么必须更快(bankSpeed
),要么以更小的角度(turnBankRatio
),或者两者兼而有之,这取决于什么看起来好看,什么感觉真实,你的偏好是什么等等。所以这是100%主观的。如果无人机快速转弯+倾斜并接近下一个航路点,或者如果有很多时间/距离,则以慢速转弯并稍微转弯,并且只有在必要时才快速转弯,这也是您的选择。
自isTurning
起:
当无人机到达某个航路点并前往下一个时,您将其设置为true并且要(转弯和)倾斜的变量设置正确。什么时候设置为false?这取决于你,但目标是在机动完成时这样做(这是第一次出现错误,因为不可能达到这种"最佳状态"),这样无人机就可以"重置银行">
有关正在进行的操作的更多详细信息,请参阅代码注释
同样,这只是一个片段,可以为您的问题提供可能的解决方案。给它一些时间,了解发生了什么。这真的很容易,你只需要一些时间来应对;)
希望这能有所帮助!享受并欢呼!:)