Page 1 sur 3

Personnage monte escalier mais sur path et doncmvt en dent de scie

Publié : 11 Nov 2019 22:23
par freepl
Bonjour

J'ai un perso qui a un mvt de montée d'escalier. Il est issu de Mixamo. J'ai pris l'animation de montée d'escalier sur place et celle où le perso avance.

Le pb vient du fait que mon perso avance le long d'un path.
Donc entre 2 repères sur ce path, l'animation "fait monter le perso sur deux marches" mais comme l'animation est en loop, le perso "redescend" et ainsi de suite. Le mvt est donc en dent de scie, quel que soit le mvt pris ( sur place ou en mouvement).

Comment faire pour que le perso monte le long du path sans dent de scie?

Merci

Re: Personnage monte escalier mais sur path et doncmvt en dent de scie

Publié : 12 Nov 2019 10:43
par Alesk
Au moment du rebouclage de l'animation, tu déplaces le personnage de l'équivalent du déplacement qu'il avait effectué en finissant sa boucle précédente d'animation.

Re: Personnage monte escalier mais sur path et doncmvt en dent de scie

Publié : 12 Nov 2019 11:48
par freepl
Bonjour
C'est sur Unity ou maya que je dois faire cela ?

si j'ai compris , je récupère la position du hips de la première image en ajoutant une image avec cette nouvelle coordonnée?

et autre question, j'ai un path qui suit un escalier, mon perso le suit mais il est toujours perpendiculaire à ce dernier.
Le perso ne reste pas vertical.
Comment modifier cela ?
Z007.jpg
Z007.jpg (132.03 Kio) Consulté 3491 fois

Merci

Re: Personnage monte escalier mais sur path et doncmvt en dent de scie

Publié : 12 Nov 2019 12:15
par boubouk50
La question est: comment déplaces-tu le personnage le long du path?
Est-ce une animation? Est-ce en code? Utilises-tu une librairie spécifique?
L'orientation n'est pas définie dans l'animation de boucle, donc c'est forcément au niveau du suivi du path.

Re: Personnage monte escalier mais sur path et doncmvt en dent de scie

Publié : 12 Nov 2019 12:20
par freepl
C'est du code. J'utilise un dérivé de ItWeen.
L'animation est jouée en même temps

code dérivé de ItWeen

Code : Tout sélectionner

using UnityEngine;
using System;
using System.Collections;
using System.Collections.Generic;
// la fonction de trajet aérien est bloquée
/* Create by :
 * Fabian Métayer
 * 27/10/2015
 */
public class TrajetVl : MonoBehaviour {
	public GameObject target_Path;
	public float kmh; // vitesse voulue
	public float kmhActuel; // vitesse reelle
	public float mEntrePoint = 5.0f;
	private float time;
	public float fraction;
	public Transform[] tabtList = new Transform[11];
	public int minTab = 0;
	public Transform detecteur;
	public LayerMask layerPanneau;
	public Collider[] toucheDetecteur;
	public bool coupeDetecteur;
	private Light jourNuit;
	private GameObject eclairage;
	private GameObject eclairageFreins;
	public GameObject clignotantsDroits;
	public GameObject clignotantsGauche;
	private IEnumerator coroutineClignotants;

	public InterieurVl interieur;

	public void DemrageVl () {
		tabtList = new Transform[11];
		TabDynamique ();
		if (transform.FindChild("Detecteur"))
			detecteur = transform.FindChild("Detecteur").transform;

		jourNuit = GameObject.Find("Sky Dome").transform.FindChild("Light").GetComponent<Light>();

		//cherche dans ces enfants un object avec le nom Eclairage
		//si existe alors on ajoute l'object portant le nom "Eclairage" dans la variable eclairage
		if (this.transform.FindChild ("Eclairage")) {
			eclairage = this.transform.FindChild ("Eclairage").gameObject;
		}

		if (this.transform.FindChild ("Eclairage_Freins")) {
			eclairageFreins = this.transform.FindChild ("Eclairage_Freins").gameObject;
			eclairageFreins.SetActive (false);
		}
		
		if (this.transform.FindChild ("Eclairage_Clignotants_droits")) {
			clignotantsDroits = this.transform.FindChild ("Eclairage_Clignotants_droits").gameObject;
			clignotantsDroits.SetActive (false);
		}

		if (this.transform.FindChild ("Eclairage_Clignotants_gauche")) {
			clignotantsGauche = this.transform.FindChild ("Eclairage_Clignotants_gauche").gameObject;
			clignotantsGauche.SetActive (false);
		}

		StartCoroutine("WalkThePath");
	}

