[Resolu][DB - AL] maintenir un enemi à une certaine distance

Questions à propos du scripting. Hors Shader, GUI, Audio et Mobile.
Derek82
Messages : 40
Inscription : 28 Mai 2020 16:36

[Resolu][DB - AL] maintenir un enemi à une certaine distance

Message par Derek82 » 17 Juin 2020 18:23

Je suis un débutant total, et j'avance à pas de fourmis sur mon projet de jeu d'aventure en 2.5D où les personnages et les décors sont en 3D mais évoluent sur un seul axe, horizontal, comme dans un jeu de plateforme 2D.

La situation :
- le personnage évolue dans l'obscurité, suivi par un drone qui plane au-dessus de sa tête et qui le protège grâce à une lumière qu'il peut allumer ou éteindre en appuyant sur une touche. (la lumière consomme de l'énergie et il faudra donc l'économiser, c'est pourquoi il peut allumer et éteindre, mais ça ce sera une prochaine étape).
- Tapies dans le noir, des hyènes se jetteront sur lui pour le tuer à mesure de sa progression dans le décors.
- Le joueur peut espérer courir assez vite pour s'en éloigner suffisamment, car au-delà d'une certaine distance, la hyène abandonne.

Jusque là, tout fonctionne à peu près.
l'étape que je n'arrive pas à mettre au point c'est la suivante :

- il peut aussi activer la lumière du drone, le faisceau lumineux le protège et il pourra continuer à avancer, les hyènes resteront à distance, autour du faisceau, tout en continuant de le suivre au pas car dès que la lumière s'éteindra (plus de batterie ou mauvaise manipulation du joueur) ou que le joueur ne sera plus sous le drone (par exemple le drone se retrouve bloqué par un élément de décors), elles se jetteront de nouveau sur lui.


bon c'est sûr que c'est un peu audacieux pour mon niveau mais j'essaie de trouver des solutions.


une petite capture pour illustrer tout ça :
Image
(désolé, la capture est un peu longue et le proto est très brouillon, les collisions ne marchent pas bien etc.)

voici donc le code de ma hyène que j'ai commenté ci-dessous :
au passage, le script appelle celui du joueur sur lequel il y a une variable isDead et isLight (quand la lumière est actionnée).

Code : Tout sélectionner

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

public class Script_Hyene : MonoBehaviour
{
    public Transform Joueur; // Appelle le joueur.
    private Animator hAnim; // L'animator de la hyène.
    public float vitesseHyene = 4;
    public float distanceCritique = 7; // Au-delà de cette distance, la hyene ne s'intéressera plus au joueur. En deça, elle le poursuivra.
    public float perimetreLight = -2; // Quand la lumière du drone est allumée (isLight) la hyène reste au-dela de ce périmetre qui protège le joueur NOTE : cette valeur DOIT être négative pour que la hyene s'éloigne du joueur.
       
    public Script_Controles_V3 ScriptJoueur; // Appeler le script du joueur pour chercher les variables "isDead" et "isLight".
    
    void Start()
    {
        hAnim = GetComponent<Animator>(); // La désignation de l'animator sur le gameObject de la hyene.
    }
    
    void Update()
    {
        transform.LookAt(Joueur); // Pour que la hyène s'intéresse au joueur.

        if (ScriptJoueur.isDead == true)  // Si le joueur est mort, la hyène ne s'y interesse plus.
        {
            hAnim.SetBool("Chasse", false);
            return;
        }
                                                  
        if (Vector3.Distance(transform.position, Joueur.position) <= distanceCritique) // Si la distance entre la hyène et le joueur est plus petite ou égale au facteur "distanceCritique" alors, elle le poursuit (et l'attaque/tue).
        {
            transform.position += transform.forward * vitesseHyene * Time.deltaTime;
            hAnim.SetBool("Chasse", true);
        }

        if (Vector3.Distance(transform.position, Joueur.position) > distanceCritique) // si la distance est plus grande, la hyène reste au repos, sur place.
        {
            hAnim.SetBool("Chasse", false);
        }

        if (ScriptJoueur.isLight == true)  // Si la lumière est allumée et qu'elle est assez près pour s'intéresser au joueur, la hyène reste à distance (perimetreLight).
        {
            transform.position += -transform.forward * vitesseHyene * Time.deltaTime;
            hAnim.SetBool("Chasse", false);
        }


    }

}
j'ai tenté de définir un périmètre de sécurité "perimetreLight" à exploiter quand la variable isLight est "true"
mais je ne sais pas très bien comment faire ce mouvement paradoxal pour que la hyène continue à aller vers le joueur tout en restant à une certaine distance. je me perds un peu dans la logique je crois, et il se peut que mon script soit déjà un peu confus...

Bref si vous aviez le chic de m'éclairer un peu, que ce soit simplement sur la logique ou me donner une piste de réfléxion :idea:

Merci ! :)
Dernière édition par Derek82 le 20 Juin 2020 15:09, édité 1 fois.

djulio74
Messages : 682
Inscription : 19 Déc 2009 22:55

Re: [DB - AL] maintenir un enemi à une certaine distance

Message par djulio74 » 17 Juin 2020 20:13

Salut,
Ce que tu pourrait faire c'est ajouter, dans la condition de la lumiere alumée, une condition de proximité :
Si la lumiere est allumée ET que la hyene est pas trop pres. un truc du genre :

Code : Tout sélectionner

       if (ScriptJoueur.isLight == true && Vector3.Distance(transform.position, Joueur.position) < perimetreLight )  // Si la lumière est allumée et qu'elle est assez près pour s'intéresser au joueur, la hyène reste à distance (perimetreLight).
        {
            transform.position += -transform.forward * vitesseHyene * Time.deltaTime;
            hAnim.SetBool("Chasse", false);
        }
