Problèmes de spawn d'un PREFAB

Questions à propos du GUI, y compris la partie script.
Avatar de l’utilisateur
jmhoubre
Messages : 602
Inscription : 05 Oct 2019 22:05

Re: Problèmes de spawn d'un PREFAB

Message par jmhoubre » 27 Nov 2021 16:17

Ton code est étrange, avec probablement des copier-coller hasardeux. Essaie de publier quelque chose de corrigé et de correctement indenté.

Avatar de l’utilisateur
boubouk50
ModoGenereux
ModoGenereux
Messages : 5683
Inscription : 28 Avr 2014 11:57
Localisation : Allériot (71)

Re: Problèmes de spawn d'un PREFAB

Message par boubouk50 » 27 Nov 2021 19:27

C'est une imbrication de classe (C# Nested Classes).
La classe imbriquée est accessible depuis la première et a accès à ses propriétés.
Par contre, je ne sais pas si les fonctions Start () et Update () de Drop sont considérées comme issue de MonoBehaviour puisque cette classe n'en dérive pas directement.

En tout cas, on ne voit pas ce genre de code tous les jours, et je ne suis pas sur du comportement final.
"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

Avatar de l’utilisateur
jmhoubre
Messages : 602
Inscription : 05 Oct 2019 22:05

Re: Problèmes de spawn d'un PREFAB

Message par jmhoubre » 27 Nov 2021 21:30

Par curiosité, j'ai essayé. Le Start de la classe Drop n'est pas appelé. VS ne le colorie d'ailleurs pas de la même manière que le Start de la classe RandomLoot.

Je pense qu'il a copié le code que je lui ai fourni à titre d'illustration au mauvais endroit. Y compris la fonction Update qui instancie un objet à chaque frame.

Avatar de l’utilisateur
jmhoubre
Messages : 602
Inscription : 05 Oct 2019 22:05

Re: Problèmes de spawn d'un PREFAB

Message par jmhoubre » 27 Nov 2021 22:45

J'ai nettoyé façon Victor le nettoyeur. Remarques générales :
  1. Quand on a un souci de code, on enlève tout ce qui ne sert à rien. Là je vois des doublons entre la définition de la classe Drop (comme spawn) et la classe RandomLoot. On teste de petites choses, et on avance petit à petit.
  2. Le nommage est important. De plus, les variables doivent tout de suite indiquer au lecteur à quoi elles servent. Le GameObject spawn : c'est le prefab à spawner ? La position de spawn ? On perd du temps à comprendre, pour s'apercevoir qu'il n'est pas utilisé.
  3. 2 mots d'ordre à connaître : DRY et KISS :
    • Don't Repeat Yourself : ou l'apologie de la paresse. Quand un code apparaît 2 fois, on factorise --> création d'une fonction.
    • Keep It Stupid and Simple : Restez simple et stupide. Il faut écrire du code lisible, généralement un code simple est lisible.
  4. Quand on met du code sur ce site pour se faire aider, on doit le limiter aux choses utiles à la résolution du problème. Là, il y a des tas de choses qui ne servent pas, ou qui sont étrangères à ton problème (itemWeight par exemple).
Oui, à terme j'aimerais que le joueur puisse réaliser 7 tirages, pour avoir idéalement 7 nouvelles cartes. Sauf dans des cas de malchance ou il n'en aura que 6 (c'est peut-être une mauvaise idée mais ce n'est pas bien grave).
En cas de malchance, il peut arriver qu'il n'ait aucune carte.

Voici une version du code dans laquelle j'ai mis en commentaires des remarques ou questions.

Code : Tout sélectionner

using System.Collections.Generic;

using UnityEngine;

public class RandomLoot : MonoBehaviour
{
    [System.Serializable]
    public class Drop
    {
        /* Nommage des identificateurs : peu importe la convention, l'essentiel est de s'y tenir !
         * Je connais trois conventions. En gros :
         * 1 - Microsoft préconise PascalCasing pour tous les identificateurs, sauf les paramètres.
         * 2 - Beaucoup de développeurs mettent les variables et les champs en camelCasing.
         * 3 - Unity préfixe les champs par m_, et utilise camelCasing pour les variables.
         * 
         * J'utilise la 2.
         */
        public string name;
        public GameObject item;        
        public int dropRarety;        
        public GameObject spawn;
        // Modif : suppression de public Transform spawnPos, non utilisé.
        // Quelle différence entre le GameObject item et le GameObject prefab ? Je le met en commentaire.
        // A quoi sert spawn ?
        // private GameObject prefab;
        // Modif :  suppression de public GameObject prefabsParent, non utilisé.
        // Suppression Start () et Update ().
    }

    public List<Drop> lootTable = new List<Drop> ();
    public int dropChance;
    // Tu ne mets pas toutes les chances de ton côté en donnant le même nom à 2 champs différents.
    public GameObject spawn;
    public int itemWeight;

    private void Start ()
    {
        // Modif : suppression de CalcDropChance, pas utilisée.        
        // Modif : suppression déclaration d'ItemWeight.

        // Calcul de la somme des poids.
        itemWeight = 0;
        for (int i = 0; i < lootTable.Count; i++)
        {
            itemWeight += lootTable[i].dropRarety;
        }
        // Modif : suppression Debug.Log : ItemWeight est dans l'inspecteur.        
    }

