- Home /
Want RotateAround() an object, but at the same speed, independently from distance to object
I noticed, when using RotateAround() to rotate around an object (In my example, the wife of the player), that if the rotating object (in my example, the player) nears the center of the orbit, the rotation speed slows down. How can i keep it the same, independently from the distance of the object it is rotating around? Currently i am using a "workaround", that if the distance decreases below a certain lower bound, the rotationSpeed is set to rotationSpeed x 2. This doesn't look that clean, because then we can see the rotationSpeed gets too fast and looks different from the normal speed. Is there a "clean" way of doing this? Here is my code with the workaround:
public class PlayerController : MonoBehaviour
{
public GameObject wife; // rotation center
public float rotationSpeed; //speed of the orbiting player
private void Update()
{
OrbitAroundWife();
if (Input.GetAxisRaw("Horizontal") == -1)
{
if (Vector3.Distance(transform.position, wife.transform.position) < 4f)
{
//increase distance from wife
transform.position = Vector3.MoveTowards(transform.position, wife.transform.position, -3 * Time.deltaTime);
}
}
else if (Input.GetAxisRaw("Horizontal") == +1)
{
if(Vector3.Distance(transform.position, wife.transform.position) > 1.7f)
{
//decrease distance from wife
transform.position = Vector3.MoveTowards(transform.position, wife.transform.position, 3 * Time.deltaTime);
}
}
//close enough we get speed increase
if (Vector3.Distance(transform.position, wife.transform.position) < 1.7f)
{
rotationSpeed = 160;
}
else
{
rotationSpeed = 80;
}
}
void OrbitAroundWife()
{
transform.RotateAround(wife.transform.position, Vector3.up, rotationSpeed * Time.deltaTime);
}
}
Answer by keviln · Apr 11, 2021 at 08:18 AM
Try using this:
void OrbitAroundWife(){
float speed = 10000f; //i really don't know if this is a good number
Vector3 dir = wife.transform.position - player.transform.position;
Vector3 vel = player.Getcomponent<Rigidbody2D>().velocity;
vel += (dir.normalized() * speed + player.transform.up * 1000f) * Time.fixedDeltaTime;
player.GetComponent<Rigidbody2d>().velocity = vel;
}
I haven't play tested it yet, but i guess it should work? if your player has gravity, then no need to add transform.up. Also, i am not really good at coding. There could be another simpler or more efficient way, but i really don't know.
Answer by andrew-lukasik · Apr 16, 2021 at 10:20 AM
Rotation, in the strict sense, is not slowing down here; absolute translation is. To compensate for changing radius you need to calculate rotation angle from expected movement speed along circumference
angle = ( step_distance / circumference ) * 360
using UnityEngine;
public class PlayerController : MonoBehaviour
{
[SerializeField] Transform _focus = null;
[SerializeField] float _tangentialSpeed = 2f;
[SerializeField] float _radialSpeed = 2f;
[SerializeField] float _rMin = 1.7f;
[SerializeField] float _rMax = 4.0f;
void Update ()
{
float horizontal = Input.GetAxisRaw("Horizontal");
float deltaTime = Time.deltaTime;
Vector3 O = _focus.position;
Vector3 P = transform.position;
Vector3 R = P - O;
float r = Mathf.Clamp(
Vector3.Magnitude(R) - ( horizontal*_radialSpeed*deltaTime ) ,
_rMin , _rMax
);
float c = 2f*Mathf.PI * r;
float angle = ( _tangentialSpeed*deltaTime / c ) * 360f;
Quaternion rot = Quaternion.AngleAxis( angle , Vector3.up );
transform.position = O + ( rot * Vector3.Normalize(R) * r );
}
#if UNITY_EDITOR
void OnDrawGizmos ()
{
if( _focus!=null )
{
Vector3 O = _focus.position;
Vector3 P = transform.position;
Vector3 Rn = Vector3.Normalize( P - O );
Gizmos.color = new Color{ g=1f , a=0.2f };
Gizmos.DrawLine( O+(Rn*_rMin) , O+(Rn*_rMax) );
}
}
#endif
}
Your answer
Follow this Question
Related Questions
Rolling Cube with Rigidbody? 5 Answers
Enemy circeling around Player 0 Answers
defining a relative axis of rotation 1 Answer
Image Rotate Gallery Snap 0 Answers
Camera Orbit Rotation Problem 0 Answers