	public void TabDynamique () {
		fraction = 0.1f;
		int count = 0;

		for (int i = 0; i < 11; i++) {
			if (minTab+i < target_Path.transform.childCount) {
				tabtList[i] = target_Path.transform.GetChild(minTab+i);
				count++;
			}
		}

		if (minTab+8 < target_Path.transform.childCount)
			minTab += 8;
		else
			minTab += count;
	}

	public void StopCoroutine () {
		StopCoroutine("WalkThePath");
	}

	IEnumerator WalkThePath () {
		while(true){
			time = (tabtList.Length * mEntrePoint)/(kmhActuel / 3.6f);
			transform.position = iTween.PointOnPath (tabtList, fraction);
			fraction += Time.deltaTime / time;
			if (fraction > 1.0f)
				fraction = 0.0f;
			transform.LookAt(iTween.PointOnPath(tabtList, fraction + 0.1f));
			if (kmhActuel < kmh){
				kmhActuel += 0.7f;// acceleration jusqu'à la vitesse kmh 0.7f
			} else if (kmhActuel > kmh && kmh != 0) {
				kmhActuel -= 0.9f;// decceleration douce 0.9
			} else if (kmh == 0) {
				kmhActuel = 0;// on stoppe brutalement le VL
			}

			if (fraction >= 0.9f) //0.9f
				TabDynamique();

			GestionDetecteur ();
			GestionLumiere ();
			GestionFreins ();

			yield return null;
		}
	}

	void GestionDetecteur () {
		if (detecteur != null) {
			if (gameObject.tag == "VEHICULE")
				toucheDetecteur = Physics.OverlapSphere(detecteur.position, 0.75f, layerPanneau);
			else
				toucheDetecteur = Physics.OverlapSphere(detecteur.position, 0.5f, layerPanneau);

			if (toucheDetecteur.Length != 0) {
				foreach (var other in toucheDetecteur) {
					if (other.tag == "CoupeDetecteur") {
						coupeDetecteur = other.GetComponent<CoupeDetecteur>().detecteur;
						kmhActuel = 50.0f;// pour degager les croisements
					}

					if (other.tag == "CoupeDetecteurAutre") {
						coupeDetecteur = other.GetComponent<CoupeDetecteur>().detecteur;
						kmhActuel = 4.0f;
					}

					if (coupeDetecteur == false) {
						if (other.tag == "ModifVitesse") {
							kmh = other.GetComponent<Panneau>().vitesse;
						} else if (other.tag == "EntreeInstersection") {
							kmh = other.GetComponent<Priorite>().vitesse;
						} else if (other.tag == "VEHICULE") {

							if (kmh > other.GetComponent<TrajetVl>().kmh)
							kmh = other.GetComponent<TrajetVl>().kmh;
						} else if (other.tag == "ClignotantsOn") {
							kmh = other.GetComponent<GestionClignotants>().vitesse;
							if (other.GetComponent<GestionClignotants>().trajet == target_Path) {
								ClignotantsOff ();
								if (other.GetComponent<GestionClignotants>().enumClignotants == EnumClignotants.Droites) {
									coroutineClignotants = ClignotantsDroits();
									StartCoroutine (coroutineClignotants);
								} else {
									coroutineClignotants = ClignotantsGauche();
									StartCoroutine (coroutineClignotants);
								}
							}
						} else if (other.tag == "ClignotantsOff") {
							kmh = other.GetComponent<GestionClignotants>().vitesse;
							ClignotantsOff ();
						}
					}
				}
			}

			if (kmhActuel == 0 && toucheDetecteur.Length == 0)
				kmhActuel = 30.0f;

		}
	}

