Page 1 sur 1

[Resolu]Gravity dans tous les sens

Publié : 15 Fév 2020 15:05
par EmileF
Bonjour,

Oui je sais dans la réalité c'est impossible, pourtant
je voudrais que mon player soit affecté par la gravité vers le bas par rapport à sa propre orientation et non par rapport au monde.

En fait je voudrais qu'il puisse marcher sur les murs ou le plafond.

J'utilise un script qui me permet de l'orienter par rapport à la surface sur laquelle il est posé. Mais je n'arrive pas le faire déplacer normalement sur cette surface

Voila mes scripts:

Code : Tout sélectionner

    Vector3 myNormal;
    Vector3 surfaceNormal;
    Quaternion targetRot;
    public float speedRot = 100f;

    private void FixedUpdate()
    {
        OrienteLePlayerSelonLaNormale();
        transform.rotation = Quaternion.Lerp(transform.rotation, targetRot, speedRot * Time.deltaTime);
    }

    void OrienteLePlayerSelonLaNormale()
    {
        Ray ray;
        RaycastHit hit;
        //ne réagit qu'au layer 8
        int mask = 1 << 8;
        ray = new Ray(transform.position, -myNormal);
        if (Physics.Raycast(ray, out hit, Mathf.Infinity, mask))
        {
            surfaceNormal = hit.normal;
        }
        else
        {
            surfaceNormal = transform.up;
        }
        myNormal = surfaceNormal;
        Vector3 myForward = Vector3.Cross(transform.right, myNormal);
        targetRot = Quaternion.LookRotation(myForward, myNormal);
    }
Est-ce que quelqu'un peut m'aider, il y a un post de 2015 dans le forum, mais le gars n'a pas eu de réponse qui aurait pu réglé son problème.

Merci

Re: Gravity dans tous les sens

Publié : 15 Fév 2020 16:07
par Aelhan
Bonjour, je ne me suis jamais posé la question sur le sujet, mais en te lisant une idée m'est venue sans savoir si cela est réalisable : pourquoi ne pas appliquer une rotation sur la caméra en même temps que sur l'ensemble de la scène ? Ainsi ta gravité serait toujours vers le bas mais sans que cela soit visible ? C'est peut-être tiré par les cheveux, mais pourquoi pas ? (Je serais très intéressé de savoir si ce que je dis est une fausse bonne idée)

Re: Gravity dans tous les sens

Publié : 15 Fév 2020 16:46
par EmileF
En 2D je pense que ce serait la solution.

Dans mon cas, mon player est, selon où il se trouve, en FPS ou en TPS, ou encore avec une vue éloignée.
Je ne peux utiliser ton idée qui pourrait être une excellente idée dans certains cas.

J'ai essayé avec un rigdbody, avec un Character Controller je ne suis arrivé à rien
J'espérais qu'il pouvait y avoir un mécanisme automatique. Je crains que ce ne soit pas le cas.

Je vais donc essayer de créer mon script moi même, si quelqu'un pouvait m'aider un peu, ce serait super.

Re: Gravity dans tous les sens

Publié : 15 Fév 2020 17:05
par Max
Hello,

C'est un sujet qui est pas mal abordé sur le net.
Tu as plusieurs approches. Si ton player reste sur des faces plane, d'un cube par exemple, tu peux regarder du coté de la gravité au niveau du moteur physique (Physics.gravity), et la changer pour lui donner la direction que tu souhaites.
Après, tu as par exemple ce genre de liens, dont tu peux t'inspirer:
https://www.youtube.com/watch?v=UeqfHkfPNh4
ou encore
http://wiki.unity3d.com/index.php/Gravity
ou encore sur le store:
https://www.assetstore.unity3d.com/en/? ... tent/65682

Re: Gravity dans tous les sens

Publié : 15 Fév 2020 17:57
par EmileF
Merci Max,

Physics.gravity, oui, je l'avais vu mais je ne suis pas arrivé à l'utiliser car elle change selon la position du player

Les autres liens que tu me fournis parlent de la gravité planétaire. Normal c'est ainsi que ca se passe.

Chez moi, c'est la gravité à l'intérieur d'une pièce, ou sur des murs extérieurs, il n'y a pas un point fixe de gravité comme le centre d'une planète.

Mais le premier lien que tu m'as fourni, va sûrement m'aider car je pense pouvoir l'adapter au script que j'ai déjà pour orienter le player selon la normale de la surface sur laquelle il se promène.

Je reviendrai dès que j'aurais réussi à pondre quelque chose.

Re: Gravity dans tous les sens

Publié : 15 Fév 2020 19:14
par EmileF
Et voilà...

Merci Max,
voilà le résultat grâce au tuto de la première vidéo,
J'ai mis quelques commentaires, ça pourra peut-être servir à quelqu'un

Code : Tout sélectionner

    public float speedMove = 4; //vitesse de déplacement
    public float speedRot = 120;//vitesse de rotation
    public float smoothRot = 10;//amortissement dans les angles du sol
    public float jumpHeight = 1f;//Hauteur pour le saut
    public float jumpForce = 40000;//Force pour le saut
    public float gravity = 50;//Force pour la gravité
    bool onGround = false;
    float distanceToGround;
    Vector3 groundNormal;
    Rigidbody rb;

    void Start()
    {
        rb = GetComponent<Rigidbody>();
        rb.freezeRotation = true;
    }


    private void FixedUpdate()
    {
        //Envoie un rayon verticalement vers le bas
        RaycastHit hit = new RaycastHit();
        Ray ray = new Ray(transform.position, -transform.up);
        
        //le layer 8 correspond à tout ce qui représente un "sol"
        int mask = 1 << 8;//ne réagit qu'au layer 8
        if (Physics.Raycast(ray, out hit, Mathf.Infinity, mask))
        {
            //si le player est tout près du sol = true
            distanceToGround = hit.distance;
            onGround = distanceToGround < 0.1f;

            //applique la rotation pour que le player soit perpendiculaire au "sol"
            groundNormal = hit.normal.normalized;
            Quaternion targetRot = Quaternion.FromToRotation(transform.up, groundNormal) * transform.rotation;
            transform.rotation = Quaternion.Lerp(transform.rotation, targetRot, smoothRot * Time.deltaTime);
        }
        else
            //on est dans le vide
            onGround = false;

        if (!onGround)
        {
            //si on touche pas le sol on applique la gravité
            rb.AddForce(groundNormal * -gravity);
        }
        else
        {
            //si on est au sol on peut sauter
            float j = Input.GetAxis("Jump");
            if (j != 0)
                rb.AddForce(transform.up * jumpForce * jumpHeight * Time.deltaTime);

            //on peut aussi tourner
            float x = Input.GetAxis("Horizontal") * Time.deltaTime * speedRot;
            transform.Rotate(0, x, 0);
        }
        //et dans tous les cas on peut avancer
        float z = Input.GetAxis("Vertical") * Time.deltaTime * speedMove;
        transform.Translate(0, 0, z);
    }

Re: [Resolu]Gravity dans tous les sens

Publié : 15 Fév 2020 19:47
par Max
merci pour le partage :super:

Re: [Resolu]Gravity dans tous les sens

Publié : 22 Fév 2020 21:48
par Alesk
Même si tu as trouvé ta solution, va faire un tour ici :

https://catlikecoding.com/unity/tutorials/movement/

Re: [Resolu]Gravity dans tous les sens

Publié : 23 Fév 2020 17:00
par EmileF
Merci Alesk

Site très intéressant, plein de choses à découvrir, merci