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

Smooth RotateAround?

Discussion in 'Scripting' started by TheChronicPhenix, Feb 4, 2011.

  1. TheChronicPhenix

    TheChronicPhenix

    Joined:
    Jan 14, 2010
    Posts:
    874
    Ok so right now I have RotateAround set so that it rotates a number of degrees, but its not smooth, it kinda jumps from place to place, heres my code. Now my question is, how would I get it to smoothly rotate from one point to the other but still be able to use the RotateAround command? Thanks.

    Code (csharp):
    1.  
    2. var target : Transform;
    3. var xOffset : float;
    4. var speed : float = 10.0;
    5.  
    6. function Update(){
    7. for (var i=0; i< iPhoneInput.touchCount; i++){
    8. var touch : iPhoneTouch=iPhoneInput.touches[i];
    9. if(touch.phase == iPhoneTouchPhase.Moved){
    10. aimCube.RotateAround(target.position, Vector3.up, touch.deltaPosition.x / xOffset * Time.deltaTime * speed);
    11. }
    12. }
    13. }
     
  2. bigmisterb

    bigmisterb

    Joined:
    Nov 6, 2010
    Posts:
    4,221
    I did a writeup on this in another thread. I could go find the thread, or simply load Unity up and dump the code here.

    It isn't quite done like yours is but it works pretty good. It is setup for a pc but I had left the iPhone stuff in there for whoever needed it later... which they did.. ;)

    A little note from the one that I had posted in the other thread. This one has a auto rotate built in. that can be disabled pretty easily.

    Code (csharp):
    1.  
    2.  
    3. var moveSpeed : float = 2.0;
    4. var damper=0.95;
    5. var leadOutMultiplier=0.03;
    6. var autoRotationSpeed = 0.5;
    7.  
    8. private var aPosX;
    9. private var bPosX;
    10. private var stopTime=0.0;
    11. private var moveMag=0.3;
    12.  
    13. function Start(){
    14.     moveMag=autoRotationSpeed;
    15. }
    16.  
    17. function Update () {
    18.     //for (var i=0; i < iPhoneInput.touchCount; i++){
    19.         //var touch : iPhoneTouch = iPhoneInput.touches[i];
    20.         //if(touch.phase == iPhoneTouchPhase.Began){
    21.         if (Input.GetMouseButtonDown(0)) {
    22.             //aPosX = touch.position.x;
    23.             aPosX = Input.mousePosition.x;
    24.         }
    25.         //if(touch.phase == iPhoneTouchPhase.Moved){
    26.         if(Input.GetMouseButton(0)){
    27.             //bPosX = touch.position.x;
    28.             bPosX = Input.mousePosition.x;
    29.         }
    30.         //if(touch.phase == iPhoneTouchPhase.Ended){
    31.         if(Input.GetMouseButtonUp(0)){
    32.             aPosX=bPosX;
    33.         }
    34.         if(aPosX!=bPosX){
    35.             stopTime=Time.time;
    36.             moveMag = (bPosX - aPosX)/moveSpeed;
    37.         }else{
    38.             moveMag = Mathf.Lerp(moveMag * damper, autoRotationSpeed, (Time.time-stopTime) * leadOutMultiplier);
    39.         }
    40.         //moveMag=1;
    41.         transform.Rotate(0, -moveMag * Time.deltaTime * 80, 0);
    42.         aPosX=bPosX;
    43.     //}
    44. }
    45.  
     
  3. TheChronicPhenix

    TheChronicPhenix

    Joined:
    Jan 14, 2010
    Posts:
    874
    Yeah but this doesn't use RotateAround, how does it rotate around a certain point? Thanks for trying to help though.
     
  4. TheChronicPhenix

    TheChronicPhenix

    Joined:
    Jan 14, 2010
    Posts:
    874
    I tried this code, but it just isn't that smooth.

    Code (csharp):
    1. var aimCube : Transform;
    2. var target : Transform;
    3. var xOffset : float;
    4. var yOffset : float;
    5. var speed : float = 10.0;
    6.  
    7. function Update(){
    8. for (var i=0; i< iPhoneInput.touchCount; i++){
    9. var touch : iPhoneTouch=iPhoneInput.touches[i];
    10. if(touch.phase == iPhoneTouchPhase.Moved){
    11. //aimCube.RotateAround(target.position, Vector3.up, touch.deltaPosition.x / xOffset * Time.deltaTime * speed);
    12. RotateObject(target.position, Vector3.up, touch.deltaPosition.x / xOffset, Time.deltaTime * speed);
    13. //aimCube.position.x += touch.deltaPosition.x / xOffset;
    14. //aimCube.position.y += touch.deltaPosition.y / yOffset;
    15. }
    16. }
    17. }
    18.  
    19. function RotateObject(point : Vector3, axis : Vector3,
    20.                       rotateAmount : float, rotateTime : float) {
    21.     var step : float = 0.0; //non-smoothed
    22.     var rate : float = 1.0/rotateTime; //amount to increase non-smooth step by
    23.     var smoothStep : float = 0.0; //smooth step this time
    24.     var lastStep : float = 0.0; //smooth step last time
    25.     while(step < 1.0) { // until we're done
    26.         step += Time.deltaTime * rate; //increase the step
    27.         smoothStep = Mathf.SmoothStep(0.0, 1.0, step); //get the smooth step
    28.         transform.RotateAround(point, axis,
    29.                                rotateAmount * (smoothStep - lastStep));
    30.         lastStep = smoothStep; //store the smooth step
    31.         yield;
    32.     }
    33.     //finish any left-over
    34.     if(step > 1.0) transform.RotateAround(point, axis,
    35.                                           rotateAmount * (1.0 - lastStep));
    36. }
     
  5. TheChronicPhenix

    TheChronicPhenix

    Joined:
    Jan 14, 2010
    Posts:
    874
    Ok so I got it working much better now, but its still not smooth. Heres my current code

    Code (csharp):
    1. var aimCube : Transform;
    2. var target : Transform;
    3. var xOffset : float;
    4. var yOffset : float;
    5. var speed : float = 10.0;
    6. var rotateDegrees : float;
    7. var rotatedDeg : float;
    8.  
    9. function Update(){
    10. for (var i=0; i< iPhoneInput.touchCount; i++){
    11. var touch : iPhoneTouch=iPhoneInput.touches[i];
    12. if(touch.phase == iPhoneTouchPhase.Moved){
    13. rotateDegrees = touch.deltaPosition.x / xOffset;
    14. if(rotateDegrees >= 0){
    15. if(rotatedDeg <= rotateDegrees){
    16. aimCube.RotateAround(target.position, Vector3.up, Time.deltaTime * speed);
    17. rotatedDeg++;
    18. rotatedDeg /= xOffset;
    19. }
    20. }
    21. else if(rotateDegrees <= 0){
    22. if(rotatedDeg <= -rotateDegrees){
    23. aimCube.RotateAround(target.position, Vector3.up, Time.deltaTime * -speed);
    24. rotatedDeg--;
    25. rotatedDeg /= xOffset;
    26. }
    27. }
    28. //aimCube.RotateAround(target.position, Vector3.up, touch.deltaPosition.x / xOffset * Time.deltaTime * speed);
    29. //aimCube.position.x += touch.deltaPosition.x / xOffset;
    30. //aimCube.position.y += touch.deltaPosition.y / yOffset;
    31. }
    32. if(touch.phase == iPhoneTouchPhase.Ended){
    33. rotatedDeg = 0;
    34. }
    35. }
    36. }
     
  6. TheChronicPhenix

    TheChronicPhenix

    Joined:
    Jan 14, 2010
    Posts:
    874
    Ok combined my code with the mouse orbit code, then modified it and took out y rotation and added in a quaternion.slerp call for rotation, and finally figured out how to have an object rotate around another object without using rotate around, all you have to do is have the transform.position of the object rotating equal to whatever times its own rotation. Heres the latest script, it is much much smoother, the only thing now is that theres a tiny bit of bumpiness when turning as your turning and its trying to modify your position, but it can never update it fast enough to get rid of bumpiness. But anyway heres the latest code for anyone interested.

    Code (csharp):
    1.  var xOffset : float;
    2. var target : Transform;
    3. var distance = 10.0;
    4. var height = 5.0;
    5. var speed = 5.0;
    6.  
    7. var xSpeed = 250.0;
    8.  
    9. private var x = 0.0;
    10.  
    11. @script AddComponentMenu("Camera-Control/iPhone Swipe Orbit")
    12.  
    13. function Start () {
    14. var angles = transform.eulerAngles;
    15. x = angles.y;
    16. y = angles.x;
    17. }
    18.    
    19. function Update(){
    20. var position = transform.rotation * Vector3(0.0, height, -distance) + target.position;
    21. transform.position = position;
    22.  
    23. for (var i=0; i< iPhoneInput.touchCount; i++){
    24. var touch : iPhoneTouch=iPhoneInput.touches[i];
    25. if(touch.phase == iPhoneTouchPhase.Moved){
    26.         x += touch.deltaPosition.x / xOffset * xSpeed * 0.02;
    27. }
    28. }
    29. }
    30.  
    31. function LateUpdate(){
    32. var rotation = Quaternion.Euler(0, x, 0);
    33. transform.rotation = Quaternion.Slerp(transform.rotation, rotation, Time.deltaTime * speed);
    34. }
     
  7. Hanross

    Hanross

    Joined:
    Aug 11, 2018
    Posts:
    11
    I had same problem and I solved it with this I posted here if it could help anyone else

    parameters : poll = the object you want to roate
    pivotPos = position of object that to rotatearound
    degree = angle of desired rotate

    at 0.45f set the value which gives you desire result

    Code (CSharp):
    1. IEnumerator RotateFunction(GameObject poll, Vector3 pivotPos,float degree)
    2.     {
    3.         float timeSinceStarted = 0f;
    4.         while (true)
    5.         {
    6.             timeSinceStarted += Time.deltaTime * 0.5f;
    7.             card.transform.RotateAround(pivotPos, new Vector3(0, 0, 1), degree*Time.deltaTime);
    8.             // If the object has arrived, stop the coroutine
    9.             if (timeSinceStarted >= 0.45f)
    10.             {
    11.                 yield break;
    12.             }
    13.  
    14.             // Otherwise, continue next frame
    15.             yield return null;
    16.         }
    17.     }