简体   繁体   中英

How to constantly rotating with WaitForSeconds in update function - Unity

I am looking for a help with make a delay in Unity in Update function.

I created something like this below. The cube is moving rotates once and then is waiting > rotates once > waiting ....

And there is my question. How i can make cube rotates constantly for some time instead of once. For Example: Wait 2sec, rotating constantly 5sec, Wait 2sec, rota....

I thinked about replace

ForCube.transform.Rotate (10, 10, 10);

by rotating Animation. But I want create it with transform.Rotate. Is there any option to do this?

using UnityEngine;
using System.Collections;

public class Ruch : MonoBehaviour
{
    public float speed = 5;
    public GameObject ForCube;
    bool work = true;

    // Use this for initializat
    void Start ()
    {
        ForCube = GameObject.Find ("Cube");
        Debug.Log (ForCube);
    }

    // Update is called once per frame
    void Update ()
    {
        if (work) {
            StartCoroutine (WaitSome ());
        }
    }

    private IEnumerator WaitSome ()
    {
        work = false;
        yield return new WaitForSeconds (3f);
        ForCube.transform.Rotate (10, 10, 10);
        work = true;
    }
}

At the moment it looks like to me you are using a StartCoroutine which will work fine, but if you want maybe a little more control over when to rotate and when to stop you can use the Time.deltaTime The time in seconds it took to complete the last frame (Read Only). http://docs.unity3d.com/ScriptReference/Time-deltaTime.html

So basically you have yourself a float variable called Rotate which is lets say 10f

Then inside of your Update function

void Update ()
{
    if(Rotate > 0)
    {
        Rotate -= Time.deltaTime;
        ForCube.transform.Rotate (10, 10, 10);
    }
}

Then when Rotate is equal to 0 it will stop, but then you can use your work bool to start a new timer.

One big think to take in is to use the Time.deltaTime, if you don't use this and you just use an int or whatever variable type the timer will differ depending on the FPS of the game for the player.

Let me know if you need anymore help :)

Instead of using coroutines, you can do it directly in the update function like this:

[SerializeField]
private float timeToWait;  //In seconds
[SerializeField]  
private float timeToRotate;  //In seconds

private float timer = 0;
private bool waiting = true;   //Set this to false if you want to rotate first, wait later

void Update() 
{
    if(!waiting) RotateYourObjectALittleBit();  //Call your own function or do whatever you want 

    timer += Time.deltaTime;

    if(timer >= timeToWait && waiting) {
        waiting = false;
        timer = 0;
    }
    else if(timer >= timeToRotate && !waiting) {
        waiting = true;
        timer = 0;
    }
}

This code is untested, so please let me know if you require further clarification or if it doesn't work.

Thanks everyone for fast Answer and help to solve my problem. I really appreciate that.

I created something like this:

Version 1.0
When the space key is down the cube start rotating for RotateTime, after this the Timer reset to start value(RotationTime), and u can click again button for rotate.

using UnityEngine;
using System.Collections;
public class Ruch : MonoBehaviour
{
public GameObject ForCube;

public float RotateTime = 5;
public float Timer = 0;
private bool Rotate = false;

// Use this for initializat
void Start ()
{
    Timer = RotateTime;
    ForCube = GameObject.Find ("Cube");
    Debug.Log (ForCube);
}

// Update is called once per frame
void Update ()
{
    //Start Rotating When Press Space Key
    if (Input.GetKeyDown (KeyCode.Space)) Rotate = true;
    else if (!(Input.GetKeyDown (KeyCode.Space))&&Timer <=0) Rotate = false;

    RotateForSec (ref Timer);
}
//Function to Rotate for X sec
void RotateForSec(ref float sec)
{
    if (Rotate && sec > 0) {
        Debug.Log (Time.time);
        ForCube.transform.Rotate (10, 10, 10);
        sec -= Time.deltaTime;
    } 
    //Reset Rotating Time after rotating 
    if (!Rotate && sec <= 0) Timer = RotateTime;
}
}

Version 2.0
The rotating of cube continues for 5 seconds and then automatically without pressing a key it wait some time and start over rotating. Again again and again ...

public GameObject ForCube;

public float RotateTime = 5;
public float Timer = 0;
public float PauseTime = 0;

private bool Pause = false;
private bool Rotate = true;

// Use this for initializat
void Start ()
{
    Timer = RotateTime;
    PauseTime = RotateTime;
    ForCube = GameObject.Find ("Cube");
    Debug.Log (ForCube);
}

// Update is called once per frame
void Update ()
{
    //Start Rotating When Press Space Key
    if (Rotate)
        Pause = false;
    else if (!Rotate) {
        Pause = true;
    }

    if (!Pause)
        RotateForSec (ref Timer);
        else RotatePause ();

}
//Function to pause PauseTime sec
void RotatePause()
{
    if (PauseTime > 0) {
        PauseTime -= Time.deltaTime;
    } else {
        Pause = false;
        Rotate = true;
        PauseTime = RotateTime;
    }

}
//Function to Rotate for X sec
void RotateForSec(ref float sec)
{
    if (Rotate && sec > 0) {
        Debug.Log (Time.time);
        ForCube.transform.Rotate (10, 10, 10);
        sec -= Time.deltaTime;

    } else Rotate = false;
    //Reset Rotating Time after rotating 
    if (!Rotate && sec <= 0) Timer = RotateTime;
}
}

Its working but what you think about that, is it done correctly or it is a bad way?

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM