I’m trying to make my character move around a tower (it’s a tower climb demo). For it i take only the horizontal input (A for left and D for right). I take only the X and Z components of the center of the tower to calculate directions. I can’t manage to get a perfect circular move using Rigidbody. I have only achieved a constant radius (distance from the player to the center) changing the position of the transform directly. Is it not possible to use Physics for this? It should be. So i’m missing something. I have tried all ForceModes btw.
I’ll leave my script here:
public class PlayerMovement : MonoBehaviour
{
[SerializeField] private float moveSpeed = 5f;
[SerializeField] private Transform centerOfTower;
private InputAction moveAction;
private float radiusTower;
private Rigidbody rb;
private Vector2 movementInput = Vector2.zero;
private float angle = 0f;
private Vector3 tangent;
private Vector3 cptForce;
private void OnDrawGizmos()
{
Gizmos.color = Color.blue;
Gizmos.DrawRay(transform.position, tangent*5f);
Gizmos.color = Color.red;
Gizmos.DrawRay(transform.position, cptForce*5f);
}
private void Awake()
{
moveAction = GetComponent<PlayerInput>().actions["Movement"];
rb = GetComponent<Rigidbody>();
radiusTower = GetDistanceToCenter();
}
private void FixedUpdate()
{
movementInput = moveAction.ReadValue<Vector2>();
MovePlayer();
}
private void MovePlayer()
{
Vector3 directionToCenter = centerOfTower.position - transform.position;
Vector3 directionXZ = new Vector3(directionToCenter.x, 0f, directionToCenter.z);
Vector3 tangent = Vector3.Cross(-directionXZ, Vector3.up).normalized;
transform.forward = Mathf.Sign(movementInput.x) * tangent;
//rigidbody
Vector3 vel = new Vector3(tangent.x * moveSpeed * movementInput.x, rb.velocity.y, tangent.z * moveSpeed * movementInput.x);
Vector3 velXZ = new Vector3(vel.x, 0f, vel.z);
//This makes the player get farther away from the center
//rb.AddForce(directionXZ.normalized * (6.67384e-11f / Mathf.Pow(radiusTower, 2)), ForceMode.Force);
//This makes the player get closer to the center
//rb.AddForce(directionXZ.normalized * (velXZ.magnitude * velXZ.magnitude) / radiusTower, ForceMode.Acceleration);
//This just does not work correctly
//Vector3 cpt = directionXZ * (velXZ.magnitude * velXZ.magnitude) / radiusTower;
//vel += cpt * Time.fixedDeltaTime;
rb.velocity = vel;
////transform
//angle += movementInput.x * moveSpeed * Time.deltaTime;
//float x = centerOfTower.position.x + Mathf.Cos(angle) * radiusTower;
//float z = centerOfTower.position.z + Mathf.Sin(angle) * radiusTower;
//Vector3 nextPos = new Vector3(x, transform.position.y, z);
//transform.position = nextPos;
//Debug
Debug.Log(GetDistanceToCenter());
//Debug.Log("Cpt Force: " + (velXZ.magnitude * velXZ.magnitude) / radiusTower);
//Debug.Log("Velocity: " + velXZ.magnitude);
this.tangent = tangent;
this.cptForce = directionXZ.normalized;
}
private float GetDistanceToCenter()
{
Vector3 playerPos = transform.position;
playerPos.y = 0f;
Vector3 towerCenter = centerOfTower.position;
towerCenter.y = 0f;
return Vector3.Distance(playerPos, towerCenter);
}
}

Very usefull! Thanks for the help!
– fransecchifst