首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Quaternion.Lerp时钟旋转

Quaternion.Lerp时钟旋转
EN

Stack Overflow用户
提问于 2020-02-25 12:39:50
回答 2查看 135关注 0票数 0

我试图在点击时旋转时钟的指针,但实际上没有发生任何事情,没有任何箭头实际移动,所以我可能做错了什么……如有任何帮助将不胜感激,谢谢

下面的脚本

代码语言:javascript
复制
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);
    }
} }
EN

回答 2

Stack Overflow用户

发布于 2020-02-25 14:27:48

当鼠标按键按下时,您的代码只能在一个单独的帧中执行。

此外,这也不是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°/小时)

代码语言:javascript
复制
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

代码语言:javascript
复制
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;
    }
}

在智能手机上输入,但我希望我的想法变得清晰

票数 2
EN

Stack Overflow用户

发布于 2021-04-19 00:11:18

对我来说只有这行得通。你不能通过修改速度来使它变得更慢,但它看起来很好(可能会对某些人有帮助)

代码语言:javascript
复制
float speed = 0.1f //how fast rotate
private void FixedUpdate()
    {
        nextRot = hour * -30;
        transform.rotation = Quaternion.Lerp(transform.rotation, Quaternion.Euler(0, 0, nextRot), speed);
     
    }
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/60387603

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档