Search Unity

Rolling and Turning a Ball

Discussion in 'Scripting' started by Kagedtiger, Jan 6, 2013.

  1. Kagedtiger

    Kagedtiger

    Joined:
    Sep 27, 2010
    Posts:
    76
    Hey Guys, looking for a little help with rotation here. I have a ball that I'm trying to roll along the ground. The left and right arrows turn the ball in the x-z plane, while the forward and backward arrows move it forward and backward. (This is all being done with physics and rigidbodies, rather than transforms.) My only problem is that I can't use the default 'forward' vector of the transform since the 'forward' of a rolling ball is often pointed towards the ground or the sky, or any number of non-useful directions.

    So what I'm *trying* to do is find the y angle rotation of the ball, then get a vector that is that rotation around the global 'up,' and use that as the new forward. It *mostly* works, except that somehow in my code there this weird course-correction thing happening. I'll be rotating the ball and then hit forward and it will start for a second to roll in the correct forward direction for the ball, but then it will suddenly veer off to a slightly altered vector and I don't know why. I was hoping someone could double-check my code and see if you can tell me what I'm doing wrong...

    Code (csharp):
    1.     void FixedUpdate () {
    2.  
    3.         //SPHERE MOVEMENT
    4.         float hor = Input.GetAxis("Horizontal");
    5.         float ver = Input.GetAxis("Vertical");
    6.                
    7.         //turning
    8.         if (Mathf.Abs(hor) > deadZone) {
    9.             rigidbody.AddTorque(Vector3.up * turnSpeed * Input.GetAxis("Horizontal")); 
    10.         }
    11.  
    12.         //get the y rotation value
    13.         float yRot = transform.rotation.eulerAngles.y;
    14.            
    15.         //apply the y rotation to the global 'forward' vector3 to get the
    16.         //forward vector direction that our sphere is moving in
    17.         Vector3 newForward = Quaternion.AngleAxis(yRot, Vector3.up) * Vector3.forward.normalized;      
    18.        
    19.         //forward
    20.         if (Mathf.Abs(ver) > deadZone) {
    21.             //move forward in that direction           
    22.             rigidbody.AddTorque(newForward * forwardSpeed * Input.GetAxis("Vertical") * -1);   
    23.         }
    24.              }
     
    TJ_Cops likes this.
  2. Kagedtiger

    Kagedtiger

    Joined:
    Sep 27, 2010
    Posts:
    76
    Allow me to rephrase, since I suspect I might be doing this completely wrong.

    What I want is to get a 2D rotation around the Y axis that corresponds to how much the side arrows have been pressed. When I press 'forward' I would like for the ball to roll in the direction of that rotation. Is this the correct way of doing so?
     
  3. Kraze

    Kraze

    Joined:
    Jan 6, 2013
    Posts:
    13
    If you want the ball only to roll and spin either left or right (2D). Then you could do something as simple as the code below.

    Code (csharp):
    1. #pragma strict
    2. var speed = 10;
    3.  
    4. function Start () {
    5.  
    6. }
    7.  
    8. function Update () {
    9.  
    10.     if (Input.GetKey(KeyCode.RightArrow))
    11.     {
    12.     rigidbody.AddTorque(0,0,speed);
    13.     }
    14.     else if (Input.GetKey(KeyCode.LeftArrow))
    15.     {
    16.     rigidbody.AddTorque(0,0,-speed);
    17.     }
    18. }
    19.  
    This will spin the ball around the Z axis and also move the ball left and right to make it look like it's rolling. Adjust speed to make it move and spin faster.
     
  4. Kagedtiger

    Kagedtiger

    Joined:
    Sep 27, 2010
    Posts:
    76
    I think this is sort of what I'm already doing for left and right - but the problem is rolling forward. The ball starts to tilt to the side, so that its right-side directional vector is no longer parallel to the ground. Because of this, it begins to tilt and roll in odd directions. I need to get it to stop doing that.
     
  5. bigmisterb

    bigmisterb

    Joined:
    Nov 6, 2010
    Posts:
    4,221
    Ball control is never really about ball position and rotation as it is about camera position and rotation.

    Left is always Camera left.

    This is a basic example, using a "cheater" object.

    Code (csharp):
    1.  
    2. Transform cheat;
    3.  
    4. void Start(){
    5. cheat = new GameObject().transform;
    6. }
    7.  
    8. void FixedUpdate(){
    9. float hor = Input.GetAxis("Horizontal");
    10. float ver = Input.GetAxis("Vertical");
    11.  
    12. Vector3 dir = new Vector3(hor, 0, ver);
    13. Vector3 rot = new Vector3(ver, 0, hor);
    14.  
    15.  
    16. cheat.position = transform.position;
    17. cheat.rotation = Camera.main.transform.rotation;
    18. Vector3 lookAt = cheat.position + cheat.forward;
    19. lookAt.y = transform.position.y;
    20. cheat.transform.LookAt(lookAt);
    21.  
    22. rigidbody.AddTorque(cheat.TransformDirection(rot) * forwardSpeed * 0.5f);
    23. rigidbody.AddForce(cheat.TransformDirection(dir) * forwardSpeed * 0.5f);
    24. }
    25.