簡體   English   中英

來回旋轉GameObject

[英]Rotate GameObject back and forth

我想在Y軸上將對象在90,-90之間來回旋轉。 問題是我可以在編輯器中將對象設置為-90,但是當我運行項目時,-90突然變成270。無論如何,這是我正在使用的代碼:

void Update()
{
    if (transform.eulerAngles.y >= 270)
    {
        transform.Rotate(Vector3.up * speed * Time.deltaTime);
    }
    else if (transform.eulerAngles.y <= 90)
    {
        transform.Rotate(Vector3.up * -speed * Time.deltaTime);

    }
}

它總是卡在360度左右的中間位置。 救命?

就像來回移動 GameObject一樣,您可以使用Mathf.PingPong來回旋轉Mathf.PingPong 這就是它的用途。 它將返回01之間的值。 您可以將該值傳遞給Vector3.Lerp並生成執行旋轉所需的eulerAngle

這也可以用協程來完成,但是如果您不需要知道何時到達目的地,則應使用Mathf.PingPong 如果您想知道何時到達旋轉目的地,則應使用協程。

public float speed = 0.36f;

Vector3 pointA;
Vector3 pointB;


void Start()
{
    //Get current position then add 90 to its Y axis
    pointA = transform.eulerAngles + new Vector3(0f, 90f, 0f);

    //Get current position then substract -90 to its Y axis
    pointB = transform.eulerAngles + new Vector3(0f, -90f, 0f);
}

void Update()
{
    //PingPong between 0 and 1
    float time = Mathf.PingPong(Time.time * speed, 1);
    transform.eulerAngles = Vector3.Lerp(pointA, pointB, time);
}

編輯:

使用協程方法可以確定每次旋轉的結束。

public GameObject objectToRotate;
public float speed = 0.36f;

Vector3 pointA;
Vector3 pointB;


void Start()
{
    //Get current position then add 90 to its Y axis
    pointA = transform.eulerAngles + new Vector3(0f, 90f, 0f);

    //Get current position then substract -90 to its Y axis
    pointB = transform.eulerAngles + new Vector3(0f, -90f, 0f);

    objectToRotate = this.gameObject;
    StartCoroutine(rotate());
}

IEnumerator rotate()
{
    while (true)
    {
        //Rotate 90
        yield return rotateObject(objectToRotate, pointA, 3f);
        //Rotate -90
        yield return rotateObject(objectToRotate, pointB, 3f);

        //Wait?
        //yield return new WaitForSeconds(3);
    }
}

bool rotating = false;
IEnumerator rotateObject(GameObject gameObjectToMove, Vector3 eulerAngles, float duration)
{
    if (rotating)
    {
        yield break;
    }
    rotating = true;

    Vector3 newRot = gameObjectToMove.transform.eulerAngles + eulerAngles;

    Vector3 currentRot = gameObjectToMove.transform.eulerAngles;

    float counter = 0;
    while (counter < duration)
    {
        counter += Time.deltaTime;
        gameObjectToMove.transform.eulerAngles = Vector3.Lerp(currentRot, newRot, counter / duration);
        yield return null;
    }
    rotating = false;
}

首先,您應始終確保角度保持在0359之間,這意味着0 == 360

float angle = transform.eulerAngles.y % 360.00f;

之后,您可以檢查它是否最小值和最大值之間

if ( angle >= 270.00f &&  angle <= 90.00f )
{
    // do your logic here ...
}

您的代碼的另一個問題是,它將卡在35010度之間的某個位置。 為了更詳細地說明這一點,我們假設您的速度為10Time.deltaTime也將為1 ,起始角度為300 ,現在進行幀步:

 Frame | Angle | Condition 
 ----- | ----- | :-----------:
    1  | 300   | angle >= 270  
    2  | 310   | angle >= 270  
    3  | 320   | angle >= 270  
    6  | 350   | angle >= 270  
    7  | 360   | angle >= 270  
    8  |  10   | angle <= 90   
    9  |   0   | angle <= 90   
   10  | 350   | angle >= 270  

...這將永遠持續下去。

為了解決這個問題,您必須根據用戶輸入來設置一些條件,或者如果您想讓相機在這兩個角度之間“反彈”,則可以嘗試如下操作:

// make private field in that object :
float currentlyRotated = 0;
bool shouldAdd = true;

void Update()
{
    var d = Vector3.up * (shouldAdd ? speed : -speed) * Time.deltaTime;
    var angle = transform.eulerAngles.y + (shouldAdd ? speed : -speed);
    angle %= 360.00f;

    transform.Rotate(d);

    if ( angle > 90 && angle < 270 )
    {
        shouldAdd = !shouldAdd;
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM