计算两个对象之间的倾斜角度



我有一架无人机在跟踪一条移动路径。也就是说,它不使用刚体,所以我无法获得速度或大小等。它沿着这条路走得很好,但我想在它向左或向右转弯时添加银行业务。我在无人机前面使用了一个虚拟对象,认为我可以使用这两个对象的变换向量来计算倾斜/倾斜量。

我已经做了好几天了,因为我没有太多的数学技能。基本上,我一直在复制代码片段,试图让事情正常工作。我所做的一切都无法使无人机成为银行。下面的代码设法旋转(而不是银行)。

// 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?这取决于你,但目标是在机动完成时这样做(这是第一次出现错误,因为不可能达到这种"最佳状态"),这样无人机就可以"重置银行">
有关正在进行的操作的更多详细信息,请参阅代码注释
同样,这只是一个片段,可以为您的问题提供可能的解决方案。给它一些时间,了解发生了什么。这真的很容易,你只需要一些时间来应对;)

希望这能有所帮助!享受并欢呼!:)

最新更新