I lurked around the net looking for information on clear spikes - they seem to be happening a lot on Android. However, I found no definite answer. And then I got this:
Now that's disgusting. Can any of the Unity gurus here elaborate on why this could be happening? Is it something wrong with Unity or Android, or can it be addressed by me?
That is a bit insane. Do you get the same spikes if you set the camera to Don't clear? I know it won't look right but maybe something else is going on?
The spikes are still there, but are now identified as DrawVBO now by the profiler. I'm fairly confident that the problem is not directly in my code, nothing is happening at the time spikes happen.
The single 600-tri mesh I am rendering is not even being modified at that time. The mesh is MarkDynamic() and is not double-buffered.
It's a tightly packed tile map, so no overdraw should be happening, setting aside minor off-screen overdraw for smooth scrolling.
Actually, I was wrong and for some reason the mesh is being updated every frame even though no change occurs - let's consider this a bug, but that's irrelevant because updating the mesh every frame will be a common scenario for the most of the time in the game.
It's a tightly packed tile map, so no overdraw should be happening, setting aside minor off-screen overdraw for smooth scrolling.
Actually, I was wrong and for some reason the mesh is being updated every frame even though no change occurs - let's consider this a bug, but that's irrelevant because updating the mesh every frame will be a common scenario for the most of the time in the game.
Just wanted to say - updating the mesh every frame in Unity is surprisingly slow, unfortunately. It's I think a consequence of how their Mesh API does its stuff. This is on all platforms, too - not just OUYA. For instance, I noted that I had an NGUI UI that had a radar sweep, which caused the entire UI to update every frame. When profiling I realized this was actually taking a large chunk of CPU time, and getting rid of the radar sweep fixed it - on Desktop, no less. Imagine how it would be on mobile.
So try fixing the mesh update and see if that fixes it.
Post edited by Killa_Maaki on
You didn't remember the plot of the Doctor Who movie because there was none; Just a bunch of plot holes strung together.
I disagree on this, updating the mesh is fast enough even without tricks like double buffering since Unity 4.0. My game and rendering logic running on top of Futile framework is profiled to be capable of maintaining 4000 fps on my PC and 120fps on Ouya while updating the mesh every frame. I think that if it actually was the mesh modification problem, I'd have huge CreateVBO times. From what I've seen on the internet, OpenGLES DrawVBO spikes usually happen to people using specific shaders.
After I fix my funny little update bug to make sure I am not updating the mesh unless I have to, I'll tell you if the spikes are still there. I assume they will be.
Using the Mobile/Particles/Alpha Blended shader instead of Sprites/Pixel Snap/Alpha Blended reduced the prominence of DrawVBO spikes to a completely satisfactory level. However, once I changed camera clearing back to SolidColor... IT KEEPS HAPPENING!
I definitely could but I have no reason to, that's not the cause of the issue. Camera clear still produces spikes that are absent in a Don't Clear scenario.
After a bit of play testing I can testify that the above mentioned camera spike does not seem to affect the game in any way - it actually runs perfectly well at 60Hz@1080p. One of my assumptions is that it is actually introduced by the presence of the profiler, or only relevant to development builds. However, if it turns out later that this is not the case, I'll update the thread.
Tim, if you're still there, I have an unrelated question in mind. Even a whole story. So here it is.
A few days ago I was basically ripping my hair out because after a series of optimizations my game was running choppy on the device for not obvious reason. I actually tested my virtual camera movement alone, and it was perfectly smooth. However, character movement was in ruins, as if I had a major screen refresh desync.
After wandering aimlessly for a bit I have suddenly managed to connect the dots: in my tests, I was moving the camera with static offset per frame. There was no delta. Promptly, I abandoned Time.deltaTime and started feeding my Update() with 1f / Screen.currentResolution.refreshRate instead. And it turned out perfectly smooth, not a twitch, not a slowdown.
So, to the actual questions.
Is it normal that Time.deltaTime is so inaccurate on the device, and do you happen to know a reason behind this? I should note that smoothDeltaTime also wasn't doing well, so the timing error was pretty damn high.
Is it okay to use the fixed delta approach as long as I can maintain a steady framerate w/vsync?
Will Ouya try and run at 120Hz if it happens to be connected to such a display (thus forcing my game to run at 120FPS - I wanna know if I should take care of this scenario)?
After a bit of play testing I can testify that the above mentioned camera spike does not seem to affect the game in any way - it actually runs perfectly well at 60Hz@1080p. One of my assumptions is that it is actually introduced by the presence of the profiler, or only relevant to development builds. However, if it turns out later that this is not the case, I'll update the thread.
Tim, if you're still there, I have an unrelated question in mind. Even a whole story. So here it is.
A few days ago I was basically ripping my hair out because after a series of optimizations my game was running choppy on the device for not obvious reason. I actually tested my virtual camera movement alone, and it was perfectly smooth. However, character movement was in ruins, as if I had a major screen refresh desync.
After wandering aimlessly for a bit I have suddenly managed to connect the dots: in my tests, I was moving the camera with static offset per frame. There was no delta. Promptly, I abandoned Time.deltaTime and started feeding my Update() with 1f / Screen.currentResolution.refreshRate instead. And it turned out perfectly smooth, not a twitch, not a slowdown.
So, to the actual questions.
Is it normal that Time.deltaTime is so inaccurate on the device, and do you happen to know a reason behind this? I should note that smoothDeltaTime also wasn't doing well, so the timing error was pretty damn high.
Is it okay to use the fixed delta approach as long as I can maintain a steady framerate w/vsync?
Will Ouya try and run at 120Hz if it happens to be connected to such a display (thus forcing my game to run at 120FPS - I wanna know if I should take care of this scenario)?
No, that's most definitely not normal. You might want to run some tests on Time.deltaTime - maybe log the value of 1f / Time.deltaTime (current framerate)?
You didn't remember the plot of the Doctor Who movie because there was none; Just a bunch of plot holes strung together.
No, that's most definitely not normal. You might want to run some tests on Time.deltaTime - maybe log the value of 1f / Time.deltaTime (current framerate)?
I could if you're interested. I didn't do that just because I didn't realize it was the problem, and when I did realize, I fixed it this wierd way.
You could even use NDK to get the clock cycles versus using time.deltaTime, but something else must be going on. It sounds fishy. And of course if your rendering is getting 100ms spikes that would account for the choppiness.
I typically instead of moving objects using delta time, I calculate when an action will finish and lerp between the two points. For example:
DateTime startTime = DateTime.Now; //start of action
DateTime endTime = DateTime.Now + TimeSpan.FromSeconds(3); //in N seconds the action will finish
Get the elapsed time in the update frame:
float elapsed = (DateTime.Now - startTime).TotalSeconds / 3.0f; //expecting a range 1 to 0 over the duration of endTime
float t = 1 - elapsed; //normalize the range to 0 to 1
now use in a lerp
transform.position = Vector3.Lerp(startPos, endPos, t); //and now you'll get a smooth move regardless of any choppiness
If I haven't been able to maintain my FPS steady (i.e., if I had real spikes), I would've gotten inconsistent speed using my fixed delta, as I'm completely framerate-dependent. But in fact, it's silky smooth. It looks like Time.deltaTime lies, that's what I'm talking about.
Yeah, my movement is calculated pretty much the way you proposed. I add the delta to my object's moving time every update, and my renderer calculates its pixel position offset as moveTime / MOVE_DURATION * TILE_SIZE. The only difference is that you use real time difference instead of Time.deltaTime (which should be the same in theory, but apparently they're not). So your solution is to calculate your own delta as well.
Comments
OUYA Inc | Android Developer
Skype: tgraupmann_prey
http://github.com/ouya/docs
http://github.com/ouya/ouya-sdk-examples
Check out the latest docs for your game engine: [setup] [adobe air] [android] [clickteam fusion] [construct 2] [corona] [libGDX] [game maker] [html5] [marmalade] [monogame] [unity] [unreal]
Use caution when setting [persistent wireless mode].
OUYA Inc | Android Developer
Skype: tgraupmann_prey
http://github.com/ouya/docs
http://github.com/ouya/ouya-sdk-examples
Check out the latest docs for your game engine: [setup] [adobe air] [android] [clickteam fusion] [construct 2] [corona] [libGDX] [game maker] [html5] [marmalade] [monogame] [unity] [unreal]
Use caution when setting [persistent wireless mode].
This is on all platforms, too - not just OUYA. For instance, I noted that I had an NGUI UI that had a radar sweep, which caused the entire UI to update every frame. When profiling I realized this was actually taking a large chunk of CPU time, and getting rid of the radar sweep fixed it - on Desktop, no less. Imagine how it would be on mobile.
So try fixing the mesh update and see if that fixes it.
OUYA Inc | Android Developer
Skype: tgraupmann_prey
http://github.com/ouya/docs
http://github.com/ouya/ouya-sdk-examples
Check out the latest docs for your game engine: [setup] [adobe air] [android] [clickteam fusion] [construct 2] [corona] [libGDX] [game maker] [html5] [marmalade] [monogame] [unity] [unreal]
Use caution when setting [persistent wireless mode].
OUYA Inc | Android Developer
Skype: tgraupmann_prey
http://github.com/ouya/docs
http://github.com/ouya/ouya-sdk-examples
Check out the latest docs for your game engine: [setup] [adobe air] [android] [clickteam fusion] [construct 2] [corona] [libGDX] [game maker] [html5] [marmalade] [monogame] [unity] [unreal]
Use caution when setting [persistent wireless mode].
OUYA Inc | Android Developer
Skype: tgraupmann_prey
http://github.com/ouya/docs
http://github.com/ouya/ouya-sdk-examples
Check out the latest docs for your game engine: [setup] [adobe air] [android] [clickteam fusion] [construct 2] [corona] [libGDX] [game maker] [html5] [marmalade] [monogame] [unity] [unreal]
Use caution when setting [persistent wireless mode].
OUYA Inc | Android Developer
Skype: tgraupmann_prey
http://github.com/ouya/docs
http://github.com/ouya/ouya-sdk-examples
Check out the latest docs for your game engine: [setup] [adobe air] [android] [clickteam fusion] [construct 2] [corona] [libGDX] [game maker] [html5] [marmalade] [monogame] [unity] [unreal]
Use caution when setting [persistent wireless mode].
OUYA Inc | Android Developer
Skype: tgraupmann_prey
http://github.com/ouya/docs
http://github.com/ouya/ouya-sdk-examples
Check out the latest docs for your game engine: [setup] [adobe air] [android] [clickteam fusion] [construct 2] [corona] [libGDX] [game maker] [html5] [marmalade] [monogame] [unity] [unreal]
Use caution when setting [persistent wireless mode].
That actually sounds to me a lot like garbage collection.
OUYA Inc | Android Developer
Skype: tgraupmann_prey
http://github.com/ouya/docs
http://github.com/ouya/ouya-sdk-examples
Check out the latest docs for your game engine: [setup] [adobe air] [android] [clickteam fusion] [construct 2] [corona] [libGDX] [game maker] [html5] [marmalade] [monogame] [unity] [unreal]
Use caution when setting [persistent wireless mode].
@tgraupmann
If I haven't been able to maintain my FPS steady (i.e., if I had real spikes), I would've gotten inconsistent speed using my fixed delta, as I'm completely framerate-dependent. But in fact, it's silky smooth. It looks like Time.deltaTime lies, that's what I'm talking about.