简体   繁体   English

旋转时如何在特定程度上更改转换名称?

[英]How can I change transform name at specific degrees while the transform is rotating?

I'm trying to use the ang variable to check the degrees and make the name change. 我正在尝试使用ang变量来检查度数并更改名称。 But it's never get to 180 degrees only close to it. 但是它永远不会接近180度。

I want that while the transform is rotating using the StartCoroutine when the object rotated 180 degrees then make the name change. 我希望当对象旋转180度时使用StartCoroutine旋转变换时,然后更改名称。

Not when the transform is at 180 degrees but after the object rotated 180 degrees then change the name. 不是在变换为180度时,而是在对象旋转180度后,才更改名称。

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

public class OnMouseOverEvent : MonoBehaviour
{
    public float speed = 5f;
    public float distanceToMove = 1f;
    public bool goForward;
    public Vector3 startPos;
    public Vector3 endPos;

    private bool isRotating = false;
    private Vector3 lastFwd;
    private float curAngleX = 0;

    private void Start()
    {
        lastFwd = transform.forward;

        startPos = transform.position;
        endPos = transform.position - Vector3.forward * distanceToMove;
    }

    void Update()
    {
        if (goForward && isRotating == false)
        {
            transform.position = Vector3.MoveTowards(transform.position, endPos, speed * Time.deltaTime);
        }
        else if (isRotating == false)
        {
            transform.position = Vector3.MoveTowards(transform.position, startPos, speed * Time.deltaTime);
        }

        var curFwd = transform.forward;
        // measure the angle rotated since last frame:
        var ang = Vector3.Angle(curFwd, lastFwd);

        if (ang == 180f)
            transform.GetChild(0).GetComponent<TextMesh>().text = "Changed";
    }

    private void OnMouseOver()
    {
        goForward = true;
    }

    private void OnMouseExit()
    {
        goForward = false;
    }

    private void OnMouseDown()
    {
        if (isRotating == false && transform.name == "Options")
            StartCoroutine(Rotate(5));
    }

    IEnumerator Rotate(float duration)
    {
        Quaternion startRot = transform.rotation;
        float t = 0.0f;
        while (t < duration)
        {
            isRotating = true;
            t += Time.deltaTime;

            transform.rotation = startRot * Quaternion.AngleAxis(t / duration * 360f, Vector3.up); //or transform.right if you want it to be locally based

            yield return null;
        }
        transform.rotation = startRot;

        isRotating = false;
    }
}

Update : 更新:

I'm not sure if it's the right solution but this is working : 我不确定这是否是正确的解决方案,但这是可行的:

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

public class OnMouseOverEvent : MonoBehaviour
{
    public float speed = 5f;
    public float distanceToMove = 1f;
    public bool goForward;
    public Vector3 startPos;
    public Vector3 endPos;

    private bool isRotating = false;
    private Vector3 lastFwd;
    private float curAngleX = 0;

    private void Start()
    {
        lastFwd = transform.forward;

        startPos = transform.position;
        endPos = transform.position - Vector3.forward * distanceToMove;
    }

    void Update()
    {
        if (goForward && isRotating == false)
        {
            transform.position = Vector3.MoveTowards(transform.position, endPos, speed * Time.deltaTime);
        }
        else if (isRotating == false)
        {
            transform.position = Vector3.MoveTowards(transform.position, startPos, speed * Time.deltaTime);
        }

        var curFwd = transform.forward;
        // measure the angle rotated since last frame:
        var ang = Vector3.Angle(curFwd, lastFwd);

        if (myApproximation(ang, 110f, 10f) == true)
            transform.GetChild(0).GetComponent<TextMesh>().text = "Changed";
    }

    private bool myApproximation(float a, float b, float tolerance)
    {
        return (Mathf.Abs(a - b) < tolerance);
    }

    private void OnMouseOver()
    {
        goForward = true;
    }

    private void OnMouseExit()
    {
        goForward = false;
    }

    private void OnMouseDown()
    {
        if (isRotating == false && transform.name == "Options")
            StartCoroutine(Rotate(5));
    }

    IEnumerator Rotate(float duration)
    {
        Quaternion startRot = transform.rotation;
        float t = 0.0f;
        while (t < duration)
        {
            isRotating = true;
            t += Time.deltaTime;

            transform.rotation = startRot * Quaternion.AngleAxis(t / duration * 360f, Vector3.up); //or transform.right if you want it to be locally based

            yield return null;
        }
        transform.rotation = startRot;

        isRotating = false;
    }
}

I'm using my own Approximation method (myApproximation) and I also changed back the lines : 我正在使用自己的近似方法(myApproximation),并且还更改了以下几行:

lastFwd = transform.forward;

And

var curFwd = transform.forward;

To be forward it was up 向前挺起来

I think the problem is that you never see 180 is because of comparing floats as someone mentioned in the comments or because you overshoot, and Vector.Angle(float a, float b); 我认为问题是,您从未看到180是因为比较注释中提到的浮点数,或者因为您超调了,而Vector.Angle(float a,float b); is never greater than 180 degrees so things you can try. 永远不会大于180度,因此您可以尝试。

I would try this first: 我会先尝试一下:

if (Mathf.Approximately(ang, 180.0f))
        transform.GetChild(0).GetComponent<TextMesh>().text = "Changed";

If this not works then you should use 如果这不起作用,那么您应该使用

Vector3.SignedAngle(Vector3 from, Vector3 to, Vector3 axis);

DOC . DOC So you will know when you overshoot cos your 181 degrees rotation would become -179. 因此,当您超调cos时,您就会知道181度旋转将变为-179。 Note that the last solution assumes you rotate more then 180 degrees in one frame 请注意,最后一个解决方案假定您在一帧中旋转超过180度

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

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