2
votes

Comment pouvez-vous vérifier si l'objet bouge / ne bouge pas?

Je veux créer un script simple qui, lorsque vous cliquerez sur l'écran, la balle dans le jeu se déplacera (20000 * Time.deltaTime) vers la droite, puis si je clique à nouveau, elle se déplacera vers le côté gauche et puis à droite et ainsi de suite.

J'ai réussi à faire bouger le ballon vers la droite, mais je dois attendre que l'animation soit terminée car je dois vérifier si le joueur a cliqué à nouveau vérifier dans quelle direction déplacer la balle). J'ai essayé de nombreuses méthodes que j'ai trouvées en ligne, comme vérifier si Rigidbody.velocity.magnitude == 0.0f cela signifie que la balle ne bouge pas ..

void Update()
{
    if (Input.GetMouseButtonDown(0))
    {
        rb.AddForce(20000 * Time.deltaTime, 0, 0); // moving ball to the right
        if(rb.velocity.magnitude < 0.05f) // if i click the ball it just prints it and not wating for the ball to not move
        {
            Debug.Log(PlayerPosition.position.x);
        }
    }
}

Et voici mon dernier essai:

public Rigidbody rb;
public Transform PlayerPosition;
// Start is called before the first frame update
void Start()
{

}

// Update is called once per frame
void Update()
{
    if (Input.GetMouseButtonDown(0))
    {
        rb.AddForce(20000 * Time.deltaTime, 0, 0); // moving ball to the right
        while (rb.velocity.magnitude != 0.0f) // I tried to check until the ball is not moving 
        {

        }
        Debug.Log(PlayerPosition.position.x);
    }
}

Je m'attendais à ce que la sortie attende la fin de l'animation, mais à la place, elle imprimera le vaule (x) au moment où je clique sur la souris.


0 commentaires

3 Réponses :


3
votes

Modifier

Vous devez vérifier si votre animation est toujours en cours de lecture. Vous vérifiez uniquement si votre vitesse est supérieure à 0,05f, ce qui imprime correctement l'instruction.

Utilisez Animation.IsPlaying (nom de la chaîne) . Une mise en garde est que cette méthode retournera false pour la même image de Update qu'elle a été invoquée, car l'animation n'a techniquement commencé qu'après.

XXX


Original

Vous ne devriez pas avoir besoin d'utiliser while dans votre méthode Update . p >

Utilisez une instruction if à l'intérieur de votre Update

void Update()
{
    if (rb.velocity.magnitude > 0.01f) Debug.Log("We're moving!");
}

9 commentaires

J'obtiens cette erreur: l'opérateur «>» ne peut pas être appliqué aux opérandes de type «Vector3»


J'ai mis à jour la réponse pour utiliser rb.velocity.magnitude à la place pour obtenir le float


donc pour vérifier s'il ne bouge pas, faites si (rb.velocity.magnitude! = 0)?


«Magnitude» en vertu est un nombre absolu. Je voudrais juste vérifier si c'est > 0 plutôt que ! = 0 , car float ne sera presque jamais 0. Ils finissent par être quelque chose comme 0,000001


Vous pouvez également utiliser Mathf.Approximately pour déterminer votre égalité de flotteur


vous pouvez simplement vérifier si la magnitude est inférieure à une petite valeur par exemple 0,05 comme ceci rb.velocity.magnitude <0,05f


Bien que la question indique "Comment pouvez-vous vérifier si l'objet bouge?", Alors allons-y avec rb.velocity.magnitude> 0,05f


@MiladQasemi J'ai mis à jour le message avec mon dernier essai, veuillez le lire, j'obtiens toujours le même résultat.


pourriez-vous donner un exemple en utilisant WatingForAnimaiton? parce qu'il obtient une chaîne



0
votes

Je pense que vous voulez le déplacer s'il est arrêté, puis appelez AddForce uniquement lorsqu'il est inactif:

var wasMovingLastTime = false;    

void Update()
{
    var isMoving = rb.velocity.magnitude > 0f;

    if (wasMovingLastTime && !isMoving)
    {
        /// Has just finished moving
        Debug.Log(PlayerPosition.position.x);
    }

    if (Input.GetMouseButtonDown(0))
    {
        if (!isMoving)
        {
            rb.AddForce(20000 * Time.deltaTime, 0, 0);
        }
    }

    wasMovingLastTime = isMoving;
}


2 commentaires

merci qui a résolu un problème pour moi, mais si je veux imprimer la valeur x une fois l'animation terminée?


@yarinCohen Vous devrez utiliser un drapeau. Découvrez la mise à jour



1
votes

First

public Rigidbody rb;
public Transform PlayerPosition;

// a flag to make sure there is only one animation at a time
private bool isMoving;

// a flag for altering between left and right movement
private bool isMovingRight;

// Update is called once per frame
void Update()
{
    // only allow clicks while not moving already
    if (!isMoving && Input.GetMouseButtonDown(0))
    {
        // stop further input until not moving anymore
        isMoving = true;

        // add the force 
        // (you might btw want to skip that Time.deltaTime here it makes no sense)
        rb.AddForce(isMovingRight ? 20000 : -20000 * Time.deltaTime, 0, 0);

        // alter the direction for the next call
        isMovingRight = !isMovingRight;

        // if you rather want to be able to interrupt the current animation by clicking again
        // remove the isMoving flag and instead use this
        //StopCoroutine(WaitForMoveStops());  

        // Start the routine
        StartCoroutine(WaitForMoveStops());
    }
}

private IEnumerator WaitForMoveStops()
{
    // Inside a Coroutine while is okey now
    // as long as you yield somwhere

    // check if velocity is below threshold
    while (!Mathf.Approximately(rb.velocity.magnitude, 0) 
    {
        // yield in simple words means "leave" this method here, render the frame
        // and than continue from here in the next frame
        yield return null;
    }

    // I would now hard reset the velocity just to be sure
    rb.velocity = Vector3.zero;

    Debug.Log(PlayerPosition.position.x);

    // whatever you want to do now

    // reset the flag to allow input again
    isMoving = false;
}

sera presque toujours true en raison de single precision floatong point : Deux valeurs float même si elles semblent être égales logiques ne le sont probablement pas.

Donc vous peut soit utiliser un seuil comme vous avez déjà essayé

if(Mathf.Approximately(rb.velocity.magintude, 0))

ou utiliser Mathf.Approximately qui utilise un très petit Epsilon ou seuil pour la comparaison

if(rb.velocity.magnitude <= 0.5f)

Il semble que vous vouliez attendre que la balle cesse de bouger et que la position soit affichée - comme par exemple pour un jeu de billard. Donc, en fait, il ne semble y avoir aucune Animation impliquée.

Dans la plupart des cas où vous pensez à une "animation", vous voulez dire en fait "faire quelque chose au fil du temps" à ne pas confondre avec l'utilisation d'un composant Animator ou Animation avec AnimationClip dans Unity.

Vous pouvez / devriez utiliser un Coroutine pour cela:

rb.velocity.magnitude != 0.0f


0 commentaires