in java:
functionABC()
{
…;
yield;
…;
}
how to wait for “just a frame” in c#?
thx
What you want to do is start a coroutine:
So in your case
void Start()
{
StartCoroutine(ABC());
}
IEnumerator ABC()
{
//returning 0 will make it wait 1 frame
yield return 0;
//code goes here
}
or another way:
var i : int = 0;
function update () {
i=i+1;
if (i==2) {
print(“this message prints every second frame”);
i=0;
}
}
Update can run many times per frame, but it’s close.
You could try to set something up with FixedUpdate, which runs every frame, based on a set frame rate.
Are you sure about this? I thought Update() was defined to execute exactly once per frame. How else would this be accurate?
You sure you’re not thinking of OnGUI() ?
No, just once per frame.
Don’t use FixedUpdate for anything except physics code; that’s what it’s for.
Anyway, the correct answer to the original question is “yield return null”. (You can make Start return an IEnumerator; you don’t have to start a coroutine.)
–Eric
thanks!
My bad, ignore late night advice.
Update runs many times per second,(many frames per second), and I got turned around.
Here is small class to wait for some amount of frames:
public static class WaitFor
{
public static IEnumerator Frames(int frameCount)
{
while (frameCount > 0)
{
frameCount--;
yield return null;
}
}
}
Here is how you can use it:
public IEnumerator CoroutineAction()
{
// do some actions here
yield return StartCoroutine(WaitFor.Frames(5)); // wait for 5 frames
// do some actions after 5 frames
}
Found this class here: [Unity3d] WaitForFrames in Coroutine
Absolutely reviving this thread to ask question about that last answer; When you ask for the return of the Coroutine “Frames”, it actually waits for the coroutine??? I had previously searched for a way to wait for coroutine to be finished and heard nothing useful!
You don’t actually have to do a StartCoroutine there, so it’s even simpler:
public IEnumerator CoroutineAction()
{
// do some actions here
yield return WaitFor.Frames(5); // wait for 5 frames
// do some actions after 5 frames
}
The rules are:
- if you yield a YieldInstruction - like WaitForSeconds or a custom one - the coroutine waits until that returns false for
keepWaiting - if you yield an IEnumerator or a StartCoroutine, you start that coroutine, and your current coroutine waits until the inner coroutine is done.
- if you yield anything else, you wait a single frame.
Here’s a question, and possible solution to the original question.
If I use WaitForSeconds in an IEnumerator, and set the time to 0, will the coroutine start again next frame, or immediately?
For example:
IEnumerator ExampleCoroutine()
{
First();
yield return new WaitForSeconds(0);
Second();
}
Will Second() happen on the same frame as First(), or one frame later?
My two cents, what about that already present one? Unity - Scripting API: WaitForEndOfFrame
Hi My i have a simple script!
public float ABC;
public float framesToWait;
void Start{ABC = 0}
void Update{ABC = ABC + 1;
if (ABC > framesToWait}
You Need to Have a consistant framerate.[/code]
-
-
- void Start()
-
- {
- StartCoroutine(ABC());
- }
- IEnumerator ABC()
- {
-
- //returning 0 will make it wait 1 frame
- yield return 0;
-
- //code goes here
-
-
- }
-
so i used this script and it actually waited for one frame when i understood it…
but… even when i changed the yield return it kept on waiting only one frame
pls help me wait different amount of frames in this script. (i understand this script and i want to keep doing things i know instead of breaking my head trying to understand other scripts…) if u have any other SIMPLE scripts i might try them.
thx, Tom Markovich.
You can also avoid something to be recalled the same frame:
public struct OneTime
{
private int _frameCount;
/// <summary> Is first time called this frame? </summary>
public bool IsFirstTimeCalledThisFrame()
{
bool result = _frameCount != Time.frameCount;
_frameCount = Time.frameCount;
return result;
}
}
Then in whatever you don’t want to be called more than once in the same frame:
// Field:
private OneTime _oneTime;
...
// Avoid recalling the same frame.
if (!_oneTime.IsFirstTimeCalledThisFrame()) { return; }
To extend on my own answer, looks like after Unity 2018 we got: await Task.Yield()
Tested example:
private async void TryNextFrame()
{
Debug.Log($"{Time.frameCount} Current frame.");
await Task.Yield();
Debug.Log($"{Time.frameCount} This log will appear next frame...");
}
Not the best solution, and coroutines are definitely cleaner, but sometimes that’s handy:
bool waitForOneFrame = true;
private void Update()
{
if (waitForOneFrame)
{
waitForOneFrame = false;
}
else
{
// your code
}
}