	private void Update ()
	{
		// CalculateLoot n'est pas appelé ? Ajout dans l'Update.
		if (Input.GetKeyDown (KeyCode.Space))
		{
            CalculateLoot ();
        }
    }

    // Modif : capitalisation du nom de la fonction.
    public void CalculateLoot ()
    {
        int randomValue = Random.Range (0, itemWeight);
        Debug.Log ($"RandomValue : {randomValue}");

        // Modif : tous les champs relatifs aux parents des objets spawnée est supprimé, puisqu'au final tu ne t'en sers pas.
        // Modif : tous les champs relatifs aux position et rotation des objets spawnés sont supprimés, tu ne t'en sers pas.

        // Je ne comprends pas ce système, mais je suppose qu'il correspond à tes besoins.
        // Pourquoi randomValue est décrémentée ?
        // Par ailleurs, à quoi sert itemWeight ?
        for (int j = 0; j < lootTable.Count; j++)
        {
            if (randomValue <= lootTable[j].dropRarety)
            {
                // Modif : ajout du parent (qui sera l'objet portant ce script).
                // Modif : suppression de "as GameObject" (à quoi sert-il, puisque les item sont des GameObject).
                GameObject go = Instantiate (lootTable[j].item, transform.position, transform.rotation, transform);
                // go.transform.SetParent (GameObject.FindGameObjectWithTag ("Test").transform, false); Parentage dans l'instantiate.
                // go.SetActive (true); Inutile.
                return;
            }
            randomValue -= lootTable[j].dropRarety;
            Debug.Log ("Random Value Decreased " + randomValue);
        }
    }
}
Voici la version sans les remarques, qui chez moi fonctionne à chaque appui sur la barre d'espace. Les objets spawnnent en (0, 0, 0). Je suis en 2020.3.23 avec Visual Studio 2019, et en 3D.

Code : Tout sélectionner

using System.Collections.Generic;

using UnityEngine;

public class RandomLoot : MonoBehaviour
{
	[System.Serializable]
	public class Drop
	{
		public string name;
		public GameObject item;
		public int dropRarety;
	}

	public List<Drop> lootTable = new List<Drop> ();
	public int itemWeight;

	private void Update ()
	{
		if (Input.GetKeyDown (KeyCode.Space))
		{
			CalculateLoot ();
		}
	}

	public void CalculateLoot ()
	{
		int randomValue = Random.Range (0, itemWeight);

		for (int j = 0; j < lootTable.Count; j++)
		{
			if (randomValue <= lootTable[j].dropRarety)
			{
				Instantiate (lootTable[j].item, transform.position, transform.rotation, transform);
				return;
			}
			randomValue -= lootTable[j].dropRarety;
			Debug.Log ("Random Value Decreased " + randomValue);
		}
	}
}
J'espère que tu prendras le temps de répondre à mes questions et à mes remarques. Une fois que tu auras simplifié ton code, je pense que tes cartes apparaîtront au bon endroit.

Avatar de l’utilisateur
boubouk50
ModoGenereux
ModoGenereux
Messages : 5683
Inscription : 28 Avr 2014 11:57
Localisation : Allériot (71)

Re: Problèmes de spawn d'un PREFAB

Message par boubouk50 » 28 Nov 2021 12:44

jmhoubre a écrit :
27 Nov 2021 21:30
Par curiosité, j'ai essayé. Le Start de la classe Drop n'est pas appelé. VS ne le colorie d'ailleurs pas de la même manière que le Start de la classe RandomLoot.
Si tu dérives la class Drop de MonoBehaviour et Start () et Update () devraient fonctionner je pense.

Code : Tout sélectionner

public class RandomLoot : MonoBehaviour
{
    [System.Serializable]
    public class Drop : MonoBehaviour
    {
Quoiqu'il en soit, ce n'est surement pas ce que cherche à faire Unitigre.
"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

Unitigre
Messages : 8
Inscription : 16 Nov 2021 17:27

Re: Problèmes de spawn d'un PREFAB

Message par Unitigre » 28 Nov 2021 13:44

Un grand merci pour vos réponses, j'ai l'impression de m'être engouffré dans un tunnel sans issue, mais grâce à vous j'aperçois la sortie.

Ma semaine chargée ne pas aidée et m'a obligé à ralentir mon développement.

Je tenais à vous dire que j'ai noté toutes vos remarques et que je les appliquerai dès que possibles. Je donnerai des nouvelles dans la semaine.

Encore merci !
Unitigre.

Unitigre
Messages : 8
Inscription : 16 Nov 2021 17:27

Re: Problèmes de spawn d'un PREFAB

Message par Unitigre » 08 Déc 2021 11:54

Bonjour tout le monde,

je ne vais pas tourner autour du pot, je ne suis plus dedans. Durant la période ou j'étais bloqué, d'autres projets sont rentré dans mon intérêt ce qui m'empêche désormais de me concentrer sur le jeu. Je préfère vous le dire clairement plutôt que de bâcler une réponse sans vraiment chercher à résoudre le problème.

Néanmoins je n'abandonne pas. Mais au vu de l'avancée des autres projets, je projette une update courant Janvier.

Je vous remercie de m'avoir aidé.
À bientôt je l'espère.

Répondre

Revenir vers « L'interface GUI »