[Resolu][MY-AL]Rotation dans une boule
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
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
[Resolu][MY-AL]Rotation dans une boule
Bonjour
J'ai besoin d'un peu d'aide, imaginons que je suis au centre d'une boule.
Je vois autour de moi l'intérieur de cette boule, en fait comme une SkyShere, mais en plus petit.
Je voudrais faire pivoter cette boule dans tous les sens avec la souris.
Je n'ai aucune idée de comment m'y prendre.
Si quelqu’un pouvait me guider une peu, ce serait formidable.
Merci d'avance.
J'ai besoin d'un peu d'aide, imaginons que je suis au centre d'une boule.
Je vois autour de moi l'intérieur de cette boule, en fait comme une SkyShere, mais en plus petit.
Je voudrais faire pivoter cette boule dans tous les sens avec la souris.
Je n'ai aucune idée de comment m'y prendre.
Si quelqu’un pouvait me guider une peu, ce serait formidable.
Merci d'avance.
Dernière édition par EmileF le 23 Jan 2019 19:09, édité 1 fois.
La différence entre l'intelligence et la stupidité est que l'intelligence est limitée.
- boubouk50
- ModoGenereux
- Messages : 6221
- Inscription : 28 Avr 2014 11:57
- Localisation : Saint-Didier-en-Bresse (71)
Re: [MY-AL]Rotation dans une boule
Comme une navigation à l'intérieur d'une vidéo 360°? -> rotation unique aux pôles
Ou plutôt une rotation externe (locale caméra) pour tourner selon 2 axes en continu?
Concernant les fonctions: Input.GetAxis
Je viens de voir l'exemple (le dernier) de la doc, ça te donne une bonne idée du lien entre rotation et axes.
Ou plutôt une rotation externe (locale caméra) pour tourner selon 2 axes en continu?
Concernant les fonctions: Input.GetAxis
Je viens de voir l'exemple (le dernier) de la doc, ça te donne une bonne idée du lien entre rotation et axes.
"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
Nétiquette du forum
Savoir faire une recherche
Apprendre la programmation
Re: [MY-AL]Rotation dans une boule
oui mis à part que la rotation doit pouvoir se faire sur les 3 axes.Boubouk a écrit : Comme une navigation à l'intérieur d'une vidéo 360°? -> rotation unique aux pôles
Sauf que la commande vient de l'intérieur de la sphère.Boubouk a écrit : Ou plutôt une rotation externe (locale caméra) pour tourner selon 2 axes en continu?
Ca c'est bon. Je connais.Boubouk a écrit : Concernant les fonctions: Input.GetAxis
Je viens de voir l'exemple (le dernier) de la doc, ça te donne une bonne idée du lien entre rotation et axes.
Je travaille sur ce problème depuis hier.
J'ai trouvé une solution qui marche à peu près.
Devant ma caméra. j'ai mis 9 quads avec le render désactivé en mode game, pour capturer les clics et mouvement de la souris.
et selon le quad sur lequel je clique et drag, le sphere fait une rotation qui suit la souris. Je ne sais si je suis assez clair?
C'est la seule méthode que j'ai réussit à faire marcher à peu près.
La différence entre l'intelligence et la stupidité est que l'intelligence est limitée.
- boubouk50
- ModoGenereux
- Messages : 6221
- Inscription : 28 Avr 2014 11:57
- Localisation : Saint-Didier-en-Bresse (71)
Re: [MY-AL]Rotation dans une boule
D'accord donc tu veux faire un drag de la sphere, c'est à dire faire une rotation en fonction du curseur.
Hum, là, comme ça, je sèche, il me faudrait expérimenter.
Lors du Drag, tu pourrais faire un Raycast pour savoir où tu touches la sphère, comparer cette position avec la précédente (hit du Raycast précédent), déterminer l'angle effectué par rapport au centre de la sphère et appliquer ensuite la rotation déterminée.
Je tenterai de ce côté là pour ma part.
Sinon, peut-être est-ce bien plus simple de déterminer 2 angles (X et Y) en fonction du delta de translation de la souris et de les appliquer sur la sphère, mais je ne sais pas si c'est simple que cela et si ça marche (surtout pour les pôles)
Hum, là, comme ça, je sèche, il me faudrait expérimenter.
Lors du Drag, tu pourrais faire un Raycast pour savoir où tu touches la sphère, comparer cette position avec la précédente (hit du Raycast précédent), déterminer l'angle effectué par rapport au centre de la sphère et appliquer ensuite la rotation déterminée.
Je tenterai de ce côté là pour ma part.
Sinon, peut-être est-ce bien plus simple de déterminer 2 angles (X et Y) en fonction du delta de translation de la souris et de les appliquer sur la sphère, mais je ne sais pas si c'est simple que cela et si ça marche (surtout pour les pôles)
"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
Nétiquette du forum
Savoir faire une recherche
Apprendre la programmation
Re: [MY-AL]Rotation dans une boule
Merci pour ta réponse.
Je maîtrise mal le RayCast. Si tu avais un petit exemple j'essayerai de l'appliquer pour voir. C'est vrai que je pense que ce serai mieux que ma solution que je vais exposer en suivant.
Devant ma caméra, j'ai disposé 9 colliders pour réceptionner les actions de la souris.
Chaque quad a un script nommé Touch :
Par rapport à sa position, les valeurs X_to... et Y_to... sont modifiées pour appliquer une rotation différente.
Ces commandes "Touchs" sont récupérées dans un script "DragRot" que voilà:
J'ai commenté mes scripts afin qu'il soient plus clairs.
Le script "DragRot" pourrait être plus simple, mais j'ai voulu lui apporter quelques options supplémentaires pour le rendre plus polyvalent.
Mes essais fonctionnent relativement bien. mais sûrement que ta méthode doit-être plus simple et surtout plus optimisée.
Voilà Qu'en penses-tu.
Tant que j'y suis, j'ai un autre problème, c'est avec les collisions.
Je ne sais pas comment filtrer les collisions.
Je voudrais que mon player n'entre pas en collision avec la sphère, mais que les autres objets eux, entrent en collision. Mais pour le moment, je n'ai pas encore fait mes recherches à ce sujet.
Merci.
Je maîtrise mal le RayCast. Si tu avais un petit exemple j'essayerai de l'appliquer pour voir. C'est vrai que je pense que ce serai mieux que ma solution que je vais exposer en suivant.
Devant ma caméra, j'ai disposé 9 colliders pour réceptionner les actions de la souris.
Chaque quad a un script nommé Touch :
Par rapport à sa position, les valeurs X_to... et Y_to... sont modifiées pour appliquer une rotation différente.
Code : Tout sélectionner
public class Touch : MonoBehaviour
{
[Tooltip("Le script qui récupère les commandes")]
public DragRot Maitre;
[Tooltip("Transfert du MousePosition.x vers une rotation.x")]
public int X_to_X;
[Tooltip("Transfert du MousePosition.x vers une rotation.y")]
public int X_to_Y;
[Tooltip("Transfert du MousePosition.x vers une rotation.z")]
public int X_to_Z;
[Tooltip("Transfert du MousePosition.y vers une rotation.x")]
public int Y_to_X;
[Tooltip("Transfert du MousePosition.y vers une rotation.y")]
public int Y_to_Y;
[Tooltip("Transfert du MousePosition.y vers une rotation.z")]
public int Y_to_Z;
bool drag;
int InverseY;
private void OnMouseDown()
{
if (Maitre.methode == DragRot.Methode.Manivelle) Maitre.drag = true;
if (Maitre.methode == DragRot.Methode.Yoyo) drag = true;
}
private void OnMouseOver()
{
if (Maitre.drag)
{
float axex = Input.GetAxis("Mouse X") * X_to_X;
float axey = Input.GetAxis("Mouse X") * X_to_Y;
float axez = Input.GetAxis("Mouse X") * X_to_Z;
axex += Input.GetAxis("Mouse Y") * Y_to_X * InverseY;
axey += Input.GetAxis("Mouse Y") * Y_to_Y * InverseY;
axez += Input.GetAxis("Mouse Y") * Y_to_Z * InverseY;
if (Maitre)
Maitre.Rotate(axex, axey, axez);
}
}
private void OnMouseDrag()
{
if (drag)
{
float axex = Input.GetAxis("Mouse X") * X_to_X;
float axey = Input.GetAxis("Mouse X") * X_to_Y;
float axez = Input.GetAxis("Mouse X") * X_to_Z;
axex += Input.GetAxis("Mouse Y") * Y_to_X * InverseY;
axey += Input.GetAxis("Mouse Y") * Y_to_Y * InverseY;
axez += Input.GetAxis("Mouse Y") * Y_to_Z * InverseY;
if (Maitre)
Maitre.Rotate(axex, axey, axez);
}
}
private void OnMouseUp()
{
if (Maitre.drag)
{
if (Maitre)
Maitre.Termine();
Maitre.drag = false;
}
if (drag)
{
if (Maitre)
Maitre.Termine();
drag = false;
}
}
private void Update()
{
//inverse la rotation verticale si le maitre tourne le dos
if (Maitre.transform.eulerAngles.y > 90 && Maitre.transform.eulerAngles.y < 270)
InverseY = -1;
else
InverseY = 1;
}
}
Code : Tout sélectionner
public class DragRot : MonoBehaviour
{
public enum Methode
{
Yoyo,
Manivelle
}
[Tooltip("Les objets à pivoter. C'est l'objet[0] qui sert de référence")]
public Transform[] objets;
[Tooltip("La méthode de drag. Yoyo : comme tirer sur la ficelle d'un yoyo")]
public Methode methode;
[Tooltip("Espace local ou mondial")]
public Space Space;
[Tooltip("Vitesse de rotation selon l'axe")]
public Vector3 Speed;
[Tooltip("Rotation finale maxi (0 si pas de controle Maxi et mini")]
public Vector3 maxi;
[Tooltip("Rotation finale mini (Maxi à 0 si pas de controle Maxi et mini")]
public Vector3 mini;
[Tooltip("Pas à adopter pour la rotation finale")]
public Vector3 Pas;
Vector3 dest;
bool move;
internal bool drag;
/// <summary>
/// Applique la rotation appelé par une commande Touch
/// </summary>
/// <param name="x">rotation axe x</param>
/// <param name="y">rotation axe y</param>
/// <param name="z">rotation axe z</param>
public void Rotate(float x, float y, float z)
{
Vector3 dir = new Vector3
{
y = x * Speed.x,
x = y * Speed.y,
z = z * Speed.z
};
for (int i = 0; i < objets.Length; i++)
{
dir = dir.normalized;
objets[i].Rotate(Vector3.up, dir.y , Space);
objets[i].Rotate(Vector3.right, dir.x, Space);
objets[i].Rotate(Vector3.forward, dir.z, Space);
}
}
/// <summary>
/// Termine la rotation des objets quand le bouton de la souris est relaché
/// </summary>
public void Termine()
{
//La rotation finale
dest = objets[0].eulerAngles;
if (Space == Space.Self)
dest = objets[0].localEulerAngles;
//Si un pas est spécifié corrige la rotation finale en fonction du pas
if (Pas != Vector3.zero)
{
dest = new Vector3(Mathf.Round(dest.x / Pas.x) * Pas.x,
Mathf.Round(dest.y / Pas.y) * Pas.y,
Mathf.Round(dest.z / Pas.z) * Pas.z);
Vector3 dest2;
dest2.x = this.dest.x + (this.dest.x > 0 ? Pas.x : -Pas.x);
dest2.y = this.dest.y + (this.dest.y > 0 ? Pas.y : -Pas.y);
dest2.z = this.dest.z + (this.dest.z > 0 ? Pas.z : -Pas.z);
if (Vector3.Distance(dest2, dest) < Vector3.Distance(this.dest, dest))
dest = dest2;
}
//Si maxi != zero limite la rotation finale au mini et maxi spécifié
if (maxi != Vector3.zero)
{
dest.x = dest.x > maxi.x ? maxi.x : dest.x;
dest.y = dest.y > maxi.y ? maxi.y : dest.y;
dest.z = dest.z > maxi.z ? maxi.z : dest.z;
dest.x = dest.x < mini.x ? mini.x : dest.x;
dest.y = dest.y < mini.y ? mini.y : dest.y;
dest.z = dest.z < mini.z ? mini.z : dest.z;
}
move = true;
}
private void Update()
{
//si move: termine la rotation en direction de la rotation finale
if (move)
{
Vector3 rot = objets[0].eulerAngles;
if (Space == Space.Self)
rot = objets[0].localEulerAngles;
Vector3 dif = new Vector3();
if (Vector3.Distance(dest, rot) > Vector3.Distance(Speed, Vector3.zero))
{
dif.x = (dest.x - rot.x) * Speed.x * Time.deltaTime;
dif.y = (dest.y - rot.y) * Speed.y * Time.deltaTime;
dif.x = (dest.z - rot.z) * Speed.z * Time.deltaTime;
AppliqueRot(dif);
}
else
{
move = false;
dif = (dest - rot);
AppliqueRot(dif);
}
}
}
/// <summary>
/// Fait pivoter les objets
/// </summary>
/// <param name="dif">la différence de pivot à appliquer</param>
private void AppliqueRot(Vector3 dif)
{
for (int i = 0; i < objets.Length; i++)
{
if (Space == Space.Self)
{
objets[i].localEulerAngles += dif;
}
else
{
objets[i].eulerAngles += dif;
}
}
}
}
Le script "DragRot" pourrait être plus simple, mais j'ai voulu lui apporter quelques options supplémentaires pour le rendre plus polyvalent.
Mes essais fonctionnent relativement bien. mais sûrement que ta méthode doit-être plus simple et surtout plus optimisée.
Voilà Qu'en penses-tu.
Tant que j'y suis, j'ai un autre problème, c'est avec les collisions.
Je ne sais pas comment filtrer les collisions.
Je voudrais que mon player n'entre pas en collision avec la sphère, mais que les autres objets eux, entrent en collision. Mais pour le moment, je n'ai pas encore fait mes recherches à ce sujet.
Merci.
La différence entre l'intelligence et la stupidité est que l'intelligence est limitée.
Re: [MY-AL]Rotation dans une boule
Salut Emile,
Perso je fais un peu pareil sur mon projet, mais depuis l'extérieur de la boule qui est une planète (mon projet)
Voici ma méthode :
Dans mon update :
Puis j'utilise OnMouseDrag :
Et ça marche quelque soit l'orientation de la sphere
Perso je fais un peu pareil sur mon projet, mais depuis l'extérieur de la boule qui est une planète (mon projet)
Voici ma méthode :
Dans mon update :
Code : Tout sélectionner
transform.RotateAround(transform.position, _cam.transform.up, -_rotSpeedX * _rotSpeedMultiplier);
transform.RotateAround(transform.position, _cam.transform.right, _rotSpeedY * _rotSpeedMultiplier);
_rotSpeedX = Mathf.Lerp(_rotSpeedX, 0, .05f);
_rotSpeedY = Mathf.Lerp(_rotSpeedY, 0, .05f);
Code : Tout sélectionner
protected virtual void OnMouseDrag()
{
RotateObjet();
}
public void RotateObjet()
{
_rotSpeedX = Input.GetAxis("Mouse X");
_rotSpeedY = Input.GetAxis("Mouse Y");
}
Re: [MY-AL]Rotation dans une boule
Grand merci Sebela
Formidable, 6 lignes de codes contre 2 scripts interminables, et ça marche très bien.
Il ne me reste plus qu'à l'étudier pour bien le comprendre.
Pour le faire fonctionner à partir de l'intérieur de la sphère, il suffit d'inverser le signe des _rotSpeed.
Encore un grand merci.
Je me suis penché sur la façon de filtrer les collisions, ça se passe au niveau des layers et dans le menu Edit/Project Settings/Physics en cas de besoin pour quelqu'un.
https://docs.unity3d.com/Manual/LayerBa ... ision.html
Edit :
J'ai regardé les explications chez unity de RotateAround Ce n'est pas très clair, surtout la traduction en français.
Mais grâce à Sebela, je crois avoir compris :
le premier paramètre c'est le point pivot, ça permet de faire des orbites,
le deuxieme parametre c'est l'axe de rotation vertical, horizontal ou autre,
et le troisième c'est la valeur de la rotation
Si ça peut aider...
Mais appliquer une rotation par rapport à l'axe de rotation d'un autre objet, je n'y aurai jamais pensé.
Utiliser l'orientation de la caméra pour calculer la rotation de l'objet, c'est tout simplement génial.
merci Sebela.
Formidable, 6 lignes de codes contre 2 scripts interminables, et ça marche très bien.
Il ne me reste plus qu'à l'étudier pour bien le comprendre.
Pour le faire fonctionner à partir de l'intérieur de la sphère, il suffit d'inverser le signe des _rotSpeed.
Encore un grand merci.
Je me suis penché sur la façon de filtrer les collisions, ça se passe au niveau des layers et dans le menu Edit/Project Settings/Physics en cas de besoin pour quelqu'un.
https://docs.unity3d.com/Manual/LayerBa ... ision.html
Edit :
J'ai regardé les explications chez unity de RotateAround Ce n'est pas très clair, surtout la traduction en français.
Mais grâce à Sebela, je crois avoir compris :
le premier paramètre c'est le point pivot, ça permet de faire des orbites,
le deuxieme parametre c'est l'axe de rotation vertical, horizontal ou autre,
et le troisième c'est la valeur de la rotation
Code : Tout sélectionner
transform.RotateAround(pivot, axe, angle de rotation);
Mais appliquer une rotation par rapport à l'axe de rotation d'un autre objet, je n'y aurai jamais pensé.
Utiliser l'orientation de la caméra pour calculer la rotation de l'objet, c'est tout simplement génial.
merci Sebela.
La différence entre l'intelligence et la stupidité est que l'intelligence est limitée.
Re: [MY-AL]Rotation dans une boule
Mais de rien
Je me souviens m'être arraché les cheveux comme toi avant d'avoir trouvé cette fonction
Tous unis contre la maltraitance capillaire !
Je me souviens m'être arraché les cheveux comme toi avant d'avoir trouvé cette fonction
Tous unis contre la maltraitance capillaire !
Re: [MY-AL]Rotation dans une boule
Port du casque obligatoire pour éviter tout accident.
Merci encore.
Merci encore.
La différence entre l'intelligence et la stupidité est que l'intelligence est limitée.