[DB-AL] Définir le parent d'un Game Object lorsque j'appuie une 2eme fois sur une touche

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
Avatar de l’utilisateur
jmhoubre
Messages : 851
Inscription : 05 Oct 2019 22:05

Re: [DB-AL] Définir le parent d'un Game Object lorsque j'appuie une 2eme fois sur une touche

Message par jmhoubre » 26 Avr 2021 23:51

Super.
Bon courage. Regarde ce que je t'ai proposé : ce pourrait t'aider...
Dernière édition par jmhoubre le 26 Avr 2021 23:53, édité 1 fois.

Matocs
Messages : 32
Inscription : 22 Oct 2016 00:24

Re: [DB-AL] Définir le parent d'un Game Object lorsque j'appuie une 2eme fois sur une touche

Message par Matocs » 26 Avr 2021 23:52

jmhoubre a écrit :
26 Avr 2021 23:50
Il est tard, et j'ai du mal à lire ton code.

Déjà, il y a une petite erreur ici :

Code : Tout sélectionner

	nombre_de_cubes = +1; // Affecte 1 à la variable.
	// Au lieu de :
	nombre_de_cubes += 1; // Ajoute 1 à la variable.
Tu devrais écrire quelques fonctions pour aérer ton Update (). Et t'inspirer de la logique de ce que je t'ai proposé ici.
ok je vais regarder si ça marche merci ;)

Matocs
Messages : 32
Inscription : 22 Oct 2016 00:24

Re: [DB-AL] Définir le parent d'un Game Object lorsque j'appuie une 2eme fois sur une touche

Message par Matocs » 27 Avr 2021 00:28

Bon ducoup le ramassage d'objet c'est bon !
je vais penssera creer des fonctions plus souvent ça change vraiment tout !
ducoup voila le code au complet

Code : Tout sélectionner

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

public class ramassage : MonoBehaviour
{
    public GameObject game_object_porter;
    public GameObject game_object_touched;
    bool ramasser;
    bool porter;
    public GameObject text_interaction_porter;
    public GameObject text_interaction_ramasser;
    public GameObject player;

    public int nombre_de_cubes;
    void Start()
    {
        text_interaction_porter.GetComponent<Text>().enabled = false;
        text_interaction_ramasser.GetComponent<Text>().enabled = false;
        ramasser = false;
    }

    // Update is called once per frame
    void Update()
    {
        
        RaycastHit hit;
        Debug.DrawRay(gameObject.transform.position, gameObject.transform.forward * 2, Color.red);
       

        if (Physics.Raycast(gameObject.transform.position, gameObject.transform.forward , out hit, 2))
        {

            game_object_touched = hit.transform.gameObject;
        }


        

            if (Input.GetKeyDown(KeyCode.E) && porter == true && game_object_touched.tag == "Ramassable")
            {
                lacher_objet();
            }
            else
            {
                if (Input.GetKeyDown(KeyCode.E) && porter == false && game_object_touched.tag == ("Ramassable"))
                {
                    ramasser_objet();

                }
            }
        
        

      
       if (Input.GetKeyDown(KeyCode.E) && game_object_touched.tag == "Cube")
        {
            collect();
            nombre_de_cubes += 1;
           

        }


    }

    void ramasser_objet()
    {

        game_object_touched.GetComponent<Rigidbody>().isKinematic = true;
        game_object_touched.transform.parent = player.transform;
        porter = true;

    }

    void lacher_objet()
    {
        game_object_touched.GetComponent<Rigidbody>().isKinematic = false;
        game_object_touched.transform.parent = null;
        porter = false;
    }

    void collect()
    {

        game_object_touched.SetActive(false);
    }
}

le seul probleme qui persiste c'est que le game_object_touched n'est jamais nul il stock constament le dernier GO a avoir été touché ducoup le texte ne disparait pas

Matocs
Messages : 32
Inscription : 22 Oct 2016 00:24

Re: [DB-AL] Définir le parent d'un Game Object lorsque j'appuie une 2eme fois sur une touche

Message par Matocs » 27 Avr 2021 00:50

Matocs a écrit :
27 Avr 2021 00:28
Bon ducoup le ramassage d'objet c'est bon !
je vais penssera creer des fonctions plus souvent ça change vraiment tout !
ducoup voila le code au complet

Code : Tout sélectionner

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

public class ramassage : MonoBehaviour
{
    public GameObject game_object_porter;
    public GameObject game_object_touched;
    bool ramasser;
    bool porter;
    public GameObject text_interaction_porter;
    public GameObject text_interaction_ramasser;
    public GameObject player;

    public int nombre_de_cubes;
    void Start()
    {
        text_interaction_porter.GetComponent<Text>().enabled = false;
        text_interaction_ramasser.GetComponent<Text>().enabled = false;
        ramasser = false;
    }

    // Update is called once per frame
    void Update()
    {
        
        RaycastHit hit;
        Debug.DrawRay(gameObject.transform.position, gameObject.transform.forward * 2, Color.red);
       

        if (Physics.Raycast(gameObject.transform.position, gameObject.transform.forward , out hit, 2))
        {

            game_object_touched = hit.transform.gameObject;
        }


        

            if (Input.GetKeyDown(KeyCode.E) && porter == true && game_object_touched.tag == "Ramassable")
            {
                lacher_objet();
            }
            else
            {
                if (Input.GetKeyDown(KeyCode.E) && porter == false && game_object_touched.tag == ("Ramassable"))
                {
                    ramasser_objet();

                }
            }
        
        

      
       if (Input.GetKeyDown(KeyCode.E) && game_object_touched.tag == "Cube")
        {
            collect();
            nombre_de_cubes += 1;
           

        }


    }

    void ramasser_objet()
    {

        game_object_touched.GetComponent<Rigidbody>().isKinematic = true;
        game_object_touched.transform.parent = player.transform;
        porter = true;

    }

    void lacher_objet()
    {
        game_object_touched.GetComponent<Rigidbody>().isKinematic = false;
        game_object_touched.transform.parent = null;
        porter = false;
    }

    void collect()
    {

        game_object_touched.SetActive(false);
    }
}

le seul probleme qui persiste c'est que le game_object_touched n'est jamais nul il stock constament le dernier GO a avoir été touché ducoup le texte ne disparait pas
bon bah enfait il sufisait de rajouter un else game_object_touched = null au if physics.raycast :)

Matocs
Messages : 32
Inscription : 22 Oct 2016 00:24

Re: [DB-AL] Définir le parent d'un Game Object lorsque j'appuie une 2eme fois sur une touche

Message par Matocs » 27 Avr 2021 01:44

il y a un probleme sauf que je ne pense pas que la mon code soit faux voila le texte pour un objet portable :

Code : Tout sélectionner

if (game_object_touched != null &&  game_object_touched.tag == "Ramassable" && porter == false)
        {
            affichertexteporter();
        }
        else

        {
            

                enlevertexteporter();
            
        }
et celui d'un objet ramassable :

Code : Tout sélectionner

if(game_object_touched.tag == "Cube" && game_object_touched != null && porter == false)
        {

            affichertexteramasser();
        }
        else
        {
            Debug.Log("text_enlevé");
            enlevertexteramasser();
        }
pourtant meme lorsque le game_object_touched est == null car il ne touche aucun game object le texte du cube ramassable reste afficher jusqua ce que je regarde un autre game object, et comme je l'ai dit il n'y a pas ce probleme sur un objet portable :/

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

Re: [DB-AL] Définir le parent d'un Game Object lorsque j'appuie une 2eme fois sur une touche

Message par boubouk50 » 27 Avr 2021 08:57

Code : Tout sélectionner

