Smooth Orbit Round Object with Adjustable Orbit Radius


I am trying to assign an object to rotate around another object and to be able to adjust the orbit radius. Also when the radius changes I am trying to get the object to smoothly adjust to the new orbit radius.

I’ve been searching for a while now and only had limited success. The best I have found is:

rotateTransform.RotateAround (objectToOrbit.position, Vector3.up, orbitAmount * Time.deltaTime);

But this does not allow me to change the actual radius. The orbitAmount value simply speeds up or down the orbit.

It does seems that RotateAround works with the initial distance from the object I want to rotate around and sets it as that, but I can’t think of a way to exploit that fact.

Any suggestions on how to go about this?



Wow, works perfectly! here is in C#, tested with a cube as the center of rotation :

using UnityEngine;
using System.Collections;

public class testRotate2 : MonoBehaviour {
	GameObject cube;
	public Transform center;
	public Vector3 axis = Vector3.up;
	public Vector3 desiredPosition;
	public float radius = 2.0f;
	public float radiusSpeed = 0.5f;
	public float rotationSpeed = 80.0f;

	void Start () {
		cube = GameObject.FindWithTag("Cube");
		center = cube.transform;
		transform.position = (transform.position - center.position).normalized * radius + center.position;
		radius = 2.0f;
	void Update () {
		transform.RotateAround (center.position, axis, rotationSpeed * Time.deltaTime);
    	desiredPosition = (transform.position - center.position).normalized * radius + center.position;
    	transform.position = Vector3.MoveTowards(transform.position, desiredPosition, Time.deltaTime * radiusSpeed);

If I could thumb up, I would really!

Here is a bit of code:

#pragma strict

public var center : Transform;
public var axis   : Vector3 = Vector3.up;
public var radius = 2.0;
public var radiusSpeed = 0.5;
public var rotationSpeed = 80.0; 

function Start() {
	transform.position = (transform.position - center.position).normalized * radius + center.position;

function Update() {
	transform.RotateAround (center.position, axis, rotationSpeed * Time.deltaTime);
    var desiredPosition = (transform.position - center.position).normalized * radius + center.position;
	transform.position = Vector3.MoveTowards(transform.position, desiredPosition, Time.deltaTime * radiusSpeed);

You will probably need to use something like Mathf.SmoothStep to smooth the rotation angle argument of RotateAround and Transform.Translate to configure the distance (radius) between the two objects prior to applying rotation.

I noticed that the objects are jittery using this script but if you change update to fixedupdate it’s smooth

using UnityEngine;
using UnityEngine;
using System.Collections;

 //[AddComponentMenu("Camera-Control/Mouse drag Orbit with zoom")]
 public class rotateonmouse : MonoBehaviour
     public Transform target;
     public float distance = 5.0f;
     public float xSpeed = 120.0f;
     public float ySpeed = 120.0f;
     public float yMinLimit = -20f;
     public float yMaxLimit = 80f;
     public float distanceMin = .5f;
     public float distanceMax = 15f;
     public float smoothTime = 2f;
     float rotationYAxis = 0.0f;
     float rotationXAxis = 0.0f;
     float velocityX = 0.0f;
     float velocityY = 0.0f;
     // Use this for initialization
     void Start()
         Vector3 angles = transform.eulerAngles;
         rotationYAxis = angles.y;
         rotationXAxis = angles.x;
         // Make the rigid body not change rotation
         if (rigidbody)
             rigidbody.freezeRotation = true;
     void LateUpdate()
         if (target)
             if (Input.GetMouseButton(1))
                 velocityX += xSpeed * Input.GetAxis("Mouse X") * 0.02f;
                 velocityY += ySpeed * Input.GetAxis("Mouse Y") * 0.02f;
             rotationYAxis += velocityX;
             rotationXAxis -= velocityY;
             rotationXAxis = ClampAngle(rotationXAxis, yMinLimit, yMaxLimit);
             Quaternion fromRotation = Quaternion.Euler(transform.rotation.eulerAngles.x, transform.rotation.eulerAngles.y, 0);
             Quaternion toRotation = Quaternion.Euler(rotationXAxis, rotationYAxis, 0);
             Quaternion rotation = toRotation;
             Vector3 negDistance = new Vector3(0.0f, 0.0f, -distance);
             Vector3 position = rotation * negDistance + target.position;
             transform.rotation = rotation;
             transform.position = position;
             velocityX = Mathf.Lerp(velocityX, 0, Time.deltaTime * smoothTime);
             velocityY = Mathf.Lerp(velocityY, 0, Time.deltaTime * smoothTime);
     public static float ClampAngle(float angle, float min, float max)
         if (angle < -360F)
             angle += 360F;
         if (angle > 360F)
             angle -= 360F;
         return Mathf.Clamp(angle, min, max);

this should do it. It allows to set the max/min distance and the distance you want.