[RESOLU] [DB - AL] Argument is out of range. (Besoin d'aide)

Pour les scripts écrits en C#
Règles du forum
Merci de respecter la NOMENCLATURE suivante pour vos TITRES de messages :

Commencez par le niveau de vos scripts
DB = Débutant
MY = Moyen
CF = Confirmé

Puis le domaine d'application
-RS = Réseau
-AL = Algorithmie

Exemple :

[DB-RS] Mouvement perso multijoueur
Aymaryk
Messages : 11
Inscription : 19 Nov 2018 22:55
Localisation : Toulouse

[RESOLU] [DB - AL] Argument is out of range. (Besoin d'aide)

Message par Aymaryk » 19 Nov 2018 23:57

Bonjour.

j'ai tenter plusieurs variante mais j'ai toujours la même erreur.
La partie de mon script qui me donne l'erreur, devrais me donnais la cible avec le tag "Ressources" la plus proche de l'unité avec ce script.

Code : Tout sélectionner

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

public class Unites : MonoBehaviour {

	NavMeshAgent agent;
	public bool selection;
	public bool testselect;
	public GameObject selectionObjet;
	public GameObject deplacementObjet;
	public float TimeDeplacement;
	public int UniteN;
	public int UniteNcalcul;
	public int posz;


	public bool Ouvrier;
	public bool mine;
	public bool ActiveMine;
	public float TempsRecolte;
	public GameObject MineOgjet;

	public bool transporteur;
	public bool transporte;
	public bool ActionPrioritaire;
	public Vector3 PosDestination;
	public GameObject Charbon;
	public GameObject Fer;
	public GameObject Aluminium;
	public GameObject Cuivre;
	public GameObject Or;
	public GameObject Diamant;
	public GameObject Entrepot;
	public int NList;

	public int ListN;
	public Vector3 Target;
	public bool recherche;
	public bool destination;
	public float RDistance;

	RaycastHit hit;

	void Start () {
		TimeDeplacement = 2;
		agent = GetComponent<NavMeshAgent> ();
		selection = false;
		testselect = false;
		ActionPrioritaire = false;
		recherche = true;
		destination = false;
	}

	void Update () {
		if (mine == true && ActiveMine == true){                       //faire apparaitre une ressource devant la mine
			TempsRecolte = TempsRecolte + 1 * Time.deltaTime;
			if (TempsRecolte > 10 /* - amelioration*/) {
				TempsRecolte = 0;
				Mine.Ressources = Mine.Ressources + 1;
			}
		}

		TimeDeplacement = TimeDeplacement + 1 * Time.deltaTime;

		if (TimeDeplacement < 1f) {                                                               // temps d'affichage du cercle blanc ( destination)
			deplacementObjet.SetActive (true);
			deplacementObjet.transform.SetPositionAndRotation (new Vector3 (agent.destination.x, 0.1f, agent.destination.z), Quaternion.identity);
			PosDestination = deplacementObjet.transform.position;
		} else {
			deplacementObjet.SetActive (false);
		}
		if (selection) {
			if (testselect == false) {
				testselect = true;
				Select.NUnitéSelec = Select.NUnitéSelec + 1;
				UniteN = Select.NUnitéSelec;
			}
			selectionObjet.SetActive (true);
		} else {
			if (testselect == true) {
				testselect = false;
				Select.NUnitéSelec = Select.NUnitéSelec - 1;
			}
			selectionObjet.SetActive (false);
		}
		if (Input.GetMouseButtonDown (0)) {
			if (Input.GetKey (KeyCode.LeftControl)) {
			} else {
				selection = false;
			}	
		}

		if (selection) {
			if (Input.GetMouseButtonDown (1)) {                                          // deplacel'unite a l'endroit cible
				if (Physics.Raycast (Camera.main.ScreenPointToRay (Input.mousePosition), out hit, 200)) {
					TimeDeplacement = 0;
					Deplacement ();
					UniteNcalcul = UniteN;
					posz = 0;
					ActionPrioritaire = true;
				}
			}
			if (Ouvrier == true){		                                                     // Unité Ouvrier
				if (hit.collider.name == "Mine") {
					mine = true;
					MineOgjet = hit.collider.gameObject;
				} else {
					mine = false;
					TempsRecolte = 0;
				}
			}
		}

		if (Vector3.Distance (gameObject.transform.position, PosDestination) < 1f) {  // Unité et arrivé à destination (mouvement indiqué par le joueur)
			ActionPrioritaire = false;
		}

		if (transporteur == true) {                                                     // Unité Transporteur
			if (ActionPrioritaire == false) {
				if ( transporte == false){
					if (GameObject.FindWithTag ("Ressources") != null) {
						if (destination == true) {
							agent.destination = Target;
							NList = ListN;
						} else if (recherche == true) {
							ListN = 0;
							RDistance = 1;
							recherche = false;
							RTarget ();
						}
					}
				}else {
					destination = false;
					recherche = true;
					agent.destination = Entrepot.transform.position;
				}
			}
		}
	}

	void OnTriggerEnter (Collider other){
		if (other.gameObject.name == "Selection") {
			selection = true;
		}
		if (other.gameObject.name == "Mine") {
			ActiveMine = true;
		}
		if (transporteur == true) {	
			if (transporte == false) {     										// le transporteur prend une ressource
				if (other.gameObject.name == "Charbon") {
					Destroy (other.gameObject);
					Instantiate (Charbon, gameObject.transform).name = "Charbon1";
					transporte = true;
					Interface.ListRessources.RemoveAt (NList);
				} else if (other.gameObject.name == "Fer") {
					Destroy (other.gameObject);
					Instantiate (Fer, gameObject.transform).name = "Fer1";
					transporte = true;
					Interface.ListRessources.RemoveAt (NList);
				} else if (other.gameObject.name == "Aluminium") {
					Destroy (other.gameObject);
					Instantiate (Aluminium, gameObject.transform).name = "Aluminium1";
					transporte = true;
					Interface.ListRessources.RemoveAt (NList);
				} else if (other.gameObject.name == "Cuivre") {
					Destroy (other.gameObject);
					Instantiate (Cuivre, gameObject.transform).name = "Cuivre1";
					transporte = true;
					Interface.ListRessources.RemoveAt (NList);
				} else if (other.gameObject.name == "Or") {
					Destroy (other.gameObject);
					Instantiate (Or, gameObject.transform).name = "Or1";
					transporte = true;
					Interface.ListRessources.RemoveAt (NList);
				} else if (other.gameObject.name == "Diamant") {
					Destroy (other.gameObject);
					Instantiate (Diamant, gameObject.transform).name = "Diamant1";
					transporte = true;
					Interface.ListRessources.RemoveAt (NList);
				}
			} else if (other.gameObject.name == "Entrepot"){ 						// Le transporteur dépose la ressource
				if (transform.GetChild (2).name == "Charbon1") {
					transform.GetChild (2).name = "1";
					Interface.Charbon = Interface.Charbon + 1;
					transporte = false;
				} else if (transform.GetChild (2).name == "Fer1") {
					transform.GetChild (2).name = "1";
					Interface.fer = Interface.fer + 1;
					transporte = false;
				} else if (transform.GetChild (2).name == "Aluminium1") {
					transform.GetChild (2).name = "1";
					Interface.Aluminium = Interface.Aluminium + 1;
					transporte = false;
				} else if (transform.GetChild (2).name == "Cuivre1") {
					transform.GetChild (2).name = "1";
					Interface.Cuivre = Interface.Cuivre + 1;
					transporte = false;
				} else if (transform.GetChild (2).name == "Or1") {
					transform.GetChild (2).name = "1";
					Interface.Or = Interface.Or + 1;
					transporte = false;
				} else if (transform.GetChild (2).name == "Diamant1") {
					transform.GetChild (2).name = "1";
					Interface.Diamant = Interface.Diamant + 1;
					transporte = false;
				}
			}
		}
	}

	void OnTriggerExit (Collider other){
		if (other.gameObject.name == "Selection") {
			selection = false;
		}
		if (other.gameObject.name == "Mine") {
			ActiveMine = false;
		}

	}

	void RTarget () {                               // Calcul pour connaitre la cible (ressources la plus proches)
		Debug.Log ("RTarget () _ recherche : " + recherche + " | destination : " + destination + " | ListN : " + ListN + " | RDistance : " + RDistance + " | " + Interface.ListRessources.Count);
		if (Vector3.Distance (gameObject.transform.position, Interface.ListRessources [ListN].transform.position) < RDistance) {
			Target = new Vector3 (Interface.ListRessources [ListN].transform.position.x, 0, Interface.ListRessources [ListN].transform.position.z);
			destination = true;
		} else if (Interface.ListRessources.Count > ListN) {
			ListN = ListN + 1;
			RTarget ();
		} else {
			Debug.Log ("teste fonctionement Rdistance +1");
			RDistance = RDistance + 1;
			ListN = 0;
			RTarget ();
		}
	}


	void Deplacement(){										// déplacement de L'unité en fonction du nombre
		if (UniteNcalcul > 5) {
			UniteNcalcul = UniteNcalcul - 5;
			posz = posz + 2;
			Deplacement ();
		} else {
			if (UniteNcalcul == 1) {
				agent.destination = hit.point + new Vector3 (0, 0, posz);
			} else if (UniteNcalcul == 2) {
				agent.destination = hit.point + new Vector3 (2, 0, posz);
			} else if (UniteNcalcul == 3) {
				agent.destination = hit.point + new Vector3 (-2, 0, posz);
			} else if (UniteNcalcul == 4) {
				agent.destination = hit.point + new Vector3 (4, 0, posz);
			} else if (UniteNcalcul == 5) {
				agent.destination = hit.point + new Vector3 (-4, 0, posz);
			}
		}
	}
}

Code : Tout sélectionner

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

public class Interface : MonoBehaviour {

	public static int Charbon;
	public static int fer;
	public static int Aluminium;
	public static int Cuivre;
	public static int Or;
	public static int Diamant;
	public Text RessourceText;



	public static List<GameObject> ListRessources = new List<GameObject>();

	public int ListR;

	void Start () {
	}

	void Update () {

		RessourceText.text = ( "Charbon : " + Charbon + " | Fer : " + fer + " | Aluminium : " + Aluminium + " | Cuivre : " + Cuivre + " | Or : " + Or + " | Diamant : " + Diamant);
	}
}
Dans la scène il y à une Unité et 3 objet avec le tag "Ressources"
L'unité à <Transporteur = true> dans l'inspector.

Quand je lance le jeux sur unity, la console me dit :

Code : Tout sélectionner

RTarget () _ recherche : False | destination : False | ListN : 0 | RDistance : 1 | 3
UnityEngine.Debug:Log(Object)
Unites:RTarget() (at Assets/Game/Joueur/Unites/Unites.cs:224)
Unites:Update() (at Assets/Game/Joueur/Unites/Unites.cs:131)

RTarget () _ recherche : False | destination : False | ListN : 1 | RDistance : 1 | 3
UnityEngine.Debug:Log(Object)
Unites:RTarget() (at Assets/Game/Joueur/Unites/Unites.cs:224)
Unites:RTarget() (at Assets/Game/Joueur/Unites/Unites.cs:230)
Unites:Update() (at Assets/Game/Joueur/Unites/Unites.cs:131)

RTarget () _ recherche : False | destination : False | ListN : 2 | RDistance : 1 | 3
UnityEngine.Debug:Log(Object)
Unites:RTarget() (at Assets/Game/Joueur/Unites/Unites.cs:224)
Unites:RTarget() (at Assets/Game/Joueur/Unites/Unites.cs:230)
Unites:RTarget() (at Assets/Game/Joueur/Unites/Unites.cs:230)
Unites:Update() (at Assets/Game/Joueur/Unites/Unites.cs:131)

RTarget () _ recherche : False | destination : False | ListN : 3 | RDistance : 1 | 3
UnityEngine.Debug:Log(Object)
Unites:RTarget() (at Assets/Game/Joueur/Unites/Unites.cs:224)
Unites:RTarget() (at Assets/Game/Joueur/Unites/Unites.cs:230)
Unites:RTarget() (at Assets/Game/Joueur/Unites/Unites.cs:230)
Unites:RTarget() (at Assets/Game/Joueur/Unites/Unites.cs:230)
Unites:Update() (at Assets/Game/Joueur/Unites/Unites.cs:131)


ArgumentOutOfRangeException: Argument is out of range.
Parameter name: index
System.Collections.Generic.List`1[UnityEngine.GameObject].get_Item (Int32 index) (at /Users/builduser/buildslave/mono/build/mcs/class/corlib/System.Collections.Generic/List.cs:633)
Unites.RTarget () (at Assets/Game/Joueur/Unites/Unites.cs:225)
Unites.RTarget () (at Assets/Game/Joueur/Unites/Unites.cs:230)
Unites.RTarget () (at Assets/Game/Joueur/Unites/Unites.cs:230)
Unites.RTarget () (at Assets/Game/Joueur/Unites/Unites.cs:230)
Unites.Update () (at Assets/Game/Joueur/Unites/Unites.cs:131)
Ci quelqu'un pourrais m'aider ça serais vraiment super, Merci.

ps : mon script contient surement d'autres erreur de débutant, mais je bloque surtout sur elle.
Dernière édition par Aymaryk le 20 Nov 2018 01:20, édité 3 fois.

Avatar de l’utilisateur
Sebela
Messages : 141
Inscription : 25 Juin 2014 21:39

Re: [DB - AL] Argument is out of range. (Besoin d'aide)

Message par Sebela » 20 Nov 2018 00:51

Hello!

A première vue le problème vient de ta condition, à savoir :

Code : Tout sélectionner

else if (Interface.ListRessources.Count > ListN) {
			ListN = ListN + 1;
			RTarget ();
		}
Le problème avec cette partie, c'est que ton tableau de ressources commence à l'id 0, donc par exemple si tu as 4 ressources, elles seront affectées de ListRessources[0] à ListRessources[3] , et avec listN = 3, il va incrémenter ListN et ensuite chercher la valeur de Interface.ListRessources[listN] soit ListRessources[4] qui n'existe pas.
Pour éviter cela tu peux changer la condition en :

Code : Tout sélectionner

else if (Interface.ListRessources.Count > ListN +1) {
			ListN = ListN + 1;
			RTarget ();
		}
ça devrait mieux marcher.
Après j'aurais quelques autres conseils à te donner sur le code si tu es intéressé :)

Avatar de l’utilisateur
Liven
Messages : 268
Inscription : 30 Nov 2017 01:48

Re: [DB - AL] Argument is out of range. (Besoin d'aide)

Message par Liven » 20 Nov 2018 00:51

Je pense que ton erreur viens de cette expression (ligne 297)

Code : Tout sélectionner

else if (Interface.ListRessources.Count > ListN)
{
        ListN = ListN + 1;
        RTarget();
}
Par exemple pour une liste avec deux entrée le ListN pourra avoir la valeur 0 ou 1 alors que ton count te renvéra la valeur 2.
Hors dans ton code tu fait en sorte que ListN soit égale au count alors qu'il devrait être égal à count-1.
Du coup tu devrais essayer quelque chose comme ça

Code : Tout sélectionner

else if (Interface.ListRessources.Count - 1 > ListN)
{
        ListN = ListN + 1;
        RTarget();
}

Avatar de l’utilisateur
Liven
Messages : 268
Inscription : 30 Nov 2017 01:48

Re: [DB - AL] Argument is out of range. (Besoin d'aide)

Message par Liven » 20 Nov 2018 00:52

Alors ça si c'est pas de la synchro !
Dernière édition par Liven le 20 Nov 2018 00:53, édité 2 fois.

Avatar de l’utilisateur
Sebela
Messages : 141
Inscription : 25 Juin 2014 21:39

Re: [DB - AL] Argument is out of range. (Besoin d'aide)

Message par Sebela » 20 Nov 2018 00:53

Excellent ! On a déjà trouvé deux façons d'obtenir le même résultat :lol:

Avatar de l’utilisateur
Liven
Messages : 268
Inscription : 30 Nov 2017 01:48

Re: [DB - AL] Argument is out of range. (Besoin d'aide)

Message par Liven » 20 Nov 2018 00:53

Mais ma solution est vachement meilleur :P

Avatar de l’utilisateur
Sebela
Messages : 141
Inscription : 25 Juin 2014 21:39

Re: [DB - AL] Argument is out of range. (Besoin d'aide)

Message par Sebela » 20 Nov 2018 00:56

La mienne est quand même vachement plus "positive" :mrgreen:
Ok je sors ==> []

Aymaryk
Messages : 11
Inscription : 19 Nov 2018 22:55
Localisation : Toulouse

Re: [DB - AL] Argument is out of range. (Besoin d'aide)

Message par Aymaryk » 20 Nov 2018 01:19

Positive ou négative merci de vos réponse :)
Tout fonctionne très bien le problème est résolue.
Pour les conseils je suis pour comme je débute et que j'apprend qu'avec des tutos mon script doit pas être jolie a vos yeux :D

Avatar de l’utilisateur
Sebela
Messages : 141
Inscription : 25 Juin 2014 21:39

Re: [RESOLU] [DB - AL] Argument is out of range. (Besoin d'aide)

Message par Sebela » 20 Nov 2018 15:49

Alors dans ce cas quelques trucs par rapport à ce que j'ai pu voir sans rentrer dans le détail :

D'abord, tu déclares toutes tes variables en public ce qui n'est pas forcément une bonne idée, même si c'est pratique :roll:
Le problème c'est qu'après d'autres classes qui ne devraient pas avoir accès à ces variables auront accès, ce qui n'est pas souhaitable. Il vaut mieux les déclarer en private (ou protected pour l'héritage) autant que possible. Si tu as besoin de setter la valeur de la variable dans l'éditeur, tu peux ajouter un [SerializedField].

Ensuite, essaye d'utiliser des conventions de nommage pour tes variable. Tu peux par exemple utiliser le camelCase qui consiste à mettre la première lettre de ta variable en minuscule, puis une majuscule pour chaque nouveau mot (=> maNouvelleVariable). Pour les variables private, tu peux ajouter un underscore devant pour les retrouver plus facilement (_maVariablePrivate).

Et j'ai remarqué que tu utilises beaucoup de variables pour gérer tous les cas de figures (je faisais comme toi avant :mrgreen: )
Du coup tu vas vite te retrouver avec plein de conditions, du style :

Code : Tout sélectionner

if (forgeron){
if (canForge){
Forge();
}
else{
Wait();
}
}else if (couturier){
Coud();
}
Et c'est vite la pagaille !
Plutôt que de faire ça, créé des nouvelles classes, et essaye de faire de l'héritage pour les classes qui ont des attributs en commun. ça t'évitera de réécrire plusieurs fois le même code.
Tu peux par exemple créer une classe mère "artisan" qui implémente une méthode Fabriquer() et deux classes enfant "forgeron" et "couturier" qui vont overrider la méthode Fabriquer() pour gérer les comportements spécifiques.
Je t'invite à regarder le cours unity sur l'héritage : Héritage

Bon courage et hésite pas à poser des questions ;)

Aymaryk
Messages : 11
Inscription : 19 Nov 2018 22:55
Localisation : Toulouse

Re: [RESOLU] [DB - AL] Argument is out of range. (Besoin d'aide)

Message par Aymaryk » 20 Nov 2018 22:55

Merci pour les conseil ça fait franchement plaisir :)

Alors pour les variables oui j'ai pris la mauvaise habitude de tout mettre en public je vais devoir faire le trie, par contre je comprend pas vraiment à quoi sert le [SerializedField], je pense faire des recherche plus tard dessus.

Pour les conventions de nommage que je ne connaissais pas je vais le faire de suite ça doit rendre le script plus propre déjà.

Et pour les conditions je pense comprendre ce que tu veux me dire, avoir une meilleur structure dans le script ça vas me permettre de mieux me retrouver et je pense aussi qu'avoir moins de code dans le void Update () m'éviteras de trop chauffer la maison avec le pc :D

Répondre

Revenir vers « (C#) CSharp »