如何使用RotateAround按角度实现不同速度区

How to use RotateAround to achieve different speed zones by angle

我正在尝试围绕特定对象旋转相机。 再加上在旋转的某个特定部位,在某个角度的时候,动作要慢

如下图所示,绿色区域是慢动作区域,红色区域是应用的正常速度:

为此,我使用了 Transform.RotateAround(Vector3 point, Vector3 axis, float angle) 方法

所以,猜测慢速是原速度的一半,angleOfSlowMotionZone如图所示为90º,我做如下:

然后我调用一个协程来做这样的运动:

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;
    }
}