[DB-AL]Rotation avec souris

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
EmileF
Messages : 673
Inscription : 18 Mars 2017 19:39

Re: [DB-AL]Rotation avec souris

Message par EmileF » 24 Juin 2019 19:00

Tu vas finir par me convaincre.

Le problème c'est que je ne sais pas à quel moment les utiliser et pour faire quoi.

Je suppose qu'en les étudiant ça me paraîtra évident.

J'ai déjà regardé un peu, mais sur Unity je trouve les exemples peu explicites,

tu as des tutos à me conseiller?

C'est surtout au niveau optimisation que ça m’intéresse, j'ai posté AbouSimbel
viewtopic.php?f=12&p=117795#p117795
J'avoue qu'il aurai tendance à ramer un peu.

Je pense que c'est au niveau graphique le problème.

Mais je crois que dans ce cas toutes les optimisations peut-être appréciables.
La différence entre l'intelligence et la stupidité est que l'intelligence est limitée.

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

Re: [DB-AL]Rotation avec souris

Message par boubouk50 » 25 Juin 2019 10:10

Dans l'idée:
Ton script, dans l'Update (), cumule les conditions pour savoir où on en est:
Update? -> Quel mode de rotation? -> Appui sur le bouton de la souris? -> Rotation
Tout ceci est inutile si tu n'appuies pas sur le bouton de la souris, car c'est l’événement déclencheur. Tu demandes donc en boucle une information qui n'est pas encore là. (Un peu comme un enfant qui demande toutes les secondes: on est arrivé? on est arrivé? on est arrivé?)
Dans ce cas, tu peux donc lier tout ceci à cet événement. Dans l'Update () cela donnerait (dans ton script tu as 3 fois cette condition redondante):
Update? -> Appui sur bouton souris? -> (oui) Quel mode de rotation? -> Rotation
Avec une coroutine, tu choisis la voie événementielle, donc sans Update ().
Appui sur le bouton de la souris! (Event: instantané)-> Test -> Appel coroutine -> Tant que le bouton est appuyé: rotation + attente (1 frame).
Tu viens de te proscrire de TOUS les tests inutiles quand tu n'utilises pas le bouton de la souris.
Maintenant l'enfant ne demande plus si on est arrivé, on lui dit au moment où on arrive.
"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

EmileF
Messages : 673
Inscription : 18 Mars 2017 19:39

Re: [DB-AL]Rotation avec souris

Message par EmileF » 25 Juin 2019 12:32

Oui, c'est vrai, je n'avais pas fait attention, mais en fait j'avais fait le script sans mode de rotation, que j'ai ajouté en second temps.

Mais pour régler ceci il me suffit de mettre l'appui sur le bouton avant le test de mode de rotation, comme tu me l'indiques.

Mais excuse, je ne vois toujours pas comment utiliser les coroutines dans ce cas, j'ai essayé

Mais une fois OnMouseDown() mis en place, j'ai l'esprit complètement vide et je ne vois pas du tout comment appliquer tes explications.
La différence entre l'intelligence et la stupidité est que l'intelligence est limitée.

EmileF
Messages : 673
Inscription : 18 Mars 2017 19:39

Re: [DB-AL]Rotation avec souris

Message par EmileF » 25 Juin 2019 13:15

Voilà ce que j'ai pondu:

Code : Tout sélectionner

    private void OnMouseDrag()
    {
        switch (modeRotation)
        {
            case ModeRotation.Forward:
                StartCoroutine("AppliqueRotationForward");
                break;
            case ModeRotation.Right:
                StartCoroutine("AppliqueRotationRight");
                break;
            case ModeRotation.Up:
                StartCoroutine("AppliqueRotationUp");
                break;
            default:
                break;
        }
    }
    private void OnMouseUp()
    {
        ButtonPressed = false;
    }
    bool ButtonPressed;
    IEnumerator AppliqueRotationForward()
    {
        Vector3 pos = RaycastPos(Camera, transform);
        if (pos != Vector3.zero)
        {
            pos.z = Objet.position.z;
            Vector3 targetDir = pos - transform.position;
            if (!ButtonPressed)
            {
                offset = Vector3.SignedAngle(Objet.up, targetDir, Vector3.forward);
                ButtonPressed = true;
            }
            else
            {
                float angleBetween = Vector3.SignedAngle(Objet.up, targetDir, Vector3.forward);
                Objet.Rotate(Objet.forward, angleBetween - offset);

                for (int i = 0; i < APivoter.Count; i++)
                {
                    APivoter[i].Rotate(APivoter[i].forward, angleBetween - offset);
                }
            }
        }
        yield return new WaitForSeconds(.1f);

    }
    IEnumerator AppliqueRotationRight()
    {
        Vector3 pos = RaycastPos(Camera, transform);
        if (pos != Vector3.zero)
        {
            pos.x = Objet.position.x;
            Vector3 targetDir = pos - transform.position;
            if (!ButtonPressed)
            {
                offset = Vector3.SignedAngle(Objet.up, targetDir, Vector3.right);
                ButtonPressed = true;
            }
            else
            {
                float angleBetween = Vector3.SignedAngle(Objet.up, targetDir, Vector3.right);
                Objet.Rotate(Objet.right, angleBetween - offset);

                for (int i = 0; i < APivoter.Count; i++)
                {
                    APivoter[i].Rotate(APivoter[i].right, angleBetween - offset);
                }
            }
        }
        yield return new WaitForSeconds(.1f);
    }
    IEnumerator AppliqueRotationUp()
    {
        Vector3 pos = RaycastPos(Camera, transform);
        if (pos != Vector3.zero)
        {
            pos.y = Objet.position.y;
            Vector3 targetDir = pos - transform.position;
            if (!ButtonPressed)
            {
                offset = Vector3.SignedAngle(Objet.right, targetDir, Vector3.up);
                ButtonPressed = true;
            }
            else
            {
                float angleBetween = Vector3.SignedAngle(Objet.right, targetDir, Vector3.up);
                Objet.Rotate(Objet.up, angleBetween - offset);

                for (int i = 0; i < APivoter.Count; i++)
                {
                    APivoter[i].Rotate(APivoter[i].up, angleBetween - offset);
                }
            }
        }
        yield return new WaitForSeconds(.1f);
    }
Est-ce que ça correspond à tes attentes ?,
En tout les cas, ça marche.

J'ai essayé aussi avec" yield return null;" et ça marche pareil.

J'ai essayé l'évènement "OnMouseDown", pour n'avoir qu'un seul appel et avoir un retour dans la coroutine automatique, mais là je sais pas si c'est possible mais je n'y suis pas arrivé.
La différence entre l'intelligence et la stupidité est que l'intelligence est limitée.

EmileF
Messages : 673
Inscription : 18 Mars 2017 19:39

Re: [DB-AL]Rotation avec souris

Message par EmileF » 25 Juin 2019 13:42

Grace à ce post et les explications de cayou66 :
viewtopic.php?t=6416

J'ai modifié mon script et là je suis sûr (presque) d'avoir tes félicitations :mdr3:

Code : Tout sélectionner

    private void OnMouseDown()
    {
        Vector3 pos = RaycastPos(Camera, transform);
        if (pos != Vector3.zero)
        {
            ButtonPressed = true;
            switch (modeRotation)
            {
                case ModeRotation.Forward:
                    {
                        pos.z = Objet.position.z;
                        Vector3 targetDir = pos - transform.position;
                        offset = Vector3.SignedAngle(Objet.up, targetDir, Vector3.forward);
                        StartCoroutine("AppliqueRotationForward");
                        break;
                    }
                case ModeRotation.Right:
                    {
                        pos.x = Objet.position.x;
                        Vector3 targetDir = pos - transform.position;
                        offset = Vector3.SignedAngle(Objet.up, targetDir, Vector3.right);
                        StartCoroutine("AppliqueRotationRight");
                        break;
                    }
                case ModeRotation.Up:
                    {
                        pos.y = Objet.position.y;
                        Vector3 targetDir = pos - transform.position;
                        offset = Vector3.SignedAngle(Objet.right, targetDir, Vector3.up);
                        StartCoroutine("AppliqueRotationUp");
                        break;
                    }
                default:
                    break;
            }
        }
    }


    private void OnMouseUp()
    {
        ButtonPressed = false;
    }

    bool ButtonPressed;
    IEnumerator AppliqueRotationForward()
    {
        while (ButtonPressed)
        {
            Vector3 pos = RaycastPos(Camera, transform);
            if (pos != Vector3.zero)
            {
                pos.z = Objet.position.z;
                Vector3 targetDir = pos - transform.position;
                float angleBetween = Vector3.SignedAngle(Objet.up, targetDir, Vector3.forward);
                Objet.Rotate(Objet.forward, angleBetween - offset);

                for (int i = 0; i < APivoter.Count; i++)
                {
                    APivoter[i].Rotate(APivoter[i].forward, angleBetween - offset);
                }
            }
            yield return null;
        }

    }
    IEnumerator AppliqueRotationRight()
    {
        while (ButtonPressed)
        {
            Vector3 pos = RaycastPos(Camera, transform);
            pos.x = Objet.position.x;
            Vector3 targetDir = pos - transform.position;
            float angleBetween = Vector3.SignedAngle(Objet.up, targetDir, Vector3.right);
            Objet.Rotate(Objet.right, angleBetween - offset);

            for (int i = 0; i < APivoter.Count; i++)
            {
                APivoter[i].Rotate(APivoter[i].right, angleBetween - offset);
            }
            yield return null;
        }
    }
    IEnumerator AppliqueRotationUp()
    {
        while (ButtonPressed)
        {
            Vector3 pos = RaycastPos(Camera, transform);
            pos.y = Objet.position.y;
            Vector3 targetDir = pos - transform.position;
            float angleBetween = Vector3.SignedAngle(Objet.right, targetDir, Vector3.up);
            Objet.Rotate(Objet.up, angleBetween - offset);

            for (int i = 0; i < APivoter.Count; i++)
            {
                APivoter[i].Rotate(APivoter[i].up, angleBetween - offset);
            }
            yield return null;
        }
    }

