Partage
  • Partager sur Facebook
  • Partager sur Twitter

Déplacement d'un personnage Unity

Character Controller Unity

Sujet résolu
31 octobre 2018 à 18:44:08

Bonjour a tout le monde,

Je développe actuellement un petit jeu en amateur sur Unity et je rencontre un problème au niveau du saut, en effet je ne parvient pas a faire sauté le personnage uniquement quand il touche le sol tout en empêchant le joueur de grimper des pentes qui ne devrait pas pouvoir l'être.

Voici mon code actuel qui a le défaut de faire des multi saut a l'infini:

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

public class CharacterController : MonoBehaviour {

    Animation animations; //Animation personnage

    public float WalkSpeed = 0; //Vitesse pour marcher
    public float RunSpeed = 0; //Vitesse pour courire
    public float RotateSpeed = 0; //Vitesse pour tourner

    public string InpDroite; //Touche droite
    public string InpGauche; //Touche gauche 
    public string InpAvant; //Touche avancer
    public string InpArriere; //Touche reculer

    public Vector3 JumpSpeed;
    CapsuleCollider ColliderPlayer; //Capsule de colision du joueur


	// Use this for initialization
	void Start () {
        animations = gameObject.GetComponent<Animation>();
        ColliderPlayer = gameObject.GetComponent<CapsuleCollider>();
	}

    bool TouchSol()
    {
        return Physics.CheckCapsule(ColliderPlayer.bounds.center, new Vector3(ColliderPlayer.bounds.center.x, ColliderPlayer.bounds.min.y, ColliderPlayer.bounds.center.z), ColliderPlayer.radius);
    }

    // Update is called once per frame
    void Update () {

        //Marche avant
        if (Input.GetKey(InpAvant) && !(Input.GetKey(KeyCode.LeftShift)))
        {
            animations.Play("walk");
            transform.Translate(0, 0, WalkSpeed * Time.deltaTime);
        }

        //Marche avant rapide
        if (Input.GetKey(InpAvant) && Input.GetKey(KeyCode.LeftShift))
        {
            animations.Play("run");
            transform.Translate(0, 0, RunSpeed * Time.deltaTime);
        }

        //Marche arrière
        if (Input.GetKey(InpArriere))
        {
            animations.Play("walk");
            transform.Translate(0, 0, -(WalkSpeed / 2) * Time.deltaTime);
        }

        //Direction droite
        if (Input.GetKey(InpDroite))
        {
            animations.Play("walk");
            transform.Rotate(0, RotateSpeed, 0);
        }

        //Direction gauche
        if (Input.GetKey(InpGauche))
        {
            animations.Play("walk");
            transform.Rotate(0, -RotateSpeed, 0);
        }

        //Aucune action
        if (((!Input.GetKey(InpGauche) && !Input.GetKey(InpDroite)) && (!Input.GetKey(InpAvant) && !Input.GetKey(InpArriere))) && TouchSol())
        {
            animations.Play("idle");
        }

        //Saut
        if(Input.GetKeyDown(KeyCode.Space) && TouchSol())
        {
            //Prépa saut
            Vector3 v = gameObject.GetComponent<Rigidbody>().velocity;
            v.y = JumpSpeed.y;
            //Saut
            gameObject.GetComponent<Rigidbody>().velocity = JumpSpeed;
        }
    }
}



  • Partager sur Facebook
  • Partager sur Twitter
16 décembre 2018 à 16:07:21

Utilises un raycast pour savoir si le player touche le sol ;)
  • Partager sur Facebook
  • Partager sur Twitter
"Le plus court chemin d'un point A à un point B : c'est de ne pas y aller"
10 janvier 2019 à 12:24:03

TTlaRage a écrit:

Utilises un raycast pour savoir si le player touche le sol ;)


Je veut bien mais je ne sais pas comment faire pouvez vous m'aider ? Je pensais que c'était se que je fessait dans mon code mais visiblement j'ai une erreur quelque part....
  • Partager sur Facebook
  • Partager sur Twitter
10 janvier 2019 à 21:08:04

Compares juste le y du perso avec le y du sol, (ou le z je sais plus, la hauteur), s’il est au-dessus de sol.y+15 au hasard, tu return, au debut de la fonction saut.
  • Partager sur Facebook
  • Partager sur Twitter
Anonyme
11 janvier 2019 à 10:53:48

PaulLou a écrit:

Compares juste le y du perso avec le y du sol, (ou le z je sais plus, la hauteur), s’il est au-dessus de sol.y+15 au hasard, tu return, au debut de la fonction saut.


Pas bonne idée. Le principe du sol, c'est qu'il n'est pas à y fixé (dès qu'il y a des pentes par exemple). Une bonne idée est en effet le cast, donc soit raycast soit capsule cast. Pour éviter de monter des pentres trop pentues, on peut regarder le vecteur normal au point d'impact et ne permettre au joueur de bouger que s'il a une inclinaison inférieure à une certaine valeur limite.

Le problème qu'il y a dans ton code initial est que le checkcapsule a exactement la même forme que le capsule collider de ton perso, donc même s'il touche le terrain avec sa tête, il va considérer qu'il touche le sol.

  • Partager sur Facebook
  • Partager sur Twitter
11 janvier 2019 à 11:22:18

Erylanor a écrit:

PaulLou a écrit:

Compares juste le y du perso avec le y du sol, (ou le z je sais plus, la hauteur), s’il est au-dessus de sol.y+15 au hasard, tu return, au debut de la fonction saut.


Pas bonne idée. Le principe du sol, c'est qu'il n'est pas à y fixé (dès qu'il y a des pentes par exemple). Une bonne idée est en effet le cast, donc soit raycast soit capsule cast. Pour éviter de monter des pentres trop pentues, on peut regarder le vecteur normal au point d'impact et ne permettre au joueur de bouger que s'il a une inclinaison inférieure à une certaine valeur limite.

Le problème qu'il y a dans ton code initial est que le checkcapsule a exactement la même forme que le capsule collider de ton perso, donc même s'il touche le terrain avec sa tête, il va considérer qu'il touche le sol.


Ce qui veut dire que je devrait modifier quelle partie ? j'ai beau essayé je ne fait que créer des bugs ou alors le code est un échecs je commence a désespérer un peu.... Je pense que je n'est pas compris une partie de la méthode mais je vois pas la quelle....
  • Partager sur Facebook
  • Partager sur Twitter
Anonyme
11 janvier 2019 à 14:12:31

Ce que je ferais perso c'est un raycast (capsule cast ça risque d'être chiant), vers le bas, mais sur une distance plutôt faible, pour que ça dépasse juste un peu du bas de ton perso. Comme ça, si c'est trop pentu, le centre de ton perso ne touchera pas direcctement le sol et le raycast ne touchera rien. En revanche, si c'est pas trop pentu, le centre de ton perso sera suffisament proche du sol pour que le raycast touche le sol.

  • Partager sur Facebook
  • Partager sur Twitter
11 janvier 2019 à 14:45:16

Erylanor a écrit:

Ce que je ferais perso c'est un raycast (capsule cast ça risque d'être chiant), vers le bas, mais sur une distance plutôt faible, pour que ça dépasse juste un peu du bas de ton perso. Comme ça, si c'est trop pentu, le centre de ton perso ne touchera pas direcctement le sol et le raycast ne touchera rien. En revanche, si c'est pas trop pentu, le centre de ton perso sera suffisament proche du sol pour que le raycast touche le sol.


Oui mais le problème c'est que je ne sais pas faire de raycast et sur le net j'ai du mal a comprendre comment faire aurai tu des conseil ou des sites/vidéo a voir pour mieux faire cette méthode?
  • Partager sur Facebook
  • Partager sur Twitter
Anonyme
11 janvier 2019 à 15:32:47

Tout est dit ici : https://docs.unity3d.com/ScriptReference/Physics.Raycast.html

Ca s'utilise comme ça : public static bool Raycast(Vector3 origin, Vector3 direction, float maxDistance = Mathf.Infinity, int layerMask = DefaultRaycastLayers, QueryTriggerInteraction queryTriggerInteraction = QueryTriggerInteraction.UseGlobal);

Donc en pratique, ce que je fais c'est :

Raycast(transform.position + Vector3.down*capsule.size.y, Vector3.down, 0.01f)

En gros, le premier argument te dit : je dommence le raycast juste en dessous de mes pieds, le deuxième dit : je lance un rayon vers le bas, le troisième te dit : sur une distance de 0.01.

Si le rayon touche quelque chose, c'est qu'il y a quelque chose entre tes pieds et un peu en-dessous de tes pieds, donc tu est par terre.

  • Partager sur Facebook
  • Partager sur Twitter
17 janvier 2019 à 15:48:25

Un collider sur ton perso et sur le sol:

Tu rajoute des fonction de ce genre.

private bool onFloor = true;
void jump()
{
}
void Update()
{
   ...
   if (onFloor && ...)
   {
      jump();
   }

}
void OnTriggerEnter(collider col)
{
   if(col.gameObject.name=="sol")
   {
      onFloor=true;
   }
}
void OnTriggerExit(collider col)
{
   if(col.gameObject.name=="sol")
   {
      onFloor=false;
   }
}

Si tu comprends pasd contacte moi par mp.

  • Partager sur Facebook
  • Partager sur Twitter
Salut c'est moi the geoffrey.
17 janvier 2019 à 21:24:51

The Geoffrey a écrit:

Un collider sur ton perso et sur le sol:

Tu rajoute des fonction de ce genre.

private bool onFloor = true;
void jump()
{
}
void Update()
{
   ...
   if (onFloor && ...)
   {
      jump();
   }

}
void OnTriggerEnter(collider col)
{
   if(col.gameObject.name=="sol")
   {
      onFloor=true;
   }
}
void OnTriggerExit(collider col)
{
   if(col.gameObject.name=="sol")
   {
      onFloor=false;
   }
}

Si tu comprends pasd contacte moi par mp.


Le problème du collider c'est que le sol n'est pas régulier il faudrait donc un collide semblable au sol ce serai pas très adapter je pense... je vais plutôt essayer la méthode du raycast mais merci
  • Partager sur Facebook
  • Partager sur Twitter
7 novembre 2020 à 15:11:34

bonjour je debut sur unity 

quelqu'un pourait me donner un script de déplacement et de saut pour une capsule de base

  • Partager sur Facebook
  • Partager sur Twitter
7 novembre 2020 à 17:54:28

Bonjour,

Déterrage

Citation des règles générales du forum :

Avant de poster un message, vérifiez la date du sujet dans lequel vous comptiez intervenir.

Si le dernier message sur le sujet date de plus de deux mois, mieux vaut ne pas répondre.
En effet, le déterrage d'un sujet nuit au bon fonctionnement du forum, et l'informatique pouvant grandement changer en quelques mois il n'est donc que rarement pertinent de déterrer un vieux sujet.

Au lieu de déterrer un sujet il est préférable :

  • soit de contacter directement le membre voulu par messagerie privée en cliquant sur son pseudonyme pour accéder à sa page profil, puis sur le lien "Ecrire un message"
  • soit de créer un nouveau sujet décrivant votre propre contexte
  • ne pas répondre à un déterrage et le signaler à la modération

Je ferme ce sujet. En cas de désaccord, me contacter par MP.

  • Partager sur Facebook
  • Partager sur Twitter