我有一架无人机跟随一条移动路径。也就是说,它不使用刚体,因此我无法获得速度或幅度等。它遵循路径就好了,但我想在向左或向右转时添加银行。我在无人机前面使用一个虚拟物体,以为我可以使用来自两个物体的变换矢量来计算倾斜/倾斜量。
由于我没有很多数学技能,因此我一直在研究这个问题。基本上我一直在复制代码试图让事情发挥作用。我没做什么工作来制造无人机银行。以下代码设法旋转(而不是银行)。
// 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;
}
答案 0 :(得分:1)
假设您有无人机跟随的航路点,您应该计算出最后两个之间的角度(即您的“现在面向”和“将面向”方向)。简单的方法是使用Vector2.Angle
我会用这个角度来确定我将无人机的身体倾斜的数量:转弯越尖锐,银行越难。我会使用一个比率值(最初 public,所以我可以从编辑器中操作它)
接下来,我不依赖引擎为我做轮换 - 所以我会选择Transform.Rotate功能。
如果银行业务太高而且看起来很傻,我会设置最大值和Clamp我计算的归零角度在零和最大之间
如果不确切知道你做了什么以及如何做,那么提供完美的代码并不容易,但为了更好地理解上述内容,这里有一些(未经测试的,即伪的)代码,我想象的解决方案:
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:
}
同样,这段代码可能不完全符合您的需求(或编译:P),因此专注于想法和方法,而不是代码本身。很抱歉因为现在无法将某些东西放在一起并测试自己 - 但我希望我帮助过。干杯!
编辑:我试图用代码回答你的问题而不是文本墙(仍然不完美,但目标不是做这个工作,而是帮助一些片段和想法:)
所以。基本上,你拥有的是两个航路点之间的距离和“角度”。这个距离和无人机的飞行/步行/任何速度(我不知道)是最大可用时间:
1。转弯,所以无人机将面向新的方向
2. 银行到一边,然后回到零/“正常”
由于在银行方面的行动要多两倍,要么必须更快(bankSpeed
),要么以更小的角度(turnBankRatio
),或两者兼而有之,这取决于看起来不错和感觉真实的东西,你的偏好是什么,等等。所以它是100%主观的。如果无人机快速转向+银行并接近下一个航路点,或者做得很慢,如果有很多时间/距离则转动一点,并且只有在必要时才能快速行动,这也是你的号召。
截至isTurning
:
当无人机到达航路点并前往下一个 AND 变量到(转弯和)银行设置正确时,您将其设置为true。当你把它设置为假?这取决于你,但目标是在机动结束时这样做(这是第一次在片段中出现错误,因为无法达到这种“最佳状态”)所以无人机可以“重置银行业务”。
有关正在进行的操作的更多详细信息,请参阅代码注释。
同样,这只是一个代码段,可以为您提供可能的问题解决方案。给它一些时间,了解发生了什么。这真的很容易,你只需要一些时间来应对;)
希望这有帮助!享受和欢呼! :)