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. Dismiss Notice

Rigidbody Rotation not working so well...

Discussion in 'Scripting' started by Chinafreak, Oct 23, 2016.

  1. Chinafreak

    Chinafreak

    Joined:
    Apr 6, 2013
    Posts:
    44
    Hello guys,

    I've there a problem with rotation of rigidbody, but lets explain me at first:

    You can control the shark with WASD key if the shark position Y is smaller than 0, the Movement is based by transform.Translate (and Rigidbody is set to Kinematic). If the Shark position Y is bigger than 0, then Rigidbody is on (Kinematic = false) and transform.Translate is now ignored - then I'm using velocity function (not AddForce!) to simulate the Shark Movement by Rigidbody (instead of transform.Translate) and then the shark goes slowy down. All works fine - EXCEPT the rotation. If the shark is above of water, then the rotation is playing sometimes crazy and I don't know why. There, a gif what I mean:


    I'm using "Quaternion.LookRotation(velocity, Vector3.left);" for simulating rotating if the shark is going to down by gravity. Velocity is from rigidbody.velocity

    The code of SharkMovement.cs:

    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3. using System.Collections.Generic;
    4. using System;
    5.  
    6. public class SharkMovement : MonoBehaviour {
    7.     public Transform camera;
    8.     public GameObject Head;
    9.  
    10.     Rigidbody rigid;
    11.     public float maxSpeed = 12f;
    12.     float speed = 0f;
    13.  
    14.     Vector3 velocity = Vector3.zero;
    15.     bool aboveEntered = false;
    16.  
    17.  
    18.     void Start () {
    19.  
    20.         rigid = Head.transform.GetComponent<Rigidbody>();
    21.     }
    22.    
    23.     void FixedUpdate () {
    24.  
    25.  
    26.         if (Head.transform.position.y > 0)
    27.         {
    28.             rigid.isKinematic = false;
    29.  
    30.             if (!aboveEntered)
    31.             {
    32.                 rigid.velocity = Head.transform.right * -speed;
    33.                 aboveEntered = true;
    34.             }
    35.          
    36.  
    37.             velocity = rigid.velocity;
    38.             speed = rigid.velocity.magnitude;
    39.          
    40.  
    41.             Vector3 rot = Head.transform.rotation.eulerAngles;
    42.  
    43.             Quaternion qua = Quaternion.LookRotation(velocity, Vector3.left);
    44.             Vector3 target = qua.eulerAngles;
    45.             Quaternion rotHead = Head.transform.rotation;
    46.  
    47.             rot.x = target.x;
    48.             rot.y = target.y;
    49.             rot.z = target.z;
    50.             rotHead.eulerAngles = rot;
    51.             Head.transform.rotation = rotHead;
    52.             Head.transform.Rotate(0, 90, 0);
    53.         }
    54.         else
    55.         {
    56.             aboveEntered = false;
    57.             speed = 6.0f;
    58.  
    59.             rigid.isKinematic = true;
    60.  
    61.             if (Input.GetMouseButton(0))
    62.             {
    63.                 speed = maxSpeed;
    64.             }
    65.             else if (Input.GetMouseButton(1))
    66.             {
    67.                 speed = 12f;
    68.             }
    69.  
    70.             if (Input.GetKey(KeyCode.W))
    71.             {
    72.                 Head.transform.Rotate(Vector3.up * 3);
    73.             }
    74.             else if (Input.GetKey(KeyCode.S))
    75.             {
    76.                 Head.transform.Rotate(-Vector3.up * 3);
    77.             }
    78.  
    79.             if (Input.GetKey(KeyCode.A))
    80.             {
    81.                 Head.transform.Rotate(-Vector3.forward * 3);
    82.             }
    83.             else if (Input.GetKey(KeyCode.D))
    84.             {
    85.                 Head.transform.Rotate(Vector3.forward * 3);
    86.             }
    87.  
    88.             Head.transform.position += (Head.transform.right * -speed) * Time.deltaTime;
    89.         }
    90.        
    91.        
    92.     }
    93.  
    94. }
    95.  
    96.  

    There is the project source file:

    https://dl.dropbox.com/s/j57vlnz8odqux4e/Sharkproject.zip

    I hope someone could help me! :S

    Thank you,

    - Chinafreak
     
  2. takatok

    takatok

    Joined:
    Aug 18, 2016
    Posts:
    1,496
    Well 2 things, the first is that all this code here:
    Code (CSharp):
    1.    
    2.             Vector3 rot = Head.transform.rotation.eulerAngles;
    3.             Quaternion qua = Quaternion.LookRotation(velocity, Vector3.left);
    4.             Vector3 target = qua.eulerAngles;
    5.             Quaternion rotHead = Head.transform.rotation;
    6.             rot.x = target.x;
    7.             rot.y = target.y;
    8.             rot.z = target.z;
    9.             rotHead.eulerAngles = rot;
    10.             Head.transform.rotation = rotHead;
    Is basically the same as this:
    Code (CSharp):
    1.  Head.transform.rotation = Quaternion.LookRotation(velocity, Vector3.left);
    And secondly, I think your glitch comes from when velocity is either the same directions as Vector3.left, or exactly opposite it. Then Look Rotation can't create a rotation that has 3 orthogonal vectors.

    What exactly is the code suppose to achieve while the shark is above the wave.. just making an arc over the water pointing up/level/down like a fish jumping?
     
  3. Chinafreak

    Chinafreak

    Joined:
    Apr 6, 2013
    Posts:
    44

    hey, thanks for your answer!

    The first one, I know but I just fetched the code so I've more freedom for customize. :)
    Yep, thats what I wanted. Maybe this picture is easier to understand what I want to have.



    Thats all what I want. The shark should modificated Pitch and Yaw by gravity. Roll isn't important (it shouldn't change from the air). I've no idea anymore how I should do. Im already trying 3 days do get work. :S

    Just in case for "Roll, Pitch and Yaw"



    Maybe somebody have a idea how to fix this? I would glad if someone could help me. :)
     
  4. takatok

    takatok

    Joined:
    Aug 18, 2016
    Posts:
    1,496
    Aren't those axis off from Unity's standard.. Roll should be Z, Yaw is Y and ptich is X?

    I'm trying to wrap my head around how your moving this thing.. If its below the water and I don't give any input it just moves along with this code:
    Code (CSharp):
    1. Head.transform.position += (Head.transform.right * -speed) * Time.deltaTime;
    why would the position move based on the shark's right vector rather than his foward? Have you turned the whole thing somehow so the forward vector of the shark is pointing out of its middle, and the head and tail are aligned on the x-axis (transform.right?) And why -speed? Is aligned backwards so the tail is pointing along the +x and the head is pointing along the -x?

    It seems very odd that you aren't aligning this thing so forward direction is forward.. any reason for this?
     
    DonLoquacious likes this.
  5. Chinafreak

    Chinafreak

    Joined:
    Apr 6, 2013
    Posts:
    44
    because there is no "transform.left", so thats why I use "transform.right * -speed", its equal to "transform.left * speed".

    Any why transform.right? Because the shark move only forward when I'm using transform.right. I mean, of course I could fix this by using parent/children object. But the main problem would still exist. :/ I've already tried that...
     
  6. DonLoquacious

    DonLoquacious

    Joined:
    Feb 24, 2013
    Posts:
    1,667
    So the problem is that the model was saved using an incorrect orientation? You should import it back into the modeling program and fix that, it's just going to keep giving you countless problems (like having a model that's off-center will). Also, you should put the negative on the vector, not the speed. It doesn't make any difference in that simple calculation, but it could later if you get into bad habits.
     
  7. Chinafreak

    Chinafreak

    Joined:
    Apr 6, 2013
    Posts:
    44
    Yep, its was exported wrong orientarion. But thats not the Problem I'm talking about. It has nothing do with this topic.

    The Problem I'm talking is that the rotation is sometimes not correct (glitch?) when the shark jump water. Look at the YouTube Video + Sketch. :)
     
  8. takatok

    takatok

    Joined:
    Aug 18, 2016
    Posts:
    1,496
    Ok so to make a "whale" I made a sphere, with a cylinder behind it a little cylinders along its back so I knew which way was up. I think attached this script to the sphere (Head), and I got it to do what you wanted:
    I changes a few things:
    • Everything is oriented as if transform.forward is the forward direction
    • I added variables for turn speed for underwater and how fast it turns in the air
    • I got rid of all the Kinematic stuff and just turned it manually like we were doing underWater
    Code (CSharp):
    1. using UnityEngine;
    2. using UnityEngine.UI;
    3. using System;
    4. using System.Collections;
    5. using System.Collections.Generic;
    6. using System.Linq;
    7. using UnityEngine.EventSystems;
    8.  
    9. public class GlobalTest : MonoBehaviour
    10. {
    11.  
    12.     public GameObject Head;
    13.  
    14.     Rigidbody rigid;
    15.     public float maxSpeed = 12f;
    16.     public float underWaterTurnSpeed = 3f;
    17.     // This turn speed is in degrees per second
    18.     public float jumpTurnSpeed = 30f;
    19.     float speed = 0f;
    20.  
    21.     Vector3 velocity = Vector3.zero;
    22.     bool aboveEntered = false;
    23.     Quaternion downDir;
    24.  
    25.  
    26.     void Start()
    27.     {
    28.         rigid = Head.transform.GetComponent<Rigidbody>();
    29.         rigid.isKinematic = true;
    30.     }
    31.  
    32.     void FixedUpdate()
    33.     {
    34.         if (Head.transform.position.y > 0)
    35.         {
    36.             if (!aboveEntered)
    37.             {
    38.                 aboveEntered = true;
    39.                 float xRot = Head.transform.rotation.eulerAngles.x;
    40.                 Vector3 eulerAngles = Head.transform.rotation.eulerAngles;
    41.                 eulerAngles.x = 360f - xRot;
    42.                 downDir = Quaternion.Euler(eulerAngles);
    43.                
    44.             }
    45.  
    46.             Head.transform.rotation = Quaternion.RotateTowards(Head.transform.rotation, downDir, Time.deltaTime * jumpTurnSpeed);
    47.             Head.transform.position += Head.transform.forward * (speed * Time.deltaTime);
    48.         }
    49.         else
    50.         {
    51.             aboveEntered = false;
    52.             speed = 4.0f;
    53.  
    54.          
    55.  
    56.             if (Input.GetMouseButton(0))
    57.             {
    58.                 speed = maxSpeed;
    59.             }
    60.             else if (Input.GetMouseButton(1))
    61.             {
    62.                 speed = 12f;
    63.             }
    64.  
    65.             // Go up
    66.             if (Input.GetKey(KeyCode.W))
    67.             {
    68.                 Head.transform.Rotate(Vector3.left * 3);
    69.             }
    70.  
    71.             // Go Down
    72.             else if (Input.GetKey(KeyCode.S))
    73.             {
    74.                 Head.transform.Rotate(Vector3.right * 3);
    75.             }
    76.  
    77.             //Go left
    78.             if (Input.GetKey(KeyCode.A))
    79.             {
    80.                 Head.transform.Rotate(Vector3.down * 3);
    81.             }
    82.             // Go right
    83.             else if (Input.GetKey(KeyCode.D))
    84.             {
    85.                 Head.transform.Rotate(Vector3.up * 3);
    86.             }
    87.          
    88.             Head.transform.position += Head.transform.forward *  (speed * Time.deltaTime);
    89.         }
    90.  
    91.  
    92.     }
    93.  
    94. }
    95.  
    Note your underwater code makes no checks for it flipping on its side, or come up out of the water with its back to the water.. this code will maintain that orientation. So if the whale come up with its belly to the sky it will do an arc of a back flip basically and splash down. Or if its turned sideways when it comes out of the water it stays sideways as it leaps in an arc. That felt the most realistic.
     
    Chinafreak likes this.
  9. Chinafreak

    Chinafreak

    Joined:
    Apr 6, 2013
    Posts:
    44
    Hello,

    thanks for your answer!

    this look fine! Rotation look very good, exactly what I want! Actually I was using this method, too. (but it was glitchy, so your method works good). But this method is sadly not realistic enough, thats why I was using Rigidbody so the shark could move back into water realistic if he swim straight to up.

    What I mean:
    Left: Your Method/Script (Transform), Right: That what I want. (Rigidbody)



    But I'm really (of course!) thankfully for your help! :)

    - Chinafreak
     
  10. takatok

    takatok

    Joined:
    Aug 18, 2016
    Posts:
    1,496
    you could try adjusting the turn speed based on angle of exit. so he flips over faster the sharper the exit angle
     
  11. Chinafreak

    Chinafreak

    Joined:
    Apr 6, 2013
    Posts:
    44
    Oh right, thats a great idea. I'm gonna try it. Thanks for the tips! :)