[Solved] Linear movement speed, reset position
Hi all, visually here is what i'm trying to do:
From the ' X ' my Object starts and moves across to that wall. It collides with the wall that I've tagged 'SheetEnd'.
I want to have the object (the dark blue piece) reset its transform.position back to X, where it repeats motion #1.
**This form is glitchy on my computer...sorry for ugly layout of question...
I'll add the code...I feel i'm close...and am over-complicating this....any hints... or right directions would help.
void Start() { initialPosition = transform.position; } // Update is called once per frame void Update() { //make a method that moves the MusicGuide from left to right if (state == State.Moving) { ScanLeftRight(); } if (state == State.FinishedMoving) { print("DING!"); // Reset position and timer (if that's possible) // Change state back to Moving. } } public void ScanLeftRight() { float timer = 0f; timer += Time.time; Vector3 musicGuidePosition = initialPosition + (vectorMagnitude * multiplier * (timer)); transform.position = musicGuidePosition; // Ignore this code, was playing around with Sin() // //take an initial transform position and add an offset with respect to time. //float cycle = Time.time / period; //float tau = 2 * Mathf.PI; //float oscillatingVector = Mathf.Sin(cycle * tau) / 2 + 0.5f; //print(oscillatingVector); //Vector3 musicGuidePosition = initialPosition - (vectorMagnitude * oscillatingVector); // update object's position so that it will move when game is running. //transform.position = musicGuidePosition; } private void ResetPosition() { if (state == State.FinishedMoving) { transform.position = new Vector3(8f, 10f, 4f); print("Reset Position " + transform.position); } } void OnTriggerEnter(Collider other) { if (other.tag == "SheetEnd") // I have used the same tag that you attached to your enemy character { Debug.Log("Code made it this far... tagged ->"); state = State.FinishedMoving; //reset position back to initial starting point once it reaches set distance ResetPosition(); } }
}
[CODE]
Answer by streeetwalker · Apr 14, 2020 at 05:24 PM
@ OwnDemise,
You trying to do a LERP - a "LInear Interpolation" and there is nothing wrong with that, but it simpler to update the object position by the fraction of time each frame takes.
To do a LERP, you need to calculate the current location as a fraction of the total distance based on the ratio of current time taken to the total time you want to move that distance. it's a simple equation to solve for:
? / total distance to target from start = current time / total time to target. Solve each update for ? which represents the current location. So first you have to decide how long you want the move to take. Current time needs to be the Time.time - starting time.
For example, using LERP, if you want the total time to the target to be 6 seconds, and the current elapsed time is 3 seconds, no matter what the total distance from start to the target is, your object will be moved half that distance. If the current time is 4 seconds, the position of the object will be 4/6 or 2/3 of the that distance. You see the pattern? That's why it is a Linear interpolation!
The "easier" way is the most commonly used algorithm when it comes to motion - it does the same thing LERP does, but in a different way. It works without respect to the total distance or total time - it just keeps moving at a constant rate until you decide to stop (constant if your multiplier remains constant, that is)
transform.position = transform.position + (vectorMagnitude * multiplier * Time.deltaTime );
//
Note: vectorMagnitude should give you the direction only.
make sure that is normalized before you use it here
those 3 values together determine how far to move in a given frame
Take the simple example: you want to move 1 meter per second directly
to the right, the +x direction.
So the direction vector normalized is = (1,0,0)
(Remove multiplier from the equation for now - that is essentially a speed factor)
//
Time.deltaTime is the fraction of a second since the last frame.
If our frame rate = 30fps, then Time.deltaTime = 1/30 = 0.0333 seconds
add that together 30 times and you have 1 second.
//
The calculation is:
//
object position = object position + direction vector * Time.deltaTime
so: + (1,0,0) * time.Delta therefore, in this simple example
we are adding 0.0333 of a meter to x every frame
if you want to go faster, put your multiplier back in.
Awesome! Thanks @streeetwalker !
First off, thanks for taking the time to explain that more in-depth. I've read it a couple times now.
I did try the Time.deltaTime, I print(time.Time) and used my multiplier to speed it up, and noticed it was jumping all over the place. Will have to play around with it.
Will give it a shot...
So I gave it a shot: I have 45-125fps, and my object skips across the page.
It looks like i'm trying to run CS:GO on a Pentium III.
So, I played around with it a bit more. I used the LERP theory you mentioned.
I was definitely over complicating by using States and colliders.
Since i'm using a set distance, linear speed and it's repeating, this is giving what I want (for now..lol)
public void ScanLeftRight() { float timer; timer = Time.time % period; Vector3 musicGuidePosition = initialPosition + (vector$$anonymous$$agnitude * (timer)); transform.position = musicGuidePosition;
}
Thanks again @streetwalker
Your answer
Follow this Question
Related Questions
Camerashake doesn´t work expected in Build c# 0 Answers
Falling object respawner 1 Answer
Code is acting different depending on call 2 Answers
Player Can Not get off platform 1 Answer