Rotation involontaire

Questions à propos du scripting. Hors Shader, GUI, Audio et Mobile.
ced_le_dingue
Messages : 70
Inscription : 29 Oct 2019 21:58

Rotation involontaire

Message par ced_le_dingue » 09 Sep 2020 18:02

Bonjour à tous,

1) Contexte

Je suis débutant en Unity et j'ai une soucis, dont voici le code ci dessous pour vous permettre de bien situer le problème:

- J'ai crée une boule qui se déplace quand je me sers des commandes horizontales/verticales:

Code : Tout sélectionner

transform.Translate(Vector3.right * Input.GetAxis("Horizontal") * Time.deltaTime*speed);
transform.Translate(Vector3.forward * Input.GetAxis("Vertical") * Time.deltaTime * speed);
- Je lui ai mis un rigid body pour qu'elle tombe et qu'elle bute contre un mur.

2) Description du problème

Le problème c'est que lorsque ma boule rencontre un mur, elle tourne sur elle même et ça change tous mes axes de déplacement (en voulant aller à droite, je vais à gauche ou en haut etc...), comme le montre le gif ci dessous (cliquez dessus):
Image

3) Ce que je voudrai obtenir

- Que ma boule se déplace toujours normalement après avoir rencontré un mur
- Pouvoir faire tourner ma boule sur elle même en la faisant se déplacer

Pourriez vous m'aider svp?
Merci beaucoup pour votre aide, et désolé si c'est un peu décousu.
Ced

Avatar de l’utilisateur
Max
Messages : 8771
Inscription : 30 Juil 2011 13:57
Contact :

Re: Rotation involontaire

Message par Max » 09 Sep 2020 18:36

Bonsoir,

Ton soucis est que tu passes par les Transform.Translate pour faire bouger ta boule, alors qu'elle est soumise à la physique. Ce qu'il faut éviter en règle générale.
Pour diriger ta boule, le conseil est de regarder plutôt du coté des fonctions spécifiques, comme par exemple RigidBody.AddForce.
En reprenant ton code, cela donnerait quelque chose comme:

Code : Tout sélectionner

        rigidbody.AddForce(Input.GetAxis("Horizontal") * speed, 0, Input.GetAxis("Vertical") * speed);
Image
Pas d'aide par MP, le forum est là pour ça.
En cas de doute sur les bonnes pratiques à adopter sur le forum, consulter la Charte et sa FAQ

ced_le_dingue
Messages : 70
Inscription : 29 Oct 2019 21:58

Re: Rotation involontaire

Message par ced_le_dingue » 09 Sep 2020 18:41

Bonjour Max,

Ah super je vais essayer ça alors et je te fais un retour, merci beaucoup,

Ced

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

Re: Rotation involontaire

Message par jmhoubre » 09 Sep 2020 18:58

Tu dois aussi interdire les rotations dans le rigidbody.

Avatar de l’utilisateur
Max
Messages : 8771
Inscription : 30 Juil 2011 13:57
Contact :

Re: Rotation involontaire

Message par Max » 09 Sep 2020 19:11

jmhoubre a écrit :
09 Sep 2020 18:58
Tu dois aussi interdire les rotations dans le rigidbody.
vu qu'il veut garder la liberté de voir tourner la boule, pas nécessairement la bonne piste.
Image
Pas d'aide par MP, le forum est là pour ça.
En cas de doute sur les bonnes pratiques à adopter sur le forum, consulter la Charte et sa FAQ

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

Re: Rotation involontaire

Message par jmhoubre » 09 Sep 2020 21:18

Il lui colle un transform.Rotate (0f, rotationSpeed *Time.DeltaTime, 0f) dans l'update, cela devrait convenir.

ced_le_dingue
Messages : 70
Inscription : 29 Oct 2019 21:58

Re: Rotation involontaire

Message par ced_le_dingue » 10 Sep 2020 00:59

Re les gars, merci beaucoup pour votre aide.

J'ai essayé les 2 solutions.

La solution de Max : Ma boule tourne bien sur elle même et avance, seulement elle a de l’inertie, car même quand j’arrête d'appuyer sur le bouton pour la faire avancer, elle continue d'avancer un peu.

La solution de jmhoubre : Ma boule tourne juste sur elle même sans avancer. MAIS!!!!!! je sais que c'est parce que je me suis contenté de copier ton code sans rajouter ce qu'il faut pour qu'elle avance... Je ne suis vraiment pas au point pour l'instant... Tellement de choses à comprendre que ça me parait insurmontable, je vais faire de mon mieux pour bien assimiler ces bases qui me paraissent si compliquées :pleur4: ... Comme ça je poserai plus de questions bêtes...

Conclusion:
En appliquant vos réponses, je me suis rendu compte que ce que je souhaiterai, c'est que:

