0
votes

C # spawn manager créant des vagues d'ennemis trop rapidement

Je suis un débutant qui crée mon premier jeu dans Unity, en suivant le cours Create With Code de Unity. Je crée un jeu de tir qui utilisera le suivi des mains. Je n'ai pas encore configuré le suivi des mains, j'ai donc créé une entrée OnTrigger qui explose les objets lorsque je frappe l'espace. J'ai créé le gestionnaire d'apparition ci-dessous pour engendrer des vagues d'attaques ennemies, mais toutes les vagues engendrent des ennemis trop rapidement. Il semble qu'ils apparaissent automatiquement au lieu de quand la première vague a été détruite.

Existe-t-il un moyen plus simple de se reproduire à un rythme plus lent? Ou apparaître seulement quand il n'y a plus d'ennemis vivants?

EDIT: Ajout du script d'attaque ci-dessous

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

public class Attack : MonoBehaviour
{
    public float speed = 0.5f;
    public GameObject Player;
    private Rigidbody enemyRb;


    // Start is called before the first frame update
    void Start()
    {
        enemyRb = GetComponent<Rigidbody>();
        Player = GameObject.Find("Player");
        this.transform.LookAt(Player.transform);

    }

    // Update is called once per frame
    void Update()
    {

        Vector3 lookDirection = (Player.transform.position - transform.position).normalized;
        enemyRb.AddForce(lookDirection * speed);
        transform.Translate(Vector3.forward * Time.deltaTime * speed);


    }
    private void OnTriggerEnter(Collider other)
    {
        Destroy(gameObject);
        Debug.Log("Game Over");
    }  
}

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

public class SpawnAttack : MonoBehaviour
{
    public GameObject Trumps;
    private float spawnRange = 9;
    public int enemyCount;
    public int waveNumber = 1;

    void Start()
    {      
        SpawnEnemyWave(waveNumber);
        //InvokeRepeating("GenerateSpawnPosition", startDelay, randomInterval); 
    }

    // Update is called once per frame
    void Update()
    {
        enemyCount = FindObjectsOfType<Attack>().Length;
         if(enemyCount == 0)
             {
                waveNumber++;
                SpawnEnemyWave(waveNumber);
             }
     }   

    void SpawnEnemyWave(int enemiesToSpawn)
    {
        for (int i = 0; i < enemiesToSpawn; i++)
        {
            Instantiate(Trumps, GenerateSpawnPosition(), Trumps.transform.rotation);
        }
    }

    private Vector3 GenerateSpawnPosition()
     {
        float spawnPosX = Random.Range(-spawnRange, spawnRange);
        float spawnPosZ = Random.Range(-spawnRange, spawnRange);
        Vector3 randomPos = new Vector3(spawnPosX, 0, spawnPosZ);
        return randomPos;      
     }
    }


4 commentaires

Le script Attack est-il réellement associé à Trumps ? Vous devriez probablement plutôt faire des Atouts de type Attack juste pour être sûr


Cette question peut être plus adaptée à gamedev.stackexchange.com


@BrianRogers ah je ne savais pas que cela existait, je vais essayer gamedev. Merci


@derHugo merci pour vos conseils. Revérifié et le script d'attaque est attaché à ces préfabriqués mais fera également ce que vous avez suggéré


3 Réponses :


0
votes

Je suppose que vous pouvez utiliser la méthode invoke:

Invoke("NameOfTheMethod", 1f)

Ce que cette méthode fait, c'est qu'elle attend un certain nombre de secondes avant d'appeler une méthode. Vous devez écrire le nom de la méthode entre guillemets, puis sélectionner le délai d'attente avant que la méthode ne soit appelée (le "1f" représente le délai en secondes.) Dans votre cas, vous pouvez faire attendre le script avant de se reproduire ennemis.


5 commentaires

et quand appellerais-tu ça exactement? ;)


Je suppose que dans son cas, il peut appeler cette méthode lorsqu'il y a un certain nombre d'ennemis (c'est-à-dire si (ennemis <5) {Invoke ("SpawnEnemies", 2f)}


Ouais, mais cela initialiserait un Invoke chaque image tant que cette condition est vraie, donc après les premières 2 secondes, vous obtiendrez une nouvelle vague à chaque image;)


C'est vrai, mais il peut également créer un booléen pour s'assurer que l'invocation ne se produit qu'une seule fois à chaque fois que la condition est vraie.


Ce qui n'est pas si trivial ici comme vous le verrez;)



0
votes

Je ne connais pas votre script Attack mais j'utiliserais quelque chose comme

public class SpawnAttack : MonoBehaviour
{
    public Attack Trumps;

    [SerializeField] private float delay = 1f;
    private float timer;

    ...

    void Update()
    {
        if(Attack.AliveAttackInstances.Count == 0)
        {
            timer -= Time.deltaTime;
            if(timer <= 0)
            {
                timer = delay;

                waveNumber++;
                SpawnEnemyWave(waveNumber);
            }
        }
    }   

Vous pouvez donc tout le temps de manière moins coûteuse vérifier combien et lesquels les ennemis sont vivants comme

public class SpawnAttack : MonoBehaviour
{
    // I would change this type here to make sure your spawned prefab actually 
    // HAS an Attack attached .. otherwise your enemyCount will always be 0
    public Attack Trumps;

    ...

    void Update()
    {
        if(Attack.AliveAttackInstances.Count == 0)
        {
            waveNumber++;
            SpawnEnemyWave(waveNumber);
        }
    }   

Ensuite, pour ajouter un certain délai avant de générer la prochaine vague, vous pouvez utiliser une simple minuterie comme

public class Attack : MonoBehaviour
{
    public static readonly HashSet<Attack> AliveAttackInstances = new HashSet<Attack>();

    private void Awake()
    {
        AliveAttackInstances.Add(this);
    }

    private void OnDestroy()
    {
        AliveAttackInstances.Remove(this);
    }
}


1 commentaires

est-il possible que la boucle for soit responsable de l'apparition d'un trop grand nombre d'ennemis? J'ai essayé de supprimer la boucle for, mais 3 clones ont continué à se reproduire et à se détruire encore et encore, au lieu de générer un grand nombre de clones. Maintenant, je pense que je dois ajouter un time.deltatime pour normaliser le code de spawn - bien que je ne sache pas comment l'ajouter au code de spawn. Suis-je sur la bonne voie avec tout cela?