	void GestionLumiere () {
		if (eclairage != null) {
			if (jourNuit.intensity < 0.15f) {
				if (eclairage.activeInHierarchy == false)
					eclairage.SetActive (true);
			}
			else {
				if (eclairage.activeInHierarchy == true)
					eclairage.SetActive (false);
			}
		}
	}

	void GestionFreins () {
		if (eclairageFreins != null){
			if (kmhActuel > kmh+3 || kmhActuel == 0) {
				if (eclairageFreins.activeInHierarchy == false)
					eclairageFreins.SetActive (true);
			} else {
				if (eclairageFreins.activeInHierarchy == true)
					eclairageFreins.SetActive (false);
			}
		}
	}

	IEnumerator ClignotantsDroits () {
		if (clignotantsDroits != null) {
			while (true) {
				clignotantsDroits.SetActive (true);
				yield return new WaitForSeconds (0.3f);
				clignotantsDroits.SetActive (false);
				yield return new WaitForSeconds (0.3f);
			}
		}
	}

	IEnumerator ClignotantsGauche () {
		if (clignotantsGauche != null) {
			while (true) {
				clignotantsGauche.SetActive (true);
				yield return new WaitForSeconds (0.3f);
				clignotantsGauche.SetActive (false);
				yield return new WaitForSeconds (0.3f);
			}
		}
	}

	void ClignotantsOff () {
		if (coroutineClignotants != null) {
			StopCoroutine (coroutineClignotants);

			if (clignotantsDroits != null)
				clignotantsDroits.SetActive (false);
			if (clignotantsGauche != null)
				clignotantsGauche.SetActive (false);
			 
			coroutineClignotants = null;
		}
	}

}
Je pense que cela se passe ici mais je ne sais pas comment dire de ne pas tourner verticalement

Code : Tout sélectionner

IEnumerator WalkThePath () {
		while(true){
			time = (tabtList.Length * mEntrePoint)/(kmhActuel / 3.6f);
			transform.position = iTween.PointOnPath (tabtList, fraction);
			fraction += Time.deltaTime / time;
			if (fraction > 1.0f)
				fraction = 0.0f;
			transform.LookAt(iTween.PointOnPath(tabtList, fraction + 0.1f));
			if (kmhActuel < kmh){
				kmhActuel += 0.7f;// acceleration jusqu'à la vitesse kmh 0.7f
			} else if (kmhActuel > kmh && kmh != 0) {
				kmhActuel -= 0.9f;// decceleration douce 0.9
			} else if (kmh == 0) {
				kmhActuel = 0;// on stoppe brutalement le VL
			}

			if (fraction >= 0.9f) //0.9f
				TabDynamique();

			GestionDetecteur ();
			GestionLumiere ();
			GestionFreins ();

			yield return null;
		}
	}

Re: Personnage monte escalier mais sur path et doncmvt en dent de scie

Publié : 12 Nov 2019 12:26
par boubouk50

Code : Tout sélectionner

transform.LookAt(iTween.PointOnPath(tabtList, fraction + 0.1f));
Ici, tu demandes à ton personnage de "regarder" en direction du chemin. Du coup, le forward est bon, mais pas l'alignement vertical. Il faut donc le corriger à ce moment. Il faut aligner le vecteur vertical de ton personnage avec le vecteur vertical du monde.
Il existe surement d'autres façons de faire, meilleures pour certaines, mais je n'ai pas le temps de chercher pour toi. Au moins, là tu sais ce que tu as à faire.

Re: Personnage monte escalier mais sur path et doncmvt en dent de scie

Publié : 12 Nov 2019 12:31
par freepl
Merci