Par contre en mettant ton perimetreLight à 2 et non -2.

regarde voir ce que ça peut donner.

______________________________________________________________
\_______________________ Impossible is nothing _______________________/

Derek82
Messages : 40
Inscription : 28 Mai 2020 16:36

Re: [DB - AL] maintenir un enemi à une certaine distance

Message par Derek82 » 18 Juin 2020 12:07

Salut Djulio74 ! :)

merci de ton aide.
ça fonctionne : quand le joueur actionne la lumière, la hyene s'arrête au périmètre défini par perimetreLight ;-)
(j'avais fixé cette valeur en négatif lors d'un essai avec Vector3 MoveTowards(Vector3 current, Vector3 target, float maxDistanceDelta) ou la valeur de maxDistanceDelta devait être négative pour que la hyene soit repoussée et non attirée par le joueur mais ça ne marchait pas vraiment comme voulu.)

mais ça ne fonctionne comme je voudrais uniquement dans un sens :
quand le joueur allume la lumière, la hyene s'arrete au périmetre, s'il repart en arrière, la hyène le suit bien et s'arrète de nouveau au perimetre. Par contre quand le joueur continue en direction de la hyene, elle reste statique et fatalement, le joueur entre en collision avec la hyene et meurt.

Image
(dans la capture, quand le joueur s'enfonce dans le sol c'est qu'il est mort :gene: je n'ai pas encore appliqué d'animation de mort vraiment adaptée en fait)

ça me semble logique, il n'y a rien dans le code qui dise à la hyene de "reculer d'une certaine distance pour éviter de franchir le périmètre lumineux s'il est activé et que le joueur avance vers elle"
pour se faire j'imaginais :
- avoir une condition isLight == true et défini la distance au périmètre comme précédemment.
- définir une variable float "recul" pour définir la distance de recul que la hyène devrait respecter

mais je me perds un peu...

djulio74
Messages : 682
Inscription : 19 Déc 2009 22:55

Re: [DB - AL] maintenir un enemi à une certaine distance

Message par djulio74 » 18 Juin 2020 12:32

Pour faire reculer la hyène, il faut déterminer dans quelle direction elle doit aller. Cette direction c'est dans le sens perso vers hyène.
La direction d'un point A vers un point B est la position de B moins la position de A. Donc si tu veux que la hyène aile en s'éloignant du joueur, la direction a prendre est la position de la hyène moins la position du joueur. Penser à normaliser le vecteur pour qu'il ai une longueur de 1.

Donc quand la hyène est dans le périmètre de la Light, tu calcul la direction à prendre et tu l'applique à la hyène, avec une vitesse légèrement supérieur à celle du joueur, pour que quand le joueur avance la hyène recul d'un peut plus pour être sur soit pas encore dans le périmètre.

En gros en pseudo code :

Code : Tout sélectionner

If (hyène trop près avec Light allumée) {
	vector3 direction = (hyène. Position - perso. Position). Normalized; 
	hyène. position += direction * vitesse joueur * 1,2 * time.DeltaTime;
}  

______________________________________________________________
\_______________________ Impossible is nothing _______________________/

Avatar de l’utilisateur
boubouk50
ModoGenereux
ModoGenereux
Messages : 6216
Inscription : 28 Avr 2014 11:57
Localisation : Saint-Didier-en-Bresse (71)

Re: [DB - AL] maintenir un enemi à une certaine distance

Message par boubouk50 » 18 Juin 2020 12:37

Si tu veux passer au travers, elle peut simplement se décaler sur la profondeur.
"Ce n'est pas en améliorant la bougie, que l'on a inventé l'ampoule, c'est en marchant longtemps."
Nétiquette du forum
Savoir faire une recherche
Apprendre la programmation

Derek82
Messages : 40
Inscription : 28 Mai 2020 16:36

Re: [DB - AL] maintenir un enemi à une certaine distance

Message par Derek82 » 18 Juin 2020 13:12

Merci les gars !

Je ne comprends pas très bien pourquoi il faut normaliser le vecteur ? (avec une longueur de 1)

Je vais essayer de trouver comment traduire le "pseudo code" en code, merci ! ça va me prendre un peu de temps mais c'est un bon exercice. Déjà avoir la bonne logique c'est un premier défi pour moi :D
(je suis les cours sur unity Fr et je m'efforce de les mettre en pratique, mais je pense qu'il me faudra du temps avant de penser "code" de façon cohérente !

Sinon Boubouk50, c'est une bonne idée !
effectivement, idéalement, une hyène qui ferait obstacle à l'avancée du joueur, se décalerait dans la profondeur pour éviter la lumière si elle est bien activée, permattant au joueur d'avancer, et dès que la distance entre la hyène et la lumière serait assez importante, la hyene pourrait reprendre sa course mais de fait elle serait derrière le joueur, à ses trousses.
ça serait super ! mais... ça me semble très compliqué non ?
je crois que j'ai obtenu lors de mes essais un truc de ce genre : la hyene était explusée hors du périmetre et faisait une rotation autour du joueur puisqu'elle restait orientée sur lui avec un lookAt mais je ne me souviens plus comment j'ai fait ça. avec un move.forward peut-être ?

Derek82
Messages : 40
Inscription : 28 Mai 2020 16:36

[DB - AL] maintenir un enemi à une certaine distance

Message par Derek82 » 20 Juin 2020 09:48

Voilà, j'ai transposé ton code en pseudo-code Djulio74, ça fonctionne bien ! :)

Image

(à la fin, la hyène bute sur la pente du décors je pense quand elle fait une rotation imprévue autour du personnage, mais je trouve ça marrant)

je vais passer à la prochaine étape ;)

Merci !

Répondre

Revenir vers « Scripting »