【问题标题】:How do i rotate an object multiple times? [duplicate]如何多次旋转对象? [复制]
【发布时间】:2018-06-25 16:10:36
【问题描述】:

所以我试图在按键时旋转一个对象(如果我按“a”向左旋转 90 度,如果我按“d”向右旋转 90 度)。 我无法让它工作,我尝试了一些东西,但我最终没有解决问题。正如您将在下一个示例中看到的那样,我只知道如何旋转到 90 度,而不是或多或少,我实际上想将对象旋转 90 度,从当前打开的度数开始。例如: 从90度到180度 从23度到113度等等…… 这是我的代码:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class ModuleBehaviour : MonoBehaviour {

    public bool rotating = false;


    private void Update()
    {
        if (rotating)
        {
            RotatePlatform();
        }
    }

    private void RotatePlatform()
    {
        Vector3 target = new Vector3(0,0,90);
        if (transform.eulerAngles.z > 90)
        {
            transform.rotation = Quaternion.Euler(target);

        }
        transform.Rotate(target * Time.deltaTime);
    }
}

(不要担心rotating 变量,我正在另一个脚本中更改它,只要我按下“d”键就可以了。我只需要知道如何朝正确的方向旋转,之后我会弄清楚如何申请左轮换)

谢谢;

【问题讨论】:

  • 协程 + Lerp。从副本中的 INCREMENTAL ANGULAR ROTATION: 中阅读,您将看到如何将对象从其已经处于的任何角度旋转 90 度。

标签: c# unity3d


【解决方案1】:

这会做你想做的事:

private IEnumerator RotatePlatform(float dir) {
    Vector3 target = new Vector3(0, 0, (transform.eulerAngles.z + dir + 360) % 360);
    while(Mathf.Abs(transform.eulerAngles.z - target.z) >= Mathf.Abs(dir * Time.deltaTime * 2)) {
        transform.Rotate(new Vector3(0,0,dir) * Time.deltaTime);
        yield return null;
    }
    transform.eulerAngles = target;
    rotating = false;
}

要从中删除的关键是我将“使其动画化”代码封装到协程中,以便对象从 any 开始旋转到任何 向任一方向 旋转。这样做的原因是协程的局部变量在迭代之间保持其状态(Unity 计划任务系统将停止执行 yield 指令上的代码并在稍后恢复:在这种情况下,null 意味着它将恢复在下一帧)。这样我们就可以存储起始旋转和目标旋转,而无需做任何疯狂的事情。

它通过获取当前旋转,添加旋转量,然后使该值位于 0-360 之间:transform.eulerAngles.z + dir + 360) % 360transform.eulerAngles.z 已经是 [0,360],减去 90 会留下 [-90,270],然后通过添加 360,我们确保该值将始终大于 0(不影响结果角度) , 然后% 360 有效地减去任何多余的 360。

Mathf.Abs(transform.eulerAngles.z - target.z) >= Mathf.Abs(dir * Time.deltaTime * 2) 语句检查“我们尚未旋转的距离”是否“大于我们将要旋转的量”并带有一些缓冲区:我们不想过冲并有我们的“我们需要走多远”是 358 度!

另一个重要的变化是我们希望使用new Vector3(0,0,dir) 而不是target 作为我们的值来旋转,这样速度就保持不变。

最后 2 条指令确保旋转实际上达到了预期值,当然,切换回 bool 跟踪是否按键是否执行任何操作(我们只需要 1 个协程实例)。

那么这里是我用来控制它的Update()方法:

private void Update() {
    if(!rotating) {
        if(Input.GetKeyDown(KeyCode.D)) {
            rotating = true;
            StartCoroutine(RotatePlatform(90));
        }
        if(Input.GetKeyDown(KeyCode.A)) {
            rotating = true;
            StartCoroutine(RotatePlatform(-90));
        }
    }
}

【讨论】:

  • 谢谢!我修改了代码以满足我的需要,它就像一个魅力!算法很完美!
【解决方案2】:

要向另一个方向旋转,减去 90。

void Update()
{
    if (Input.GetKeyDown(KeyCode.D))
        transform.Rotate(0, 0, transform.rotation.z + 90);
}

【讨论】:

  • 是的,我知道,但我不想那样旋转它,我不想知道之前的角度,我只想将对象从它已经存在的角度旋转 90 度在...
  • 这会将它从 90 度旋转到任何位置。
猜你喜欢
  • 1970-01-01
  • 2019-07-15
  • 1970-01-01
  • 2016-08-27
  • 1970-01-01
  • 2017-12-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多