Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice
  3. Join us on November 16th, 2023, between 1 pm and 9 pm CET for Ask the Experts Online on Discord and on Unity Discussions.
    Dismiss Notice

Rotation Problem with LocalEulerAngles

Discussion in 'Scripting' started by SirBoboHobo, Jul 9, 2015.

  1. SirBoboHobo

    SirBoboHobo

    Joined:
    Feb 26, 2015
    Posts:
    41
    Hello.

    I'm working on a game currently in which you can rotate the player around the z axis (2D game).
    This is my script

    Vector3 rotation;

    float x = CrossPlatformInputManager.GetAxis ("RotateX") * 180;
    float y = CrossPlatformInputManager.GetAxis ("RotateY") * 180;

    rotation.Set (x,y,0);

    transform.localEulerAngles = new Vector3 (0,0,rotation.x + rotation.y);

    I'm trying to simply rotate the player the way the joy stick is rotated, but I'm having a problem when rotating, it's very unreliable and switches degrees for no reason, when at 180 y it can go to 180 on the x, doesn't complete a full circle, just switches direction in the middle...I don't know what to do, I have tried countless stuff... does anyone know how to make this work?
     
  2. SirBoboHobo

    SirBoboHobo

    Joined:
    Feb 26, 2015
    Posts:
    41
    Anyone? I just can't figure this out...
     
  3. GroZZleR

    GroZZleR

    Joined:
    Feb 1, 2015
    Posts:
    3,201
    What does RotateX and RotateY represent? Two different analog stick values? Why are you multiplying them by 180? Does it normally range in value from -1 to +1? I'm not familiar with this CrossPlatformInputManager class but I'm going to assume it works like Unity's built-in input.

    Adding two different angles together isn't going to what you what you want. If one is -180 and the other is 180, you'd end up at 0 but actually want to be heading southwest.

    You need to use Mathf.Atan2 here, try this:
    Code (csharp):
    1.  
    2. float x = CrossPlatformInputManager.GetAxis ("RotateX"); // get rid of the * 180
    3. float y = CrossPlatformInputManager.GetAxis ("RotateY");
    4.  
    5. transform.rotation = Quaterion.Euler(0f, 0f, Mathf.Atan2(y, x) * Mathf2.Rad2Deg);
    6.  
     
  4. SirBoboHobo

    SirBoboHobo

    Joined:
    Feb 26, 2015
    Posts:
    41
    Ahm, that's weird, my spaceship shoots the bullet in a direction 90 degrees from the given position, like if the joystick at x -90 y 90 then it does the opposite to the right, which means 90x 90y, if at 90x 90y it'll go to 90x -90y.
    and there is no rotation, like the sprite doesn't rotate, something like an imaginary rotation, rotates but doesn't show it does... weird...
     
  5. GroZZleR

    GroZZleR

    Joined:
    Feb 1, 2015
    Posts:
    3,201
    Is the ship itself correct now though?

    If so, post how you create and aim your bullets so we can tackle that problem now.
     
  6. SirBoboHobo

    SirBoboHobo

    Joined:
    Feb 26, 2015
    Posts:
    41
    I made a gif to show you what really it looks like. http://gyazo.com/2fffc3664d03c60e7348a76036ed11d8
    Also, when you hold the joystick at the same position then the bullet will randomly switch between shooting it straight down and shooting it the other way. absolutely random... Maybe my other scripts somehow effect that... I don't know, here is Player Shooting

    Code (CSharp):
    1. public static float timeBetweenShots = 2f;
    2.     public GameObject bullet;
    3.  
    4.     float timer;
    5.     GameObject player;
    6.  
    7.     void Awake ()
    8.     {
    9.         player = GameObject.FindGameObjectWithTag ("Player");
    10.     }
    11.  
    12.     void Update ()
    13.     {
    14.         timer += Time.deltaTime;
    15.         if (timer >= timeBetweenShots) {
    16.  
    17.             Shoot();
    18.         }
    19.  
    20.     }
    21.  
    22.     void Shoot(){
    23.         timer = 0f;
    24.         Instantiate (bullet, transform.position, player.transform.rotation);
    25.     }
    and here is the bullet physics
    Code (CSharp):
    1. void FixedUpdate ()
    2.     {
    3.         rb2d.velocity = transform.up * -1f * speed;
    4.     }
     
  7. GroZZleR

    GroZZleR

    Joined:
    Feb 1, 2015
    Posts:
    3,201
    Maybe the input asset you're using isn't returning values that I think it is. Can you add a debug log statement under your code and tell me the values when the joystick is at the top (north), right (east), bottom (south) and left (west)?

    Code (csharp):
    1.  
    2. float x = CrossPlatformInputManager.GetAxis ("RotateX"); // get rid of the * 180
    3. float y = CrossPlatformInputManager.GetAxis ("RotateY");
    4.  
    5. Debug.Log("x: " + x + " - y: " + y);
    6.  
     
  8. SirBoboHobo

    SirBoboHobo

    Joined:
    Feb 26, 2015
    Posts:
    41
    I have just checked and it does return values, and accurate ones too. That's really weird, I've been developing for 6 months, never encountered such a thing
    All the values are correct, top (0,1) bottom (0,-1) right (1,0) left (-1, 0)
     
  9. SirBoboHobo

    SirBoboHobo

    Joined:
    Feb 26, 2015
    Posts:
    41
    It always shoots 90 degrees ahead, if my joystick is at (0,1) it will shoot to (1,0), if at (0,-1) then to (-1,0), (-1,0) to (0,1)
     
  10. GroZZleR

    GroZZleR

    Joined:
    Feb 1, 2015
    Posts:
    3,201
    Can you post the code where you set the player's rotation? Since the gif doesn't have the sprite moving, it's hard to tell where it's facing and if that's accurate. We should solve that problem first.
     
  11. SirBoboHobo

    SirBoboHobo

    Joined:
    Feb 26, 2015
    Posts:
    41
    Code (CSharp):
    1. public class Player : MonoBehaviour {
    2.  
    3.     public static float speed = 4.7f;
    4.  
    5.  
    6.     Vector3 movement;
    7.     Rigidbody2D playerRigidbody2d;
    8.     Vector3 rotation;
    9.  
    10.     void Awake()
    11.     {
    12.         playerRigidbody2d = GetComponent<Rigidbody2D> ();
    13.     }
    14.  
    15.     void FixedUpdate ()
    16.     {
    17.  
    18.         float h = CrossPlatformInputManager.GetAxisRaw ("Horizontal");
    19.         float v = CrossPlatformInputManager.GetAxisRaw ("Vertical");
    20.  
    21.         Move (h, v);
    22.  
    23.         Turning ();
    24.     }
    25.    
    26.     void Move(float h, float v)
    27.     {
    28.         movement.Set (h, v, 0f);
    29.  
    30.         movement = movement.normalized * speed * Time.deltaTime;
    31.  
    32.         playerRigidbody2d.MovePosition (transform.position + movement);
    33.     }
    34.  
    35.     void Turning()
    36.     {
    37.  
    38.         float x = CrossPlatformInputManager.GetAxis ("RotateX");
    39.         float y = CrossPlatformInputManager.GetAxis ("RotateY");
    40.         Debug.Log("x: " + x + " - y: " + y);
    41.  
    42.         transform.rotation = Quaternion.Euler(0f, 0f, Mathf.Atan2(y, x) * Mathf.Rad2Deg);
    43.  
    44.     }
    45.  
    46.        
    47. }
    48.  
    all of the code for the player. this is movement/rotation
     
  12. GroZZleR

    GroZZleR

    Joined:
    Feb 1, 2015
    Posts:
    3,201
    Does the player rotate properly? The gif doesn't show them moving at all.
     
  13. SirBoboHobo

    SirBoboHobo

    Joined:
    Feb 26, 2015
    Posts:
    41
    Nope, the player doesn't rotate at all... which is very weird. I'm not sure, I can rotate it with localeuler tho, it rotates but badly...
     
    Last edited: Jul 14, 2015
  14. GroZZleR

    GroZZleR

    Joined:
    Feb 1, 2015
    Posts:
    3,201
    How is your scene and hierarchy setup? Is the player a compound GameObject or a single GameObject?
     
  15. SirBoboHobo

    SirBoboHobo

    Joined:
    Feb 26, 2015
    Posts:
    41
    The shooting is done from a child object, theres a player with 3 scripts (player ^the one above, playerhealth, powerupHandle) and a child with a script of shooting. also posted the shooting script up there.
    the rotation is done from my Player script which attached to the parent. I could try and attach the shooting to the parent aswell and see what happens

    UPDATE: just tried, same result
     
  16. GroZZleR

    GroZZleR

    Joined:
    Feb 1, 2015
    Posts:
    3,201
    Not sure what to tell you mate - something wonky is going on if it's not moving at all. Any other scripts possibly interfering or anything like that? Maybe it's because you're sampling input in FixedUpdate rather than Update? I'm not really sure what it could be.

    Here's the result of my code:


    And here's the code:
    Code (csharp):
    1.  
    2. using System.Collections;
    3. using System.Collections.Generic;
    4. using UnityEngine;
    5.  
    6. public class RotateSprite : MonoBehaviour
    7. {
    8.    protected float horizontalAxis;
    9.    protected float verticalAxis;
    10.  
    11.    protected void Update()
    12.    {
    13.      horizontalAxis = Input.GetAxis("Horizontal");
    14.      verticalAxis = Input.GetAxis("Vertical");
    15.  
    16.      transform.rotation = Quaternion.Euler(0f, 0f, Mathf.Atan2(verticalAxis, horizontalAxis) * Mathf.Rad2Deg);
    17.    }
    18.  
    19.    protected void OnGUI()
    20.    {
    21.      GUI.Label(new Rect(5, 5, 100, 25), "H: " + horizontalAxis);
    22.      GUI.Label(new Rect(5, 30, 100, 25), "V: " + verticalAxis);
    23.    }
    24. }
    25.  
    Maybe try playing around with it in a blank project to see if it works there and then start tearing apart your current project trying to find anything that might be interfering.

    Sorry I can't be of more help.
     
  17. SirBoboHobo

    SirBoboHobo

    Joined:
    Feb 26, 2015
    Posts:
    41
    Thanks a lot dude, probably something interfering, I'll find the source of the problem, you helped me a lot. thank you :)
     
  18. SirBoboHobo

    SirBoboHobo

    Joined:
    Feb 26, 2015
    Posts:
    41
    Hey mate, I know this is an old thread, I just came back from a 1 month vacation abroad and solved it, I just applied root motion in the animator attached, that was what caused the problem, but there are 2 problems left, it rotates 90 degrees to the right above what it should like i explained in this thread, and another one is when i leave the joystick it goes back to default state, a thing i prefer it not to do, I prefer it stay in the rotation it is at before releasing, any ideas?
     
  19. GroZZleR

    GroZZleR

    Joined:
    Feb 1, 2015
    Posts:
    3,201
    Is your graphic facing up / north (270 degrees) and not the correct right / east (0 degrees)? That's a commonly made mistake and might explain the 90 degree offset.

    The second issue could be fixed by simply checking if the axis is not 0 before updating anything.
     
  20. SirBoboHobo

    SirBoboHobo

    Joined:
    Feb 26, 2015
    Posts:
    41
    fixed the second problem, regarding the 1st, should all my sprites when creating them face right?
    the default rotation (when z set to 0) is down / south
     
  21. SirBoboHobo

    SirBoboHobo

    Joined:
    Feb 26, 2015
    Posts:
    41
    By the way, I found a fix simply by adding + 90 to the quaternion euler z.
    it fixed it but should i make my sprites face right to avoid these kind of things?
     
  22. GroZZleR

    GroZZleR

    Joined:
    Feb 1, 2015
    Posts:
    3,201
    If you want to avoid some unnecessary math, then yes. If you're cool with it, it shouldn't come back to haunt you.

    Glad you got everything sorted.
     
    SirBoboHobo likes this.