Ok désolé c'est pas évident à expliquer simplement, je vais poster le code et rentrer un peu plus dans le détail.
En fait j'ai un script Enemy.cs qui donne les mécaniques de base des ennemis. Chaque type d'ennemi possède un script qui hérite d'Enemy.cs et qui override les fonctions de tirs, de déplacements, etc. ainsi que les valeurs de l'ennemi type speed, damage, health, etc. ça donne ça :
Code : Tout sélectionner
public class Enemy : MonoBehaviour
{
protected float _speed = 4.0f;
protected float _fireRate = 2.0f;
protected int _health = 1;
protected int _damage = 5;
protected int _score = 10;
protected bool _isBig;
protected Player _player;
protected virtual void Start()
{
InitializeEnemy();
}
void InitializeEnemy()
{
_player = GameObject.Find("Player").GetComponent<Player>();
if (_player == null)
{
Debug.LogError("Player is NULL");
}
}
public bool isBig()
{
return _isBig;
}
Et pour chaque type d'ennemi on a donc un script de ce genre là :
Code : Tout sélectionner
public class Big_Enemy : Enemy
{
protected override void Start()
{
base.Start();
InitializeDefaultValue();
}
void InitializeDefaultValue()
{
_speed = 1.0f;
_fireRate = 10f;
_health = 1;
_damage = 20;
_score = 10;
_isBig = true;
}
}
Parmi tous mes types d'ennemis, il y a un booléen _isBig qui détermine la place que va prendre l'ennemi à son spawn. C'est important pour mon SpawnManager, car je suis en train de créer un éditeur de spawn qui permettra avant le lancement du jeu de choisir les types d'ennemis qui vont spawner, la quantité etc. dans une limite de 30 à la fois. Donc un ennemi dont _isBig est false va prendre 1 place, un ennemi dont _isBig est true va prendre 2 places. Ainsi on ne pourra spawner que 15 gros ennemis au lieu de 30 ennemi simples. Mais on peut aussi spawner des gros ennemis en même temps que des petits, donc j'ai une fonction qui calcule la taille prise par les ennemis lorsqu'on les choisit en fonction de cette variable _isBig. Tout le reste est expliqué dans les commentaires du code ci-dessous.
Code : Tout sélectionner
public class SpawnManager : MonoBehaviour
{
[SerializeField]
private Enemy[] _enemiesPrefab;
[SerializeField]
private Transform[] _spawnPositions;
void Start()
{
//Exemple ci-dessous qui retourne false au lieu de true, car ce big ennemy
//n'étant pas instancié au moment de l'appel de la fonction (puisque le
//choix des ennemis se fait avant le niveau), sa variable _isBig conserve la
// valeur du parent ! Puisque _isBig est overridé dans le script de cet ennemi
// qui hérite de Enemy.cs. Bien sûr je ne saurais pas à l'avance le type de
// script de mon ennemi mais c'est simplement pour démontrer que même
// en le sachant je n'arrive pas à avoir la bonne valeur de _isBig.
Big_Enemy bigEnemyScript = _enemiesPrefab[1].GetComponent<Big_Enemy>();
Debug.Log(bigEnemyScript.isBig());
//Ici c'est l'application réel. J'ai un ennemi à l'index[0] qui est un ennemi simple,
// soit _isBig = false, il prend 1 place. Contrairement à l'ennemi à l'index[1],
// dont _isBig = true, il prend deux places. Je passe en paramètre de ma fonction
// de spawn que je veux 25x le [0], et 3x le [1]. Le calcul de la taille qu'ils vont
// prendre est donc 25 x 1 + 3 x 2 = 31. Le soucis c'est que comme _isBig
// sera toujours false, j'obtient 25 x 1 + 3 x 1 = 28. Comme ma limite d'ennemis
//est de 30, ma fonction me retourne que tout est OK, alors qu'en vérité avec 31 ça
//ne passerait pas.
Debug.Log(CheckTotalEnemies(0, 25, 1, 3));
}
private bool CheckTotalEnemies(int firstEnemyType, int firstEnemyNumber, int secondEnemyType = -1, int secondEnemyNumber = 0, int thirdEnemyType = -1, int thirdEnemyNumber = 0)
{
int total = 0;
//en fonction de _isBig, je multiplie par 2 ou non pour déterminer la taille totale du groupe.
total = _enemiesPrefab[firstEnemyType].isBig() ? total += firstEnemyNumber * 2 : total += firstEnemyNumber;
//Ajouter un deuxième ou un troisième type d'ennemi est optionnel
if (secondEnemyType != -1)
{
total = _enemiesPrefab[secondEnemyType].isBig() ? total += secondEnemyNumber * 2 : total += secondEnemyNumber;
if (thirdEnemyType != -1)
total = _enemiesPrefab[thirdEnemyType].isBig() ? total += thirdEnemyNumber * 2 : total += thirdEnemyNumber;
}
//Je vérifie enfin si le total n'excède pas la taille totale qui est de 30
return total <= 30 ? true : false;
}
}
Voilà, donc soit j'ai un problème de conception concernant l'héritage, soit je rate un truc qui me permet de savoir à l'avance la valeur de cette variable overridée par le script enfant...
Merci en tout cas de ton intérêt à la question je sais que ça fait beaucoup d'infos...