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

How to rotate sphere when move?

Discussion in 'Scripting' started by black0n3, Nov 29, 2011.

  1. black0n3

    black0n3

    Joined:
    Nov 29, 2011
    Posts:
    4
    Hi I wonna make sphere rotete when i move it I try this but sphere is not rotete can you help me?

    Code (csharp):
    1. public void Update()
    2.  
    3.     {
    4.        
    5.  
    6.         Vector3 horMovement = Input.GetAxis("Horizontal") * transform.right * Time.deltaTime * speed;
    7.  
    8.          if (Input.GetKey ("w")) {
    9.         this.transform.Rotate (0,0, Time.deltaTime * 100);
    10.                                                  }
    11.  
    12.    
    13.         Vector3 forwardMovement = Input.GetAxis("Vertical") * transform.forward * Time.deltaTime * speed;
    14. }
    15.  
     
  2. bigmisterb

    bigmisterb

    Joined:
    Nov 6, 2010
    Posts:
    4,221
    The first problem that you have is that if you "roll" the ball transform.forward will not be "forward" anymore. So first, you will want to correct movement based on that.

    To correct this we look at what the person see's. What device in the game alows the person to see the ball? Easy, the camera. So all movement, forward, back, left and right need to come from the camera's perspective, not the ball's. However, there is a catch. What happens when the camera is facing down on the ball? Well, we also need to make sure that the camera is based off of a flat plane, not a tilted one.

    So start off with the standard script "MouseOrbit" Drag it onto your camera, and set the ball as the target.

    Next, give the ball a texture and make a box 50x1x50 and place it exactly 1 unit below the ball, so you can see your efforts.

    Now, just make sure you add a light into the scene or everything will look dull and lightless.

    now, lets look at the script.

    Code (csharp):
    1.  
    2. // speed of the ball
    3. var speed = 5.0;
    4.  
    5. function Update () {
    6.     // base movement off of the camera, not the object.
    7.     // reset the camera's X to zero, so that it is always looking horizontally.
    8.     var x = Camera.main.transform.localEulerAngles.x;
    9.     Camera.main.transform.localEulerAngles.x = 0;
    10.    
    11.     // now collect the movement stuff This is generic direction and rotation.
    12.     var direction = Vector3(Input.GetAxis("Horizontal"),0,Input.GetAxis("Vertical"));
    13.     var rotation = Vector3(Input.GetAxis("Vertical"),0,-Input.GetAxis("Horizontal"));
    14.    
    15.     // prevent the ball from moving faster diagnally
    16.     if(direction.magnitude > 1.0) direction.Normalize();
    17.     if(rotation.magnitude > 1.0) rotation.Normalize();
    18.    
    19.    
    20.     // reorientate the movement stuff to align to the camera.
    21.     direction = Camera.main.transform.TransformDirection(direction);
    22.     rotation = Camera.main.transform.TransformDirection(rotation);
    23.    
    24.     // multiply the direction by the speed and deltaTime
    25.     direction *= Time.deltaTime * speed;
    26.     // multiply the rotation by the speed, deltaTime, circumference and 10...
    27.     // dunno why I had to add 10, but it works
    28.     rotation *= Time.deltaTime * speed * (2 * Mathf.PI * transform.localScale.magnitude) * 10;
    29.    
    30.     // now update the position by the direction
    31.     transform.Translate(direction, Space.World);
    32.     // and rotate by the rotation
    33.     transform.Rotate(rotation, Space.World);
    34.    
    35.     // return the camera's x rotation.
    36.     Camera.main.transform.localEulerAngles.x = x;
    37. }
    38.  
    I annotated it so that you get what's going on with it. This of course.. is not the way to do it... lol
     
  3. black0n3

    black0n3

    Joined:
    Nov 29, 2011
    Posts:
    4
    Thx for your help!

    I added "MouseOrbit" on camera and add texture on ball and added script that you write on ball and it's not working.
    Show me null error on line 7..

    var x = Camera.main.transform.localEulerAngles.x;

    and game doesn't start
     
  4. bigmisterb

    bigmisterb

    Joined:
    Nov 6, 2010
    Posts:
    4,221
    The camera must be the main camera.... in other words it must have the MainCamera tag. If not, then you have no MainCamera, thus it will error.
     
  5. black0n3

    black0n3

    Joined:
    Nov 29, 2011
    Posts:
    4
    Now it's working! =)

    Thank you very much!!!
     
  6. bigmisterb

    bigmisterb

    Joined:
    Nov 6, 2010
    Posts:
    4,221
    Ok, so lets add in some code so that we can accurately measure the radius and apply it to the ball. So any ball of any size will work. (odd, in testing it was as easy as making the ball have a radius of 0.5 and tinkering with the number, then giving it a radius of 1 and tinkering and it gave me the exact number to modify it by)

    Code (csharp):
    1.  
    2. // speed of the ball
    3. var speed = 5.0;
    4. [COLOR="red"]var radius = 0.5;
    5.  
    6. function Start(){
    7.     transform.localScale = Vector3.one * radius * 2;
    8.     var hit : RaycastHit;
    9.     if(Physics.Linecast(transform.position, transform.position - Vector3.up * 500, hit)){
    10.         transform.position = hit.point + Vector3.up * radius;
    11.     }
    12. }[/COLOR]
    13.  
    14. function Update () {
    15.     // base movement off of the camera, not the object.
    16.     // reset the camera's X to zero, so that it is always looking horizontally.
    17.     var x = Camera.main.transform.localEulerAngles.x;
    18.     Camera.main.transform.localEulerAngles.x = 0;
    19.    
    20.     // now collect the movement stuff This is generic direction and rotation.
    21.     var direction = Vector3(Input.GetAxis("Horizontal"),0,Input.GetAxis("Vertical"));
    22.     var rotation = Vector3(Input.GetAxis("Vertical"),0,-Input.GetAxis("Horizontal"));
    23.    
    24.     // prevent the ball from moving faster diagnally
    25.     if(direction.magnitude > 1.0) direction.Normalize();
    26.     if(rotation.magnitude > 1.0) rotation.Normalize();
    27.    
    28.    
    29.     // reorientate the movement stuff to align to the camera.
    30.     direction = Camera.main.transform.TransformDirection(direction);
    31.     rotation = Camera.main.transform.TransformDirection(rotation);
    32.    
    33.     // multiply the direction by the speed and deltaTime
    34.     direction *= Time.deltaTime * speed;
    35. [COLOR="red"]   // multiply the rotation by the speed, deltaTime and (60 / radius)...
    36.     rotation *= Time.deltaTime * speed *  60 / radius;[/COLOR]
    37.    
    38.     // now update the position by the direction
    39.     transform.Translate(direction, Space.World);
    40.     // and rotate by the rotation
    41.     transform.Rotate(rotation, Space.World);
    42.    
    43.     // return the camera's x rotation.
    44.     Camera.main.transform.localEulerAngles.x = x;
    45. }
    46.  
    With these changes we also drop the ball down to whatever it is supposed to be sitting on.

    Later on, we will adjust this so that it uses a faux gravity. ;)
     
  7. bigmisterb

    bigmisterb

    Joined:
    Nov 6, 2010
    Posts:
    4,221
    Wandering around on a flat box is fun and all, but lets look at some other key features. Velocity and some fake gravity.

    Code (csharp):
    1.  
    2. // speed of the ball
    3. var speed = 5.0;
    4. var radius = 5.0;
    5. var velocity : Vector3 = Vector3.zero;
    6.  
    7. function Start(){
    8.     transform.localScale = Vector3.one * radius * 2;
    9.     var hit : RaycastHit;
    10.     if(Physics.Linecast(transform.position, transform.position - Vector3.up * 500, hit)){
    11.         transform.position = hit.point + Vector3.up * radius;
    12.     }
    13. }
    14.  
    15. function Update () {
    16.     // base movement off of the camera, not the object.
    17.     // reset the camera's X to zero, so that it is always looking horizontally.
    18.     var x = Camera.main.transform.localEulerAngles.x;
    19.     Camera.main.transform.localEulerAngles.x = 0;
    20.    
    21.     // now collect the movement stuff This is generic direction and rotation.
    22.     var direction = Vector3(Input.GetAxis("Horizontal"),0,Input.GetAxis("Vertical"));
    23.    
    24.     // prevent the ball from moving faster diagnally
    25.     if(direction.magnitude > 1.0) direction.Normalize();
    26.    
    27.     // lets setup a modifier that will speed up the ball quickly, but only gradually stop it.
    28.     // at this point, direction is nothing but what we get from the keyboard.
    29.     var modifier = 3.0;
    30.     if(direction.magnitude == 0) modifier = 1.0;
    31.     // lets set the direction according to the camera now.
    32.     direction = Camera.main.transform.TransformDirection(direction);
    33.    
    34.     // Now, lets keep track of a velocity.
    35.     // This will let the ball move while we are not pressing anything.
    36.     velocity = Vector3.Lerp(velocity, direction, modifier * Time.deltaTime);
    37.     // Now, lets break the rotation out from the movement.
    38.     var rotation = Vector3(velocity.z,0,-velocity.x);
    39.    
    40.     // multiply the direction by the speed and deltaTime
    41.     direction *= Time.deltaTime * speed;
    42.     // rotation by (60 / radius)
    43.     rotation *= 60 / radius;
    44.    
    45.     // now update teh position by the direction
    46.     transform.Translate(velocity, Space.World);
    47.     // and rotate by the rotation
    48.     transform.Rotate(rotation, Space.World);
    49.    
    50.     // lets check to see if the ball is on something, if so, lets snap it to it.
    51.     var hits : RaycastHit[];
    52.     // get all the hits we have between 250 up and down.
    53.     hits = Physics.RaycastAll(transform.position + Vector3.up * 250, -Vector3.up, 500);
    54.     // run through them all
    55.     for(var i=0; i<hits.Length; i++){
    56.         var hit : RaycastHit= hits[i];
    57.         // if the hit is not the object we are controlling
    58.         if(hit.transform.root != transform){
    59.             // we need to be sitting on it.
    60.             transform.position = hit.point + Vector3.up * radius;
    61.             break;
    62.         }
    63.     }
    64.    
    65.     // return the camera's x rotation.
    66.     Camera.main.transform.localEulerAngles.x = x;
    67. }
    68.  
    So this is a truely basic movement, that adheres to a terrain, but has no actual physics. Again, this is NOT the way to do it, you would really want to control this by physics.

    So lets check that one out next. :D
     
  8. bigmisterb

    bigmisterb

    Joined:
    Nov 6, 2010
    Posts:
    4,221
    OK, lastly, lets look at this in physics. This is the actual way we should go.

    Basic controls, mouse and keyboard, but lets add a jump, using the space bar. The actual object is handled by physics, but we have some affect on it. forward and such, we can move around as we want, jump if we can. The differences here are that if we don't press anything, we just let the physics engine handle what is going on, trying to over complicate math to do nothing is a pretty hard thing to do. Also, we are checking to see if we are close enough to the ground to use a jump, lets also use this to limit the abilities of the player. We don't full blown movement while the ball is in the air, but we do want just enough control to have an affect.

    Code (csharp):
    1.  
    2. // speed of the ball
    3. var speed = 5.0;
    4. var radius = 5.0;
    5. private var velocity : Vector3 = Vector3.zero;
    6.  
    7. function Start(){
    8.     transform.localScale = Vector3.one * radius * 2;
    9.     var hit : RaycastHit;
    10.     if(Physics.Linecast(transform.position, transform.position - Vector3.up * 500, hit)){
    11.         transform.position = hit.point + Vector3.up * radius;
    12.     }
    13.     // add a rigidbody if we dont have one.
    14.     if(!rigidbody)
    15.         gameObject.AddComponent(Rigidbody);
    16.     // set the mass according to the radius.
    17.     rigidbody.mass = 100 * radius;
    18. }
    19.  
    20. function FixedUpdate () {
    21.     // let see if our body is on the ground.
    22.     var hit : RaycastHit;
    23.     var isGrounded = Physics.Raycast(transform.position, -Vector3.up, hit, radius * 1.5);
    24.    
    25.     // base movement off of the camera, not the object.
    26.     // reset the camera's X to zero, so that it is always looking horizontally.
    27.     var x = Camera.main.transform.localEulerAngles.x;
    28.     Camera.main.transform.localEulerAngles.x = 0;
    29.    
    30.     // now collect the movement stuff This is generic direction.
    31.     var direction = Vector3(Input.GetAxis("Horizontal"),0,Input.GetAxis("Vertical"));
    32.    
    33.     // prevent the ball from moving faster diagnally
    34.     if(direction.magnitude > 1.0) direction.Normalize();
    35.    
    36.     // If we are grounded, then lets see if we want to jump.
    37.     if(isGrounded  Input.GetKeyDown(KeyCode.Space))
    38.         rigidbody.AddForce(Vector3.up * rigidbody.mass * 500);
    39.    
    40.     // if we arent pressing anything, dont mess with the physics.
    41.     if(direction.magnitude > 0){
    42.         // convert isGrounded into something we can use
    43.         var modifier = isGrounded ? 3.0 : 0.5;
    44.         // lets set the direction according to the camera now.
    45.         direction = Camera.main.transform.TransformDirection(direction) * speed * 2;
    46.         // lets take the downward velocity from the current so that we dont get wierd physics results
    47.         direction.y = rigidbody.velocity.y;
    48.        
    49.         // Now, lets keep track of a velocity.
    50.         // This will let the ball move while we are not pressing anything.
    51.         rigidbody.velocity = Vector3.Lerp(rigidbody.velocity, direction, modifier * Time.deltaTime);
    52.         // Now, lets break the rotation out from the movement.
    53.         var rotation = Vector3(rigidbody.velocity.z,0,-rigidbody.velocity.x) * 20;
    54.        
    55.        
    56.         // Lets add some spin to make the ball move better
    57.         rigidbody.angularVelocity = Vector3.Lerp(rigidbody.angularVelocity, rotation, modifier * Time.deltaTime);
    58.     }
    59.    
    60.     // return the camera's x rotation.
    61.     Camera.main.transform.localEulerAngles.x = x;
    62. }
    63.  
    Well, OK, guys that does it for me for this issue, Way over did everything, but if anyone was out there following and finds this helpful. Well, that is what I did it for. And to waste an afternoon having fun playing in 3d... while I am supposed to be working. :D
     
  9. black0n3

    black0n3

    Joined:
    Nov 29, 2011
    Posts:
    4
    This is exactly what I needed Jump is very cool ;) Thank you again!!! How can I make to ball jump litle higher but not to far?
    i set this code to 200 instead of 500
    rigidbody.AddForce(Vector3.up * rigidbody.mass * 500);
     
  10. Dabeh

    Dabeh

    Joined:
    Oct 26, 2011
    Posts:
    1,614
    Seems like you figured it out for yourself, but if its still to high then lower it a little more.
     
  11. mhardy

    mhardy

    Joined:
    Apr 3, 2011
    Posts:
    48
    Why "60 / radius" here? It works perfectly, but what's the math behind choosing 60 in this equation?