Quaternion.Lerp вращение часов - PullRequest
0 голосов
/ 25 февраля 2020

Я пытаюсь повернуть стрелку часов на клике, но на самом деле ничего не происходит, ни одна из стрелок на самом деле не движется, поэтому я, вероятно, сделал что-то не так ... любая помощь будет высоко ценится, спасибо

скрипт ниже

public class Clock : MonoBehaviour {

public GameObject minuteHand;
public GameObject hourHand;
private Quaternion targetRotation;
float speed = 0.1f;

void Start()
{
    targetRotation = transform.rotation;
}

void Update()
{
    if (Input.GetMouseButtonDown(0))
    {
        minuteHand.transform.rotation = Quaternion.Lerp(minuteHand.transform.rotation, targetRotation, Time.deltaTime * speed);
    }
} }

1 Ответ

2 голосов
/ 25 февраля 2020

Ваш код выполняется только в одном кадре, когда кнопка мыши нажимается.

Кроме того, Lerp работает не так. Lerp ожидает коэффициент от 0 до 1 и интерполирует оба значения. Если вы умножите свою скорость (0.1) и Time.deltaTime, который для 60FPS имеет значение около 1/60f = 0.017f, вы получите результирующий коэффициент около 0.0017f => Вы всегда будете оставаться довольно близко к первому значению

тем более, что дополнительно ваш targetRotation всегда равен текущему transform.rotation!


Я предполагаю, что вы хотели: Каждый щелчок перемещает на 6 ° вперед (360 ° / 60 минут =) 6 ° / минута).

Как только полный круг закончен, переместите час на 30 ° вперед (360 ° / 12 часов = 30 ° / час)

public class Clock : MonoBehaviour 
{
    public GameObject minuteHand;
    public GameObject hourHand;

    Quaternion originalRotationMinute;
    Quaternion originalRotationHour;

    int minutes;
    int hours;

    // Store original orientations
    void Start()
    {
        originalRotationMinute = minuteHand.transform.rotation;
        originalRotationHour = hourHand.transform.rotation;
    }

    void Update()
    {
        if (Input.GetMouseButtonDown(0))
        {
            // First calculate the new time
            minutes++;
            if(minutes == 60)
            {
                minutes = 0;
                hours++;
                if(hours = 12)
                {
                    hours = 0;
                }
            }

            // Now update the rotations with the new time
            // I'm assuming here you want to rotate around the Z axis
            // if this is not the case change this according to your needs
            var targetMinuteRotation = originalRotationMinute * Quaternion.Euler(0, 0, 6.0f * minutes);
            var targetHourRotation = originalRotationHour * Quaternion.Euler(0, 0, 30.0f * hours);

            minuteHand.transform.rotation = targetMinuteRotation;
            hourHand.transform.rotation = targetHourRotation;
        }
    }
}

Это приведет к тому, что часы «прыгать» к цели вращения. Если вам нужно плавное вращение (что я предполагаю из использования Lerp), я бы, вероятно, использовал для этого Coroutine :

public class Clock : MonoBehaviour 
{
    public GameObject minuteHand;
    public GameObject hourHand;
    float speed = 0.1f;

    Quaternion originalRotationMinute;
    Quaternion originalRotationHour;

    int minutes;
    int hours;

    void Start()
    {
        originalRotationMinute = minuteHand.transform.rotation;
        originalRotationHour = hourHand.transform.rotation;
    }

    void Update()
    {
        if (Input.GetMouseButtonDown(0))
        {
            // cancel the current routines 
            StopAllCoroutines();

            // calculate the new time
            minutes++;
            if(minutes == 60)
            {
                minutes = 0;
                hours++;
                if(hours = 12) hours = 0;
            }

            // I'm assuming here you want to rotate around the Z axis
            // if this is not the case change this according to your needs
            var targetMinuteRotation = originalRotationMinute * Quaternion.Euler(0, 0, 6.0f * minutes);
            var targetHourRotation = originalRotationHour * Quaternion.Euler(0, 0, 30.0f * hours);

            // This time instead of directly setting the values start coroutines
            // to rotate the hands smoothly according to the given speed
            StartCoroutine (RotateTo(minuteHand, targetMinuteRotation));
            StartCoroutine (RotateTo(hourHand, targetHourRotation));
        }
    }

    // rotate the given object to the given target rotation
    // according to the given speed
    private IEnumerator RotateTo(GameObject obj, Quaternion targetRotation)
    {
        var targetTransform = obj.transform;
        var current = targetTransform.rotation;
        // I your are not rotating on the Z axis change this accordingly to your needs
        var difference = targetRotation.eulerAngels.z - current.eulerAngles.z;

        if(Mathf.Approximately(0, difference)) yield break;

       var duration = difference / speed;

       var timePassed = 0f;
       while(timePassed <= duration)
       {
           var factor = timePassed / duration;

           targetTransform.rotation = Quaternion.Lerp(current, targetRotation, factor);

           timePassed += Time.deltaTime;
           yield return null;
       }

       // t be sure set the final rotation once in the end
       targetTransform.rotation = targetRotation;
    }
}

Типизированный на смартфоне, но я надеюсь, что идея проясняется

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...