C# 当角色在y轴上达到0时,如何停止角色旋转?

C# 当角色在y轴上达到0时,如何停止角色旋转?,c#,unity3d,C#,Unity3d,两个字符都以欧拉角0f、180f、0f的局部旋转开始。 我希望它们在Y轴上旋转到0,然后停止。尝试使用标志,但我猜比较浮动是错误的。我应该使用StartCustomer吗 我尝试使用时间线制作动画剪辑,但一旦我创建了一个新的动画轨迹,并出于某种原因拖动其中一个角色,它就会改变角色的位置,并且它的武器没有连接到他。不知道为什么时间线会出现这种情况。比较浮动没有什么错,只是要知道精度-基本上不可能精确地在0处停止。但你能做的是,当它非常接近时停止,然后再调整。例如: using System.Col

两个字符都以欧拉角0f、180f、0f的局部旋转开始。 我希望它们在Y轴上旋转到0,然后停止。尝试使用标志,但我猜比较浮动是错误的。我应该使用StartCustomer吗


我尝试使用时间线制作动画剪辑,但一旦我创建了一个新的动画轨迹,并出于某种原因拖动其中一个角色,它就会改变角色的位置,并且它的武器没有连接到他。不知道为什么时间线会出现这种情况。

比较浮动没有什么错,只是要知道精度-基本上不可能精确地在0处停止。但你能做的是,当它非常接近时停止,然后再调整。例如:

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

public class AnimatorController : MonoBehaviour
{
    public Animator[] animators;
    public Transform target;
    public float speed = 1f;
    public float rotationSpeed;

    private bool endRot = false;

    // Use this for initialization
    void Start()
    {
        for (int i = 0; i < animators.Length; i++)
        {
            animators[i].SetFloat("Walking Speed", speed);
        }
    }

    // Update is called once per frame
    void Update()
    {
        float distanceFromTarget = Vector3.Distance(animators[2].transform.position, target.position);
        if (distanceFromTarget < 15)
        {
            float speed = (distanceFromTarget / 15) / 1;
            for (int i = 0; i < animators.Length; i++)
            {
                animators[i].SetFloat("Walking Speed", speed);
            }
        }

        if (distanceFromTarget < 2f)
        {
            for (int i = 0; i < animators.Length; i++)
            {
                animators[i].SetFloat("Walking Speed", 0);
            }

            if (animators[0].transform.localRotation.y != 0 && endRot == false)
            {
                animators[0].transform.Rotate(Vector3.up, rotationSpeed * Time.deltaTime);
                animators[1].transform.Rotate(Vector3.up, -rotationSpeed * Time.deltaTime);
            }

            if (animators[0].transform.localRotation.y == 0)
                endRot = true;
        }
    }
}
然后有:

if (animators[0].transform.localRotation.y >= 0.1f && endRot == false)

根据旋转速度的不同,您可能需要调整边距,使其停止旋转的点与0之间几乎没有差异。

比较浮动没有错,您只需要知道精度-基本上不可能精确地停止在0。但你能做的是,当它非常接近时停止,然后再调整。例如:

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

public class AnimatorController : MonoBehaviour
{
    public Animator[] animators;
    public Transform target;
    public float speed = 1f;
    public float rotationSpeed;

    private bool endRot = false;

    // Use this for initialization
    void Start()
    {
        for (int i = 0; i < animators.Length; i++)
        {
            animators[i].SetFloat("Walking Speed", speed);
        }
    }

    // Update is called once per frame
    void Update()
    {
        float distanceFromTarget = Vector3.Distance(animators[2].transform.position, target.position);
        if (distanceFromTarget < 15)
        {
            float speed = (distanceFromTarget / 15) / 1;
            for (int i = 0; i < animators.Length; i++)
            {
                animators[i].SetFloat("Walking Speed", speed);
            }
        }

        if (distanceFromTarget < 2f)
        {
            for (int i = 0; i < animators.Length; i++)
            {
                animators[i].SetFloat("Walking Speed", 0);
            }

            if (animators[0].transform.localRotation.y != 0 && endRot == false)
            {
                animators[0].transform.Rotate(Vector3.up, rotationSpeed * Time.deltaTime);
                animators[1].transform.Rotate(Vector3.up, -rotationSpeed * Time.deltaTime);
            }

            if (animators[0].transform.localRotation.y == 0)
                endRot = true;
        }
    }
}
然后有:

if (animators[0].transform.localRotation.y >= 0.1f && endRot == false)

根据旋转速度的不同,您可能需要调整边距,使其停止旋转的点与0之间几乎没有差异。

