Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice
  3. Join us on November 16th, 2023, between 1 pm and 9 pm CET for Ask the Experts Online on Discord and on Unity Discussions.
    Dismiss Notice

My android game ran smoothly in old versions of Unity but not the new versions

Discussion in 'Editor & General Support' started by TheSaviour, Jul 31, 2018.

  1. TheSaviour

    TheSaviour

    Joined:
    Apr 20, 2015
    Posts:
    68
    I've been trying to make a more "3d-fied" clone of this game:
    rapid roll.jpg

    Basically there are platforms moving up across the screen and the player has to keep the ball on the platforms. If the ball touches any of the spikes at the top and bottom, then the player loses a life.

    I started making my clone back in 2016 and the version of Unity I was using was Unity 4.3. When I built it for Android, everything want smoothly. There was no lag, no stutter, nothing. The crazy thing is that I didn't even make any optimizations (no GPU instancing, no object pooling, no change to Quality settings). And it still ran smoothly. I eventually removed the game from the Play Store so that I can make more enhancements (think of it as a remake, instead of an update).

    Now I'm using Unity 2018.1.8 and the platforms jitter like crazy. It doesn't move smoothly anymore. If I remember correctly, I encountered the same problem in the 2017 versions of Unity. I initially thought this might be because I added too many enhancements (like power-ups and new UI's). So to test my theory, I created a new project and recreated my game from scratch. But this time, I didn't include the enhancements and I used all the original scripts from version 4.3. Unfortunately, the platforms are still jittering. It doesn't jitter that much in the editor, but on my Android device, it jitters a lot.

    So my new theory is that this is being caused by the newer versions of Unity. Any idea what kinds of new settings were added that might possibly be causing this problem?
     
    Last edited: Aug 12, 2018
  2. Nicolas1212

    Nicolas1212

    Joined:
    Dec 18, 2014
    Posts:
    139
    Have you profiled to see what's going on and if there's any obvious performance issue? Is it stuttering in the Editor or in the build?

    Unity 5 had the big graphics update, and all the shaders changed, so there's a chance it's that - are you using the defaults or custom?

    Also verify VSync is on - we had an issue with jittering where when VSync was off, it jittered like crazy, especially on iOS
     
  3. TheSaviour

    TheSaviour

    Joined:
    Apr 20, 2015
    Posts:
    68
    It's stuttering in the build (even without the power-up enhancements), but works fine in the editor. Also what did you mean by "default or custom"? I'm using the built-in materials for like 99% of my game objects. There are just 1 or 2 objects where I'm using a texture from photoshop.
     
  4. Nicolas1212

    Nicolas1212

    Joined:
    Dec 18, 2014
    Posts:
    139
    Basically are you using the default shaders, or your own, custom shaders? Different shaders will break batching and result in more draw calls, but the default Unity shader handles a lots of things that you probably don't need (e.g. lights, transparency, tinting, etc). It's possible to make a slimmer version.

    Turn on VSync (every V blank) to see if that helps

    That said, profile your code to see where the issue is. Check your draw calls etc

    Check out:
    https://docs.unity3d.com/Manual/OptimizingGraphicsPerformance.html
    https://unity3d.com/fr/learn/tutori...ion/optimizing-graphics-rendering-unity-games
    https://unity3d.com/fr/learn/tutorials/topics/performance-optimization
     
  5. TheSaviour

    TheSaviour

    Joined:
    Apr 20, 2015
    Posts:
    68
    I'm using the default shader for every material except for a few particle materials but those only play when the ball collects a pick-up object.

    Also, after playing around with the settings, I found out that the main problem was with the resolution. In Quality Settings, there is an option called "Resolution Scaling Fixed DPI". I set that to 1 and in the Player Settings, I set the target dpi to 240. After that, the platforms no longer jitter when I start playing the game. I was relieved.

    However, I noticed that after playing the game for about a minute or two, the jitter comes back. I originally thought that maybe something is building up in my scene. But I don't see how that's possible, given that I'm using object pooling and I'm not using "Instantiate" or "Destroy" anywhere. I checked the profiler and it seems that in almost every frame, Initialization.PlayerUpdateTime is taking up most of the CPU power (more than 40%). Draw calls stay at 30 every frame.

    I'll play around with the VSync as you suggested. But are you sure that turning on the VSync will be efficient for an Android phone?
     
    Last edited: Aug 3, 2018
  6. TheSaviour

    TheSaviour

    Joined:
    Apr 20, 2015
    Posts:
    68
    Also, I've turned on VSync but it didn't work. During the first 4 minutes of gameplay, it was working fine (no jitter). But eventually the jitter came back (same problem as previous post).
     
  7. Joe-Censored

    Joe-Censored

    Joined:
    Mar 26, 2013
    Posts:
    11,847
    As mentioned, use the profiler. Otherwise you're just going to keep guessing.
     
  8. TheSaviour

    TheSaviour

    Joined:
    Apr 20, 2015
    Posts:
    68
    I just used the profiler for Development Build. So I managed to track exactly what happens when the game starts to stutter.

    It seems that whenever the game starts to stutter, PostLateUpdate.FinishFrameRendering takes up most CPU power.

    Profiler.png

    I expanded the PostLateUpdate.FinishFrameRendering section and turns out it's Gfx.WaitForPresent that's eating up most of the cpu power and lowering the frame rate.

    So this is what's causing the problem.
     
    Last edited: Aug 4, 2018
  9. TheSaviour

    TheSaviour

    Joined:
    Apr 20, 2015
    Posts:
    68
    Oh dear. It turns out that there are loads of threads about Gfx.WaitForPresent and not a single one of them solves the issue. There's no getting out of this one, is there...
     
  10. Nicolas1212

    Nicolas1212

    Joined:
    Dec 18, 2014
    Posts:
    139
    On some phones (e.g. iOS), VSync is forced, while on some Android phones (Android 5+), it's possible to render at more than 60fps, so if you don't force VSync, you run the risk of an unresponsive device, as it's rendering too quickly. Generally, it's a good idea to leave it on (you want your CPU idle as much as possible, otherwise your battery is going to die pretty quickly)

    WaitForPresent is literally just the CPU waiting for the GPU to be ready for the next frame. It can mean that you're going over budget (i.e. you've missed the current frame), or that your CPU is finished it's task early and is waiting for the GPU to be ready. With VSync on, it should lower, BUT you can't profile this running the game in the Editor, as the Editor doesn't use VSync (I understand you're connected to your Android here, but I thought I'd mention it).

    If your game is working fine for a few minutes, then starts to jitter, it points to possible a different issue. For example, in the screenshot, you have 232 bytes being allocated in an Update. While it might not seem that much, 232 bytes @ 60 FPS is 13,920 bytes per second (13KB), or 815KB per minute - e.g. nearly a MB of garbage a minute. Sort by GC Alloc to see if there's others. Also, what's going on in Camera.Render?
     
  11. TheSaviour

    TheSaviour

    Joined:
    Apr 20, 2015
    Posts:
    68
    Alright I fixed the GC Alloc issue.
    And as for the Gfx.WaitForPresent, after lots of testing, I found out that it causes the game to stutter every frame whenever there's a game object in my scene that's using a photoshop texture as its material. I have no idea why that's the case. When I removed all those photoshop texture-dependent game objects, my game started to run smoothly (even though there were a couple of WaitForPresent spikes here and there which didn't really affect the performance).

    I read on a Reddit forum that the Gfx.WaitForPresent can be avoided if I keep the CPU busy during every frame. Do you know any codes that wouldn't really have any affect on my game but would keep the CPU busy during every frame (so that it would never go idle)?
     
  12. Nicolas1212

    Nicolas1212

    Joined:
    Dec 18, 2014
    Posts:
    139
    This is not something you want to do. WaitForPresent is highly subjective, but it's literally just the CPU waiting on the GPU - you *want* your CPU doing as little as possible - on mobile it means that you don't run down the battery as fast. Giving it useless work to do might make it run on *your* device, but now it's twice as slow on Billy Bad Phone's device.

    https://forums.oculusvr.com/developer/discussion/comment/260638/#Comment_260638 is a good explanation of what's going on, specifically:

    In your case, if your framerate is suffering on the device, you need to look at why, or if, your rendering is going over budget. Perhaps your textures are too high of a resolution (lower, or look into mipmaps), need to be compressed to the right format, and uploaded to the GPU.

    https://unity3d.com/fr/learn/tutori...ng-performance-problems-using-profiler-window has a good tutorial on learning how to diagnose these problems. But if you can't get GPU profiling in Unity (make sure and close the Scene/Game views when doing this btw), then you may need to look into Android-specific tools, such as TraceView
     
    sandolkakos likes this.
  13. TheSaviour

    TheSaviour

    Joined:
    Apr 20, 2015
    Posts:
    68
    I've tried using a texture with lower resolution. It still led to the same Gfx problem. Turns out it's not just the texture. I get WaitForPresent spikes even when I use a background (by creating a cube and resizing it to fit the whole screen and adding a material to it).
     
  14. TheSaviour

    TheSaviour

    Joined:
    Apr 20, 2015
    Posts:
    68
    Every time I think I've fixed it, I find out that there's more to fix. It's very frustrating. I also realized that the default Standard shader I've been using for the past year didn't even exist before Unity 5. So I guess that might have to change it back to the default Diffuse shader that was used before Unity 5. I'm starting to feel like a noob again.

    When I first released the game for Android, it worked FLAWLESSLY. And the crazy part is that I didn't even make any optimizations. I didn't set a target frame rate. I didn't enable gpu instancing (maybe it was enabled by default, who knows). I didn't even bother looking at the Quality Settings. I didn't even know that the Profiler even existed, but it didn't matter because my game still ran very smoothly regardless.

    Unity has clearly made a lot of changes to their software since version 4.3. Unfortunately it's these changes that causing my game to perform horribly. I'm trying to tackle this issue by finding each and every one of those new changes so that I can make my game run smoothly on Android again like it did when Unity 4.3 was around. Here are the changes I've made so far:

    1. I set the quality level to the lowest possible level in Project Settings > Quality

    2. I created a script that executes Application.TargetFrameRate = 60in the Awake function

    3. I enabled GPU instancing for all materials that are used by multiple objects in the scene

    4. I set the Target DPI to 240 in Project Settings > Player > Resolution and Presentation

    5. For all particle-based materials, I set the shader to Mobile > Particles > Additive

    6. I turned off Realtime Global Illuminations under Windows > Lighting > Settings

    So are there any other changes I need to make? Anyone have any suggestions? To be honest, it's very frustrating searching for all the settings by myself so I'm asking for help. I know I can fix the problem by simply downgrading back to Unity 4.3 but I don't want to do that (except as a last resort). I want to learn the ways of the new Unity versions.
     
  15. samizzo

    samizzo

    Joined:
    Sep 7, 2011
    Posts:
    487
    You really need to dig into the profiler to find out what the problem is, otherwise you're just fumbling in the dark and guessing. Did you follow the suggestions for profiling in that oculusvr link that @Nicolas1212 posted? It has some good advice. Also if you like you can save the profile log and post it in the thread here and maybe we can take a look and help you figure out where the time is going.

    Sam
     
  16. sledgeman

    sledgeman

    Joined:
    Jun 23, 2014
    Posts:
    389
    I think you are not the only one, who has that prob with performance on mobiles when publishing out of Unity 5 / 2017 / 2018. As you mentioned , it is strange that on the older Unity 4.3 your game runs smoothly without any optimization. Also your Build is much larger, about +7mb. I would stick with U4.3 when targeting mobiles.
     
  17. TheSaviour

    TheSaviour

    Joined:
    Apr 20, 2015
    Posts:
    68
    I already used the profiler and already have a fairly good idea of what's causing the problem. But let me start from the beginning to make things more clear. It's gonna be pretty long so bear with me. It will be very detailed and have some screenshots of the profiler log.

    When I first started testing this game on Android, I noticed that the platforms were stuttering. So to find out what's causing this, I created a new project and only imported the platforms and all related scripts, and nothing else. It was stuttering. Next, I turned on GPU instancing and set target frame rate to 60. When I tested it on my android, the stutter was gone.

    Next I imported the ball (to be controlled by the player). The platforms started stuttering again. So I removed the ball and imported the blender prefabs (pick-up objects). The platforms were still stuttering. Next I removed the blender prefabs and imported the UI canvas. The platforms started stuttering even more. So I removed the UI canvas. The stutter was gone. So I decided to play around with some of the settings. I went to Project Settings > Player and under Resolution and Presentation, I set the Target DPI to 240. Then I imported all the other prefabs (ball, blender stuff, canvas, background, obstacles, etc) back into the game. And voila. The game was running smoothly again. At that point I thought to myself that maybe it was just the DPI that was causing the problem.

    The next day I was just casually playing my game. At first, it was running smoothly as expected. But around 200-300 seconds into my game, the platforms started to stutter again. That's when I used the profiler (connected to my android). This was the result:

    Profiler.png

    Gfx.WaitForPresent was taking over the CPU at every frame rate. So what did I do to fix it? I ran a series of experiments and used the profiler during every experiment. Here are the experiments and the results

    Exp 1: Remove/disable every asset/feature that might be GPU intensive. This includes removing all blender prefabs, particle effects, photoshop textures and transparent objects. For all mesh renderers in the scene, set Light Probes, Reflection Probes and Cast Shadows to 'Off' and disable Receive Shadows. Also turn off Reflections and Specular Highlights for all materials.

    Result 1: During entire 630 seconds of gameplay, Gfx.WaitForPresent stayed at 0%. There was no stutter.

    Exp 2: For all materials, turn on Reflections and Specular Highlights

    Result 2: During entire 765 seconds of gameplay, Gfx.WaitForPresent stayed at 0%. There was no stutter.

    Exp 3: For all mesh renderers in the scene, set Light Probes and Reflection Probes to 'Blend Probes' and Cast Shadows to 'On' and enable Receive Shadows.

    Result 3:
    (1st trial): During entire 690 seconds of gameplay, Gfx.WaitForPresent stayed at 0% (apart from a few occasional spikes that didn't have any noticeable change in performance). There was no stutter as far as I noticed.
    (2nd trial): During entire 650 seconds of gameplay, Gfx.WaitForPresent stayed at 0% (apart from a few occasional spikes that didn't have any noticeable change in performance). There was no stutter as far as I noticed.

    Exp 4: Re-import all the blender prefabs (pick-up objects), background and the obstacles

    Result 4:
    (1st trial): After 100 seconds of gameplay, Gfx.WaitForPresent fluctuated between 20-50% in every frame. Game started to stutter
    (2nd trial): After 60 seconds of gameplay, Gfx.WaitForPresent fluctuated between 20-50% in every frame. Game started to stutter

    Exp 5: Delete all the objects using photoshop textures (i.e. the background and the obstacles)

    Result 5:
    (1st trial) Performance restored. During entire 800 seconds of gameplay, Gfx.WaitForPresent stayed at 0%. No stutter.
    (2nd trial) Performance still intact. During entire 700 seconds of gameplay, Gfx.WaitForPresent stayed at 0%. No stutter.

    This is when I became confident that the blender prefabs weren't causing the stutter/Gfx problem

    Exp 6: Re-import all particle effects back into the game

    Result 6:
    (1st trial): During entire 800 seconds of gameplay, Gfx.WaitForPresent stayed at 0% (apart from a few occasional spikes that didn't have any noticeable change in performance). There was no stutter as far as I noticed.
    (2nd trial): During entire 700 seconds of gameplay, Gfx.WaitForPresent stayed at 0% (apart from a few occasional spikes that didn't have any noticeable change in performance). There was no stutter as far as I noticed.

    Exp 7: Re-import all objects using photoshop textures (i.e. the background and the obstacles)

    Result 7:
    (1st trial): After 65 seconds of gameplay, Gfx.WaitForPresent fluctuated between 20-50% in every frame. Game started to stutter
    (2nd trial): After 90 seconds of gameplay, Gfx.WaitForPresent fluctuated between 20-50% in every frame. Game started to stutter

    Exp 8: Remove (again) all objects using photoshop textures (i.e. the background and the obstacles)

    Result 8:
    Performance restored. During entire 600 seconds of gameplay, Gfx.WaitForPresent stayed at 0% (apart from a few occasional spikes that didn't have any noticeable change in performance). There was no stutter as far as I noticed.

    Exp 9: Re-import all objects using transparent materials into the scene:

    Result 9:
    During entire 700 seconds of gameplay, Gfx.WaitForPresent stayed at 0% (apart from a few occasional spikes that didn't have any noticeable change in performance). There was no stutter as far as I noticed.

    Exp 10: Remove all objects using transparent materials in the scene

    Result 10:
    During entire 720 seconds of gameplay, Gfx.WaitForPresent stayed at 0% (apart from a few occasional spikes that didn't have any noticeable change in performance). There was no stutter as far as I noticed.

    Exp 11: Import only the background (it uses a photoshop texture)

    Result 11:
    (1st trial) After 90 seconds of gameplay, Gfx.WaitForPresent fluctuated between 20-50% in every frame. Game started to stutter
    (2nd trial) After 38 seconds of gameplay, Gfx.WaitForPresent fluctuated between 20-50% in every frame. Game started to stutter

    Exp 12: Change the background texture to Sprite (2D and UI), create a material out of it and attach the material to a Quad object. This quad is the new background.

    Result 12:
    During entire 720 seconds of gameplay, Gfx.WaitForPresent stayed at 0% (however, some of the WaitForPresent spikes that popped up were larger, wider and a bit more frequent in terms of occurrence). Still no stutter as far as I noticed.

    Exp 13: This is the part where @Nicolas1212 pointed out the 232 bytes being allocated every update. I fixed that in the scripts and removed the background.

    Result 13: Performance restored. During entire 700 seconds of gameplay (both trials), Gfx.WaitForPresent stayed at 0% (apart from a few occasional spikes that didn't have any noticeable change in performance). There was no stutter as far as I noticed.

    Exp 14: Import the obstacles (the other object using photoshop textures)

    Result 14:
    During entire 700 seconds of gameplay, Gfx.WaitForPresent stayed at 0% (however, some of the WaitForPresent spikes that popped up were larger, wider and a bit more frequent in terms of occurrence). Some of those spikes cause the platforms to slightly jerk for a second.

    So to summarize, it looks like the background is what's causing the stutter. The obstacles may also have some minor role. Matter of fact, I just tested the game with the background again, and after 390 seconds of gameplay, this is what the profiler started showing:

    With Background and Tiles Texture.png

    I even tried using a lower resolution texture for the background. The stutter and Gfx.WaitForSecond problem was still there. Following @Nicolas1212 VSync solution did not solve the problem either.

    So do you have any feedback?
     
  18. sledgeman

    sledgeman

    Joined:
    Jun 23, 2014
    Posts:
    389
    There are some threads about the prob. I managed to get a good performance with U5.6 by:

    - check / activate: "Disable Deph and Stencil" (Resolution & Presentation) for Android (somehow turns out to
    boost all)
    - untick 'Auto Graphics API' (it should be only: OpenGLES2 & Vulkan & DX9)
    - turn on multithreaded rendering

    But as said before, U4.6 managed to be much better on mobiles. Maybe this will change with 2018 / 2019 when 72kb core runtime will be finalized.
     
  19. TheSaviour

    TheSaviour

    Joined:
    Apr 20, 2015
    Posts:
    68

    Thanks I'll definitely give these a try
     
  20. samizzo

    samizzo

    Joined:
    Sep 7, 2011
    Posts:
    487
    You don't want to disable the depth buffer if you're doing 3D.

    Can you also send a screenshot of what was happening in the frame before the spike? What does your background object look like? Is it just one GameObject or multiple? What scripts are on it? What materials and shaders is it using?

    Sam
     
  21. Ryiah

    Ryiah

    Joined:
    Oct 11, 2012
    Posts:
    20,150
    Ironically you've been using it this entire time. Vertical sync is the process of holding back the results of the frame buffer till the screen is ready for the next visible frame. If you've read the post by @Nicolas1212 you might have noticed that the explanation he gave matches the definition of VSync. That's because Gfx.WaitForPresent is more or less VSync.

    https://docs.unity3d.com/Manual/class-QualitySettings.html

    That being said simply disabling it won't necessarily have any effect on mobile devices because the game engine itself is enforcing a limit on the frame rate. By default mobile devices will run at 30 FPS. You need to override that too.

    https://docs.unity3d.com/ScriptReference/Application-targetFrameRate.html

    Just be aware that both of these may not have any effect either depending on the mobile device as it may have its own limit in place that overrides the game engine. Just throwing it out there because I've seen enough statements to that effect. I'll include links to a couple of them including Unity's own support entry.

    https://support.unity3d.com/hc/en-u...game-flips-between-running-at-30FPS-and-60FPS
    https://stackoverflow.com/questions/47031279/unity-mobile-device-30fps-locked/47031517#47031517
     
    Last edited: Aug 13, 2018
  22. TheSaviour

    TheSaviour

    Joined:
    Apr 20, 2015
    Posts:
    68
    To keep things organized, let me start with how I made the background:

    I created a cube. Then I scaled it so that it fits the screen (matter of fact, I made it even bigger than the screen to reduce any possibility of the player being able to see around it). And then I added the texture to the cube.

    Next, I duplicated the cube and placed it right under the first cube (so that it looks like one big plane). And then I made both of the cubes children of an empty game object. So now this game object is a background consisting of 2 large cubes (technically they're not even cubes anymore because I resized them). The reason I did it this way is that I was planning on creating a background scrolling effect by following this tutorial:



    So the game object holding the 2 "cubes" was the real background and it had a script attached to it that controls scrolling just like in the tutorial above. But you should know that the game stutters even when the background doesn't have any scripts attached.

    And as a matter of fact, I even created a new project to test whether the background has any effect there. And it did. It was causing the game to stutter due to Gfx.WaitForPresent spikes just like in the previous project. Except this time, the spikes looked more like this:

    SpikyGFX.png

    I'm not sure why the spikes looked different here even though it's technically the same game but in a different project.

    And as for what the profiler looks like before the spikes show up and cause stutter, here's a screenshot:

    occasional spike.png

    For the most part it looks clean but occasionally some spikes to show up (like the one above). But they usually don't have any noticeable effect on performance.
     
    Last edited: Aug 18, 2018
  23. TheSaviour

    TheSaviour

    Joined:
    Apr 20, 2015
    Posts:
    68
    Just to give you guys an update, I initially thought that the background is causing the game to stutter because it is somehow "colliding" with the UI elements. So I removed the entire canvas and tested it but it didn't make any difference. Only after I removed the background did the game start performing well again.

    Now I'm suspecting that the reason the background is causing the Gfx.WaitForPresent to spike is its size. I'm guessing that for some reason, my phone can't handle a game object that's too big. Maybe this has something to do with the shader. But I don't know. These are just theories right now.
     
  24. samizzo

    samizzo

    Joined:
    Sep 7, 2011
    Posts:
    487
    What shader is the background object using?
     
  25. bart_the_13th

    bart_the_13th

    Joined:
    Jan 16, 2012
    Posts:
    485
    some stuff I suggest you to try:
    • instead of creating a new project using unity2018, try creating new project on unity 4 (if you still have it of course) and update it to unity2018, then check if it run smoother...
    • instead of using cubes, try using quads (it's minor actually, might solve nothing at all)
    • also try scrolling the background using uv shifting instead of moving the whole background
     
  26. TheSaviour

    TheSaviour

    Joined:
    Apr 20, 2015
    Posts:
    68
    All materials are using the standard shader. But you did understand my description of how I implemented the background, right? The reason I didn't upload pics of the background is that I'm worried about the possibility of plagiarism. The way I made the background look is something I'm kinda proud of.
     
    Last edited: Aug 20, 2018
  27. TheSaviour

    TheSaviour

    Joined:
    Apr 20, 2015
    Posts:
    68
    I just changed all the material shader to Legacy/Diffuse and made the following changes:

    1) Enable "Disable Depth and Stencil" under Player Settings > Resolution and Presentation
    2) Disable "Auto Graphics API" under Player Settings > Other settings
    3) "Multithreaded Rendering" is turned on by default so no need to change that.

    And then I tested it on my Android (without the background).

    To be honest, it's hard to tell whether it made any difference. Even though the game doesn't stutter (because I'm not using the background), I still get occasional Gfx.WaitForPresent spikes that look like this:

    occasional spike 2.png

    But in terms of performance, these spikes hardly make any noticeable difference. The game still runs smoothly. Is it normal for Gfx.WaitForPresent to spike every now and then?
     
  28. TheSaviour

    TheSaviour

    Joined:
    Apr 20, 2015
    Posts:
    68
    Alright I'll give these a try. Thanks for the advice.
     
  29. samizzo

    samizzo

    Joined:
    Sep 7, 2011
    Posts:
    487
    The Standard Shader is completely different to the default shader in Unity 4.x. It's not very performant on mobile at all, and on top of that it sounds like you're drawing with it to the full screen twice if I understand your background cube setup correctly. Try using a quad or a plane and either Unlit/Texture, Unlit/Transparent, or Mobile/Diffuse depending on whether you need transparency or lighting.

    I would probably first start with using a SpriteRenderer for the background though if all you need is a texture.

    Sam
     
  30. AcidArrow

    AcidArrow

    Joined:
    May 20, 2010
    Posts:
    11,023
    I also suggest not using the Standard Shader.

    I would also suggest to go into the Unity Android player settings and change the Blit Type to Never, or Auto, which will probably give you a performance boost.... BUT, it's currently bugged and has been for a while, so it will result in a black screen. But once they fix it, this should be on Auto.

    Also. Even with the above, Unity 5+ is slower than Unity 4 on mobile and it tends to stutter, no matter what.
     
  31. tsibiski

    tsibiski

    Joined:
    Jul 11, 2016
    Posts:
    569
    So you have a massive game object as the background? Have you tried making the background scroll infinitely on a screen-sized squad. Or even mad the quad a video player object that runs a simple gif or vid of the background scrolling and looping?
     
  32. TheSaviour

    TheSaviour

    Joined:
    Apr 20, 2015
    Posts:
    68
    I'm trying to choose between Unlit/Color and Legacy/Diffuse. Which one do you think would be better in terms of performance in a mobile device? I don't wanna use any of the Mobile shaders because they don't have an option to choose material color.
     
  33. samizzo

    samizzo

    Joined:
    Sep 7, 2011
    Posts:
    487
    What shader were you using previously, in Unity 4.x? I don't think you can use Unlit/Color because you want a texture right? It's trivial to add a colour to the shader. I've attached to this post a shader called TransparentWithColour. Give that a try if you like! It uses alpha blending which can also have a not insignificant cost. If you don't need transparency then we can remove that for better performance too.

    Sam
     

    Attached Files:

  34. TheSaviour

    TheSaviour

    Joined:
    Apr 20, 2015
    Posts:
    68
    Thanks for the shader. I'm actually gonna try all the built-in stuff first. That way it will be easier to find out what's really causing the Gfx.WaitForPresent spikes.

    And as for which shader I was using in 4.x, I honestly don't remember. I do remember that it had options for changing the color, metallic-ness, smoothness, as well as Tiling and Offset for the texture. I don't remember any other options. However, speaking from vague memory, I think the shader was called "Default-Diffuse".

    UPDATE:

    I just changed all the shaders attached to the background materials to Legacy/Diffuse and I'm seeing much better performance. Apart from occasional spikes that didn't cause any noticeable changes in performance, Gfx.WaitForPresent stayed at 0% during entire 15 minutes of gameplay.

    I'm gonna try the quad now and see if it makes any difference.
     
    Last edited: Aug 25, 2018
  35. samizzo

    samizzo

    Joined:
    Sep 7, 2011
    Posts:
    487
    Great stuff. You can potentially get even better performance if you use a custom shader that does only exactly what you need.

    Sam
     
  36. AcidArrow

    AcidArrow

    Joined:
    May 20, 2010
    Posts:
    11,023
    You could also try disabling Vulkan. ES3.0 is really faster for my game in the latest Unity versions, but maybe it's something specific to my game.
     
  37. Nicolas1212

    Nicolas1212

    Joined:
    Dec 18, 2014
    Posts:
    139
    As @samizzo mentioned, the Standard shader is pretty complex, and is built for transparency (and support for PBR), so by using it for your background, it's equivalent to doing full-screen alpha, so your perf issues are likely to be fill-rate related (remember that mobile screens are *huge* pixel-wise, especially if you're drawing at native resolution). Basically you're drawing into the same pixels multiple times. If you can, try to draw your background last - it's quicker to do a depth check and not draw a pixel, than to draw a pixel multiple times.

    Legacy/Diffuse is a much simpler shader on a simpler pipeline, though it also supports alpha, which you might not need.

    I'd also recommend keeping VSync on, and set to every blank (60fps). It'll make sure that your CPU will wait until your GPU is ready before giving it a new frame. Otherwise you can end up with your CPU thrashing (I was having the same issue: https://forum.unity.com/threads/gfx...for-intermittent-periods.538254/#post-3576847)

    In terms of shader speed, unlit, no-alpha is probably as quick as you're going to get it. Preference no alpha over lighting if you can. You can see how much alpha drawing is taking in the profiler or frame debugger.

    If you haven't already done it, make sure all UI elements that you don't want to interact with have Raycast Target unselected.

    Finally, take a look at the lightweight render pipeline (https://blogs.unity3d.com/2018/02/2...er-pipeline-optimizing-real-time-performance/). It's very easy to set up, but can simplify things greatly.
     
  38. TheSaviour

    TheSaviour

    Joined:
    Apr 20, 2015
    Posts:
    68
    Sorry for not replying in a while. I got waaay too distracted. So anyways, I used your shader and attached it to 2 quads instead of 2 big cubes. During entire 10 minutes of gameplay, Gfx.WaitForPresent stayed at 0%. (apart from some occasional spikes which usually didn't change performance; although some of the spikes led to a brief jerk in platform movement which may or may not be noticeable to the players). Overall, I don't think there's been a significant change in performance compared to when I used a legacy-diffuse shader and 2 large cubes. When the spikes do show up, they sort of look like this:

    occasional spike 3.png

    But like I said these spikes aren't very frequent so I don't think they'll be that big of an issue. But just to be on the safe side, is there any way I can solve this problem?
     
    Last edited: Sep 6, 2018
  39. TheSaviour

    TheSaviour

    Joined:
    Apr 20, 2015
    Posts:
    68
    Regarding VSync, I already tried turning it on. But it didn't really change anything in terms of performance.

    I've been hearing about the render pipeline quite often these days. I'll give that a shot eventually. I hope it does its job.
     
    Last edited: Sep 6, 2018
  40. samizzo

    samizzo

    Joined:
    Sep 7, 2011
    Posts:
    487
    To really get to the bottom of it I would use a GPU profiler to get detailed information about performance. For example if you're using a device with a Mali GPU you can use the Mali Graphics Debugger. Otherwise it's pretty hard to do anything more especially when it's so rare now that you've cut the low hanging fruit.

    Sam
     
  41. Nicolas1212

    Nicolas1212

    Joined:
    Dec 18, 2014
    Posts:
    139
    Is there anything significant going on in Camera.Render?
     
  42. TheSaviour

    TheSaviour

    Joined:
    Apr 20, 2015
    Posts:
    68
    I just used the Lightweight Rendering Pipeline and it messed up my game big time.

    1) The background no longer shows up behind the platforms. It only shows up in front of the platforms. When I change the z-axis of the background to move it further to the back, it doesn't make any difference (except for looking smaller on my phone). And the crazy part is that this only happens when I play it on my android. It looks fine when I play it in the editor.

    2) There are a lot of z-fighting on the platforms. I should mention that I created the platforms by scaling many game objects and making them children of a game object (so this game object is technically the platform). Most of the platform children are overlapping with one another (which is fine because that's how I created it). But when I play it on the phone, these overlapping children start flickering like crazy. Once again, this only happens when I play it on the phone. Works fine in the editor.

    EDIT: All my materials are now using the LightweightPipeline/Standard (Simple Lighting) shader. Also it's not just the platforms where there is z-fighting. It pretty much happens in any overlapping game objects,
     
    Last edited: Sep 11, 2018
  43. Nicolas1212

    Nicolas1212

    Joined:
    Dec 18, 2014
    Posts:
    139
    Have you turned off the depth buffer?

    If you're having z-fighting issues, it could also be that your camera clipping planes are too far apart. If it's working fine in the Editor, but not on Android, then it's generally one of your platform-specific settings
     
  44. TheSaviour

    TheSaviour

    Joined:
    Apr 20, 2015
    Posts:
    68
    It was already turned off.

    And as for the clipping planes, they're set to Near 0.3 and Far 1000. This never really caused a problem (not even on mobile). Only after implementing LWRP, were the z-fighting present.
     
  45. TheSaviour

    TheSaviour

    Joined:
    Apr 20, 2015
    Posts:
    68
    I've been thinking about using Mobile/VertexLit for all the materials. However, I noticed that this shader doesn't have an "Enable GPU Instancing" option. The Legacy/Diffuse shader has it. Since I'm gonna have multiple platforms in my scene using the same materials, would it be a better idea to stick to the Legacy/Diffuse shader (since it has gpu instancing)?
     
  46. Nicolas1212

    Nicolas1212

    Joined:
    Dec 18, 2014
    Posts:
    139
    If you're using 3D, not having a depth buffer will probably kick off z-fighting. For what it's worth, on our game, we have the depth buffer active. Alternatively, if you're drawing everything using the Unity UI system, you should be able to get away with just setting the Pos Z of the RectTransform (I haven't tested though, so I can't be 100% on that)

    We don't use GPU Instancing, but from what I understand of it, it primarily affect draw calls if you're using Meshes. How many draw calls are you getting? Based on the image in the original post, is each one of those dots a sphere?
     
  47. TheSaviour

    TheSaviour

    Joined:
    Apr 20, 2015
    Posts:
    68
    Ok now I'm super confused. I created a new project. This time I'm only testing the platforms. Instead of using the custom platforms I will use for the game, I'm using simple cube game objects. Nothing too complicated. I'm doing this to keep the project simple. Here's what the game looks like:

    tetracube platforms.jpg

    But here's what the profiler looks like:

    Spikes.png

    I have no idea what's causing these spikes. They're literally just cube game objects (with a different scaling). Nothing else. They're using the legacy/diffuse shader. What on earth is going on...

    EDIT: I should also mention that the platforms weren't stuttering. It's just the spikes that I'm worried about.
     
  48. TheSaviour

    TheSaviour

    Joined:
    Apr 20, 2015
    Posts:
    68
  49. samizzo

    samizzo

    Joined:
    Sep 7, 2011
    Posts:
    487
    Are you profiling the editor or your device there? It's hard to say just from a profiler screenshot. Can you upload a small test project somewhere that reproduces the issue? Then I could take a look on my own device.

    Sam
     
  50. TheSaviour

    TheSaviour

    Joined:
    Apr 20, 2015
    Posts:
    68
    Whoops I totally forgot about this.

    I was profiling the android device. I noticed that after I added a lot of the other assets back into the game, most of the spikes disappeared. I'm guessing that's because there were less opportunities for the cpu to remain idle so the Gfx.WaitForPresent calls dropped significantly.

    But anyways, during this time, I found another thing that's been responsible for the large number of Gfx.WaitForPresent spikes earlier on: Color.Lerp

    In my game, there's a stage where a lot of the platforms start changing their colors. Every time I reached that stage during development build, there would eventually be a large number of Gfx.WaitForPresent spikes (which would lead to game stutter). But when I removed all the code that calls Color.Lerp, the number of Gfx.WaitForPresent spikes reduced significantly and the stutter was gone (as far as I noticed).

    Do you know why this is the case? Is the Color.Lerp call very gpu intensive? If so, I guess I probably shouldn't be using that function in android games.
     
    Last edited: Oct 31, 2018