Как использовать RotateAround для достижения разных скоростных зон по углу - PullRequest
1 голос
/ 17 марта 2020

Я пытаюсь повернуть камеру вокруг определенного объекта. С добавлением, что на некоторой определенной c части поворота, и в течение определенного угла движение должно быть медленным .

Иллюстрированное представление ниже, зеленая зона - зона замедленного движения, красная - применяемая нормальная скорость:

enter image description here

Для достижения это, я использую 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;
    }
}

Моя проблема в том, что на каждом ходу момент замедления движения немного по-другому. Как я могу исправить это, чтобы быть ТОЧНО как угол предложил?

1 Ответ

1 голос
/ 17 марта 2020

Ваш код имеет проблемы с обработкой, когда он превышает 360, он устанавливается точно на 0 вместо соответствующего значения больше 0. Кроме того, вы предполагаете, что скорость вращения должна быть одинаковой для всего кадра на основе раздела кадра начинается с того, что вместо того, чтобы зависеть от того, как рано или поздно в кадре изменяется сечение.

Я бы использовал для этого вложенное значение l oop, которое также учитывало бы, достаточно ли быстра скорость или 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;
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...