您需要夹紧旋转,以便在单个旋转帧内不会超调。这里有一种方法可以做到这一点

设置目标轮换:

if (animators[0].transform.localRotation.y <= 0.1f)
{
    endRot = true;
    // set y to zero, keep x and z rotation the same.
    animators[0].transform.localRotation = Quaternion.Euler(animators[0].transform.localEulerAngles.x, 0, animators[0].transform.localEulerAngles.z);
}
查找第一个变换的旋转距离(以度为单位):

Quaternion goalRotation = Quaternion.Euler(0f,0f,0f); // or Quaternion.identity
确定哪一个更小:速度*增量时间给出的角度或剩余角度,以确定您应该旋转此帧多远。这是重要的夹紧部件:

然后,旋转该数量。如果确实按角度旋转,则设置endRot=true

这可能是这样的:

float angleThisFrame = Mathf.Min(angleToGoal, rotationSpeed * Time.deltaTime);

您需要夹紧旋转,以便在单个旋转帧内不会超调。这里有一种方法可以做到这一点

设置目标轮换:

if (animators[0].transform.localRotation.y <= 0.1f)
{
    endRot = true;
    // set y to zero, keep x and z rotation the same.
    animators[0].transform.localRotation = Quaternion.Euler(animators[0].transform.localEulerAngles.x, 0, animators[0].transform.localEulerAngles.z);
}
查找第一个变换的旋转距离(以度为单位):

Quaternion goalRotation = Quaternion.Euler(0f,0f,0f); // or Quaternion.identity
确定哪一个更小:速度*增量时间给出的角度或剩余角度,以确定您应该旋转此帧多远。这是重要的夹紧部件:

然后,旋转该数量。如果确实按角度旋转,则设置endRot=true

这可能是这样的:

float angleThisFrame = Mathf.Min(angleToGoal, rotationSpeed * Time.deltaTime);

这并不能防止它超调,当它超调时,旋转不会停止。例如,如果它超调2度,使得localRotation.y==358f,那么它将继续旋转。正确,它不会阻止超调。但是如果它从>0向下旋转过零,localrotation将变为负值并停止旋转。只是测试了一下以确定。为了防止超调,您可以将原始旋转调整为零,然后调整。但这显然需要您更改旋转的方式。我很确定,要获得与编辑器中显示的完全相同的euler角度值,唯一的方法是使用内部GetLocalEulerAngles方法。测试时,您是在代码中读取localRotation.y的输出,还是只是在查看检查器中的值?这些可能是非常不同的值。我使用了相同的旋转方法,并将localrotation.y的值打印到控制台,该值与正在检查以停止旋转的值相同。我明白了原因。出于某种原因,我认为这是在比较欧拉角分量y。但实际上,它是将旋转的四元数表示的y分量与0进行比较,所以我可以看到它的工作方式不同。这并不能防止它超调,当它超调时,旋转不会停止。例如,如果它超调2度,使得localRotation.y==358f,那么它将继续旋转。正确,它不会阻止超调。但是如果它从>0向下旋转过零,localrotation将变为负值并停止旋转。只是测试了一下以确定。为了防止超调,您可以将原始旋转调整为零,然后调整。但这显然需要您更改旋转的方式。我很确定,要获得与编辑器中显示的完全相同的euler角度值,唯一的方法是使用内部GetLocalEulerAngles方法。测试时,您是在代码中读取localRotation.y的输出,还是只是在查看检查器中的值?这些可能是非常不同的值。我使用了相同的旋转方法,并将localrotation.y的值打印到控制台,该值与正在检查以停止旋转的值相同。我明白了原因。出于某种原因,我认为这是在比较欧拉角分量y。但实际上,它是将旋转的四元数表示的y分量与0进行比较,所以我可以看到它的工作方式不同。这是可行的,但这是我在我的原始版本中提出问题的原因
我使用的代码是:Vector3.up,rotationSpeed和Vector3.up,-rotationSpeed加上一个负号是我希望其中一个字符向右旋转,一个向左旋转,两个字符都向里旋转。现在它们都向左或向左旋转。@DubiDuboni我现在明白了。我将第二个改为使用Vector3.up使其朝另一个方向旋转。试试看。这是可行的,但我在我的原始代码中使用的问题的原因是:Vector3.up,rotationSpeed和Vector3.up,-rotationSpeed加上一个负号是,我希望其中一个字符向右旋转,一个向左旋转,两个都向里旋转。现在它们都向左或向左旋转。@DubiDuboni我现在明白了。我将第二个改为使用Vector3.up使其朝另一个方向旋转。试试看。