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?

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
}
}