Page 2 sur 2

Re: [DB-AL]Rotation avec souris

Publié : 24 Juin 2019 19:00
par EmileF
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.

Re: [DB-AL]Rotation avec souris

Publié : 25 Juin 2019 10:10
par boubouk50
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.

Re: [DB-AL]Rotation avec souris

Publié : 25 Juin 2019 12:32
par EmileF
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.

Re: [DB-AL]Rotation avec souris

Publié : 25 Juin 2019 13:15
par EmileF
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é.

Re: [DB-AL]Rotation avec souris

Publié : 25 Juin 2019 13:42
par EmileF
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.

Re: [DB-AL]Rotation avec souris

Publié : 25 Juin 2019 14:05
par boubouk50
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.

Re: [DB-AL]Rotation avec souris

Publié : 25 Juin 2019 14:13
par EmileF
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.