- Home /
Move and Rotate player in circular motion?
i want to move and rotate player in circular motion i have a script but that move and rotate player alwayes from zero position? i want to move player in circular motion from its current position.
public Vector3 TargetPos;
public int speed;
float TimeCounter = 0.0f;
float x,y,z;
public float radius;
void Start () {
}
// Update is called once per frame
void Update () {
TimeCounter += Time.deltaTime *speed;
}
public void Forward()
{
x = transform.position.x;
y = Mathf.Cos (TimeCounter) * radius;
z = Mathf.Sin (TimeCounter) * radius;
transform.position = new Vector3(x,y,z);
transform.Rotate (speed,0,0);
}
Answer by JVene · Jul 21, 2018 at 04:52 AM
There's a lot to unpack, and I must guess at some of your intent.
None of this appears to be working as you expect from what I can see, but the main question you've asked I shall answer first.
The reason this is at the origin (0,0) is because the version of the rotation formula you're using is supposed to be at the origin (this concept must be performed in a local space, so that's correct). The resulting y and z must be "vectored" to the transform's current position, so if I assumed y and z were correctly calculated to begin with (and I'm fairly sure they're not), this would suffice:
transform.position = new Vector3(x, transform.position.y + y, transform.position.z + z);
There's more work to be done, but I'll leave that after I know more about the following issues:
I have no idea, for example, what speed and TimeCounter are, but because you're using TimeCounter as a parameter to Cos and Sin, you intend that to represent the angle of rotation. I have to be certain this is an angle of rotation expressed in radians, but I see nothing that would "wrap" the value so as to ensure it remains within a logical range of a radian value.
Further, in the form of rotation you're using, there is no width and height to be used. In this form the rotation assumes a length (the radius) starts on the y axis (in this yz format), and is rotated clockwise where the angle is positive, so both of the trig functions should be multiplied by radius, not two different values (width and height).
Finally, among my caveats of assumption here, the transform.Rotate suggests you intend not only to move the object's position around a central point, but to have the object's orientation to rotate synchronously so as to maintain relative orientation to the center of rotation, but I assume that isn't working because, in theory, speed should not be changing. I think what you should do here is to apply the same rotation you're using for the trig above, but create a Quaternion from Euler angles, duplicating the current Y and Z axis, but setting the X axis of rotation to that of your computed angle (or some mirrored version of it as appropriate).
Answer by cap_L · Jul 21, 2018 at 05:12 AM
Hello all, I am also working in similar problem. I want to rotate an object in a circular way but I do not clearly understand if there should be the use of Time.deltatime for making the movement in circular rotation. I have searched for so many videos but still I am confused. This is my code:
float x, y, z;
float radius = 5;
public float timeCounter = 0;
private void MoveBall()
{
x = Mathf.Cos(timeCounter * Mathf.PI/180) * radius;
y = 0.5f;
z = Mathf.Sin(timeCounter * Mathf.PI / 180) * radius;
timeCounter += 1;
transform.position = new Vector3(x, y, z);
}
Is this code correct to make an object move around in circular path? I have printed out and checked the answers for few angles (0 to 5 degrees ) and it shows right. Still I am not sure. Is there a need to add Time.deltatime in this ? Does deltatime contribute to anything ?
i want to move player in circular motion so i was use Time.deltatime (for smooth movement). i was run you code that not move player smoothly(it give wrong output). my code is move and rotate player in circular in z direction.
First, you have the basic formula for a rotation correct, but to be clear about what it gives you here's what it does:
The opening assumption is that the length (radius in your case) is a coordinate on the X axis (in your x/z orientation, x will be radius, z will be zero). That point is rotated by the angle in radians given as the parameter to Cos and Sin, clockwise for positive angles.
That said, there are some potential misunderstandings from the code. $$anonymous$$athf provides two convenience factors, $$anonymous$$athf.Rad2Deg and $$anonymous$$athf.Deg2Rad, which you should use for conversion because they avoid a division (which is time costly). So, if you have an angle in degrees (which in this case seems to be timeCounter), multiply by $$anonymous$$athf.Deg2Rad to convert that to radians.
You should take some effort to limit timeCounter to stay within one rotation, that is, it should not exceed 360. It appears in your example you are incrementing by 1 degree steps.
The reason you should consider using Time.deltaTime in this is because in this example, whenever $$anonymous$$oveBall is called it will increment timeCounter by 1, which is apparently 1 degree, at whatever rate of speed this is being called. Put another way, you have no control over the speed of the rotation, and that speed will vary on different hardware as the call to this function may be faster on faster computers.
So, what's the rate and how is it expressed. Do you want this to rotate at 5 RP$$anonymous$$, 3 degrees per second, or what rate?
Time.deltaTime is the elapsed time since the last Update. From frame to frame, this tracks a coefficient you can use to control rates of speed without regard (or one could say independent) of the rate at which any particular computer calls this function.
If, for example, you think in terms of degrees per second, you must have a rate declared and defined, say:
float degPerSecond = 12.5f;
Since your approach is to use timeCounter to track the current rotation (which is fine), your increment should be
timeCounter += degPerSecond * Time.deltaTime;
This controls the rate independent of the computer's speed. You can adjust speed by adjusting degPerSecond.
In order to avoid duplicate calculations, you should compute an angle and use it for both trig calls, like:
float angleRad = timeCounter * $$anonymous$$athf.Deg2Rad;
x = $$anonymous$$athf.Cos( angleRad ) * radius;
z = $$anonymous$$athf.Sin( angleRad ) * radius;
With all that said, timeCounter isn't actually counting time. It is tracking the current angle in degrees, and should probably be named to reflect that.
Finally, x and z are rotated around the origin. If your rotating an object around, say, 25, 0, 17, you probably have a Vector3 indicating that point. Let's say that's:
Vector3 p = new Vector3( 25, 0, 17 );
Then, your final vector is:
transform.position = new Vector3(x + p.x, y, z + p.z);
Or something to that effect.
Hello @JVene ,
Thank you for your suggestions. As per your reply, I made the required changes to my program. I am still a bit confused about one thing though.
This is my changed code
public float timeCounter = 0;
float speed;
float angleRad = 0;
float radius = 5;
public float x, y, z;
void Start()
{
speed = 100;
}
private void $$anonymous$$oveBall()
{
timeCounter += speed * Time.deltaTime;
angleRad = timeCounter * $$anonymous$$athf.Deg2Rad;
x = $$anonymous$$athf.Cos(angleRad) * radius;
y = 0.5f;
z = $$anonymous$$athf.Sin(angleRad) * radius;
print("@ X = " + x + "@ Y = " + y + "@ Z = " + z + " &&& angleRad = " + angleRad);
transform.position = new Vector3(x, y, z);
}
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 $$anonymous$$ute changes in the angleRad, whereas I want to find the value of x and y at every angle (0 to 360).
How do I do this ?
Please help me understand. Thank you :)