- Home /
can anyone explain to me how to set a gameobject movement to zero after second and then start it back again to moving regularly after seconds?
basically i have an pendulum game and i am having trouble making fluid pendulum motion so i wanted to stop the pendulum motion after some amount of seconds and then start it back again after some amount of seconds. I have tried using couroutines but it hasn't worked properly. I also tried making an if then statement for the game object using vectors saying that if this game object position is -5.36 on the x axis then pause the game object for seconds but still could not do it correctly. can anyone help please?
How you are moving your pendulum ? Post your code what you are doing in couroutine and explain movement of pendulum(physics based or you are rotating). well explained pendulum movement https://rdgamestudio.wordpress.com/2016/05/04/simple-pendulum-in-unity/
I actually created a pendulum class that incrementally returns $$anonymous$$/max values and ping pongs back when it reaches the end. If your interested it is on my Github Pendulum Class
Basically you would need a separate pendulum for each axis, but if you're only using one axis, you could use it like this.
public float $$anonymous$$X;
public float maxX;
public float swingTime;
public Pendulum pendulum;
void OnEnable()
{
pendulum = new Pendulum($$anonymous$$X, maxX, swingTime);
}
void Update()
{
Quaternion rot = transform.rotation;
rot.x = pendulum.$$anonymous$$oveNext(Time.deltaTIme);
transform.rotation = rot;
}
Are you looking for something like in this video?
Answer by GoldenProlix · May 25, 2017 at 08:51 AM
You could use a timer method like this:
float timer = 0;
float waitTime = 1; //seconds
bool waiting = false;
Vector3 previousVelocity;
Vetcor3 previousAngularVelocity;
Rigidbody rigidbody; //your gameObject's rigidbody
Update(){
if(timer >= waitTime && waiting){
//this starts the object again with its old velocity once the time you specify has passed
waiting = false;
rigidbody.velocity = previousVelocity;
rigidbody.angularVelocity = previousAngularVelocity;
}
if(waiting){
timer += Time.deltaTime;
//this stores the velocity info and then stops the object
previousVelocity = rigidbody.velocity;
previousAngularVelocity = rigidbody.angularVelocity;
rigidbody.velocity = Vector3.zero;
rigidbody.angularVelocity = Vector3.zero;
}
}
then when you want to stop the gameObject for that amount of time just call waiting = true; : )
Answer by troopy28 · May 25, 2017 at 02:37 PM
Hello!
I would really use the coroutine, instead of doing a unnecessarily complex update function, which will in addition slow your game.
There are two things that can be done here. First, you could only remove the velocity / angular velocity of your object, but this will only stop it before it starts moving again. That is the following code:
[SerializeField]
private Rigidbody rigidBody; // The rigidbody to stop
[SerializeField]
private float delay = 1f; // The delay to wait
private Vector3 prevVelocity;
private Vector3 prevAngularVelocity;
// Use this for initialization
void Start()
{
StartCoroutine(StopCoroutine());
}
IEnumerator InterruptCoroutine()
{
yield return new WaitForSeconds(delay); // Wait for the specified delay
prevVelocity = rigidBody.velocity; // Get the current velocity to put it again after
prevAngularVelocity = rigidBody.angularVelocity; // Get the current angular velocity to put it again after
// Stop the motion of the rigidbody
rigidBody.velocity = Vector3.zero;
rigidBody.angularVelocity = Vector3.zero;
yield return new WaitForSeconds(delay); // Wait again for the specified delay
rigidBody.velocity = prevVelocity; // Set the previous motion (the one before we stopped the object)
rigidBody.angularVelocity = prevAngularVelocity;
}
But if you want to completely stop the motion, then you should use the rigidbody.isKinematic property, which enable you to disable the physics for the specified rigidbody. This would give you the following code:
[SerializeField]
private Rigidbody rigidBody; // The rigidbody to stop
[SerializeField]
private float delay = 1f; // The delay to wait
private Vector3 prevVelocity;
private Vector3 prevAngularVelocity;
// Use this for initialization
void Start()
{
StartCoroutine(StopCoroutine());
}
IEnumerator StopCoroutine()
{
yield return new WaitForSeconds(delay);
prevVelocity = rigidBody.velocity;
prevAngularVelocity = rigidBody.angularVelocity;
rigidBody.isKinematic = true; // Stop physics for this rigidbody
yield return new WaitForSeconds(delay);
rigidBody.velocity = prevVelocity;
rigidBody.angularVelocity = prevAngularVelocity;
rigidBody.isKinematic = false; // Enable physics for this rigidbody
}
Regards,
it says that there is an error with the stop couroutine something about arguments
Strange. I don't have any error. $$anonymous$$aybe you could give me the line where the error is? I don't see where there could be any argument error as the only "function" that's called is the WaitForSeconds.
Answer by Ali-hatem · May 27, 2017 at 12:34 PM
public float time;
bool move = true;
public List <Vector3> pos = new List<Vector3>();
void Update () {
if (move) {
move = false;
StartCoroutine(wait_move());
}
}
IEnumerator wait_move(){
for (int i = 0; i < pos.Count; i++) {
yield return new WaitForSeconds (time);
transform.position = pos [i];
//adjust rotation
}
move = true;
}