[Non résolu]Curseur centré

Questions à propos du scripting. Hors Shader, GUI, Audio et Mobile.
EmileF
Messages : 742
Inscription : 18 Mars 2017 19:39

[Non résolu]Curseur centré

Message par EmileF » 07 Sep 2024 11:47

Bonjour
Je m'agace sur un truc qui paraît simple mais que je n'arrive pas à régler.
Je souhaite avoir mon curseur centré au départ du jeu et ma caméra est orienté avec le déplacement de la souris.
Tout fonctionne bien en cours du jeu, mais un petit détail m'agace.
Quand je démarre l'exécution si je garde le curseur sur le bouton start et que j'attend que le curseur soit centré tout ce passe bien. Mais si je déplace la souris pendant que démarre le jeu la caméra est complètement pivotée.
J'utilise Unity 2022 et l'Input System.
J'ai téléchargé ce package pour avoir l'exécution du curseur même en si le jeu n'est pas construit car Unity à enlevé cette possibilité il y a quelques années. On ne peut centrer le curseur que si le jeu est construit.
Et voici le script que j'utilise pour mon player et c'est le seul actuellement dans mon projet

Code : Tout sélectionner

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

public class PlayerController : MonoBehaviour
{
    public InputActionReference moveAction;
    public InputActionReference lookAction;
    public InputActionReference jumpAction;
    private CharacterController controller;
    private Vector3 direction;
    public float speed = 8f;

    private Vector3 playerVelocity;
    private bool grounded;
    public float gravity = -9.8f;
    public float jumpForce = 2f;

    public Camera cam;
    private Vector2 lookPos;
    private float xRotation = 0;
    private float yRotation = 0;
    public float xSens = 30f;
    public float ySens = 30f;

    bool start = true;

    private void Awake()
    {
        controller = GetComponent<CharacterController>();
        Cursor.lockState = CursorLockMode.Locked;
        Cursor.visible = true;
        xRotation = 0;

    }

    private void OnEnable()
    {
        start = true;
        moveAction.action.performed += OnMovePerformed;
        moveAction.action.canceled += OnMoveCanceled;
        moveAction.action.Enable();

        lookAction.action.performed += OnLookPerformed;
        lookAction.action.canceled += OnLookCanceled;
        lookAction.action.Enable();

        jumpAction.action.started += OnJumpStarted;
        jumpAction.action.Enable();
    }

    private void OnDisable()
    {
        moveAction.action.performed -= OnMovePerformed;
        moveAction.action.canceled -= OnMoveCanceled;
        moveAction.action.Disable();

        lookAction.action.performed -= OnLookPerformed;
        lookAction.action.canceled -= OnLookCanceled;
        lookAction.action.Disable();

        jumpAction.action.started -= OnJumpStarted;
        jumpAction.action.Disable();
    }

    private void OnMovePerformed(InputAction.CallbackContext obj)
    {
        //Cursor.lockState = CursorLockMode.Locked;
        //Cursor.visible = true;
        direction.x = obj.ReadValue<Vector2>().x;
        direction.z = obj.ReadValue<Vector2>().y;
    }

    private void OnMoveCanceled(InputAction.CallbackContext obj)
    {
        //Cursor.lockState = CursorLockMode.Confined;
        direction = Vector3.zero;
    }

    private void OnLookPerformed(InputAction.CallbackContext obj)
    {
        xRotation += (obj.ReadValue<Vector2>().y * Time.deltaTime) * ySens;
        yRotation = (obj.ReadValue<Vector2>().x * Time.deltaTime) * xSens;

    }

    private void OnLookCanceled(InputAction.CallbackContext obj)
    {
        yRotation = 0;
    }

    private void OnJumpStarted(InputAction.CallbackContext obj)
    {
        if (grounded)
        {
            playerVelocity.y = Mathf.Sqrt(jumpForce * -3f * gravity);
        }
    }

    //// Start is called before the first frame update
    void Start()
    {
        start = true;
        Cursor.lockState = CursorLockMode.Locked;
        xRotation = 0;
    }

    // Update is called once per frame
    void Update()
    {
        if (start)
            xRotation = 0;
        start = false;
        Cursor.visible = true;
        grounded = controller.isGrounded;
        MovePlayer();
        PlayerLook();
    }

    public void MovePlayer()
    {
        controller.Move(transform.TransformDirection(direction) * speed * Time.deltaTime);

        playerVelocity.y += gravity * Time.deltaTime;
        if (grounded && playerVelocity.y < 0)
        {
            playerVelocity.y = -2f;
        }
        controller.Move(playerVelocity * Time.deltaTime);
    }

    public void Jump()
    {
        if (grounded)
        {
            playerVelocity.y = Mathf.Sqrt(jumpForce * -3f * gravity);
        }
    }

    public void PlayerLook()
    {
        xRotation = Mathf.Clamp(xRotation, -80f, 80f);

        cam.transform.localRotation = Quaternion.Euler(xRotation, 0, 0);

        transform.Rotate(Vector3.up * yRotation);
    }
}

J'ai même ajouté un petit bolléan "start" pour ne faire les mises à jour que quand le jeu est démarré, mais rien n'y fait.
Si quelqu'un avait une petite idée ce serait sympa
Dernière édition par EmileF le 09 Sep 2024 12:36, édité 1 fois.
La différence entre l'intelligence et la stupidité est que l'intelligence est limitée.

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

Re: Curseur centré

Message par boubouk50 » 09 Sep 2024 09:30

Normalement, les commandes ne sont exécutées uniquement lorsque le jeu est exécuté.
As-tu des chargements différés ? Par exemple, le script de caméra est sur une scène préchargée, et tu charges une autre scène avec le décor ?
De ce que tu me décris, l'Update () est exécuté avant que ne soit chargé le reste, donc tout mouvement de la souris est pris en compte avant ce chargement.

Code : Tout sélectionner

cam.transform.localRotation = Quaternion.Euler(xRotation, 0, 0);
C'est le seul endroit où la caméra subit une rotation, si xRotation vaut 0 alors pas de problème.
Il faut aussi savoir que OnEnable (), qui s'abonne à OnLookPerformed (), est exécuté après l'Awake () mais dans la même frame. Ensuite, tu as le Start (), puis l'Update (). Il y a donc au moins un décalage d'une frame qui peut faire bouger le curseur, donc la caméra.
Je soupçonnerai donc le OnLookPerformed () de faire ce saut parce qu'il serait exécuté après PlayerLook (). Quand est-il appelé ? (-> lookAction.action.performed)
Mets des Debug.Log () dans ces deux fonctions pour voir qui s'exécute en premier.
"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

EmileF
Messages : 742
Inscription : 18 Mars 2017 19:39

Re: Curseur centré

Message par EmileF » 09 Sep 2024 12:35

Je te remercie Boubouk d'avoir étudié ce problème, mais vraiment les versions récentes d'Unity m'agacent. On a de moins en moins le pouvoir de gérer les évènements.
Il on fait ce Input System qui est bien plus difficile à gérer que les quelques lignes de code qu'il remplace et je ne suis pas sur que ça crée un réel avantage. Et là, j'en suis qu'au tout début.
Je suis donc déjà découragé par les nouvelles versions d'Unity et je vais revenir sur la version 2019 que je maîtrise mieux et qui est suffisante pour mes créations.
Encore merci Boubouk.
La différence entre l'intelligence et la stupidité est que l'intelligence est limitée.

Répondre

Revenir vers « Scripting »