- Home /
Circular movement not working
Hello all, I am working on a code that makes an object move in circular motion until the game is paused. I am just a beginner and I would really appreciate any help.
This is my code. Please help me clear out what is wrong with my code:
float angle = 0;
float speed;
float radius = 5;
float x, y, z;
void Start()
{
speed = 10.0f;
}
private void MoveBall()
{
angle += speed * Time.deltaTime;
float angleRad = angle * Mathf.Deg2Rad;
x = Mathf.Cos(angleRad) * radius;
y = 0.5f;
z = Mathf.Sin(angleRad) * radius;
angle++;
transform.position = new Vector3(x, y, z);
}
void Update()
{
MoveBall();
}
Actually I want to find the value of x and z co-ordinates (since y is constant for any values of x and z) at every angle(in integer - 0,1,2,3, 4.. 360) from 0 to 360 degrees. But when i run this, it gives values like 1.123, 1.128, 1.341, 1.369 etc. I mean there is very small minute changes in the angleRad, whereas I want to find the value of x and y at every angle (0 to 360).
Some other members of the community helped me up to this step. But i still do not understand the need of speed and Time.deltatime and the increment of angle at the beginning of MoveBall() method.
Please help me fix this. Thank you all.
Answer by JVene · Jul 24, 2018 at 04:07 AM
First, about angleRad:
Your code is sweeping through angles expressed in degrees, and based on the text you've posted you want to see that sweep from 0 to 360 degrees. angleRad is a conversion of degrees into radians, because the formula for rotation (from which you get X and Z) requires radians. A radian is 2 * pi, or about 6.28318. In this way 90 degrees is 1.570795, while 180 degrees is 3.14159. In your series, 1.123 is 64.34316 degrees, 1.128 is 64.629639 degrees, 1.369 is 78.437922 degrees. In that sequence the sweep was a little over 14 degrees.
The first line of MoveBall computes a rate per second, which you have set at 10 degrees per second. It will take 36 seconds to sweep from 0 to 360 degrees. If you want a faster rate, you'll need to choose a higher speed reflective of how long it should take to complete the sweep. When that speed is multiplied by Time.deltaTime, you've computed the change in angle for that one frame based on a rate of 10 degrees per second. The sweep you listed must have taken about 1.5 seconds to complete.
It appears you may have attempted to move the speed up by incrementing angle (second to last line of MoveBall). It isn't necessary. Just change the value of speed. If you want the sweep to complete in 5 seconds, you need a speed of 360/5 or 72 degrees per second.
That said, if what you wanted was to calculate every even degree (0, 1, 2....25, 26, 27.....358, 359), then you don't want a particular speed, you want 1 degree increments of the angle. In that case, change the first line of MoveBall to increment angle, but be warned - you have no control over speed doing that. Each computer or device has a maximum potential speed at which frames can flip, so the speed may be different on each device. If you're locked to the sync of the display that may be limited to 60 fps, which would be a slower rotation than the 72 degrees per second I mentioned, meaning at 60 fps, increment 1 degree at a frame, it would be about 6 seconds to complete the sweep. On a device that syncs at 30 fps, it would take 12 seconds. Using speed will not produce every integer angle by degree, but it can sweep through the rotation at any speed you choose (within reason).
Otherwise, the rotation formula looks correct. X is taken from cosine, Z is taken from sine. These are trigonometric functions which track the points on a circle for a unit radius (a radius of 1), giving every x and y (or z in your case) for any angle.
Hey @JVene , Thanks. This really cleared out my confusion. Yes actually I wanted values of x and z from 0 to 360 degrees. I used the code below and got the exact value for x and z (For 0 to 360 degrees):
float angleRad = angle * $$anonymous$$athf.Deg2Rad;
x = $$anonymous$$athf.Cos(angleRad) * radius;
y = 0.5f;
z = $$anonymous$$athf.Sin(angleRad) * radius;
angle++;
But as you said, the speed of circular motion began to decrease over time. Is there a way to resolve this speed issue without affecting the degrees value that is being obtained for 0 to 360 (integer format - 0,1,2,3,4,5,6,.....,360) ?
Hey @JVene ,
The problem is solved. Thank you for explaining very deeply.
Can you help me in one more question: When I press the 'Play' button or when the game object starts to move in a circle, Is there a method in unity that helps to display and store (in a .txt file) the screen co-ordinates of the game object as it moves along in the circle ? How do I achieve this ? Thank you
Well, it's not so much a Unity thing, but a C# thing. Incidentally, you can get this chart from Excel in a spreadsheet (it can do Cos and Sin, too).
You are basically interested in opening a text file and "printing" to that file after you calculate X and Z. StreamWriter is one approach. TextFile is another. You write out strings you format to the file.
Your answer
Follow this Question
Related Questions
Simple Circular jump along local normal- similar to planetary gravity 0 Answers
Lerp in circular motion 1 Answer
circular progress bar 1 Answer