[RÉSOLU] [AL] Condition Input qui ne fonctionne pas à 100%

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
Avatar de l’utilisateur
Axel74
Messages : 100
Inscription : 23 Mai 2014 16:47
Localisation : Thonon - Lyon

[RÉSOLU] [AL] Condition Input qui ne fonctionne pas à 100%

Message par Axel74 » 11 Avr 2017 18:15

Bonjour bonsoir tout le monde !

J'ai un petit soucis de code qui ne fonctionne avec un Input qui ne se lance pas à 100%, je m'explique :

J'ai donc un Character Controller et mon script qui me permet d'effectuer des mouvements à un personnage, jusque là tout va bien et ça fonctionne.

J'ai en revanche un de ces Input qui me pose problème, pour sauter plus exactement. Ma condition et le reste de mon script fonctionne correctement, mais de temps en temps dans mon application il arrive que mon personnage ne saute pas ! (c'est le cas 1 fois sur 15 par exemple, c'est juste très aléatoire)

Alors je suis certains que cela ne vient pas d'un faux contact avec mon bouton, ayant fait plusieurs essais à sauter pendant 1 minute avec différentes touches entre mon clavier et ma manette de jeux...

J'avais lu que la fonction Update () est plus appropriée pour des Input que le FixedUpdate (). Cependant le problème est plus récurant dans la fonction Update que dans la fonction FixedUpdate, pour avoir essayé les deux...

Voilà à quoi ressemble mon code :

Code : Tout sélectionner

	void Update () {
	
		Vector3 movement = new Vector3 (0, vertVelocity, 0);
		movement = transform.rotation * movement * Time.deltaTime;
		controller.Move (movement);	// controller est mon CharacterController
	}

	void FixedUpdate () {
	
		Jump ();
	}
	
	void Jump (){
	
		if (controller.isGrounded) {
			jumpTime = 2;	// Possibilité de faire un double jump
			vertVelocity = 0;
		} 
		else
			vertVelocity += Physics.gravity.y * rb.mass * Time.deltaTime;

		if (Input.GetButtonDown (inputSetting.JUMP_BUTTON))

			if (jumpTime > 0) {
			
			vertVelocity = jumpPower;
			jumpTime--;
		}
	}
Je ne pense pas que cela vienne réellement du code, mais si c'est le cas.. Merci pour votre aide.
Dernière édition par Axel74 le 14 Avr 2017 05:43, édité 1 fois.
Douille ou l'ail que pote étaux ? Yes I like.

Avatar de l’utilisateur
evereal
Messages : 109
Inscription : 06 Nov 2015 18:46

Re: [AL] Condition Input qui ne fonctionne pas à 100%

Message par evereal » 12 Avr 2017 08:24

Hello,
Premièrement, pour être propre, les informations d'input doivent être mis dans update et la physique dans fixedupdate.

En second je te conseille de traquer ta variable controller.isGrounded pour voir si elle ne change pas de valeur même quand tu ne sautes pas.
“La théorie, c'est quand on sait tout et que rien ne fonctionne. La pratique, c'est quand tout fonctionne et que personne ne sait pourquoi. Ici, nous avons réuni théorie et pratique : Rien ne fonctionne... et personne ne sait pourquoi !”

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

Re: [AL] Condition Input qui ne fonctionne pas à 100%

Message par boubouk50 » 12 Avr 2017 09:36

Comme le pointe Evereal, dans ton code, tu ne peux faire un saut que si tu es au sol. Il suffit que ton perso fasse un petit saut sur une aspérité ou autre, donc que isGrounded soit à false, et hop tu ne peux pas sauter.
Traque donc isGrounded comme conseillé, et si c’est bien cela, il va falloir ruser un peu sur les conditions, notamment le InputButtonDown (). Il n'est joué que sur une seule frame, peut-être faudrait-il le garder en mémoire sur 2-3 frames pour éviter les artéfacts.
"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

Avatar de l’utilisateur
Axel74
Messages : 100
Inscription : 23 Mai 2014 16:47
Localisation : Thonon - Lyon

Re: [AL] Condition Input qui ne fonctionne pas à 100%

Message par Axel74 » 12 Avr 2017 12:38

Alors j'ai bien une class "GetInput" dans la fonction Update, j'ai juste remplacé ici dans l'exemple montré ma variable par "Input.GetButtonDown ...", j'y penserai la prochaine fois à mettre la notation à quoi correspond la variable plutôt que de modifier le code pour faire au plus clair.

Quoi qu'il arrive même si je ne saute pas et que je fasse tomber mon personnage dans le vide, je peux toujours faire mon double saut (mon saut ne dépend pas du isGrounded, indirectement. le isGrounded remet mon compteur de double saut à 2, sinon retour au sol, cependant je peux toujours sauter).
J'ai fait un Debug.Log et il y a vraiment des fois mon script ne relève pas ce GetButtonDown.

J'ai donc légèrement modifié et mis mes calculs de position dans la fonction FixedUpdate, voilà mon script que j'ai modifié pour que vous ayez juste à le copier coller pour l'essayer. Appliquez le sur une capsule, sans plus, le script fera le reste. Avec un plan sous la capsule pour faire le sol, juste par curiosité si vous avez aussi le même problème (si vous avez envie de faire le test) :

