Partage
  • Partager sur Facebook
  • Partager sur Twitter

Collisions et Raycast en Unity

    20 août 2024 à 23:16:07

    Bonsoir,

    J'essaie de faire un mini-jeu 2D durant ma semaine d'initiation à Unity.

    Voilà le topo : 

    Sur la map, j'ai des obstacles, et j'ai 2 chars. L'un est contrôlé par le joueur, l'autre est contrôlé par un "bot". 
    Le bot en question, c'est juste que le char ennemi cherche à rejoindre le char du joueur. 

    Jusque là, tout va bien.

    Mais depuis que j'ai rajouté mes obstacles, le char ennemi fonce tout droit vers le char du joueur, mais se heurte au mur. J'aimerais qu'il contourne donc les obstacles s'il y en a, et j'ai entendu parlé des Raycast pour faire cela. 
    J'ai donc essayé, mais lorsque le char ennemi détecte un mur, il se met à "trembler" et ne sait plus où aller...

    Voilà le script C#de mon char ennemi : 
    void MoveTowardsPlayer()
    {
        if (player == null) return;
    
        // Calculer la direction vers le joueur
        Vector2 direction = (player.position - transform.position).normalized;
        float distance = Vector2.Distance(player.position, transform.position);
    
        // Détecter les obstacles avec des Raycasts
        RaycastHit2D frontHit = Physics2D.Raycast(transform.position, (transform.up + (Vector3.forward * 100)), obstacleLayer);
        RaycastHit2D leftHit = Physics2D.Raycast(transform.position, (transform.up + (Vector3.left * 100)).normalized, 1f, obstacleLayer);
        RaycastHit2D rightHit = Physics2D.Raycast(transform.position, (transform.up + (Vector3.right * 100)).normalized, 1f, obstacleLayer);
    
        //Debug.DrawRay(transform.position, Vector3.forward, Color.red); // Raycast vers l'avant
        Debug.DrawRay(transform.position, transform.up * 1f, Color.red); // Raycast vers l'avant
        Debug.DrawRay(transform.position, (transform.up + (Vector3.left * 0.5f)).normalized * 1f, Color.green); // Raycast gauche
        Debug.DrawRay(transform.position, (transform.up + (Vector3.right * 0.5f)).normalized * 1f, Color.blue); // Raycast droit
    
        if (frontHit.collider != null || leftHit.collider != null || rightHit.collider != null)
        {
            AvoidObstacle();
        }
        else
        {
            // Tourner le char vers le joueur
            float targetAngle = Mathf.Atan2(direction.y, direction.x) * Mathf.Rad2Deg;
            float angleDifference = Mathf.DeltaAngle(rb.rotation, targetAngle - 90); // -90 pour compenser la rotation initiale du char
    
            rb.rotation = Mathf.MoveTowardsAngle(rb.rotation, targetAngle - 90, turnSpeed * Time.deltaTime);
    
            // Déplacer le char vers le joueur uniquement s'il est suffisamment aligné et à une certaine distance
            if (Mathf.Abs(angleDifference) < 10f && distance > stopDistance)
            {
                rb.velocity = transform.up * moveSpeed;  // Utiliser la vélocité pour un mouvement plus stable
                HandleEngineSound(true);
            }
            else
            {
                rb.velocity = Vector2.zero;  // Arrêter le mouvement si le char est trop proche ou mal aligné
                HandleEngineSound(false);
            }
        }
    }
    
    void AvoidObstacle()
    {
        // Arrêter le mouvement
        rb.velocity = Vector2.zero;
    
        // Tourner légèrement pour essayer d'éviter l'obstacle
        // Tourner dans une direction aléatoire
        float turnDirection = Random.Range(0, 2) == 0 ? 1 : -1;
        rb.angularVelocity = turnSpeed * turnDirection;
    
        StartCoroutine(WaitBeforeContinue());
    }
    
    IEnumerator WaitBeforeContinue()
    {
        yield return new WaitForSeconds(0.5f); // Ajuster ce délai si nécessaire
        rb.angularVelocity = 0; // Arrêter la rotation
        HandleEngineSound(false); // Arrêter le son pendant la pause
    }

    Je reste disponible pour toutes autres questions.

    Merci d'avance pour votre aide !

    -
    Edité par Romsito 20 août 2024 à 23:29:02

    • Partager sur Facebook
    • Partager sur Twitter
      26 août 2024 à 19:58:04

      Je pense que c'est ta rotation aléatoire qui pose soucis, le char ne doit probablement tourner suffisamment pour pouvoir éviter l'obstacle et donc relance une rotation aléatoire, donc éventuellement dans le sens opposé à la fois précédent, donc oscille; donc il faudrait le tourner de façon à ce qu'il n'ai plus d'obstacle devant lui (ensuite le faire tourner systématiquement vers la position du joueur va faire qu'il va se retrouver à nouveau dans une position de blocage par un obstacle)
      • Partager sur Facebook
      • Partager sur Twitter
        29 août 2024 à 14:52:02

        Merci pour ta réponse, effectivement, je m'en étais rendu compte après. J'ai réussi à jouer avec la rotation pour finir par avoir un "bot" convenable.
        • Partager sur Facebook
        • Partager sur Twitter

        Collisions et Raycast en Unity

        × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
        × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
        • Editeur
        • Markdown