Search Unity

  1. Unity 2018.3 is now released.
    Dismiss Notice
  2. The Unity Pro & Visual Studio Professional Bundle gives you the tools you need to develop faster & collaborate more efficiently. Learn more.
    Dismiss Notice
  3. Want more efficiency in your development work? Sign up to receive weekly tech and creative know-how from Unity experts.
    Dismiss Notice
  4. Build games and experiences that can load instantly and without install. Explore the Project Tiny Preview today!
    Dismiss Notice
  5. Nominations have been announced for this years Unity Awards. Celebrate the wonderful projects made by your peers this year and get voting! Vote here!
    Dismiss Notice
  6. Want to provide direct feedback to the Unity team? Join the Unity Advisory Panel.
    Dismiss Notice
  7. Improve your Unity skills with a certified instructor in a private, interactive classroom. Watch the overview now.
    Dismiss Notice

Battery-preserving low frame-rate but with immediate new frame upon input

Discussion in 'New Input System' started by runevision, Jun 12, 2017.

  1. runevision

    runevision

    Unity Technologies

    Joined:
    Nov 28, 2007
    Posts:
    1,379
    This is a follow-up to discussion in the welcome thread about preserving battery by allowing longer frames when there's no input without getting lag when there is. Taking it here to avoid hi-jacking that thread any longer.

    We have talked some more internally about what we could potentially do. We are thinking about this approach:
    • Implement a way to reduce the frame rate when there's no input but get a new frame immediately when there is.
    • Implement this functionality only for touch input for a start. It will treat all touch input as events that can interrupt sleep and only touch input. We may expand it with other event types in the future if there is demand for it.
    We're considering different approaches for what the API would be like.

    Potentially:
    • int Application.targetFrameRate
    • int Application.targetSleepFrameRate
    • bool Application.sleepAndWakeOnEvent
    Or alternatively:
    • float Application.minFrameTime
    • float Application.maxFrameTime
    • bool Application.sleepAndWakeOnEvent
    If we at one point support handling different event types than touches for this, we may add API to specify what types of input should unblock.

    Example use case:

    You’d set targetFramerate to a normal active rate like 30 fps and targetSleepFrameRate to 1 fps. Then, when nothing needs animation etc. and you just want to wait for the next input, you set sleepAndWakeOnEvent to true.

    If there’s input, it will trigger the next frame. If the input causes an animation or similar to start you can set sleepAndWakeOnEvent to false. Then when the animation has finished, set it to true again.

    Questions for you:

    A) Should input always halt a wait immediately, or still ensure a minimum frame time?


    If you have set sleepAndWakeOnEvent to true so you only want a new frame quickly if there's input, do you want:
    1. To immediately halt the sleep, even if it results in a frame that's shorter than the normal targetFrameRate?
    2. To use the normal targetFrameRate to ensure the sleep is halted as soon as a normal frame length has passed?
    The former can result in very fast frames during a swipe. If sleepAndWakeOnEvent is set to false as soon as the swipe starts, most of the frames will have normal length, but the initial one could still be shorter.

    The latter guarantees a minimum frame time (max frame rate) even when there's input.

    B) For your own current use cases, would you need sleep to resume on any other types of events than touch events?

    And if so, which types of input is that? What game is this for? (platform, brief description of style and interaction, etc.)
     
  2. Ferazel

    Ferazel

    Joined:
    Apr 18, 2010
    Posts:
    309
    Thanks for making a thread about it. I'm very happy that we're having a discussion about it.

    From what you said, I think it makes more sense to keep the targetFrameRate naming convention.

    A) In terms of expected behavior of the sleepAndWakeOnEvent, I feel that an interrupted frame would be better. It would reduce the latency, and the impact on battery life would be minimal. The user is unlikely to notice the uneven frame pacing. The user is also unlikely to trigger significant qty of input frames with touchscreen input. If the game is going into these sleep framerates, I would expect game already is in a state where a normalized frame time isn't going to be important. I expect only the first frame to have an "incorrect" frame time and every subsequent frame would rely on the targetFrameRate.

    B) I am OK with just touch to start, but there are other input mechanisms that I want to be able to register depending on the application. Bluetooth controllers, keyboards, mice (Android), and Apple pencils to name a few. In terms of other systems that would use this functionality, the only other system that I could even potentially think might want to force a frame update would be networking. However, there is such an embedded latency already associated with networking that I don't think it would be a problem to delay until the next sleep frame.

    The rest of my feedback below is mainly just semantics about the API. At the end of the day, I'll take any API you can give us to give us the behavior we're looking for.

    To me, having a separate sleep frame rate variable or bumping back to targetFrameRate after the first wake event assumes behavior from game logic. I'd argue that setting the target frame rate is more indicative of what you directly want the application to do. When I tell the targetFrameRate to go down I am telling the application to sleep, when I tell the targetFrameRate to go higher I am telling the application to wake-up. It is unlikely that we would be doing this throughout the entire application and have a centralized MonoBehaviour to control it or give what our desired sleep frame rate so storing that frame rate at the application side seems weird. Unless there is some concern with setting the target frame rate frequently or just triggering one frame. I'm not sure I see the point of adding another field on Application. I would argue that just giving the managed scripting an immediate frame should be enough for us to determine if it is input in game logic that would trigger "a wake up" and we would set the targetFrameRate with game logic instead of relying pre-defined Application's logic. Sure we could enforce our sleep frame rate again by setting the bool with your API, but why have the Application change its frame rate state without being told to explicitly by the game logic scripting? This also muddies the source of truth. Instead of having a single variable for what is the current application render time, you need to check the bool that would then need to check another int field.

    I do agree with having a bool flag, but again to match the previous point something like "triggerFrameOnWakeEvent" would fit better. We are designating the type of event that we can define an API for later. For example, the later API it could be something like RegisterFrameRateWakeEvent() and the purpose of this event would be clearly associated with this "WakeEvent" term we've defined for this system.

    Thanks for your consideration of this functionality. If there is anything else I can do to help clarify our use case, let me know.
     
    Last edited: Jun 12, 2017
  3. greggtwep16

    greggtwep16

    Joined:
    Aug 17, 2012
    Posts:
    1,428
    Your alternative with floats for the framerate times is a bit more flexible. 1 FPS saves a decent amount of battery but I would think that anyone doing that actually wants "sleep forever until woken up". Floats would allow you to enter .5, .25, etc. That being said keeping the ints for backwards compatibility and wrapping them in an enum with one entry for "sleep until input" or something similar.

    Responses to specific feedback requested.

    A) This depends at what rate your input gathering piece is running at, but assuming its running faster than the framerate then no it should not interrupt the targetFrameRate (normal fast framerate). It should only interrupt the sleep framerate when the bool is active. It's a bit redundant though the bool should only be active when we're ready to sleep. I'd expect Unity to set it back to false and our normal framerate when it detected input (meaning the bool wouldn't be active when running at the fast framerate). Let's say the user was checking a box, that triggered an animation to play we wouldn't set it back to true until that was done. Even if the user touched part of the screen we didn't care about, I'd still expect to have to query the input and determine that and set it back to true.

    B) My current use case is mostly mobile but it would help out on laptops as well. I'm making a gcode editor for 3d printing modifications and virtual rendering of imported files with different materials (so you don't have to waste filament if your slicer messed up). On mobile touch would be all that I need. On laptops the same would be the case just monitoring keyboard keys and the mouse instead (although a unity app takes over an hour to kill a laptop battery, where many times it can take under 45 minutes to kill a mobile battery on some smaller phones).
     
  4. greggtwep16

    greggtwep16

    Joined:
    Aug 17, 2012
    Posts:
    1,428
    If I'm understanding this right (a callback specifically called when interrupted) I guess this would be an alternative to Unity always setting the sleep bool back to false when it detects input to interrupt sleep, I'm not sure if I'd like it better or not. Having the frame forced is already going to run my whole game loop once with all my other scripts an logic for what to do when buttons were hit, etc. So I already should have a mechanism to decide whether I cared about any of the interrupting input and either sleep again or go to the fast framerate and play an animation or something else. I'd probably prefer that Unity just set the bool back to false every time and leave it up to me to turn it on again.

    If you're just talking about specifying which mediums will invoke the interrupt then I misunderstood.
     
  5. superpig

    superpig

    Quis aedificabit ipsos aedificatores? Unity Technologies

    Joined:
    Jan 16, 2011
    Posts:
    4,089
    So this suggests another possibility for the API - we could expose a method, maybe something like:
    Code (csharp):
    1.  
    2. Application.ReduceFrameRateUntilWakeEvent(float frameRate, WakeEventMask wakeEvents = WakeEventMask.AnyInput);
    3.  
    where "frameRate" is the reduced frame rate you want the engine to use, and "wakeEvents" specifies the kind of events that can wake it up (which maybe for now would just be "any input", but perhaps someday we'd have ways to say "input" vs "networking", or "mouse movement" vs "mouse clicks" etc). What do you think of this, compared to the properties approach?

    BTW, I am in favour of changing all this 'frame rate' stuff to be 'frame time' instead. It behaves more linearly and means you're thinking in the same units as both the profiler and input event timestamps. On the other hand, it's definitely a less common way of describing the overall player loop execution, and would need more explaining to people...
     
  6. Ferazel

    Ferazel

    Joined:
    Apr 18, 2010
    Posts:
    309
    Based on the API that Rune suggested, I'd rather just have the one application frame rate/time with a bool flag to trigger a managed script update ASAP on the player loop in certain wake cases. Then the game logic maintains full control over the frame rate and interrupt mechanics and nothing is changed automatically by the engine. If I tell the engine to go to a sleep frame rate with wakeup events, it should stay in that state until I tell the engine otherwise. For example, lets say I wanted to manage three game frame rates 2fps sleep (pause/static screen), 20 fps (2D frame animation), 30/60 fps fast (3D action sequence). If I handled that API on the game logic side, I would find it clearer if I just had a single frame rate field on Application which fed into the player loop. Any changes I made were explicitly made by game logic. It is purely API preference. I could definitely live with the API either way. If others feel strongly that having a separate sleep/wake frame rates set in the application and it automatically bounces between them, that's fine too.

    In regards to frame rate vs frame time, I really don't have an opinion. I agree that frame time on the back-end would likely be cleaner, but at the end of the day it should be what the users of the API will understand the most and what has already existed prior (which is frame rate). I personally wouldn't want my frame rate to go below 1 fps personally, but I could see that being a use case someone could bring up later.

    That works for me. I like the functionality of adding an input mask, but the goal would be to have the wake functions be driven by the new ActionMap system so that any inputs not on the active ActionMap would be ignored. However, I'll take what I can get. ;)
     
    Last edited: Jun 13, 2017
  7. greggtwep16

    greggtwep16

    Joined:
    Aug 17, 2012
    Posts:
    1,428
    I'm all in favor of this, I had suggested something similar in the 2nd to last paragraph of this post.

    https://forum.unity3d.com/threads/w...d-info-please-read.397153/page-4#post-3104329

    There are some inputs that it would likely never make sense or be very tricky to ever do it on like controller joysticks or accelerometers and gyros and should probably be excluded from "any input". But other than those setting a mask would make sense.

    I do probably favor something like this over having multiple player settings. To me the "low framerate" would always be triggered at runtime, and the new framerate only applies until a matching input is detected.

    Whichever is easier for you guys and most people. Obviously internally you guys are already taking the current int and sleeping by 1 / targetFrameRate. I would thing regardless of the naming there should also be a way to specify "sleep forever until input".
     
    Last edited: Jun 13, 2017
  8. greggtwep16

    greggtwep16

    Joined:
    Aug 17, 2012
    Posts:
    1,428
    Totally agree. I like the suggestion by @superpig .
     
  9. runevision

    runevision

    Unity Technologies

    Joined:
    Nov 28, 2007
    Posts:
    1,379
    Great, it sounds like we a form of consensus on what form this feature could take. :)
     
    neoshaman likes this.
  10. Ferazel

    Ferazel

    Joined:
    Apr 18, 2010
    Posts:
    309
    Just a note, that if the API is going to look like superpig's I'd still want a way to wake up the framerate via game logic. Either by calling Application.targetFrameRate = 30 or by another method. There may be a use case where if I set the framerate to sleep, but I receive a network packet or I want to occassionally trigger a particle effect or animation to help convey that the game isn't frozen. I'd want to manually relinquish my sleep framerate during that period and re-enable it once the animation/particle effect has concluded, and we're on a static screen again.
     
    radimoto and superpig like this.
  11. larku

    larku

    Joined:
    Mar 14, 2013
    Posts:
    1,411
    Sounds great.

    I'd be happy with either runevision's or superpig's API suggestions.

    superpig's API is my preferred (at first glance) as it looks neat and concise and would suit my needs which are:

    • Reduce the target frame rate to a rate I choose (eg 1fps, 10fps, 15fps, 30fps, etc)
    • Wake immediately on input (selected by sleep flag) and allow me to either leave in sleep reduced fps or set a new target (eg 60fps)
    I also agree with Ferazel that on the awake from sleep event we set the frame rate to resume to - the API used is of no concern to me.

    It's fantastic to hear Unity showing interest in doing this - this will make battery use and thermal load of some games significantly better (that's an understatement).

    I'm currently using a hand crafted solution that reduces down to 15fps while idle - this works but input lag is ugly and certain swipe events etc don't always register which make my UI feel low quality.

    Out of interest - how far away is such a feature? Weeks, months or years?
     
  12. _Daniel_

    _Daniel_

    Joined:
    Feb 28, 2007
    Posts:
    2,616
    Wow, what a coincidence. I was actually working on just this feature a few months ago. I actually went so far as to snapshot the game view and disable all rendering when no user input was detected. I can post my code if anyone is interested.
     
    Polff, larku and neoshaman like this.
  13. greggtwep16

    greggtwep16

    Joined:
    Aug 17, 2012
    Posts:
    1,428
    How much did you save with just the rendering turned off (obviously everything else is still happening at the specified framerate). I never did a full test, but a long time ago it was always much more effective to just lower the whole framerate.

    In either case hopefully this is a thing of the past soon with full support.
     
  14. _Daniel_

    _Daniel_

    Joined:
    Feb 28, 2007
    Posts:
    2,616
    I didn't test that, but I agree lowering the frame rate is likely much more effective (and simpler) than snapshotting the game view. One issue I ran into with lowering the frame rate was the initial delay of waking up. When I dragged my finger on the screen, there would be a pause until the next frame came. This initial stall was worse the lower I set the targetFramerate. If the new input system could force the next frame to come immediately, that would be perfect.
     
  15. Noisecrime

    Noisecrime

    Joined:
    Apr 7, 2010
    Posts:
    1,488
    Its great to see this issue finally getting addressed.

    I'm a little confused by the approach though, but maybe i'm just not aware of the intricacies involved under the hood in Unity? For me whenever I've needed such a feature all I've wanted is to stop unity from rendering, but still maintain targetframerate for registering inputs and other events. I want to stop/pause rendering as that is the biggest drain, the culling, shadow generation, rendering of the scene etc.

    I looked into doing this myself on my projects, but I could never find a good and reliable method that wasn't overly complex to implement - both in my own code and coercing Unity to do what I wanted. So in the end I just shelved it.

    I find myself wondering why in your example targetSleepframerate is set to 1, I would have assumed 0 would be more desirable, but again perhaps there is something fundamental within Unity that requires this?

    As to your 'sleepAndWakeOnEvent' question I think I'd rather have it wait for the normal targetFrameRate to avoid weirdness like a very fast frame. Although most of the time i'm using deltaTime for framerate independence I'd still be a little concerned that getting a ultra fast frame might mess up some logic somewhere and might be hard to track down bugs.

    I guess If others favor waking immediately, then perhaps this needs to be provided as a choice/option that developers can choose in Project settings.


    As for use case I'd present a recent ( and ongoing) client app I did for QEPrize.
    Links to store - Android
    Links to store - iOS

    Its essentially a 3D modeling/design app where users can construct models/trophies from basic building blocks based on platonic solids. As such like many 3d modelling apps there are frequent and various periods of inaction by the user, yet the app keeps chugging along at 30/60 fps.

    In terms of inactivity you have several different scopes
    • Long inactive period - User is thinking about what to do next. Range: 2 seconds to infinity
    • Short inactive period - User is pressing buttons, but these actions happen between 1s - 2s intervals.
    • Very short inactive period - User is tapping to place primitives 0s - 1s intervals.
    The suggested solution would have to work with all these without glitches, delta time issues etc.

    One problem is that whenever the user taps to place a primitive the camera auto-adjusts to 'frame' the model and the newly placed primitive, so during this time I'd need to run at the targetFramerate. I guess I could just toggle sleepAndWakeOnEvent, though I feel being able to send a custom 'virtual' touch event would be nicer a solution?

    One area that concerns me though is that the user can save and load previous designs. Saving happens within a single frame, but loading is split across multiple frames in order to not lock up the app. There is also a hidden feature where loading is made to take even longer, where only a single primitive ( or more) is loaded per frame, in order to have the model 'build' in front of you eyes. This is currently used internally to generate video of designs, but we want to open this up to users in the future. Again I guess during the loading process i'd just disable sleepAndWakeOnEvent and everything should work ok?

    Anyway i'd be more than happy to look at retro-fitting this project with the proposed solution once you get an experimental build produced. I could even provide Unity the source if they wanted, though its a complex project and due to time constraints not the best code architecture.


    Finally one other big issue I had with the project was the directional light shadow casting. Its a big drain on the gpu, yet most of time the shadow never changes. It would be great to be able to re-use shadowmap texture. At various times I looked into trying to do this myself, but never made any real progress. I want to look at it again sometime since this was back in Unity 5.2 /5.4 and see if its possible now.
     
  16. greggtwep16

    greggtwep16

    Joined:
    Aug 17, 2012
    Posts:
    1,428
    It was a long time ago when I profiled but while preventing rendering helps a bit, don't underestimate all the other things going on under the hood (physics, scripts, etc.). They drain a lot of battery too.

    There have been responses since then and yes sleeping until woken by input is desired in some cases. At that previous point in time, the design was related to current behavior where the sleep time is 1/targetFramerate. Obviously dividing by zero isn't desired. The runtime method talked about since then should address this concern.

    Setting this at runtime avoids the problem of ever having interruptions super fast over and over. Your app will have its normal framerate (say 60fps) and it's up to you to set when to sleep and how long to sleep for. Upon input waking up the sleep Unity would resume the normal framerate and if you didn't care about the particular input you can set it back to sleep.
     
  17. Noisecrime

    Noisecrime

    Joined:
    Apr 7, 2010
    Posts:
    1,488
    True and in my case physics and scripts were not a worry, but how will this work with physics anyway? If you still had physics simulation going on why would you want to stop or reduce rendering updates, wouldn't that just look worse, even with interpolation? My memory is a bit fuzzy but reducing the framerate wont affect physics, it will still be updating on its own frequency and thus still doing the same amount of work regardless?


    Yeah this sounds like a good idea, though I still prefer the idea of being able to use event masks and being able to send a dummy event from my code when needed rather than turning some application.setting on/off.
     
  18. greggtwep16

    greggtwep16

    Joined:
    Aug 17, 2012
    Posts:
    1,428
    With physics or the other stuff it isn't about having things happening (just like with your rendering) it's about shutting off the Unity plumbing for rendering, physics, scripts, etc. that happen regardless even if everything is still. Obviously when you're sleeping it only makes sense if the scene became static and your trying to prevent Unity from doing anything as well, instead of still doing all of it's bookkeeping draining battery.

    Event masks were in the latest design. It's not an application setting it will be a method in their API.
     
  19. Elecman

    Elecman

    Joined:
    May 5, 2011
    Posts:
    1,298
    Without getting into technicalities at this moment, I would just like to say that I am very happy to see that this issue is finally being taken seriously.

    My app has very little frame change, probably only 2%, so I welcome any battery usage improvements.
     
  20. tswalk

    tswalk

    Joined:
    Jul 27, 2013
    Posts:
    1,103
    imo, I prefer:

    • int Application.targetFrameRate
    • int Application.targetSleepFrameRate
    • bool Application.sleepAndWakeOnEvent
    I think this would make more sense... i'm not so keen on the idea of having to come up with my own routines to determine the device per frame time, which can vary wildly. I also like having a way to 'trigger' sleep, so that I can control when it should be waiting to sleep.

    This would allow me so much more control over power usage.. as long as input events are captured. That I believe has been the big problem with controlling framerates.. you miss inputs.

    I actually created a B2B app with unity... and the biggest complaint from the client that I have not been able to truly address is power usage. The reason is that when I put in my own frame rate controls, inputs get missed.. they complain the app isn't responsive enough >.<

    So.. in summary, I've been using the TouchScript library, which is wonderful. If these updates to Unity API were implemented, I could hook its' touch events to trigger an Application.sleepAndWakeOnEvent state change. This would awesome sauce and candy land goodness.

    One question I have though, will we be able to set a type of delay timer for going "into" sleep mode.. which could be a float value? Or are you designing this into sleep so that it gets triggered when no changes to the display are happening?

    [edit]
    OH, also... could there be overrides on your sleepAndWakeOnEvent to accept a callback function? I was thinking about this because it would be nice to be able to optionally have this for either logging or analytics... something like:

    Code (CSharp):
    1.  
    2. Application.sleepAndWakeOnEvent(OnTriggeredEvent);
    3.  
    4.  
    5. private void OnTriggeredEvent(SleepAwakeEventArgs _event)
    6. {
    7.   if(_event.Sleep)
    8. {
    9.   Debug.Log("app is going to sleep");
    10. }
    11. if(_event.Awake)
    12. {
    13.   Debug.Log("app is being awoke");
    14. }
    15.  
    16. }

    ...AND, could these please be backported to 5.6x !!! PLEASE :D
     
    Last edited: Jul 13, 2017
  21. salmelo

    salmelo

    Joined:
    Nov 25, 2014
    Posts:
    4
    I just wanted to say, in regards to the types of input that should trigger a new frame / platforms this feature would make sense on, in addition to phones/tablets and maybe laptops, there's also handheld consoles. Maybe Wii U and Switch as well depending on how they're wireless screen stuff works internally, I don't know.
     
  22. Prodigga

    Prodigga

    Joined:
    Apr 13, 2011
    Posts:
    596
    Not suggesting that the 'feature' be removed, but can someone give me an example as to when I would want to set 'target sleep frame rate' to anything other than 0?

    I guess it is just in case we want to perform some 'game logic' (at 1 FPS in the Update loop) and 'wake the device up' again in case we need to? (return back to 30 FPS)?

    If so, it feels a little 'hacky'. Like, we have no other way to update the game except the Update function, so lets 'sleep' at 1FPS which'll let us do some processing and wake the device if necessary.

    I know I am not offering any solutions here, just raising concerns. I really want a battery preserving feature like this. :)
     
  23. Elecman

    Elecman

    Joined:
    May 5, 2011
    Posts:
    1,298
    Even better would be just not clearing the frame buffer and then manually calling Camera.Render()

    This will give you complete manual control. Of course the input has to be disconnected from the frame rate.
     
    _Daniel_ likes this.
  24. greggtwep16

    greggtwep16

    Joined:
    Aug 17, 2012
    Posts:
    1,428
    There are a lot of times where you want to set the framerate to something in between to save battery but still have some interactivity, but these can all be achieved today. In the new proposal as long as input is decoupled and can wake Unity up early at least in my cases you are correct that I'd always want to sleep forever until woken up. There are times where you want to save some battery but still have things like animations but you can accomplish that in the current API by just setting the framerate to 24 or whatever level is acceptable for your game.

    I agree the current way of setting it to 1 is hacky, that's why we're trying to get an API to do away with the hack.
     
  25. greggtwep16

    greggtwep16

    Joined:
    Aug 17, 2012
    Posts:
    1,428
    That only controls rendering not the full game loop. Battery is still wasted on all the other things that happen every frame.
     
  26. larku

    larku

    Joined:
    Mar 14, 2013
    Posts:
    1,411
    I can think of a number of thing Updating on screen timers/score. Other animated items that don't require the full framerate, perform game logic, etc

    As mentioned above, it's not just game logic, we may want to update some screen elements during "low framerate/sleep" mode.

    Fortunately it seems you should have no concern here since if you'd have the freedom to go 0 or X for your target framerate.

    Remember, this solution is presenting a way to detect user input disconnected from the update/render loop. If you choose a framerate of 0 the fact that you could choose a non 0 value should be of no concern :)
     
  27. Janxor

    Janxor

    Joined:
    Jul 19, 2017
    Posts:
    1
    I'm not like 100% in the topic because i am a new Unity "Developer" but i try to figure out how to stop the visible render (not the scripts) of the Gameobjects, and keep the canvas objects rendering. The moment i open the UI, (even if its an image which fills out the whole screen and its white) my drawcalls just suck so much performance.
    well you can just take a screenshot, disable all objects, put the screenshot under the UI , and if you close the UI, enable objects.... well you know thats stuff

    my idea: for UI based games you have like always static camera, what about you can just say like disable rendering for objects with tag "xy" and take the last render rendered for them to display.
    so if you get an event you can say "start render objects "xy" again, - do stuff- , stop render again and take last shot

    im not 100% into unity and how all this background works but is this possible ? i hope you get my idea, maybe you got another way to solve this idea, or if there is already another way to solve that (please gimme a hint how to solve it tho)
     
  28. petersvp

    petersvp

    Joined:
    Dec 20, 2013
    Posts:
    37
    GameMaker have a feature set_autimatic_draw() and screen_redraw(). With this in mind, why you just don't add thread-safe Application.autoRenderingEnabled, Application.RenderFrame() and a callback, Application.RenderScheduler that is always called once when autoRendering is disabled. The event will be C# function running in its own thread that calls Application.RenderFrame() when user manually wants to. (separate from Unity's render loop). This will require these precise sync methods to most likely be thread safe but will allow us to write our rendering scherulers that dynamically control the frame rate.

    Example for a RenderScheduler may be something like:

    Code (CSharp):
    1. void RenderScheduler(){
    2. while(!Application.autoRenderingEnabled)
    3. {
    4.     if(highFrequency)    Thread.sleep(1000/60);
    5.     else     Thread.sleep(1000/15);
    6.  
    7.     Application.RenderFrame();
    8. }
    9. }
     
  29. petersvp

    petersvp

    Joined:
    Dec 20, 2013
    Posts:
    37
    @Janxor, unfortunately Unity is extremely complex and your request is something that only you know how to do. There are too many variables, like alpha blending, and whatnow so this is just not possible, while my idea is far more reachable. You wither render everything or render nothing. Or, render something to texture then render this texture manually (using Camera's API)
     
  30. greggtwep16

    greggtwep16

    Joined:
    Aug 17, 2012
    Posts:
    1,428
    There are a couple of ways to stop rendering, even currently. As discussed before rendering is only a small subset of what Unity is doing every frame (physics, animations, bookkeeping, scripts, etc.). Currently, that is why lowering the framerate is much more effective at saving battery than only stopping rendering. That's why the proposal with new input system is to provide an API to slowdown/shutoff the whole game loop until woken up by input.
     
    larku likes this.
  31. badweasel

    badweasel

    Joined:
    Jan 11, 2015
    Posts:
    18
    I too am very interested in this. I have a game that is essentially a puzzle/board game but has good 3d graphics and shadows. When the user is just looking and thinking about what to do next, the screen really doesn't update. I have a timer that will click once per second. So what I'd like to see is some way to pause the screen updating (but as others have said still execute all the code). I'll track in my code when it's ok to do that. Once per second I'll unpause for a frame to update the timer text. And when they click and something start moving I'll unpause it and keep track of when it's time to repause it again.

    People have complained in the past about my game taking up too much battery. I had sort of hoped this type of optimization was built in to Unity. But I guess for most games it would never come up.

    I will say this. I'm ok with instead of it being a PAUSE rendering, it's a target fps. But I don't want it to be automatic. I want to control it. I know when it's ok to drop the frame rate down to 10fps or whatever. And when it needs to be 60fps again.
     
    _Daniel_ likes this.
  32. _Daniel_

    _Daniel_

    Joined:
    Feb 28, 2007
    Posts:
    2,616
    My 3D app runs way cooler than an empty scene simply by reducing the target FPS when there is no activity. You can optimize your game right now, no need to wait for an update.
     
  33. larku

    larku

    Joined:
    Mar 14, 2013
    Posts:
    1,411
    Agreed, many of us already do this - the issue is that the input is bound to the update frequency, as such you can get some nasty input delay if you put your FPS too low.
     
    _Daniel_ likes this.
  34. badweasel

    badweasel

    Joined:
    Jan 11, 2015
    Posts:
    18
    Yeah, I'm a bit of a noob in Unity. I started my port from Objective-C like 2-3 years ago and got sidetracked with.. you know.. needing to make a living. So here I am back at it. And I just found this in my code:

    Application.targetFrameRate = 60;

    So yeah it seems like I can just do it now. But what is safe to drop down to? 15? Thanks!!

    Or should I use:

    QualitySettings.vSyncCount = 4;
     
  35. _Daniel_

    _Daniel_

    Joined:
    Feb 28, 2007
    Posts:
    2,616
    Yes 60 FPS will heat up your computer. 30 will still look decent and be some cooler. 15 is way to low in my opinion, it would ruin user experience.
     
  36. greggtwep16

    greggtwep16

    Joined:
    Aug 17, 2012
    Posts:
    1,428
    There isn't a magic number you can ever quote, it all depends on what the apps requirements are. For VR 60 is pretty much the minimum and 90 preferred. For regular games most can get away with 30 maybe even 24 (what movies used to be). The requirements for an action game (where you want closer to 60) are going to be totally different than a trading card game (where at times you can set it to 1 or 10 as things get more static). When you go very low currently lets say 1 when the scene gets static though your input responsiveness is going to suffer (it will take up to 1 full second for that button press to respond). Whenever the new system comes out hopefully that is a thing of the past, so when your app is static you can halt the game loop but yet wake-up instantly when input is detected.

    You'll always want to test this out for your specific game and go with what makes sense for it.
     
  37. superpig

    superpig

    Quis aedificabit ipsos aedificatores? Unity Technologies

    Joined:
    Jan 16, 2011
    Posts:
    4,089
    Folks, just to be clear about something: this is not a feature we are actively working on right now.

    It's absolutely a problem we want to solve, and the first step to a solution is designing it - this thread has been very helpful in that regard. We broadly know how we will solve this problem when we solve it. But we've got other problems to solve too, and right now they're taking precedence over this one. We will get back to this one eventually, but it's not something we will be taking past the design stage in the immediate future.

    Sorry, I know this will be disappointing for you to hear. We felt it's better to be honest and not have anyone expecting to see this in 2017.3 or something like that.
     
    Garth-Smith, greggtwep16 and larku like this.
  38. larku

    larku

    Joined:
    Mar 14, 2013
    Posts:
    1,411
    Ah, thanks for the heads-up.

    Obviously it's not what we really wanted to hear, but it's a lot better than believing it's imminent when it's not :)
     
  39. Andrew_unity

    Andrew_unity

    Joined:
    Dec 18, 2015
    Posts:
    1
    What is it that Unity is doing when the applications are idle? When I test on iOS, the CPU is running at 40-80% (of a single core) and none of my code is running:

    http://answers.unity3d.com/questions/1298921/cpu-usage-always-high-on-all-types-of-iphone.html

    I can manually set the targetframerate to 1 when I know the code isn't running and CPU usage drops to around 5%. Then I put it back to 60 on input but it stutters before it gets back to 60FPS.

    It shouldn't need a way for developers to individually clamp the framerate or choose longer frames, the application shouldn't be using anywhere near that much CPU when none of the application developer's code is running.

    Unity should be processing the developer's code and update loops and drawing screen updates when objects have changed. When nothing needs to be drawn and code is idle, the CPU usage should be under 10%.

    When I debug the CPU performance, I get high CPU usage from the VSync code (WaitForTargetFPS), which I can disable on desktop with the quality options but doesn't make a difference on mobile. On iOS, the highest thread looks to be something called UnityGfxDeviceWorker. This is when nothing is changing in the UI.

    At 30FPS, my iPhone CPU idles at 20% with a blank screen, at 60FPS it's 40% (of 1 core). When there are static objects on screen, this jumps to as high as 80%. This is a crazy amount of CPU to be using when nothing is happening. Whatever those gfx threads are doing, they need to stop when there's nothing changing. It's not GPU usage, my tests show the GPU hardly doing anything, the CPU is getting choked on something.
     
    Last edited: Aug 28, 2017
    _Daniel_ likes this.
  40. greggtwep16

    greggtwep16

    Joined:
    Aug 17, 2012
    Posts:
    1,428
    Thanks for communicating this! I wish in other areas when timelines slipped that others would communicate early and not leave a surprise as well.
     
  41. _Daniel_

    _Daniel_

    Joined:
    Feb 28, 2007
    Posts:
    2,616
    Good research. It's fascinating how a completely empty/blank scene causes my computer to get hot and fans kick on. Luckily setting the target frame rate helps enormously in this regard.
     
  42. Noisecrime

    Noisecrime

    Joined:
    Apr 7, 2010
    Posts:
    1,488
    Having checked back into the thread as I have a potential project that could really benefit from ( and likely be essential to have) battery preservation as discussed, its really disappointing to hear this has been shelved for the foreseeable future. Was kinda hoping after almost 6 months it might have already been implemented or at least planned for release in the next few months.

    Has there been any new pushes on this feature since your post? Have there been any other features implemented in the meantime that might be usable in helping preserve battery life when running Unity?
     
  43. superpig

    superpig

    Quis aedificabit ipsos aedificatores? Unity Technologies

    Joined:
    Jan 16, 2011
    Posts:
    4,089
    Noisecrime likes this.
  44. Janoschii

    Janoschii

    Joined:
    Oct 15, 2014
    Posts:
    9
    +1 Here. It is really disappointing, if you optimize your code and the power consumption is still high cause of needles rendering. I did'nt get, why it is a problem to freeze the last frame and skip rendering on the following, somethink like:

    Application.FreezeRendering();
    Camera.FreezeRendering();
    Canvas.FreezeRendering();

    Then we could manage it by ourself.
    Is this really a problem? Why?
     
    _Daniel_ likes this.
  45. _Daniel_

    _Daniel_

    Joined:
    Feb 28, 2007
    Posts:
    2,616
    Yes, this would be awesome. My project needs this badly right now, it's suffering from Touch misses due to lowered frame rate. Without lowering the frame rate I get bad overheating. I'm between a rock and a hard place. In my opinion they need freeze the main app with just a single Input thread running at 60 FPS. The moment the Input thread detects a touch it wakes up the app and passes on the input. No one would ever know that the app was paused.
     
  46. greggtwep16

    greggtwep16

    Joined:
    Aug 17, 2012
    Posts:
    1,428
    You want to freeze more than rendering (physics, bookkeeping, animations, etc.). To really save battery you need to sleep for decent sized intervals from the CPUs perspective. But aside from needing to freeze more than rendering 100% agreed. Before this latest iteration was canned at least it was acknowledged by Unity. Maybe will see it in a year or two.
     
  47. Janoschii

    Janoschii

    Joined:
    Oct 15, 2014
    Posts:
    9
    @greggtwep16 You can manage disabling physics, animations etc. by code. But you can not stop rendering.
    For instance, if you have a freezed camera, you can simply disable the root gameObject to stop all these.
    I was asking only for a freeze feature, cause I believe it is more easily to include by the Unity Developers.
    @superpig Can you ask a developer that is in charge if a freezed camera or canvas feature can be done?


    Summary description:
    • a method that enables a freezed display of the last frame (whether it is canvas, camera or whatever is easy to implement)
    • we could then disable everything, that is eating the battery, for instance:
      • canvas component
      • gameObjects with physics etc.
    • if the user interacts, we could enable all the disabled things and start rendering

    Would be a good workaround for the most use cases and it does not depend on the input system. At the moment, I am afraid that we really have to wait 2 years, until we can solve the power consumption problem. It is hard to explain our customers, why this is still a problem after all the optimization we have done.
     
    Last edited: Feb 1, 2018
  48. RazaTech

    RazaTech

    Joined:
    Feb 27, 2015
    Posts:
    169
    Hello!
    Thanx for Making this Thread !!!

    It would be better to obey previous naming conventions, like "targetFrameRate"

    (B) If user is scrolling after swipe , frame rate will be decreased , it will not appropriate. ScrollRect.OnScroll should also interrupt the sleep.

    Thanx
     
  49. Player7

    Player7

    Joined:
    Oct 21, 2015
    Posts:
    1,139
    I must have missed this thread... hard to believe it isn't getting higher priority in implementation because it really should and be. Along with UGUI improvements.. provide a real Unity based app that implements far better battery usage while being much better than any sort of end user hacked solution of trying to improve battery life via lowering framerates.

    As I think many are coming to see Unity as somewhat viable framework for making just general apps that aren't games for mobile devices.. but it doesn't matter what homebrew and even elegant solution that tries to be smart about it that you do beceause it all involves lowering the framerate down to an absolute minimum and UNity's current input handling at that point is just shttt sadly.. I found the lowest was about 5fps otherwise any lower and the moment the end user provides some input there is that awful and very noticable delay in ramping up the framerate for whatever interaction is neded. I feel it's kinda pointless asking us what direction it should take as you're the guys who can try various implementations and find out what really does work and feel best for achieving better battery usage, while being seamless in fast responsiveness on input. The biggest area I find it very problem matic is anything that involves swipes.. and scrollling lists, but even just clicking on buttons from a low fps, sometimes just doesn't register at all.. unless there is multiple presses.. this is easily testable on your own end with whateveer implementations you do..

    Right now I don't even care how it's implemented and what sort of api things would need to be used.. it just needs something, anything, doing, like this year preferably :)
     
    Dave-Ruske and _Daniel_ like this.
  50. Obsurveyor

    Obsurveyor

    Joined:
    Nov 22, 2012
    Posts:
    239
    I wonder if the new tiny core runtime for small experiences will cover this. They talked about it in their Unity at GDC keynote and is supposed to be out in some form this year. I know I'm looking forward to something because I'm currently dealing with this. edit: It didn't actually work. Leaving for posterity though. Right now, I'm doing a hacky thing where I'm going to control when the camera is enabled for running animations combined with a 20-60 or lower target FPS(haven't really worked out what yet). That will allow responsive UI input and not drain the batteries so much on a phones. Still nowhere close to what a native app can achieve though.
     
    Last edited: May 12, 2018
    _Daniel_ likes this.