Restrict player movement to circle's circumference and rotate to lookat

I have a gameObject that I would like to keep restricted to the perimeter of a circle. I want to be able to move the object around the edge of the circle (image example 1) and look in towards the circle (maybe this can be done with SmoothLookAt script) but I do not want the player to be able to enter or leave the circle. Also, I want to prevent the player from looking away from the circle. How can this be done?

115497-unity.jpg
I’m using the following script, but the gameobject get away from the circle’s edge as the player move (image example 2).

using UnityEngine;
using System.Collections;

public class SpiralMovement : MonoBehaviour {

	public float walkSpeed;
	Rigidbody playerRigidBody;
	Transform playerTransform;
	public Transform playerPivot;
	Vector3 inputMovement;

	// Use this for initialization
	void Awake () {
		playerRigidBody = this.rigidbody; //just caching the rigidbody for speed reasons, rather than calling rigidbody.velocity later, which is much slower.
		playerTransform = this.transform; //same with the transform, caching it for performance reasons
	}
	
	// Update is called once per frame
	void Update () {

		playerPivot.position = new Vector3(playerPivot.position.x,playerTransform.position.y,playerPivot.position.z); //make the pivot object the same y height as the player, so it doesn't stay down on the ground

		playerPivot.LookAt(playerTransform,Vector3.up); //make the pivot look at the player

		Quaternion pivotRotation = playerPivot.localRotation; //get the rotation of the pivot, so that we can adjust the inputs below to be relative to that

		inputMovement = Vector3.zero; //resetting the inputMovement vector which will hold all our input information

		if(Input.GetKey(KeyCode.W)){
			inputMovement += pivotRotation * Vector3.back;  
		}
		if(Input.GetKey(KeyCode.S)){
			inputMovement += pivotRotation * Vector3.forward;  
		}
		if(Input.GetKey(KeyCode.A)){	
			inputMovement += pivotRotation * Vector3.right;
		}
		if(Input.GetKey(KeyCode.D)){
			inputMovement += pivotRotation * Vector3.left;  
		}

		inputMovement = inputMovement.normalized * walkSpeed; //normalising the inputMovement vector so it's not too large and then we can cleanly multiply it by whatever walk speed we desire

		playerRigidBody.velocity = new Vector3(inputMovement.x,playerRigidBody.velocity.y,inputMovement.z); //apply the inputMovement vector to the players velocity, but not on the y axis otherwise it will overwrite gravity.
		playerTransform.localRotation = pivotRotation; //keep the player rotated the same as the pivot so it doesn't start walking backwards

	}
}

Edit

This is the working code:

using UnityEngine;
using System.Collections;

public class SpiralMovement : MonoBehaviour {

	public float walkSpeed;
	Rigidbody playerRigidBody;
	Transform playerTransform;
	public Transform playerPivot;
	Vector3 inputMovement;
	Vector3 circleCenter;
	float radius = 1.787921f;
	public Transform circleCenterObject;

	// Use this for initialization
	void Awake () {
		playerRigidBody = this.GetComponent<Rigidbody>(); //just caching the rigidbody for speed reasons, rather than calling rigidbody.velocity later, which is much slower.
		playerTransform = this.transform; //same with the transform, caching it for performance reasons
	}
	
	// Update is called once per frame
	void Update () {

		playerPivot.position = new Vector3(playerPivot.position.x,playerTransform.position.y,playerPivot.position.z); //make the pivot object the same y height as the player, so it doesn't stay down on the ground

		playerPivot.LookAt(playerTransform,Vector3.up); //make the pivot look at the player

		Quaternion pivotRotation = playerPivot.localRotation; //get the rotation of the pivot, so that we can adjust the inputs below to be relative to that

		inputMovement = Vector3.zero; //resetting the inputMovement vector which will hold all our input information

		/*if(Input.GetKey(KeyCode.W)){
			inputMovement += pivotRotation * Vector3.back;  
		}
		if(Input.GetKey(KeyCode.S)){
			inputMovement += pivotRotation * Vector3.forward;  
		}*/

		if(Input.GetKey(KeyCode.A)){
			inputMovement += pivotRotation * Vector3.right;
		}
		if(Input.GetKey(KeyCode.D)){
			inputMovement += pivotRotation * Vector3.left;  
		}

		inputMovement = inputMovement.normalized * walkSpeed; //normalising the inputMovement vector so it's not too large and then we can cleanly multiply it by whatever walk speed we desire

		
		circleCenter = circleCenterObject.position;

		Vector3 offset = transform.position - circleCenter;
		offset = offset.normalized * radius;
		transform.position = offset;

		playerRigidBody.velocity = new Vector3(inputMovement.x,playerRigidBody.velocity.y,inputMovement.z); //apply the inputMovement vector to the players velocity, but not on the y axis otherwise it will overwrite gravity.
		playerTransform.localRotation = pivotRotation; //keep the player rotated the same as the pivot so it doesn't start walking backwards

	}
}

To constrain an object to a circle you simply force the object to remain a set distance (the radius) from centre of the circle. Here is a code example.

Vector3 circleCentre;
Vector3 radius;

void Update (){
    // Do all other movement first
    // Constrain to a circle with the following
    Vector3 offset = transform.position - circleCenter;
    offset.Normalise();
    offset = offset * radius;
    transform.position = offset;
}

The problem may be the fact that you are using a smoothLokAt script. If you use something like transform.LookAt, the object will constantly be snapped looking at the object you set it to. If you use this alone, however, you will have no control over the camera. Then you would simply need to change the movement to left or right instead of pivoting around that point. As far as I can tell, that is what you want.

float maxRadius = 2.0f
var allowedPos = mousePos - initialPos;
allowedPos = Vector3.ClampMagnitude(allowedPos, maxRadius);
transform.position = initialPos + allowedPos;

Use Vector3.Cross to get the tangent Vector3 relative to the Radius (circumference radius - transform.position) and the transform.up of the player.