Je n'ai plus qu'à comprendre ce que veux dire Alesk.

Re: Personnage monte escalier mais sur path et doncmvt en dent de scie

Publié : 13 Nov 2019 17:08
par freepl
Pour le code, tout est dans ItWeen.
J'ai vu ceci
https://answers.unity.com/questions/920 ... aints.html
Mais il est question e Unity5 que je n'ai pas.

J'ai recherché dans le code le mot physic et je trouve plusieurs occurences.
de ce type

Code : Tout sélectionner

//need physics?
		postUpdate=transform.position;
		if(physics){
			transform.position=preUpdate;
			rigidbody.MovePosition(postUpdate);
		}
Si j'ai bien compris, le code prend en compte le rigidbody mais à quel moment je demande la reconnaissance du physique ?
Où dois-je écrire et lequel j'utilise pour des personnages ?
Est-ce que cela va planter mes véhicules ?

Merci

Code : Tout sélectionner

//non-physics i used: If(isRunning && physics){ 
ou
 //physics i used: If(isRunning && !physics){

Re: Personnage monte escalier mais sur path et doncmvt en dent de scie

Publié : 13 Nov 2019 18:08
par boubouk50
On ne connait pas ton code, on ne peut pas te répondre.
Si tu utilises le même script pour tes voitures et tes personnages, alors ça pourrait avoir son importante.
Une voiture suit totalement le path, un personnage reste vertical.
Comme dit précédemment, il faut gérer "l'inclinaison" juste après le LookAt (), en remettant le personnage vertical.
ça donnerait quelque chose comme ça:

Code : Tout sélectionner

transform.rotation = Quaternion.FromToRotation(Vector3.up, Vector3.up);
ou bien

Code : Tout sélectionner

transform.up= Vector3.up;

Re: Personnage monte escalier mais sur path et doncmvt en dent de scie

Publié : 13 Nov 2019 22:29
par freepl
Bonsoir

Le seul code que j'utilise est celui-ci

Code : Tout sélectionner

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

public class TrajetVl : MonoBehaviour {
	public GameObject target_Path;
	public float kmh; // vitesse voulue
	public float kmhActuel; // vitesse reelle
	public float mEntrePoint = 5.0f;
	private float time;
	public float fraction;
	public Transform[] tabtList = new Transform[11];
	public int minTab = 0;
	public Transform detecteur;
	public LayerMask layerPanneau;
	public Collider[] toucheDetecteur;
	public bool coupeDetecteur;
	private Light jourNuit;
	private GameObject eclairage;
	private GameObject eclairageFreins;
	public GameObject clignotantsDroits;
	public GameObject clignotantsGauche;
	private IEnumerator coroutineClignotants;

	public InterieurVl interieur;

	public void DemrageVl () {
		tabtList = new Transform[11];
		TabDynamique ();
		if (transform.FindChild("Detecteur"))
			detecteur = transform.FindChild("Detecteur").transform;

		jourNuit = GameObject.Find("Sky Dome").transform.FindChild("Light").GetComponent<Light>();

		//cherche dans ces enfants un object avec le nom Eclairage
		//si existe alors on ajoute l'object portant le nom "Eclairage" dans la variable eclairage
		if (this.transform.FindChild ("Eclairage")) {
			eclairage = this.transform.FindChild ("Eclairage").gameObject;
		}

		if (this.transform.FindChild ("Eclairage_Freins")) {
			eclairageFreins = this.transform.FindChild ("Eclairage_Freins").gameObject;
			eclairageFreins.SetActive (false);
		}
		
		if (this.transform.FindChild ("Eclairage_Clignotants_droits")) {
			clignotantsDroits = this.transform.FindChild ("Eclairage_Clignotants_droits").gameObject;
			clignotantsDroits.SetActive (false);
		}

		if (this.transform.FindChild ("Eclairage_Clignotants_gauche")) {
			clignotantsGauche = this.transform.FindChild ("Eclairage_Clignotants_gauche").gameObject;
			clignotantsGauche.SetActive (false);
		}

		StartCoroutine("WalkThePath");
	}

