简体   繁体   English

如何使用多个枚举(两个枚举)来控制对象同时旋转的两个轴?

[英]How can I use multiple enums (two enums) to control two axis the object will rotate at the same time?

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

public class Rotate : MonoBehaviour
{
    public enum Axistorotate { Back, Down, Forward, Left, Right, Up, Zero };
    public Vector3[] vectorAxises = new Vector3[7];

    public Axistorotate[] myAxis;
    public float angle;
    public float speed;

    private bool stopRotation = true;

    // Start is called before the first frame update
    void Start()
    {
        vectorAxises[0] = Vector3.back;
        vectorAxises[1] = Vector3.down;
        vectorAxises[2] = Vector3.forward;
        vectorAxises[3] = Vector3.left;
        vectorAxises[4] = Vector3.right;
        vectorAxises[5] = Vector3.up;
        vectorAxises[6] = Vector3.zero;

        StartCoroutine(RotateObject());
    }

    public Vector3 GetAxis(Axistorotate axis)
    {
        return vectorAxises[(int)axis];
    }

    // Update is called once per frame
    void Update()
    {
        if(Input.GetKeyDown(KeyCode.S))
        {
            stopRotation = false;
        }

        if (Input.GetKeyDown(KeyCode.C) && stopRotation == false)
        {
            stopRotation = true;
            StartCoroutine(RotateObject());
        }
    }

    IEnumerator RotateObject()
    {
        while (stopRotation == true)
        {
            for (int i = 0; i < myAxis.Length; i++)
            {
                transform.Rotate(GetAxis(myAxis[i]), angle);
            }
            yield return new WaitForSeconds(speed);
        }
    }
}

For some reason while the game is running and I'm changing one of the enums to forward or back or down each time it's rotating another direction. 由于某种原因,在游戏运行时,我将每个枚举旋转另一个方向时都将其枚举向前或向后或向下移动。 If I'm starting when both enums on back states and then changing one of them to down it looks like it's rotating to the left or right and then when changing back to back it's not rotating like it was when they were both set to back. 如果我开始时两个枚举都处于后退状态,然后将它们中的一个更改为向下,则看起来好像是在向左或向右旋转,然后当更改为后退时,它并没有像将它们都设置为后退时那样旋转。

How can I update the vectorAxises array in real time while the game is running to show in the Inspector the current axis state for example : vectorAxises[0] -> 1, 0, -1 ..... vectorAxises[7] -> 0,-1, 0 I want that when I'm changing one of the enums that it will show it on the vectorAxises. 如何在游戏运行时实时更新vectorAxises数组以在检查器中显示当前轴状态,例如: vectorAxises[0] -> 1, 0, -1 ..... vectorAxises[7] -> 0,-1, 0我想要当我更改一个枚举时将其显示在vectorAxises上。

Maybe I need to create another vectorAxises array one for each enum ? 也许我需要为每个枚举创建另一个vectorAxises数组?

And maybe when doing two myAxis it's changing the same one the same angle so it's not realy two enums that change individual axis ? 也许当执行两个myAxis它会以相同的角度更改相同的一个,因此改变单个轴的两个枚举不是真的吗?

Use Quaternions for multiple rotations at the same time: 同时使用四元数进行多次旋转:

Quaternion rotationQuaternion = Quaternion.identity;
for (int i = 0; i < myAxis.Length; i++)
{
    rotationQuaternion *= Quaternion.AngleAxis(angle, GetAxis(myAxis[i]));
}
transform.rotation *= rotationQuaternion;

It should fix your problem with wrong rotations 旋转错误应该可以解决您的问题

transform.Rotate has an optional parameter transform.Rotate有一个可选参数

relativeTo 关系到
Determines whether to rotate the GameObject either locally to the GameObject or relative to the Scene in world space. 确定是将GameObject局部旋转到GameObject还是相对于世界空间中的Scene旋转。

which by default is Space.Self . 默认情况下是Space.Self

So your 所以你

transform.Rotate(GetAxis(myAxis[i]), angle);

is always done in the local coordinate system of the GameObject. 总是在GameObject的局部坐标系中完成。 This local system is rotated along with the GameObject so the local transform.up , transform.forward etc axis change all the time. 该本地系统与GameObject一起旋转,因此本地transform.uptransform.forward等轴始终在变化。


Instead make it rotate around world axis 而是使其绕世界轴旋转

transform.Rotate(GetAxis(myAxis[i]), angle, Space.World);

How can I update the vectorAxises array in real time while the game is running to show in the Inspector the current axis state 如何在游戏运行时实时更新vectorAxises数组以在Inspector中显示当前轴状态

This should already be the case. 情况应该已经如此。 Or do you mean you want to see the currently "selected" value. 或者您是说要查看当前的“选定”值。 You should use Debugging and Breakpoints for that. 您应该为此使用调试和断点。 Since you do 既然你做

for (int i = 0; i < myAxis.Length; i++)
{
    transform.Rotate(GetAxis(myAxis[i]), angle);
}

without any further yield return the object will directly "jump" into the new rotation and in the inspector you would always only see the last GetAxis(myAxis[i]) . 没有任何进一步的yield return ,对象将直接“跳入”新的旋转,在检查器中,您始终只会看到最后一个GetAxis(myAxis[i])

If you are looking for a smooth rotation then checkout Dest's answer slightly modified you could eg let the object rotate within 1 second 如果您希望平滑旋转,请稍稍修改一下目标的答案 ,例如可以让对象在1秒钟内旋转

while (stopRotation == true)
{
    // calculate the target rotation
    Quaternion rotationQuaternion = Quaternion.identity;
    for (int i = 0; i < myAxis.Length; i++)
    {
        rotationQuaternion *= Quaternion.AngleAxis(angle, GetAxis(myAxis[i]));
    }

    // before starting to rotate store initial and target rotation
    var initialRotation = transform.rotation;
    var targetRotation = initialRotation * rotationQuaternion;

    // could also get this from the Inspector e.g.
    var rotationDuration = 1;

    // Do a smooth rotation from the initial to target rotation
    // within the defined rotationDuration 
    var timePassed = 0f;
    do
    {
        // additionally ease-in and -out the rotation
        var lerpFactor = Mathf.SmoothStep(0, 1, timePassed / rotationDuration);
        transform.rotation = Quaternion.Slerp(initialRotation, targetRotation, lerpFactor);

        timePassed += Time.deltaTime;

        // let this state be rendered
        yield return null;
    } while(timePassed < rotationDuration);

    // if you still want the pause 
    yield return new WaitForSeconds(speed);
}

Just out of curiosity: Why even use an enum here? 出于好奇:为什么还要在此处使用enum Couldn't you directly iterate through the vectorAxises index instead and only add those entries you will be using? 您不能直接遍历vectorAxises索引,而仅添加将要使用的那些条目吗?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM