2 votes

Faire tourner le GameObject d'avant en arrière

Je voudrais faire pivoter un objet d'avant en arrière entre 90,-90 sur l'axe Y. Le problème est que je peux définir l'objet dans l'éditeur à -90, mais lorsque je lance le projet, -90 devient soudainement 270. Voici donc le code que j'utilise :

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);

    }
}

Il reste toujours coincé au milieu à environ 360 degrés. Comment faire ?

2voto

Programmer Points 69203

Tout comme déménagement GameObject d'avant en arrière, vous pouvez faire pivoter GameObject d'avant en arrière avec Mathf.PingPong . C'est à cela qu'il sert. Il retournera une valeur comprise entre 0 y 1 . Vous pouvez transmettre cette valeur à Vector3.Lerp et générer le Angle d'euler nécessaire pour effectuer la rotation.

Cela peut également être fait avec une coroutine mais Mathf.PingPong doit être utilisé si vous n'avez pas besoin de savoir quand vous avez atteint la destination. La coroutine doit être utilisée si vous voulez savoir quand vous avez atteint la destination de la rotation.

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);
}

EDIT :

Avec le coroutine que vous pouvez utiliser pour déterminer la fin de chaque rotation.

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;
}

1voto

Mateusz Points 5130

Tout d'abord, vous devez toujours vous assurer que l'angle reste entre 0 y 359 ce qui signifie que 0 == 360 :

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

Après cela, vous pouvez vérifier si c'est entre votre valeur minimale et maximale :

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

Un autre problème avec votre code est qu'il sera coincé quelque part entre 350 y 10 degrés. Pour expliquer cela plus en détail, supposons que votre vitesse est de 10 , Time.deltaTime sera 1 ainsi que l'angle de départ est 300 , maintenant les étapes du cadre :

 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  

... et cela durera toujours.

Pour gérer cela, vous devez créer des conditions basées sur l'entrée de l'utilisateur ou si vous voulez que votre caméra "rebondisse" entre ces deux angles, vous pouvez essayer quelque chose comme ceci :

// 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;
    }
}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X