	public void TabDynamique () {
		fraction = 0.1f;
		int count = 0;

		for (int i = 0; i < 11; i++) {
			if (minTab+i < target_Path.transform.childCount) {
				tabtList[i] = target_Path.transform.GetChild(minTab+i);
				count++;
			}
		}

		if (minTab+8 < target_Path.transform.childCount)
			minTab += 8;
		else
			minTab += count;
	}

	public void StopCoroutine () {
		StopCoroutine("WalkThePath");
	}

	IEnumerator WalkThePath () {
		while(true){
			time = (tabtList.Length * mEntrePoint)/(kmhActuel / 3.6f);
			transform.position = iTween.PointOnPath (tabtList, fraction);
			fraction += Time.deltaTime / time;
			if (fraction > 1.0f)
				fraction = 0.0f;
			transform.LookAt(iTween.PointOnPath(tabtList, fraction + 0.1f));
			if (kmhActuel < kmh){
				kmhActuel += 0.7f;// acceleration jusqu'à la vitesse kmh 0.7f
			} else if (kmhActuel > kmh && kmh != 0) {
				kmhActuel -= 0.9f;// decceleration douce 0.9
			} else if (kmh == 0) {
				kmhActuel = 0;// on stoppe brutalement le VL
			}

			if (fraction >= 0.9f) //0.9f
				TabDynamique();

			GestionDetecteur ();
			GestionLumiere ();
			GestionFreins ();

			yield return null;
		}
	}

	void GestionDetecteur () {
		if (detecteur != null) {
			if (gameObject.tag == "VEHICULE")
				toucheDetecteur = Physics.OverlapSphere(detecteur.position, 0.75f, layerPanneau);
			else
				toucheDetecteur = Physics.OverlapSphere(detecteur.position, 0.5f, layerPanneau);

			if (toucheDetecteur.Length != 0) {
				foreach (var other in toucheDetecteur) {
					if (other.tag == "CoupeDetecteur") {
						coupeDetecteur = other.GetComponent<CoupeDetecteur>().detecteur;
						kmhActuel = 50.0f;// pour degager les croisements
					}

					if (other.tag == "CoupeDetecteurAutre") {
						coupeDetecteur = other.GetComponent<CoupeDetecteur>().detecteur;
						kmhActuel = 4.0f;
					}

					if (coupeDetecteur == false) {
						if (other.tag == "ModifVitesse") {
							kmh = other.GetComponent<Panneau>().vitesse;
						} else if (other.tag == "EntreeInstersection") {
							kmh = other.GetComponent<Priorite>().vitesse;
						} else if (other.tag == "VEHICULE") {

							if (kmh > other.GetComponent<TrajetVl>().kmh)
							kmh = other.GetComponent<TrajetVl>().kmh;
						} else if (other.tag == "ClignotantsOn") {
							kmh = other.GetComponent<GestionClignotants>().vitesse;
							if (other.GetComponent<GestionClignotants>().trajet == target_Path) {
								ClignotantsOff ();
								if (other.GetComponent<GestionClignotants>().enumClignotants == EnumClignotants.Droites) {
									coroutineClignotants = ClignotantsDroits();
									StartCoroutine (coroutineClignotants);
								} else {
									coroutineClignotants = ClignotantsGauche();
									StartCoroutine (coroutineClignotants);
								}
							}
						} else if (other.tag == "ClignotantsOff") {
							kmh = other.GetComponent<GestionClignotants>().vitesse;
							ClignotantsOff ();
						}
					}
				}
			}

			if (kmhActuel == 0 && toucheDetecteur.Length == 0)
				kmhActuel = 30.0f;

		}
	}

	void GestionLumiere () {
		if (eclairage != null) {
			if (jourNuit.intensity < 0.15f) {
				if (eclairage.activeInHierarchy == false)
					eclairage.SetActive (true);
			}
			else {
				if (eclairage.activeInHierarchy == true)
					eclairage.SetActive (false);
			}
		}
	}

