Character Controller Circular Motion Drifting issue

Hi all, I have been struggling with trying to get to control a character through a character controller, but only in circular motion. I have stumbled upon the following script and it works! But not quite… I am observing some weird drift away from the center of rotation. I have verified this by checking the actual distance:

var distance = Vector3.Distance(target.position, transform.position);
Debug.Log (distance);

It gets even stranger, because the direction in which the object is moving does not matter (i.e. CW and CCW both increase the distance between the object and its target).

Because I did not fully understand exactly how the maths behind this worked, I tried writing something similar on my own based on LookAt:

var speed : float = 60.0;
var target : Transform;
private var moveDirection : Vector3 = Vector3.zero;

function Update()
{
        var controller : CharacterController = GetComponent(CharacterController);

        transform.LookAt(target.position);
        
        var right = transform.right;
        right *= Input.GetAxis("Horizontal");
        Debug.DrawRay (transform.position, right*5f, Color.red);
        
        moveDirection = right;
        moveDirection *= speed;

        controller.Move(moveDirection * Time.fixedDeltaTime);
        
        var distance = Vector3.Distance(target.position, transform.position);
        Debug.Log (distance);
}

I have also removed gravity, so the character controller basically orbits the object around its target, but I still get this increase in distance between the two objects.

I am wondering if this is something to do with the way CharacterController.Move() works, or Character Controllers in general… I have also noticed that this drift is related to the speed variable - this makes me think it might be due to float imprecision.

Does anyone have a clue why this might be happening? Any solutions to the problem? If not, what would be a good way of implementing circular motion within a character controller?

After another day of googling, I found this thread (not sure how/why I didn’t find it before). It basically solves the problem using a different technique, but it still works for me. I have translated it into C# at the end, not sure why it had the weird formatting. Thanks, aldonaletto, for showing me the way around (haha, get it…) Anyways, I am still getting a ±0.000005 error on the distance, but it always fluctuates around the actual distance and it never gets out of control as it did with the previous two solutions, but I think this is due to floating point error and cannot be solved (maybe apart from manually correcting the error - I will experiment).

using UnityEngine;
using System.Collections;

public class MoveTest : MonoBehaviour {

	public Transform target;
	public float speed = 360f;	// speed in degrees per second 
	public float gravity = 10f; // gravity, if you want to use it
	CharacterController character;

	// Use this for initialization
	void Start () {
	
	}
	
	// Update is called once per frame
	void Update () {
	
	}

	void LateUpdate() {
		RotateChar();
	}

	// call this function in LateUpdate
	void RotateChar(){
		// make sure the variable "character" contains the controller: 
		if (!character)
			character = transform.GetComponent<CharacterController> (); 
		// curPos = vector from target to character: 
		Vector3 curPos = transform.position - target.position; 
		// rotate curPos by the appropriate angle and save in newPos: 
		Vector3 newPos = Quaternion.Euler(0, speed*Time.deltaTime, 0)*curPos; 
		// calculate the displacement to move 
		Vector3 displacement = newPos - curPos; 
		// if you don't need gravity, comment out this line: 
		//displacement -= gravity*Vector3.up*Time.deltaTime*Time.deltaTime; 
		character.Move(displacement); 
		// move by the distance calculated 
		transform.LookAt(target); 
		// keep looking to the target 

		Debug.Log (Vector3.Distance(target.position, transform.position));
	}
}

PS: Still no idea why the issues described before are happening.