par contre j'ai remarqué une petite chose, quand je suis en mode right ou forward il faut un délai de 2 ou 3 secondes pour l'exécution au premier clic ensuite tout va bien, en mode up tout va bien sans delai. A tel point que je crois que ça ne marche pas, Je n'arrive pas à comprendre pourquoi.
La différence entre l'intelligence et la stupidité est que l'intelligence est limitée.

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

Re: [DB-AL]Rotation avec souris

Message par boubouk50 » 25 Juin 2019 14:05

Tu te sers ici de la coroutine comme d'une fonction donc elle n'a pas d'utilité réellement.
En cherchant, je ne suis pas sur qu'on puisse récupérer l'event d'un appui de souris en dehors d'un Update (), sauf si on doit cliquer sur un objet (donc avec OnMouseDown). Déjà un point pour toi...
J'essaie de te donner un code, mais je ne sais pas quels éléments doivent être recalculés à chaque frame ou non, donc ça risque de pas être bon. (Par ex pos, targetDir, etc), ils sont soit dans ou en dehors de la boucle.

Code : Tout sélectionner

private void OnMouseDown() //Récupérer le clic sur l'objet
{
	switch (modeRotation)
        {
		case ModeRotation.Forward:
			StartCoroutine("AppliqueRotationForward");
			break;
		case ModeRotation.Right:
			StartCoroutine("AppliqueRotationRight");
			break;
		case ModeRotation.Up:
			StartCoroutine("AppliqueRotationUp");
			break;
        }
}
	
private void OnMouseUp() //Récupérer la fin du drag
{
	ButtonPressed = false;
}

IEnumerator AppliqueRotationForward ()
{
	//On va boucler tant que le bouton n'est pas relâcher (par l'event OnMouseUp)
	do {
		Vector3 pos = RaycastPos(Camera, transform);
		if (pos != Vector3.zero)
		{
			pos.z = Objet.position.z;
			Vector3 targetDir = pos - transform.position;
			if (!ButtonPressed)
			{
				offset = Vector3.SignedAngle(Objet.up, targetDir, Vector3.forward);
				ButtonPressed = true; //Cela nous permet de rester dans la boucle
			}
			else
			{
				float angleBetween = Vector3.SignedAngle(Objet.up, targetDir, Vector3.forward);
				Objet.Rotate(Objet.forward, angleBetween - offset);
				//Comme je ne connais pas ton code, il y a des trucs que je ne comprends pas
				for (int i = 0; i < APivoter.Count; i++)
				{
					APivoter[i].Rotate(APivoter[i].forward, angleBetween - offset);
				}
			}
		}
		//Attendre la fin de la frame en cours pour recommencer. Tu peux également définir toi-même le temps d'attente avec WaitForSeconds (x).
		yield return new WaitForEndOfFrame ();
	} while (ButtonPressed);
}
EDIT - Je réponds à ton post d'avant pas le dernier.
"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

EmileF
Messages : 673
Inscription : 18 Mars 2017 19:39

Re: [DB-AL]Rotation avec souris

Message par EmileF » 25 Juin 2019 14:13

Il me semblait bien que le script précédent n'allait pas.

L'exemple que tu m'a donné, correspond à mon 2ème script je pense, je crois que là j'ai à peu près compris comment ça fonctionne.

Merci pour "WaitForEndOfFrame ()" et merci pour tout boubouk. Je vais essayer de mettre davantage en application ce que tu viens de m'apprendre.
La différence entre l'intelligence et la stupidité est que l'intelligence est limitée.

Répondre

Revenir vers « (C#) CSharp »