Search Unity

Camera Rotation arround the player going wrong on the X Axis.

Discussion in 'Scripting' started by Valoo24, Apr 21, 2018.

  1. Valoo24

    Valoo24

    Joined:
    Apr 19, 2018
    Posts:
    4
    Hello Everyone !
    I tried to write a script for making a camera that follows the player and you can turn freely in space on the Y and X Axis as its for a 3D platformer game. So to do that, I put an Empty called "Pivot" in the position of my gameObject "Player" and the camera follows the rotation of the "Pivot" Object instead of the rotation of the "Player" object, in order to let the player move freely with. But while the camera rotates perfectly on the Y Axis, it seems to make a half-circle shape when I want to move it on the X Axis, and I can't figure out why. So if anybody can help me, i would be really happy and it would be really kind from you.

    Here are my scripts as attached files.
     

    Attached Files:

  2. Valoo24

    Valoo24

    Joined:
    Apr 19, 2018
    Posts:
    4
    Sorry, I didn't Used Code tags.

    Here is my code fore the CameraController:

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. public class CameraController : MonoBehaviour
    6. {
    7.  
    8.     #region Variables publiques
    9.     public GameObject target;
    10.     public Transform Pivot;
    11.     public float cameraRotationSpeed;
    12.     [Range (0, 85)]
    13.     public float maxViewAngle;
    14.     [Range (-80, 0)]
    15.     public float minViewAngle;
    16.     [Range (0, 1)]
    17.     public float CameraYFloorOffset;
    18.     public Vector3 Offset;
    19.     public bool invertYAxis;
    20.     public bool invertXAxis;
    21.     #endregion
    22.  
    23.     #region Variables privées
    24.     private int invertY;
    25.     private int invertX;
    26.     #endregion
    27.  
    28.     void Start ()
    29.     {
    30.         // Mets le pivot (Empty) à la même position que la target (Player).
    31.         Pivot.position = target.transform.position;
    32.  
    33.         // S'asssure que le pivot n'est parenté à aucun objet.
    34.         Pivot.parent = null;
    35.     }
    36.    
    37.     void LateUpdate ()
    38.     {
    39.         // Vérifie que la position du pivot est toujours la même que celle de la target (Player).
    40.         Pivot.position = target.transform.position;
    41.  
    42.         #region Conditions d'inversions des axes
    43.         if (invertYAxis)
    44.         {
    45.             invertY = -1;
    46.         }
    47.         else if (!invertYAxis)
    48.         {
    49.             invertY = 1;
    50.         }
    51.  
    52.         if (invertXAxis)
    53.         {
    54.             invertX = -1;
    55.         }
    56.         else if (!invertXAxis)
    57.         {
    58.             invertX = 1;
    59.         }
    60.         #endregion
    61.  
    62.         // Fait roter le pivot selon la valeur des inputs.
    63.         float horizontal = Input.GetAxis("CameraX") * cameraRotationSpeed * Time.deltaTime;
    64.         //target.transform.Rotate(0, horizontal * invertX, 0);
    65.         Pivot.Rotate(0, -horizontal * invertX, 0);
    66.  
    67.         float vertical = Input.GetAxis("CameraY") * cameraRotationSpeed * Time.deltaTime;
    68.         Pivot.Rotate(-vertical * invertY, 0, 0);
    69.  
    70.         // Limite l'angle de la caméra pour éviter de faire un tour à 360° sur une rotation de l'axe X. "Max View Angle" étant l'angle le
    71.         // plus grand que la caméra peut prendre sur l'axe X.
    72.         if (Pivot.rotation.eulerAngles.x > maxViewAngle && Pivot.rotation.eulerAngles.x < 180f)
    73.         {
    74.             Pivot.rotation = Quaternion.Euler(maxViewAngle, 0f, 0f);
    75.         }
    76.  
    77.         //Limite l'angle de la caméra pour éviter de faire un tour à 360° sur une rotation de l'axe X. "Min View Angle" étant l'angle le
    78.         // plus petit que la caméra peut prendre sur l'axe X et permet d'éviter de rapprocher la caméra trop près de la target.
    79.         if (Pivot.rotation.eulerAngles.x > 180f && Pivot.rotation.eulerAngles.x < 360 + minViewAngle)
    80.         {
    81.             Pivot.rotation = Quaternion.Euler(360f + minViewAngle, 0f, 0f);
    82.         }
    83.  
    84.         // Fais une rotation de la camera selon la rotation du pivot.
    85.         //float desiredYAngle = target.transform.eulerAngles.y;
    86.         float desiredYAngle = Pivot.eulerAngles.y;
    87.         float desiredXAngle = Pivot.eulerAngles.x;
    88.         Quaternion rotation = Quaternion.Euler(desiredXAngle, desiredYAngle, 0);
    89.  
    90.         // La position de la caméra est celle de la target (Le Player) + son Offset.
    91.         transform.position = Pivot.position + (rotation * Offset);
    92.  
    93.         // Empêche la caméra d'aller plus bas que la position de la target (Player) et l'empêche également de zoomer trop près
    94.         // du sol grâce au "Camera Y Floor Offset".
    95.         if (transform.position.y < target.transform.position.y)
    96.         {
    97.             transform.position = new Vector3(transform.position.x, target.transform.position.y + CameraYFloorOffset,
    98.             transform.position.z);
    99.         }
    100.  
    101.         // Pointe la vue de la caméra vers la position de l'objet (Le Player normalement).
    102.         transform.LookAt(target.transform);
    103.     }
    104. }
    105.  
    And Here is my code for the Character controller

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. [RequireComponent(typeof(Rigidbody))]
    6. public class PlayerController : MonoBehaviour
    7. {
    8.     #region Variables publiques
    9.     [Range (1, 20)]
    10.     public float moveSpeed = 8f;
    11.     [Range(1, 20)]
    12.     public float jumpForce = 5.5f;
    13.  
    14.     // A modifier selon la taille de l'objet Player. Sert à la détection du sol.
    15.     public float playerHeight;
    16.     public float playerLength;
    17.     public float playerWidth;
    18.     // Marge d'erreur à modificer pour la détection du sol par les RayCast.
    19.     [Range(0, 1)]
    20.     public float groundDetectionOffset = 0.1f;
    21.  
    22.     // A ne mettre que si on utilise le système de pivot de la caméra.
    23.     public Transform Pivot;
    24.     public GameObject playerModel;
    25.     public float rotationSpeed;
    26.  
    27.     public bool jump;
    28.     public bool doubleJump;
    29.  
    30.     public bool betterJump;
    31.     [Range (1, 10)]
    32.     public float fallMultiplier = 3f;
    33.     [Range (1, 10)]
    34.     public float lowJumpMultiplier = 2f;
    35.     [Range (1, 20)]
    36.     public float gravityScale = 1f;
    37.     #endregion
    38.  
    39.     #region Variables privées
    40.     private bool allowDoubleJump = false;
    41.     private float globalGravity = -9.81f;
    42.     private Rigidbody rb;
    43.     #endregion
    44.  
    45.     void Start()
    46.     {
    47.         rb = GetComponent<Rigidbody>();
    48.  
    49.         #region Vérification du mode Better Jump
    50.         // Désactive la fonction "Use Gravity" du RigidBody du Player si la fonction "Better Jump" est activée.
    51.         if (betterJump)
    52.         {
    53.             rb.useGravity = false;
    54.         }
    55.         else
    56.         {
    57.             rb.useGravity = true;
    58.         }
    59.         #endregion
    60.     }
    61.  
    62.     void Update()
    63.     {
    64.         #region Fonction de déplacement
    65.         Vector3 movement = new Vector3(Input.GetAxis("Horizontal"), 0f, Input.GetAxis("Vertical"));
    66.         GetComponent<Transform>().Translate(movement * moveSpeed * Time.deltaTime, Space.Self);
    67.         #endregion
    68.  
    69.         #region Fonction de saut + Double Saut
    70.         // Permet de faire un saut si la fonction "Jump" est activée.
    71.         if (Input.GetButtonDown("Jump") && IsGrounded() && jump)
    72.         {
    73.             GetComponent<Rigidbody>().AddForce(Vector3.up * jumpForce, ForceMode.Impulse);
    74.             allowDoubleJump = true;
    75.         }
    76.  
    77.         // Permet de faire un double saut si la fonction "Double Jump" est activée.
    78.         else if (Input.GetButtonDown("Jump") && allowDoubleJump && doubleJump)
    79.         {
    80.             GetComponent<Rigidbody>().AddForce(Vector3.up * jumpForce, ForceMode.Impulse);
    81.             allowDoubleJump = false;
    82.         }
    83.         #endregion
    84.  
    85.         // Fait bouger le Player dans des directions différentes selon la direction de la caméra.
    86.         /*if (Input.GetAxis("Horizontal") != 0 || Input.GetAxis("Vertical") != 0)
    87.         {
    88.             transform.rotation = Quaternion.Euler(0f, Pivot.rotation.eulerAngles.y, 0f);
    89.             Quaternion newRotation = Quaternion.LookRotation(new Vector3(movement.x, 0f, movement.z));
    90.             playerModel.transform.rotation = Quaternion.Slerp(playerModel.transform.rotation, newRotation, rotationSpeed * Time.deltaTime);
    91.         }*/
    92.     }
    93.  
    94.     void FixedUpdate()
    95.     {
    96.         #region Mode Better Jump
    97.         // Améliore la gravitée appliquée sur le joueur si le mode "Bette Jump" est activé.
    98.         if (betterJump)
    99.         {
    100.             Vector3 gravity = globalGravity * gravityScale * Vector3.up;
    101.  
    102.             // Force appliquée quand le Player tombe.
    103.             if (rb.velocity.y < 0)
    104.             {
    105.                 rb.AddForce(gravity * fallMultiplier, ForceMode.Acceleration);
    106.             }
    107.  
    108.             // Force appliquée quand le Player est dans sa phase asendante du saut.
    109.             else if (rb.velocity.y > 0 && !Input.GetButton("Jump"))
    110.             {
    111.                 rb.AddForce(gravity * lowJumpMultiplier, ForceMode.Acceleration);
    112.             }
    113.  
    114.             // Force appliquée quand le Player est au sol.
    115.             else
    116.             {
    117.                 rb.AddForce(gravity, ForceMode.Acceleration);
    118.             }
    119.         }
    120.         #endregion
    121.     }
    122.  
    123.     #region Méthodes Custom
    124.     #region Méthode IsGrounded()
    125.     // Renvoie un booléen selon que l'objet touche le sol ou non.
    126.     bool IsGrounded()
    127.     {
    128.         // Envoie un Raycast à partir de chaque coté de l'objet Player pour détecter si il y a un sol en dessous de lui.
    129.  
    130.         // Selon la taille de l'objet player, il faut modifier les variable "playerWidth", "playerLength" et "playerHeight"
    131.         // pour que les raycast détectent le sol correctement.
    132.         if (Physics.Raycast(new Vector3(transform.position.x - playerWidth / 2, transform.position.y, transform.position.z),
    133.             Vector3.down, playerHeight / 2 + groundDetectionOffset)
    134.             || Physics.Raycast(new Vector3(transform.position.x + playerWidth / 2, transform.position.y, transform.position.z),
    135.             Vector3.down, playerHeight / 2 + groundDetectionOffset)
    136.             || Physics.Raycast(new Vector3(transform.position.x, transform.position.y, transform.position.z - playerLength / 2),
    137.             Vector3.down, playerHeight / 2 + groundDetectionOffset)
    138.             || Physics.Raycast(new Vector3(transform.position.x, transform.position.y, transform.position.z + playerLength / 2),
    139.             Vector3.down, playerHeight / 2 + groundDetectionOffset))
    140.         {
    141.             return true;
    142.         }
    143.         else
    144.         {
    145.             return false;
    146.         }
    147.     }
    148.     #endregion
    149.     #endregion
    150. }
     
  3. Valoo24

    Valoo24

    Joined:
    Apr 19, 2018
    Posts:
    4
    Anaybody can't help me fixing my problem ? :D
     
  4. methos5k

    methos5k

    Joined:
    Aug 3, 2015
    Posts:
    8,712
    Are you looking for a sort of common 3rd person camera?
    Full Y-axis rotation, with some clamped x-axis rotation?
     
  5. Valoo24

    Valoo24

    Joined:
    Apr 19, 2018
    Posts:
    4
    Thank you for your reply :)
    Well I was trying to do a 3rd Person camera yes, but my problem wasn't really the clamp that worked nice. But I tried to make a Camera with a pivot system and the rotation in the X-Axis (from right to left, sorry, I'm always confused about the rotation axis ^^') was glitchy and i really don't know why, because the rotation on the Y-Axis (from down to up) worked great. Anyway, this code works fine if I use the target rotation instead of the pivot rotation for the X-Axis rotation of the camera, but then, the player rotation will depend of the camera rotation. Or I wanted my Player to move freely in the world Using the camera Axis independantly of the camera position.

    I don't know if my explanation was clear enough, sorry for that ^^'. Anyway, I found a solution thanks to this guy's method, so I share it with anyone who could have the same problem as me and now, my player's movement works perfectly as I expected :)



    Also I had to make a new script for my camera, but this wasn't so hard to do :)