if(game_object_touched.tag == "Cube" && game_object_touched != null && porter == false)
Cette condition génèrera une erreur si game_object_touched vaut null car tu ne pourras pas accéder à propriété tag (null.tag n'existe pas).
Donc soit game_object_touched n'est pas remis à null, soit tu as une erreur.

Il me semble (à vérfiier) que les conditions logiques && se font par la gauche, donc modifier l'ordre évitera l'erreur:

Code : Tout sélectionner

if(game_object_touched != null && game_object_touched.tag == "Cube" && porter == false)
Ainsi, si game_object_touched vaut null, game_object_touched.tag ne sera pas vérifié car la condition vaudra déjà false.

Peux-tu poster l'entièreté de ton code stp? Qu'on puisse te donner un diagnostic complet.
"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 : 851
Inscription : 05 Oct 2019 22:05

Re: [DB-AL] Définir le parent d'un Game Object lorsque j'appuie une 2eme fois sur une touche

Message par jmhoubre » 27 Avr 2021 12:32

Bonjour,

content pour toi.

Une remarque : quand as-tu besoin de faire un raycast ? A mon sens, quand tu désires prendre un objet. Pour moi le code du raycast devrait être à l'intérieur du test de la touche E. Et même être une fonction. Quelque chose comme :

Code : Tout sélectionner

private void Update()
{
	// Prendre un objet
	if (Input.GetKeyDown(Keycode.E)
	{
		TestObject ();
	}
}

private void TestObject ()
{
	// Un objet ramassable est-il à portée ?
	if (Physics.Raycast(gameObject.transform.position, gameObject.transform.forward , Raycast out hit, 2)
	{
		game_object_touched = hit.transform.gameObject;
	
		if (game_object_touched.CompareTag("Ramassable")
		{
			DropObject ();
			TakeObject ();
		}
		else
		{
			game_object_touched = null;
		}
	}
}

private void DropObject ()
{
	game_object_touched.GetComponent<Rigidbody>().isKinematic = false;
    game_object_touched.transform.parent = null;
}

Matocs
Messages : 32
Inscription : 22 Oct 2016 00:24

Re: [DB-AL] Définir le parent d'un Game Object lorsque j'appuie une 2eme fois sur une touche

Message par Matocs » 27 Avr 2021 17:20

boubouk50 a écrit :
27 Avr 2021 08:57

Code : Tout sélectionner

if(game_object_touched.tag == "Cube" && game_object_touched != null && porter == false)
Cette condition génèrera une erreur si game_object_touched vaut null car tu ne pourras pas accéder à propriété tag (null.tag n'existe pas).
Donc soit game_object_touched n'est pas remis à null, soit tu as une erreur.

Il me semble (à vérfiier) que les conditions logiques && se font par la gauche, donc modifier l'ordre évitera l'erreur:

Code : Tout sélectionner

if(game_object_touched != null && game_object_touched.tag == "Cube" && porter == false)
Ainsi, si game_object_touched vaut null, game_object_touched.tag ne sera pas vérifié car la condition vaudra déjà false.

Peux-tu poster l'entièreté de ton code stp? Qu'on puisse te donner un diagnostic complet.
ça a marché merci beaucoup !
sinon voici le code complet comme demandé

Code : Tout sélectionner

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

public class ramassage : MonoBehaviour
{
    
    public GameObject game_object_touched;

    bool porter;
    public GameObject text_interaction_porter;
    public GameObject text_interaction_ramasser;
    public GameObject player;

    public int nombre_de_cubes;
    void Start()
    {
        text_interaction_porter.GetComponent<Text>().enabled = false;
        text_interaction_ramasser.GetComponent<Text>().enabled = false;
        
    }

    // Update is called once per frame
    void Update()
    {
        
        RaycastHit hit;
        Debug.DrawRay(gameObject.transform.position, gameObject.transform.forward * 3, Color.red);
       

        if (Physics.Raycast(gameObject.transform.position, gameObject.transform.forward , out hit, 3))
        {

            game_object_touched = hit.transform.gameObject;
        }
        else
        {
            game_object_touched = null;
        }


        if (game_object_touched != null &&  game_object_touched.tag == "Ramassable" && porter == false)
        {
            affichertexteporter();
        }
        else

        {
            

                enlevertexteporter();
            
        }



            if (Input.GetKeyDown(KeyCode.E) && porter == true && game_object_touched.tag == "Ramassable")
            {
                lacher_objet();
            
        }

            else
            {
                if (Input.GetKeyDown(KeyCode.E) && porter == false && game_object_touched.tag == ("Ramassable"))
                {
                    ramasser_objet();
               

            }
            }
        
        
            if(game_object_touched != null && porter == false && game_object_touched.tag == "Cube" )
        {

            affichertexteramasser();
        }
        else
        {
           
                enlevertexteramasser();
            
            
        }
      
       if (Input.GetKeyDown(KeyCode.E) && game_object_touched.tag == "Cube" && porter == false)
        {
            collect();
            nombre_de_cubes += 1;
            enlevertexteramasser();


        }


    }

    void ramasser_objet()
    {

        game_object_touched.GetComponent<Rigidbody>().isKinematic = true;
        game_object_touched.transform.parent = player.transform;
        porter = true;

    }

    void lacher_objet()
    {
        game_object_touched.GetComponent<Rigidbody>().isKinematic = false;
        game_object_touched.transform.parent = null;
        porter = false;
    }

    void collect()
    {

        game_object_touched.SetActive(false);
    }

    void affichertexteporter()
    {
        text_interaction_porter.GetComponent<Text>().enabled = true;
    }
    void enlevertexteporter()
    {
        text_interaction_porter.GetComponent<Text>().enabled = false;
    }

    void affichertexteramasser()
    {
        text_interaction_ramasser.GetComponent<Text>().enabled = true;
    }

    void enlevertexteramasser()
    {
        text_interaction_ramasser.GetComponent<Text>().enabled = false;
    }
}



Dernière édition par Matocs le 27 Avr 2021 17:30, édité 1 fois.

Matocs
Messages : 32
Inscription : 22 Oct 2016 00:24

Re: [DB-AL] Définir le parent d'un Game Object lorsque j'appuie une 2eme fois sur une touche

Message par Matocs » 27 Avr 2021 17:20

jmhoubre a écrit :
27 Avr 2021 12:32
Bonjour,

content pour toi.

Une remarque : quand as-tu besoin de faire un raycast ? A mon sens, quand tu désires prendre un objet. Pour moi le code du raycast devrait être à l'intérieur du test de la touche E. Et même être une fonction. Quelque chose comme :

Code : Tout sélectionner

private void Update()
{
	// Prendre un objet
	if (Input.GetKeyDown(Keycode.E)
	{
		TestObject ();
	}
}

private void TestObject ()
{
	// Un objet ramassable est-il à portée ?
	if (Physics.Raycast(gameObject.transform.position, gameObject.transform.forward , Raycast out hit, 2)
	{
		game_object_touched = hit.transform.gameObject;
	
		if (game_object_touched.CompareTag("Ramassable")
		{
			DropObject ();
			TakeObject ();
		}
		else
		{
			game_object_touched = null;
		}
	}
}

private void DropObject ()
{
	game_object_touched.GetComponent<Rigidbody>().isKinematic = false;
    game_object_touched.transform.parent = null;
}
en effet c'est vrai que je ne réfléchis pas a l'optimisation en utilisant des fonctions merci du conseil

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

Re: [DB-AL] Définir le parent d'un Game Object lorsque j'appuie une 2eme fois sur une touche

Message par jmhoubre » 27 Avr 2021 18:50

Bonjour,

de rien.

Créer des fonctions n'est pas vraiment une optimisation dans ton cas (on ne les appelle qu'une fois), mais aide à la lisibilité du code et à sa maintenance.
Un codeur US (oncle Bob peut-être) estime qu'un codeur passe 90% de son temps à lire ou relire du code, contre 10% à l'écrire. Il est donc indispensable de prendre le temps d'améliorer sa lisibilité :
- indentation
- nommage des variables, membres de classe, méthodes ... Un nom long sera toujours mieux qu'un nom court avec un commentaire de 3 lignes, car le commentaire n'est qu'à un seul endroit.
- logique du code (ne pas se lancer dans l'écriture de plus de 2 ou 3 lignes de code sans avoir réfléchi, voire fait un schéma ou poser son algo en pseudo-code)
- ne pas se répéter (le code dupliqué devrait faire l'objet d'une méthode. On voit assez souvent l'acronyme DRY (Don't Repeat Yourself))
- commentaires :

Code : Tout sélectionner

// Commentaire inutile :
private void TakeObject ()
{
	// Cette fonction sert à prendre un objet.
}

// Commentaire utile (parce que cela ne saute pas aux yeux...)
public static T[] ShuffleArray<T>(T[] array, int seed)
{
	// Cette méthode renvoie un tableau mélangé selon l'algorithme de Fisher-Yates. 
}

Répondre

Revenir vers « (C#) CSharp »