I want it to spin at speed from 0 to very fast.
But if I'm changing the value of the spin to 10 it's almost not moving and 200 make it move slowly. 2000 make it move fast, but how fast is that? If I want to make it spin 10 times per second how do I use Rotate to do that?
public float rotationSpeed;
private void Update()
{
scaling.objectToScale.transform.Rotate(Vector3.up, rotationSpeed * Time.deltaTime);
}
The way you are using it, rotationSpeed is a measure of degrees turned per second
Rotate's second parameter takes in a number of degrees to rotate.
Time.deltaTime is how many seconds have passed since the last frame.
10 degrees per second means it rotates once every 36 seconds (360/10 = 36).
2000 degrees per second means it rotates once every 0.18 seconds (360/2000 = 0.18) or in other words, it rotates 5.56 times per second (2000/360 = 5.56).
If you want to rotate n times per second, do:
rotationSpeed = n * 360f;
// ...
scaling.objectToScale.transform.Rotate(Vector3.up, rotationSpeed * Time.deltaTime);
If you want to take n seconds to rotate once, do:
rotationSpeed = 360f / (float)n;
// ...
scaling.objectToScale.transform.Rotate(Vector3.up, rotationSpeed * Time.deltaTime);
Related
private void RotateTargetsRandom()
{
timer += Time.deltaTime;
if (timer > rotationTime)
{ // timer resets at 2, allowing .5 s to do the rotating
qTo = Quaternion.Euler(new Vector3(0.0f, Random.Range(-180.0f, 180.0f), 0.0f));
timer = 0.0f;
}
foreach (var target in targets)
{
target.transform.rotation = Quaternion.Slerp(target.transform.rotation, qTo, Time.deltaTime * speed);
}
}
The function make that each 2 seconds the targets(GameObjects) will rotate.
But in the comment not my comment it say "timer resets at 2, allowing .5 s to do the rotating"
Where is the 0.5 part in the code ?
So each 2 seconds there is a rotation and the rotation is taking 0.5 seconds. I just don't understand where is the 0.5 part ? And if I want it to rotate duration of 0.1 time instead 0.5 ?
What makes it rotate following a speed is the
target.transform.rotation = Quaternion.Slerp(target.transform.rotation, qTo, Time.deltaTime * speed);
Slerp is the spherical interpolation and it is basically interpolating between the current rotation of the object and the qTo value using the deltaTime (elapsed time since last frame in seconds) and an arbitrary speed.
e.g.
imagine you are only rotating in one axis to simplification, say the z-axis.
if the rotation is 0 and qTo is 45 in the first iteration it will be:
45 * deltaTime * speed
But since it is already set it to the transform rotation the next iteration will use the new rotation as the initial value of the interpolation:
(45 - previousRotation) * deltaTime * speed + previousRotation
Thus it is converging to 45 when speed * sum(all deltaTimes) is one.
So I suppose your speed is 2 since it is taking 0.5s to reach the target rotation.
But the code is a little flaky since it would behave weirdly if rotationTime is lower than 1 / speed.
It is not specified in the question but I believe you are calling it inside an Update(ish) method, to allow deltaTime to have a reasonable meaning.
So to control the duration of your rotation you set the speed to a desired value, to have a 0.1s duration set the speed to 10.
I've just recently been introduced to Time.deltaTime and lerping and have been kinda stuck for the past few days.
So when I plug in Time.deltaTime for the last float and then multiply by another float variable called speed, what exactly is happening? What is Time.deltaTime doing to speed each frame that gives the end result?
Thank you!!
public class CameraMovement : MonoBehaviour
{
public GameObject followTarget;
public float moveSpeed;
void Update()
{
if (followTarget != null)
{
transform.position = Vector3.Lerp(transform.position, followTarget.transform.position, moveSpeed * Time.deltaTime);
}
}
}
Vector3.Lerp expects a factor between 0 and 1 and interpolates the two positions so
0 would mean transform.position
1 would mean followTarget.transform.position
any other value between those the interpolation between them meaning something like
transform.position + (followTarget.transform.position - transform.position) * factor;
Time.deltaTime = time past since last frame rendered so most likely a value close to 0.017 (for 60FPS). You can calculate by yourself what value this gives you in average for moveSpeed * 0.017.
It looks like what you are actually looking for is rather Vector3.MoveTowards
void Update()
{
if (followTarget != null)
{
transform.position = Vector3.MoveTowards(transform.position, followTarget.transform.position, moveSpeed * Time.deltaTime);
}
}
Using Time.deltaTime * scalar in Lerp is perfectly fine, but it's not the "expected" way to use it.
LERP means "Linear intERPolation". With this mathematic tool, you are able to interpolate a value between two others using a linear function ( y = ax + b ) and a coefficient t between 0 and 1.
Supposing you are trying to get a position (C) between two others (A and B) (like your problem), you have the folowing drawing :
1°) If the initial and destination position does not change, having the parameter t vary between 0 and 1, the movement curve will be perfectly straight : the speed will be the same over time.
transform.position = Vector2.Lerp(InitialPosition, DestinationPosition, t ); // t from 0 to 1
2°) However, having t (almost) not vary over time (with Time.deltaTime), but chaning the position of A, the movement will decelerate over time, because you take a fixed percentage of the remaining distance each time. Since the distance decrease over time, you travel less distance over time too
transform.position = Vector2.Lerp(transform.position, DestinationPosition, 0.017 ); // 0.017, approx of Time.deltaTime at 60FPS
I decrease the maxFuelCount value by -1. the counter goes down as expected.but it goes very fast when I long press the pedal. how can I slowdown counter value? I tried this * Time.deltaTime / 1.5f its works, not as I expected. can anyone suggest a method or give any guidance
Many thanks for your help
private void FixedUpdate()
{
if (move == true)
{
// decreasing the float value
maxFuelCount--;
if (maxFuelCount > 0 && timeLeft > 0)
{
rb.AddForce(transform.right * engineCapacity * Time.fixedDeltaTime * turboCapacity, ForceMode2D.Force);
//asigning the decreased value to the slider
UIBS.NewValue = maxFuelCount * Time.deltaTime / 1.5f;
}
}
}
Well you decrease 1 each frame gas is pressed. In one second with 50 fps it will almost decrease 50 which is a lot. Just lower the amount which decreases the MaxFuelCount. You can maybe use MaxFuelCount -= Time.deltaTime;
To make it even better you can use a speed counter which can be adjusted based on the terrain features such as if you are in mud fuel consumption speed increases like this:
MaxFuelCount -= Time.deltaTime * speed;
Increase or decrease the speed to an extent which you are comfortable about the speed.
Also UIBS.NewValue = maxFuelCount * Time.deltaTime / 1.5f; this will not work. Again with 50 fps you divide the value to almost 33 this time which will lower the value extremely fast.
Also it makes more sense to hold two variables as MaxFuelAmount (amount of fuel the tank can hold) and CurrentFuelAmount.
Then you can calculate percentage like: CurrentFuelAmount / MaxFuelAmount * 100 and use it in your UI value.
im trying to move a object in unity between 2 points, and at the moment it kinda works strange, i read the documentation and it says that the object begin point is (0,0,0) so my object goes under my other mesh that i have there, and the end point i can actually control, in my case it is 10, i want the object to move between 1.5 and 10(not 0 to 10)
i have this
void Update () {
transform.position = new Vector3(transform.position.x,Mathf.PingPong(Time.time,10.0f), transform.position.z);
}
when i try to put speed on the ball doing this:
void Update () {
transform.position = new Vector3(transform.position.x,Mathf.PingPong(Time.time,10.0f) * 10, transform.position.z);
}
the object does not colide and goes back at the end point it just stop looping and never came back how can i correct this 2 problems?
If your object has a collider, I suggest you move it via its Rigidbody rather than its Transform, to avoid potential collision issues. Try this:
public float MinY = 1.5f; // y position of start point
public float MaxY = 10f; // y position of end point
public float PingPongTime = 1f; // how much time to wait before reverse
public Rigidbody rb; // reference to the rigidbody
void Update()
{
//get a value between 0 and 1
float normalizedTime = Mathf.PingPong(Time.time, PingPongTime) / PingPongTime;
//then multiply it by the delta between start and end point, and add start point to the result
float yPosition = normalizedTime * (MaxY - MinY) + MinY;
//finally update position using rigidbody
rb.MovePosition(new Vector3(rb.position.x, yPosition, rb.position.z));
}
Here you have a better control on the distance to travel, and the speed.
Actually I didn't get exactly what are the problem you faced. But don't forget here and in your try, that you are directly modifying the position of the object, not adding forces or else.
Hope that helps you.
I think you simply misunderstood how the Mathf.PingPong method works :
first argument t is the value you want to "clamp" between 0 and the given length : this is were you want to put the Time.time as you did since this value will increase over time and therefore perpetually oscillate. If you want to increase/decrease the oscillation speed you have to multiply it.
second argument length is the max value of the "clamp" : if you want to increase/decrease the distance (in your case) you have either set it to 0 and multiply the whole Mathf.PingPong(...) by a value or directly give it the wanted value (both implementations will have a different effect.
Mathf.PingPong(Time.time * speed, 1.0f) * value : speed will affect the oscillation speed / value will affect the max value reached AND the speed / time to complete the oscillation (back and forth) will remain the same as value changes and decrease as speed increases
Mathf.PingPong(Time.time * speed, value) : speed will affect the oscillation speed / value will affect the max value reached BUT NOT the speed / time to complete the oscillation (back and forth) will increase as value increases and decrease as speed increases
About your other problems :
If you want to move your object between 1.5 and 10 you have to write something like this :
transform.position = new Vector3(transform.position.x, 1.5f + Mathf.PingPong(Time.time, 10.0f - 1.5f), transform.position.z);.
Also if you want to detect collision, avoid setting position manually as it will mess up with Physics and cause weird behaviors. Best way to move your object while keeping physic working is to do as #Heldap said using Rigidbody.MovePosition.
I am testing the accelerometer code in Unity3D 4.3. What I want to do is simple change the object angle while tilting the ipad, to fake view angle like real live. Everything works fine except for the fact that the accelerometer is a bit too sensitive and I can see the GameObject is like of flickering even I put it on table. How can I make it less sensitive so that even when you hold with your hand the angle will change according to the tilt and the object remain steady?
Here are my code:
void Update () {
Vector3 dir = Vector3.zero;
dir.x = Mathf.Round(Input.acceleration.x * 1000.0f) / 1000.0f;
dir.y = Mathf.Round(Input.acceleration.y * 1000.0f) / 1000.0f;
dir.z = Mathf.Round(Input.acceleration.z * 1000.0f) / 1000.0f;
// clamp acceleration vector to the unit sphere
if (dir.sqrMagnitude > 1)
dir.Normalize();
// Make it move 10 meters per second instead of 10 meters per frame...
dir *= Time.deltaTime;
dir *= speed;
acx = dir.x;
acy = dir.y;
acz = dir.z;
transform.rotation = Quaternion.Euler(dir.y-20, -dir.x, 0);
}
You may need to use a low pass filter (s. Exponential Moving Average for a better description regarding software) before using the signal output. I always use native code to get accelerometer and gyroscope values on iPhone so I am not 100% sure how Unity handles this. But from what you are describing the values appear unfiltered.
A low pass filter calculate a weighted average from all your previous values. Having for example a filter factor on 0.1 your weighted average is:
Vector3 aNew = Input.acceleration;
float a = 0.1f * aNew + 0.9f * a;
This way your values are smoothed at the expense of a small delay. Running the accelerometer with 50 Hz you won't notice it.
I couldn't make Kay's example work as it was not multiplying the last part, so here's my small correction:
Vector3 aNew = Input.acceleration;
a = (0.1 * aNew) + (0.9 * a);