Code : Tout sélectionner

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class TestJump : MonoBehaviour {

	CharacterController characterController;
	Rigidbody rb;

	bool inputJump;
	float vertVelocity;
	int jumpPower = 10;


	void Start () {
		characterController = this.gameObject.AddComponent<CharacterController> ();
		rb = this.gameObject.AddComponent<Rigidbody> ();
		rb.mass = 10;
	}

	void GetInput () {
		inputJump = Input.GetButtonDown ("Jump");
	}
	
	// Update is called once per frame
	void Update () {
		GetInput ();
	}

	void FixedUpdate () {

		Jump (); 

		Vector3 movement = new Vector3 (0, vertVelocity, 0);
		movement *= Time.deltaTime;
		characterController.Move (movement);
	}

	void Jump () {
		if (characterController.isGrounded)
			vertVelocity = 0;
		else
	 		vertVelocity += Physics.gravity.y * rb.mass * Time.deltaTime;

		if (inputJump) 
			vertVelocity = jumpPower;
	}
}
boubouk50 a écrit :il va falloir ruser un peu sur les conditions, notamment le InputButtonDown (). Il n'est joué que sur une seule frame, peut-être faudrait-il le garder en mémoire sur 2-3 frames pour éviter les artéfacts.
C'est à dire que je dois le jouer sur plusieurs frame ? Du coup ça me chamboule un peu car Update est appelé chaque frame et le FixedUpdate plusieurs fois par frame, et là il faudrait faire appel à cette condition plusieurs fois par frame ? :aille2: Faut t-il que je change le frameRate ? C'est étonnant que ce problème ne parle à personne..
https://docs.unity3d.com/ScriptReferenc ... eRate.html
Douille ou l'ail que pote étaux ? Yes I like.

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

Re: [AL] Condition Input qui ne fonctionne pas à 100%

Message par boubouk50 » 12 Avr 2017 13:13

Il peut y avoir plusieurs Update () pour un seul FixedUpdate (), donc potentiellement inputJump peut passer à la trappe. Laisser inputJump jusqu'au prochain fixedUpdate () pourrait donc régler le problème.
En gros, ton Update () met le inputJump à true si l'input à été concluant dans l'Update () et le FixedUpdate () le remet à false à la fin. Je ne sais pas si le FixedUpdate () accepte les inputs correctement, si c'est le cas, alors il faudrait gérer l'inputJump dans le FixedUpdate ().
"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

Avatar de l’utilisateur
Axel74
Messages : 100
Inscription : 23 Mai 2014 16:47
Localisation : Thonon - Lyon

Re: RÉSOLU [AL] Condition Input qui ne fonctionne pas à 100%

Message par Axel74 » 12 Avr 2017 13:31

Wah super merci beaucoup boubouk ça répond tout à fait à mon problème :-D Voilà le résultat des modifications :

Code : Tout sélectionner

 void GetInput () {
	if ( !inputJump )	// la condition ajoutée au [i]GetInput [/i]de mon Jump
      inputJump = Input.GetButtonDown ("Jump");
   }

   void Jump () {
      ...
	jumpInput = false; // à la fin de cette fonction
}
Comment se fait t-il que l'Update est plus adapté aux Input si dans ce cas ça "interfère" entre les frames de ces deux fonctions ?
Douille ou l'ail que pote étaux ? Yes I like.

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

Re: [AL] Condition Input qui ne fonctionne pas à 100%

Message par boubouk50 » 12 Avr 2017 13:57

Tous les jeux n'utilises pas la physique et l'Update () est approprié pour récupérer un événement sur une unique image affichée.
Admettons que ton frameRate est à 3 et ton FixedUpdate () est à 30.
Si ton Input est dans ton FixedUpdate (), tu verras 3 images mais tu pourrais contrôler ton personnage entre ses frames (10 fois chacune) à cause d'inputs différents, donc tu contrôlerais ton personnage sans le voir se déplacer. Bon c'est extrême mais c'est l'idée, je pense: Que les contrôles soient associés au visuel.
A l'inverse, ça reviendrait au même puisque quoi qu'il arrive tu contrôles par la physique dans un FixedUpdate ().
Il semble donc plus juste de gérer ses contrôles dans l'Update ().

je suis sur que sur le net tu peux trouver des classes ou des coroutines qui gèrent le décalage Update () - FixedUpdate () pour les Inputs.
"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

Avatar de l’utilisateur
Axel74
Messages : 100
Inscription : 23 Mai 2014 16:47
Localisation : Thonon - Lyon

Re: [AL] Condition Input qui ne fonctionne pas à 100%

Message par Axel74 » 13 Avr 2017 07:07

boubouk50 a écrit :je suis sur que sur le net tu peux trouver des classes ou des coroutines qui gèrent le décalage Update () - FixedUpdate () pour les Inputs.
Voilà ce que j'ai trouvé, peut être que ça répondrai aussi au problème :
https://docs.unity3d.com/ScriptReferenc ... pdate.html
Douille ou l'ail que pote étaux ? Yes I like.

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

Re: [AL] Condition Input qui ne fonctionne pas à 100%

Message par boubouk50 » 13 Avr 2017 09:12

Tout a fait.
Tu peux faire une coroutine qui gère les Inputs et qui attend le FixedUpdate () pour les lui 'envoyer'.

Si tu as résolu ton problème, merci de mettre [RESOLU] en début de titre du premier post stp. Merci.
"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

Répondre

Revenir vers « (C#) CSharp »