[Débutant] Raycast et Quick Outline

Questions à propos du scripting. Hors Shader, GUI, Audio et Mobile.
Zumo
Messages : 23
Inscription : 08 Déc 2022 01:08

[Débutant] Raycast et Quick Outline

Message par Zumo » 28 Jan 2023 11:21

Bonjour à tous !
Pour mettre en evidence les objets (porte, interupteur, etc..) j'utilise Quick Outline que j'active en visant un objet avec cette fonction que j'appelle dasn upadte :

Code : Tout sélectionner

    void highlight()
    {
        if (Physics.Raycast(cam.transform.position, cam.transform.TransformDirection(Vector3.forward), out RaycastHit hit, Mathf.Infinity)) //lance le rayon vers le premier objet touché
        {
            
            if(hit.transform.GetComponent<Outline>() && hit.distance < highlightDistance) //si possede le script outline et bonne distance
            {

                hittedObject = hit.transform.gameObject;
                if (isDebugLog) Debug.Log("OT on " + hittedObject.name);
                hittedObject.GetComponent<Outline>().enabled = true;

            }
            else if (hittedObject != null)
            {
                    hittedObject.GetComponent<Outline>().enabled = false;
                    if (isDebugLog) Debug.Log("OT off " + hittedObject.name);
                     hittedObject = null;
            }

            if (actionInputValue && hittedObject != null)
            {
                if (isDebugLog) Debug.Log("ACTION  " + actionInputValue);
                action(hittedObject);
            }
        }
    }


Cela marche plutôt pas mal sauf quand je passe d'un object possedant le script outline à un autre, dasn ce cas le premier "outline" n'est pas desactivé. Je me creuse la tête mais je pense manquer de connaissance et je ne vois pas comment gérer ça.
Autre chose est-ce que ce genre de code n'est pas trop gourmand ? Je fais plusieurs "GetComponent" et il me semble que ce n'est pas génial. Est-ce qu'il vaut mieux utiliser un objet isTrigger qui representerait mon champ de vision avec OnTriggerEnter/OnTriggerExit ? L'utilisation d'un raycast est quand même super rapide et intuitif et sera sans doute utile par la suite.

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

Re: [Débutant] Raycast et Quick Outline

Message par boubouk50 » 30 Jan 2023 11:00

Salut,
c'est plus une question de logique/d'algorithme qu'autre chose. Il faut donc d'abord réfléchir au résultat escompté avant de déterminer comment le faire.
But:
- Mettre en surbrillance un ou plusieurs objets en fonction de leur visibilité?
- Mettre en surbrillance un ou plusieurs objets s'ils sont sous le curseur/viseur?
- Mettre en surbrillance uniquement l'objet le plus visible? (celui le plus au centre de l'écran par ex)
Algo:
- Un ou plusieurs : chacun des objets sera traité indépendamment des autres pour ne pas qu'une activation désactive un autre. Passer par un manager nécessite de garder trace de chacun des objets actifs pour pouvoir les désactiver, contrairement à gérer l'outline directement sur l'objet lui même.
- Un seul : Faire comme plusieurs ou bien utiliser un manager comme tu l'as fait. Ne pas oublier de désactiver l'outline en cours AVANT d'activer le nouveau (ce que tu dois corriger dans ton code actuel ;-) )

Ensuite, à voir comment déterminer l'apparition/disparition : Trigger, Renderer.isVisible, Raycast, etc. En fonction du résultat attendu. Passer par un collider permet de définir une zone d'action et donc de tout gérer en design et pas en code. Par ex, placer un collider cylindrique de rayon 1 et de longueur 5 sur le forward de la caméra te permettra de détecter automatiquement les objets contenu dans ce collider à moins de 5 metres. Ainsi, dans le OnTriggerEnter / Exit, tu n'as plus qu'à activer ou désactiver l'oultine.
"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

Zumo
Messages : 23
Inscription : 08 Déc 2022 01:08

Re: [Débutant] Raycast et Quick Outline

Message par Zumo » 30 Jan 2023 19:33

Encore toi ^^ merci pour ton aide. !
Bon au final j'ai fait un mix, j'allume l'objet avec le raycast et je l'eteint avec avec un OnTriggerExit et un collider que j'ai ajouté. Ce n'est sans doute pas super mais pour le moment c'est ce que trouvé car je n'ai pas réussi à le désactiver avec le raycast comme tu me l'as suggéré, je vais passer à un autre bug que j'ai et je reviendrai sur ce bout de code plus tard, ça le fait des fois ! ^^

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

Re: [Débutant] Raycast et Quick Outline

Message par boubouk50 » 31 Jan 2023 09:39

Si tu as le OnTriggerExit, alors tu as aussi le OnTriggerEnter. Ca pourrait donc être très simple. Après, comme dit, tout est une question d'objectif. Plus tu veux être précis, plus ça sera complexe à mettre ne place (en théorie)
"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

Zumo
Messages : 23
Inscription : 08 Déc 2022 01:08

Re: [Débutant] Raycast et Quick Outline

Message par Zumo » 31 Jan 2023 14:30

Le problème du OntriggerEnter c'est que par exemple si je regarde une commode (et donc le collider touche deux tiroirs) il va allumer et ouvrir les deux :(
Pour faire la mm chose avec le raycast j'imagine qu'il faut que je passe par une variable "current" et que je désactive le outline avant d'attribué une nouvelle valeur, j'ai pas encore la méthode en tête...

Code : Tout sélectionner

if(hitObject != currentObject)
{
currentObject.outline.active = false;
currentObject = hitObject;
}
ou un truc dns le genre...

Zumo
Messages : 23
Inscription : 08 Déc 2022 01:08

Re: [Débutant] Raycast et Quick Outline

Message par Zumo » 31 Jan 2023 16:12

Bon ta réponse m'a motivé pour mettre mon nez la dedans et ça a l'air de marcher maintenant même si j'ai l'impression d'avoir fait une usine à gaz :

Code : Tout sélectionner

 void highlight()
        {
        if (Physics.Raycast(cam.transform.position, cam.transform.TransformDirection(Vector3.forward), out RaycastHit hit, Mathf.Infinity)) //lance le rayon vers le premier objet touché
            {
            if (hittedObject == null) { hittedObject = hit.transform.gameObject; } //si hittedobject est null  alors je lui donne une valeur (eviter l'erreur avant d'avoir vu un premier objet)
            if (hit.transform.gameObject != hittedObject && hittedObject.GetComponent<Outline>()) { hittedObject.GetComponent<Outline>().enabled = false; } //si l'object visé a changé je desactive OT sur l'ancien
            if (hit.transform.GetComponent<Outline>() && hit.distance < highlightDistance) //si possede le script outline et bonne distance
                {
                hittedObject = hit.transform.gameObject; //je donne une valeur a l'object actuel
                if (isDebugLog) Debug.Log("OT ON ");
                hittedObject.GetComponent<Outline>().enabled = true; //j'active OT sur l'objet actuel
                }

            if (actionInputValue && hittedObject != null && hit.distance < highlightDistance && hit.transform.GetComponent<Outline>())
                {
                if (isDebugLog) Debug.Log("ACTION  " + actionInputValue);
                action(hittedObject);
                }
            }
        }

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

Re: [Débutant] Raycast et Quick Outline

Message par boubouk50 » 31 Jan 2023 16:50

Il va falloir un peu bûcher la logique mais dans le principe c'est déjà bien que ça fonctionne.

Voici ma proposition (faite à main levée ici, donc risque de typo):

Code : Tout sélectionner

 void highlight()
    {
        if (Physics.Raycast(cam.transform.position, cam.transform.TransformDirection(Vector3.forward), out RaycastHit hit, Mathf.Infinity)) //lance le rayon vers le premier objet touché
		{
			// Si c'est le meme objet ou si le nouvel objet n'a pas de component Outline on ne fait rien
			Outline outline = hit.GetComponent <Outline> ();
			if (hittedObject != hit.transform.gameObject && outline != null)
			{
				// On s'occupe d'abord de l'ancien objet -> désactivation
				if (hittedObject != null)
				{
					hittedObject.GetComponent<Outline>().enabled = false; // CELA SUPPOSE QU'IL POSSEDE LE COMPONENT OUTLINE
				}
				
				// Ensuite on s'occupe du nouveau
				if (hit.distance < highlightDistance) //si bonne distance
				{
					hittedObject = hit.transform.gameObject; //je donne une valeur a l'object actuel
					if (isDebugLog)
						Debug.Log("OT ON ");
					outline.enabled = true; //j'active OT sur l'objet actuel
					
					// On a déjà testé : Bonne distance, outline et hittedObject pas null, donc plus qu'a savoir si actionInputValue
					if (actionInputValue )
					{
						if (isDebugLog)
							Debug.Log("ACTION  " + actionInputValue);
						action(hittedObject);
					}
				}
			}
		}
	}
Ca a le mérite de rendre plus lisible le code.
Pour info : des fois il vaut mieux s'occuper des non-cas que des cas, s'ils sont plus simples ou moins nombreux. Aussi, essayer de regrouper les cas : Si une condition doit remplir A et B et qu'une autre A et C, alors d'abord tu regardes si tu remplis A, et si oui, tu regardes si tu remplis B puis C.
"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

Zumo
Messages : 23
Inscription : 08 Déc 2022 01:08

Re: [Débutant] Raycast et Quick Outline

Message par Zumo » 06 Fév 2023 18:48

Je vais etudier ça merci

Répondre

Revenir vers « Scripting »