	void GestionFreins () {
		if (eclairageFreins != null){
			if (kmhActuel > kmh+3 || kmhActuel == 0) {
				if (eclairageFreins.activeInHierarchy == false)
					eclairageFreins.SetActive (true);
			} else {
				if (eclairageFreins.activeInHierarchy == true)
					eclairageFreins.SetActive (false);
			}
		}
	}

	IEnumerator ClignotantsDroits () {
		if (clignotantsDroits != null) {
			while (true) {
				clignotantsDroits.SetActive (true);
				yield return new WaitForSeconds (0.3f);
				clignotantsDroits.SetActive (false);
				yield return new WaitForSeconds (0.3f);
			}
		}
	}

	IEnumerator ClignotantsGauche () {
		if (clignotantsGauche != null) {
			while (true) {
				clignotantsGauche.SetActive (true);
				yield return new WaitForSeconds (0.3f);
				clignotantsGauche.SetActive (false);
				yield return new WaitForSeconds (0.3f);
			}
		}
	}

	void ClignotantsOff () {
		if (coroutineClignotants != null) {
			StopCoroutine (coroutineClignotants);

			if (clignotantsDroits != null)
				clignotantsDroits.SetActive (false);
			if (clignotantsGauche != null)
				clignotantsGauche.SetActive (false);
			 
			coroutineClignotants = null;
		}
	}

}
il fait référence à ItWeen ici, comme tu l'as dit

Code : Tout sélectionner

IEnumerator WalkThePath () {
		while(true){
			time = (tabtList.Length * mEntrePoint)/(kmhActuel / 3.6f);
			transform.position = iTween.PointOnPath (tabtList, fraction);

			fraction += Time.deltaTime / time;
			if (fraction > 1.0f)
				fraction = 0.0f;
			transform.LookAt(iTween.PointOnPath(tabtList, fraction + 0.1f));
			if (kmhActuel < kmh){
				kmhActuel += 0.7f;// acceleration jusqu'à la vitesse kmh 0.7f
			} else if (kmhActuel > kmh && kmh != 0) {
				kmhActuel -= 0.9f;// decceleration douce 0.9
			} else if (kmh == 0) {
				kmhActuel = 0;// on stoppe brutalement le VL
			}

			if (fraction >= 0.9f) //0.9f
				TabDynamique();

			GestionDetecteur ();
			GestionLumiere ();
			GestionFreins ();

			yield return null;
		}
	}
C'est le seul endroit où il est question du path et de la façon dont fonctionne ItWeen.
Par contre où dois-je mettre la ligne de code ?
Je dois surement l'intégrer dans la ligne

Code : Tout sélectionner

transform.position = iTween.PointOnPath (tabtList, fraction);
car cela ne fonctionne pas

Code : Tout sélectionner

IEnumerator WalkThePath () {
		while(true){
			time = (tabtList.Length * mEntrePoint)/(kmhActuel / 3.6f);
			transform.position = iTween.PointOnPath (tabtList, fraction);
			transform.rotation = Quaternion.FromToRotation(Vector3.up, Vector3.up);

			fraction += Time.deltaTime / time;
			if (fraction > 1.0f)
				fraction = 0.0f;
			transform.LookAt(iTween.PointOnPath(tabtList, fraction + 0.1f));
			if (kmhActuel < kmh){
				kmhActuel += 0.7f;// acceleration jusqu'à la vitesse kmh 0.7f
			} else if (kmhActuel > kmh && kmh != 0) {
				kmhActuel -= 0.9f;// decceleration douce 0.9
			} else if (kmh == 0) {
				kmhActuel = 0;// on stoppe brutalement le VL
			}

			if (fraction >= 0.9f) //0.9f
				TabDynamique();

			GestionDetecteur ();
			GestionLumiere ();
			GestionFreins ();

			yield return null;
		}
	}