如何使用RotateAround按角度实现不同速度区
How to use RotateAround to achieve different speed zones by angle
我正在尝试围绕特定对象旋转相机。
再加上在旋转的某个特定部位,在某个角度的时候,动作要慢。
如下图所示,绿色区域是慢动作区域,红色区域是应用的正常速度:
为此,我使用了 Transform.RotateAround(Vector3 point, Vector3 axis, float angle)
方法
所以,猜测慢速是原速度的一半,angleOfSlowMotionZone如图所示为90º,我做如下:
计算相机到达慢区(绿色)所需的时间为:
timeToArriveToSlowZone = (270 - (angleOfSlowMotionZone / 2)) / speed;
计算结束慢区所需时间:
timeToEndSlowZone = angleOfSlowMotionZone / slowSpeed;
最后计算完成整个转机的时间:
timeToFullTurn = timeToArriveToSlowZone + timeToEndSlowZone;
然后我调用一个协程来做这样的运动:
IEnumerator Rotation()
{
second = 0;
while(true)
{
second += Time.deltaTime;
if(second >= timeToFullTurn)
second = 0;
newSpeed = (second <= timeToArriveToSlowZone || second >= timeToArriveToSlowZone + timeToEndSlowZone) ? speed : slowSpeed;
transform.RotateAround(targetGO.transform.position, Vector3.up, newSpeed * Time.deltaTime);
yield return null;
}
}
我的问题是,在每个回合中,减速运动的时刻都有些不同。我怎样才能按照建议的角度将其固定为 EXACTLY?
当超过 360 时,您的代码在处理时出现问题,它被精确设置为 0,而不是适当的大于 0 的值。此外,您假设基于部分的整个帧的旋转速度应该相同框架开始于,而不是依赖于该部分更改到框架的早晚时间。
我会为此使用嵌套的 while 循环,这也会考虑速度是否足够快或 deltaTime 是否足够大以在同一帧中多次更改部分。评论中的解释:
IEnumerator Rotation(float startAngle)
{
// parameters - could be fields
float baseMoveSpeed = 90f;
float slowMoveSpeed = 45f;
float slowMoveAngle = 90f;
float angleAtStartOfFrame = startAngle;
while(true)
{
float timeLeft = Time.deltaTime;
float newAngle = angleAtStartOfFrame;
// Travel through sections until time this frame is accounted for
while (timeLeft > 0)
{
float speed;
float curRegionRemaining;
// assume slow move region is from newAngle=0 to newAngle=slowMoveAngle
if (newAngle < slowMoveAngle)
{
speed = slowMoveSpeed;
curRegionRemaining = slowMoveAngle - newAngle;
}
else
{
speed = baseMoveSpeed;
curRegionRemaining = 360f - newAngle;
}
// travel to end of current region or as much as you can
// travel with remaining time
float angleTraveledThisSection = Mathf.Min(timeLeft * speed,
curRegionRemaining);
// how much time did that use?
float timeUsedThisSection = angleTraveledThisSection / speed;
// how much time is left to travel this frame?
timeLeft -= timeUsedThisSection;
// sum up how much travel has done
newAngle = Mathf.Repeat(newAngle + angleTraveledThisSection, 360f);
}
transform.RotateAround(targetGO.transform.position, Vector3.up,
newAngle - angleAtStartOfFrame);
angleAtStartOfFrame = newAngle;
yield return null;
}
}
我正在尝试围绕特定对象旋转相机。 再加上在旋转的某个特定部位,在某个角度的时候,动作要慢。
如下图所示,绿色区域是慢动作区域,红色区域是应用的正常速度:
为此,我使用了 Transform.RotateAround(Vector3 point, Vector3 axis, float angle)
方法
所以,猜测慢速是原速度的一半,angleOfSlowMotionZone如图所示为90º,我做如下:
计算相机到达慢区(绿色)所需的时间为:
timeToArriveToSlowZone = (270 - (angleOfSlowMotionZone / 2)) / speed;
计算结束慢区所需时间:
timeToEndSlowZone = angleOfSlowMotionZone / slowSpeed;
最后计算完成整个转机的时间:
timeToFullTurn = timeToArriveToSlowZone + timeToEndSlowZone;
然后我调用一个协程来做这样的运动:
IEnumerator Rotation()
{
second = 0;
while(true)
{
second += Time.deltaTime;
if(second >= timeToFullTurn)
second = 0;
newSpeed = (second <= timeToArriveToSlowZone || second >= timeToArriveToSlowZone + timeToEndSlowZone) ? speed : slowSpeed;
transform.RotateAround(targetGO.transform.position, Vector3.up, newSpeed * Time.deltaTime);
yield return null;
}
}
我的问题是,在每个回合中,减速运动的时刻都有些不同。我怎样才能按照建议的角度将其固定为 EXACTLY?
当超过 360 时,您的代码在处理时出现问题,它被精确设置为 0,而不是适当的大于 0 的值。此外,您假设基于部分的整个帧的旋转速度应该相同框架开始于,而不是依赖于该部分更改到框架的早晚时间。
我会为此使用嵌套的 while 循环,这也会考虑速度是否足够快或 deltaTime 是否足够大以在同一帧中多次更改部分。评论中的解释:
IEnumerator Rotation(float startAngle)
{
// parameters - could be fields
float baseMoveSpeed = 90f;
float slowMoveSpeed = 45f;
float slowMoveAngle = 90f;
float angleAtStartOfFrame = startAngle;
while(true)
{
float timeLeft = Time.deltaTime;
float newAngle = angleAtStartOfFrame;
// Travel through sections until time this frame is accounted for
while (timeLeft > 0)
{
float speed;
float curRegionRemaining;
// assume slow move region is from newAngle=0 to newAngle=slowMoveAngle
if (newAngle < slowMoveAngle)
{
speed = slowMoveSpeed;
curRegionRemaining = slowMoveAngle - newAngle;
}
else
{
speed = baseMoveSpeed;
curRegionRemaining = 360f - newAngle;
}
// travel to end of current region or as much as you can
// travel with remaining time
float angleTraveledThisSection = Mathf.Min(timeLeft * speed,
curRegionRemaining);
// how much time did that use?
float timeUsedThisSection = angleTraveledThisSection / speed;
// how much time is left to travel this frame?
timeLeft -= timeUsedThisSection;
// sum up how much travel has done
newAngle = Mathf.Repeat(newAngle + angleTraveledThisSection, 360f);
}
transform.RotateAround(targetGO.transform.position, Vector3.up,
newAngle - angleAtStartOfFrame);
angleAtStartOfFrame = newAngle;
yield return null;
}
}