- Ma boule avance par palier d'une unité sur un seul axe (celui dans lequel la caméra est dirigée)
(e.g. mon sol est une plaque carrée de (13, 1, 13) : je voudrai que tout en tournant sur elle même, la boule avance de 1 en 1 (ex: (1,0,0) ou (0,0,1)) à chaque appuie sur le bouton vertical pour la faire avancer, et si je reste appuyé sur le bouton elle va toujours de 1 en 1 tant que je n’arrête pas d'appuyer)....

- Et que quand j'appuie mes touches d'axe horizontal, ma caméra tourne de 90° dans le sens + ou - (selon si j'ai appuyé à droite ou à gauche): ce qui change l'axe vers lequel la boule va tourner (ie: au lieu de tourner en direction de (+ou-)z, elle tournera en direction de (+ou-)x .

- Qu'à chaque fois que le boule se déplace de 1 en 1, la caméra la suive. J'ai déjà pu faire cela grâce à ce code:

Code : Tout sélectionner

public class Camera : MonoBehaviour
{

    public GameObject player;
    private Vector3 offset;

    // Start is called before the first frame update
    void Start()
    {
        offset = transform.position - player.transform.position;
    }

    // Update is called once per frame
    void LateUpdate()
    {
        transform.position = player.transform.position + offset;
    }
}
MALHEUREUSEMENT, la caméra bouge de haut en bas à chaque rotation, comme si elle suivait l'extremité de la boule et non son centre... Sauriez vous ce qui manque pour éviter ça?

N.B: Pour ce dernier point, je n'ai pas utilisé le principe Parent/enfant (mettre hiérarchiquement la caméra dans ma boule), car si je fais ça, j'ai vu que quand ma boule rencontre un mur, la caméra devient folle :happy1:

Merci à vous,
Ced

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

Re: Rotation involontaire

Message par jmhoubre » 10 Sep 2020 03:25

Bonsoir,
il est tard, je vais faire court :
- pour déplacer/pivoter un objet, il y a plusieurs façons de faire : sans la physique (par le transform), avec la physique (par le rigidbody), les animations (pour mémoire), ... Comme cela a été indiqué plus haut, il faut éviter de mélanger physique et non physique, car cela provoque des comportements étranges.
- avant de choisir l'une ou l'autre des manières, il y a des questions à trancher, comme "mon jeu a-t-il besoin de la physique ?", ou autrement dit, "des objets vont-ils s'entrechoquer ?" ou "ai-je besoin de la gravité ?".

Une fois que tu auras choisi, ce sera plus aisé de t'indiquer le bon chemin. Ton dernier billet ne parle plus de murs et de faire tomber la boule : as-tu vraiment besoin de la physique ?

Si tu persistes dans la physique, il y a une méthode supplémentaire utilisée par Unity : en plus d'Update à chaque frame, il y a FixedUpdate dans laquelle s'effectuent les calculs de physique. Et leur fréquence d'appel n'est pas la même.

Personnellement, quand je ne peux pas éviter la physique, je fais en gros ceci :

Code : Tout sélectionner

[SerializeField] private float force = 10f; // Dépend de la masse de la boule, de la friction...
[SerializeField] private float rotationForce = 5f; // A régler selon la masse et la friction angulaire.
private Vector3 playerInputs;
private Rigidbody rigidbody;

private void Start () {
	rigidbody = GetComponent<Rigidbody> ();
}

private void Update () {
	playerInputs = new Vector3 (Input.GetAxis("Horizontal"), 0f, Input.GetAxis("Vertical"));
}

private FixedUpdate() {
	Vector3 drection = playerInputs.normalized;
	Vector3 forceApplied = direction * force;
	
	// En utilisant AddForce, on applique la force dans le référentiel du monde.
	// Les rotations de la boule ne comptent pas.
	rigidbody.Add(forceApplied);
	// Pour que la boule tourne sur elle-même.
	rigidbody.AddTorque(rotationForce);
}
Difficile d'aller plus loin : je ne sais pas pourquoi ta boule tourne sur elle-même (j'ai supposé que c'était pour le fun, comme certaines soucoupes volantes tournent en se déplaçant),
De plus dans ton dernier billet ta boule doit avancer par palier : je ne comprends pas trop. Elle disparaît et réapparaît 1 unité plus loin ?
Si la boule est sur une plaque, et qu'il n'y a pas de murs, pourquoi utiliser la gravité ? (Dans ton premier message, il y a un mur, on ne sait pas trop où, et dans le dernier, tu n'en parles plus. Dans le premier, quand la boule rencontre un mur, la boule se déplace toujours normalement : elle rebondi quand même, elle s'arrête, ou elle traverse le mur ?)
Pour la caméra, il me parait plus simple de la traiter quand le problème de la boule sera réglé.

Pour résumer ce que j'ai compris :
- le terrain est un plane. Il y a 4 murs qui délimitent le terrain. Ces murs empêchent la boule de sortir du terrain (pas de rebond).
- la boule avance (flèche haut) recule (flèche bas), tourne de 90° (flèches gauche et droite). Ces mouvements sont discrets (avance et recule par pas d'une unité).
- pour faire joli, la boule tourne sur elle-même.
Pour moi, la physique est inutile. En plus, ce n'est pas vraiment le premier truc à faire quand on débute.
J'attends une réponse avant d'aller plus loin.

ced_le_dingue
Messages : 70
Inscription : 29 Oct 2019 21:58

Re: Rotation involontaire

Message par ced_le_dingue » 10 Sep 2020 11:30

Bonjour jmhoubre,

D'abord, merci beaucoup pour le temps que tu m'accorde alors que c'est clair que je ne devrai pas commencer par là étant débutant tu as parfaitement raison.

J'ai bien lu ton code dans ton dernier message et en effet je ne saisi pas tout, ce qui confirme ce que je pense après coup et ce que tu as compris: je dois partir de zero dans mon apprentissage. (J'avais commencé il y a 1-2 ans mais j'avais laché l'affaire car ça me paraissait insurmontable... du coup j'ai pas bien retenu les bases que j'avais apprises en ce temps là, et j'ai essayé de continuer là où je m’étais arrêté; mais faut que je re-reparte de zéro car j'ai oublié plein de choses.

Mais en gros ce que je voulais faire (je vais mettre ça en suspend pour repartir de zéro dans mon apprentissage), c'était que la boule parcourt ce type de forme, et qu'elle suive la structure, comme ceci en gros (tout en tournant la caméra à chaque fois):

Image

Et j'avais pensé qu'il fallait de la physique à ma boule boule pour qu'elle reste collée à la structure (comme sur l'image ci dessus). Mais si je comprends bien ce que tu me dis, ce n'est pas nécessaire? Je pensais qu'il fallait que je change le sens de la gravité à chaque fois que la boule changerai de surface, c'est pour ça que j'ai supposé qu'il fallait lui mettre de la physique. Et aussi pour pas qu'elle passe à travers un mur mais j'ai compris en te lisant que ça n'avait rien à voir... En revanche je suppose que pour que la boule reste collé faut tout de même faire jouer la gravité non?

Bref, je vais reprendre les bases et comme ça la prochaine fois si j'ai des questions, ce sera + précis et moins incohérent (vu qu'il me manque des bases solides, je pars dans tous les sens... J'ai l'habitude de programmer en VBA c'est pour ça: quand je me suis mis au VBA, j'avais appris de cette manière, bout de code par bout de code. Mais cette façon d'apprendre, n'est pas faisable en C# je m'en rend compte.

Je, je reprendrai ça et vos précieuses réponses à tous à ce sujet quand j'aurai acquis de solides connaissances (si j'y arrive un jour lol). Merci beaucoup en tout cas vous êtes tous super sympas et super patients ;-) :amen:

Excellente journée à tous,
Ced

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

Re: Rotation involontaire

Message par jmhoubre » 10 Sep 2020 13:45

Bonjour,
je pense qu'il est plus raisonnable, en effet, de partir avec les bonnes bases. Je te conseille cette page du forum, tu trouveras des routes bien balisées dans la jungle d'Unity.

Merci pour les scans, c'est maintenant super clair. Et oui, tu aurais besoin de la physique. Sauf si ...

J'ai lu plusieurs fois que le développement de jeux vidéos n'est pas obligé d'être une simulation parfaite, et qu'il faut parfois utiliser des artifices et des subterfuges. Par exemple, pour produire de la pluie, tu n'es pas obligé de créer un lac, ajouter de la chaleur à un soleil pour que l'eau s'évapore, imaginer un système de turbulences pour que la vapeur d'eau monte et se refroidisse pour former des nuages qui enfin, produiront de la pluie. Un système de particules ou une texture rendue par-dessus la caméra produiront un effet suffisamment réaliste, sans consommer toute la puissance de ton ordinateur.

Dans ton cas, j'essaierai ceci :
- je place la forme à plat sur un plane invisible
- je construis un mur invisible à l'extérieur de la forme, séparé de la forme par la taille de la boule (objets vides avec des colliders)
- je filme en vue de dessus.
Je n'ai pas essayé, mais je pense que cela fonctionne. L'illusion sera parfaite si dans ton décor, tu déplaces quelques objets du faux haut vers le faux bas. Enfoncé Christopher Nolan ^^

Répondre

Revenir vers « Scripting »