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

How do I run the game at a lower framerate?

Discussion in 'General Discussion' started by ManofDog, May 4, 2020.

  1. ManofDog

    ManofDog

    Joined:
    Nov 6, 2019
    Posts:
    9
    I'm going for a PS1 inspired look with my game and I want the framerate to stay around 25-30.

    I've tried using Application.targetFrameRate but no matter where I plug it, I still get smooth performance.
     
  2. Murgilod

    Murgilod

    Joined:
    Nov 12, 2013
    Posts:
    9,806
    Did you remember to disable vsync?
     
  3. ManofDog

    ManofDog

    Joined:
    Nov 6, 2019
    Posts:
    9
    I did that and it worked, but unfortunately, now my character is running through walls lol
     
  4. QFSW

    QFSW

    Joined:
    Mar 24, 2015
    Posts:
    2,905
    If your character is running through walls because you disabled vsync then your game has some much bigger fundamental issues
     
  5. IgnisIncendio

    IgnisIncendio

    Joined:
    Aug 16, 2017
    Posts:
    223
    Are you using Update or FixedUpdate to move your character? It should be FixedUpdate to be framerate independent.
     
  6. neginfinity

    neginfinity

    Joined:
    Jan 27, 2013
    Posts:
    13,337
    Access target framerate, assign desired value.
    https://docs.unity3d.com/ScriptReference/Application-targetFrameRate.html
    Do keep in mind that PS1 could do 50 or 60 fps. This wasn't common, however.

    FixedUpdate should ONLY be used for interacting with physics because it fires in bursts. You should never handle user input in there.
     
    angrypenguin and Ryiah like this.
  7. angrypenguin

    angrypenguin

    Joined:
    Dec 29, 2011
    Posts:
    15,519
    And there are better ways to make your code framerate independent in almost all cases.
     
  8. EternalAmbiguity

    EternalAmbiguity

    Joined:
    Dec 27, 2014
    Posts:
    3,144
    Suggestions? Been doing some stuff there that I didn't necessarily want to fire every frame (targeting higher than 60, so FixedUpdate would be less taxing than Update).

    InvokeRepeating?
     
  9. Billy4184

    Billy4184

    Joined:
    Jul 7, 2014
    Posts:
    5,984
    I would just use coroutines. Otherwise you'll mess things in unexpected ways just by changing the physics timestep for example.
     
    EternalAmbiguity likes this.
  10. QFSW

    QFSW

    Joined:
    Mar 24, 2015
    Posts:
    2,905
    I have a "ticker" class so that I can give it some behaviour to do at some given rate, then update that ticker inside of update. I have two modes for whether it needs to "catch up" on missed events or not.

    For example, say you set the rate to 10/s but the game freezes for 1s, once unfrozen does the ticker fire off 10 events or only 1? Sometimes you want to fire off all 10 so that you maintain the same rate, in other cases firing off 10 would be a waste of time and you only need the 1 (say your code is to update some UI somewhere)
     
  11. angrypenguin

    angrypenguin

    Joined:
    Dec 29, 2011
    Posts:
    15,519
    For being framerate independent, appropriate use of Time.deltaTime is almost always the way to go.

    That's not quite the same as being framerate independent. Suggestions for this are a bit different.

    Using an event based paradigm almost always means that I don't have to worry much further than that. Essentially, most components are only enabled when they need to be doing something, and most data is only updated when something relevant has changed. If the data does need to be constantly updated then it's probably related to something interactive and/or animated, in which case I probably want it updated every frame.

    For heavy / bulk data processing, I design to not use individual components in the first place. Basically I use the same approach as DOTS / ECS, and in the future will probably just change over to using DOTS because... well, why do it myself now?

    For stuff that just doesn't need to be re-done every frame, something like @QFSW's "Ticker" class would likely be my approach. That said, I don't recall ever having to actually implement it before, because after doing either of the above it's never been relevant to any of my game/sim scripts.
     
    EternalAmbiguity likes this.
  12. MDADigital

    MDADigital

    Joined:
    Apr 18, 2020
    Posts:
    2,198
    I always find it amusing when people optimize by not doing things every frame. I mean, if you miss the mark doing it every frame you will still miss the mark only doing it once a second for example.

    Only reason todo that is if you make sure two expensive operations are not done on the same frame thus helping not to miss the mark.
     
  13. QFSW

    QFSW

    Joined:
    Mar 24, 2015
    Posts:
    2,905
    That's only true for execution time, there's also garbage to worry about. If a function produces are large amount of garbage then running it at a lower rate is definitely an optimisation
     
  14. MDADigital

    MDADigital

    Joined:
    Apr 18, 2020
    Posts:
    2,198
    True but continues execution code should not allocate in my opionion. It's fine for user actions etc that can only happen seldom
     
  15. angrypenguin

    angrypenguin

    Joined:
    Dec 29, 2011
    Posts:
    15,519
    I thought all the stuff where you couldn't avoid allocation had alternatives now?
     
  16. Murgilod

    Murgilod

    Joined:
    Nov 12, 2013
    Posts:
    9,806
    Yeah, though there's loads of reasons you might want to make things not happen every frame, like if you need to do a lot of operations across a large series of things, content streaming considerations on lower-power devices, all sorts of things. In fact, a lot of these considerations are why Unity's ECS implementation in DOTS is a pretty big deal.
     
    EternalAmbiguity likes this.
  17. EternalAmbiguity

    EternalAmbiguity

    Joined:
    Dec 27, 2014
    Posts:
    3,144
    (Apologies for hijacking the thread)

    I definitely had not planned to change the physics timestep.

    I was hoping to avoid Update entirely actually. I know, I know, over optimizing.

    These are AI agents who have a few different behaviors and cycle through them. I was using a simple "busy" bool and then switch. There's no reason the rate couldn't be once or twice per second. There's no real need to catch up.

    I tried to engage with System.Timers.Timer, but quickly realized that doesn't run (some) Unity stuff, probably because it's on another thread (tried to do GameObject.Find and thought I was losing my mind).

    Events would probably be a good way to do it (or just calling a convoluted loop of methods), but I wanted at least SOME kind of recurring method to ensure I didn't get trapped in an "Action.Idling" stage somehow.

    It'd also be nice to employ a little jitter (how can Firefox recognize "jittery" but not "jitter?"), though I imagine that will happen automatically.
     
    Last edited: May 5, 2020
  18. angrypenguin

    angrypenguin

    Joined:
    Dec 29, 2011
    Posts:
    15,519
    I understand wanting to avoid it broadly speaking, but in the context of having a class that takes Unity's Update() calls and then propagates its own calls an as-needed basis you only need one Update() method. Removing a single Update() call isn't "optimisation". And if it's your only one then removing it seems like making life harder for yourself on a matter of principle.

    I wasn't saying you shouldn't do it, I was saying I haven't had to.
     
    EternalAmbiguity likes this.
  19. QFSW

    QFSW

    Joined:
    Mar 24, 2015
    Posts:
    2,905
    I can't imagine an update manager like @angrypenguin alluded to being slower than the alternatives (coroutine/invoke repeating)
     
    EternalAmbiguity likes this.
  20. EternalAmbiguity

    EternalAmbiguity

    Joined:
    Dec 27, 2014
    Posts:
    3,144
    I'm probably missing what you're saying, but the "issue" (in the most benign sense) is that that single call happens 60-??? times per second, as opposed to something that happens less often. Isn't that optimization?
     
  21. QFSW

    QFSW

    Joined:
    Mar 24, 2015
    Posts:
    2,905
    I think what he's saying isn't about repeated execution, but the non zero overhead of Update. What you can do is make an Update manager, where you essentially have one MB hooked into Unity's update system, then propagates that call to all of your "updatable entities" (which in my example would have been the ticker)

    Edit
    The overhead of one of these is nothing, but if you have a million items, then it stacks up and at that point could be considered an optimisation

    Or you could go full DOTS style, have a TickerController or whatnot that loops over every ticker and does the behaviour itself, really micro optimisations at this point though
     
  22. neginfinity

    neginfinity

    Joined:
    Jan 27, 2013
    Posts:
    13,337
    Calling a delegate creates garbage, because C# spawns an anonymous class. That's a language feature.
    ...
    I don't think you have alternatives for everything.

    You avoid updates in situation where you have a LOT of objects, because of overhead. The overhead is calling C# code from C++ part of the engine.
    If you create one object with update() and have that object call Pseudo-Update on thousands of objects, the "cross language call" overhead is gone.

    Also, I'd expect TargetFramerate to be sufficient for most cases when you need to limit framerate.
     
    EternalAmbiguity likes this.
  23. MDADigital

    MDADigital

    Joined:
    Apr 18, 2020
    Posts:
    2,198
    Only if that delegate uses a closure
     
  24. EternalAmbiguity

    EternalAmbiguity

    Joined:
    Dec 27, 2014
    Posts:
    3,144
    Ah, I think I see it a bit clearer now. I have no knowledge of the C++-C# integration (and associated overhead).

    Does that overhead persist for other recurrent methods in Unity (InvokeRepeating, Coroutines)? Where would I read about this (edit - found this but it doesn't talk about other methods)?
     
    Last edited: May 5, 2020
  25. MDADigital

    MDADigital

    Joined:
    Apr 18, 2020
    Posts:
    2,198
    Foobar(f => f.Amount) //No allocation
    Foobar(f => f.GetAmount(scopedOtherPlace)) //Allocation
     
  26. IgnisIncendio

    IgnisIncendio

    Joined:
    Aug 16, 2017
    Posts:
    223
    I never said to do user input in FixedUpdate (though if you're using the new Input System, there's an option to do that). I buffer inputs in Update and process them in FixedUpdate for physics-related things. A character moving is pretty much a physics thing, even if you're using CharacterController, IMO.
     
  27. neginfinity

    neginfinity

    Joined:
    Jan 27, 2013
    Posts:
    13,337
    That's the article. It does talk about other methods.
    See the example with virtual class.
     
  28. neginfinity

    neginfinity

    Joined:
    Jan 27, 2013
    Posts:
    13,337
    Read this article:
    https://docs.unity3d.com/ScriptReference/MonoBehaviour.FixedUpdate.html

    If you handle input in FixedUpdate, then in situation when your game is running at 200fps but your physics are running at 50fps (default), you'll be processing input at 50fps, and not 200.

    FixedUpdate should be used when you're implementing custom constraints, custom forces, anti-gravity, black hole bombs and the like. Not for input.
     
  29. angrypenguin

    angrypenguin

    Joined:
    Dec 29, 2011
    Posts:
    15,519
    In a technical sense, sure. But in a practical sense, no. If your game only has one Update() function then that is getting called once per frame. That's negligible. There will be no practical benefit to eliminating that one call.

    Even in a technical sense, though, even if you can find a "better" approach, what difference will it make to your game's exection time?

    If you have lots of things getting Update() called then reducing the number could indeed be an optimisation. Note that that the performance benefit might not actually come from cutting out the method call. It's likely to come from having an overall more efficient design in terms of how your CPU and memory work. And that's precisely what DOTS / ECS is about, too.

    Yep, though in my case I was assuming that the "ticker" and the "update manager" would be the same thing.
     
    Last edited: May 6, 2020
  30. angrypenguin

    angrypenguin

    Joined:
    Dec 29, 2011
    Posts:
    15,519
    True, but if your input has to control physics objects which are only getting updated at 50hz anyway it doesn't make any real difference. Buffering in Update() and then applying in FixedUpdate() seems reasonable there.
     
  31. neginfinity

    neginfinity

    Joined:
    Jan 27, 2013
    Posts:
    13,337
    There are objects controlled by player but not governed by physics. A good example is camera movement.
    -----
    Actually judging by documentation, by moving input handling into FixedUpdate in high fps situation, you should be losing portions of mouse movement, because:
    https://docs.unity3d.com/Manual/class-InputManager.html
    Zero mention of any sort of input buffering as well...
     
  32. angrypenguin

    angrypenguin

    Joined:
    Dec 29, 2011
    Posts:
    15,519
    Definitely. I wouldn't move that into FixedUpdate() for exactly that reason. You still have to know what you're doing, and design accordingly.

    I also wouldn't move all input responses into FixedUpdate() just because some of it was there. There's no reason not to have stuff like Cameras handled in Update() and physics objects handled in FixedUpdate().

    Indeed. If you need it you've got to do it yourself.

    Mind you, I haven't checked either of those things for the new Input System.
     
  33. EternalAmbiguity

    EternalAmbiguity

    Joined:
    Dec 27, 2014
    Posts:
    3,144
    It sounds like you're saying the definition of "optimization" requires a measurable performance difference. Good point.

    I've moved away from Unity for this now, but many moons ago I had a simulation where I processed up to 1,000,000 agents every timestep. In such a case it might have been useful.

    Maybe I'm dumb but I don't see anything about InvokeRepeating for example. Just today I've been using that (with Time.fixedDeltaTime as the increment) to move an agent for short little behaviors that it starts in Update().
     
  34. neginfinity

    neginfinity

    Joined:
    Jan 27, 2013
    Posts:
    13,337
    I would not use any method that calls a function by its name. It is unsafe, as calling by name does not support refactoring, and uses reflection to find the function you need, which is not necessarily fast.

    Regarding InvokeRepeating, the answer is "it is unknown whether the caller is on C++ or C# part of the engine". Use a profiler. The article, however, explains where common methods of monobehavior are being called from.
     
  35. EternalAmbiguity

    EternalAmbiguity

    Joined:
    Dec 27, 2014
    Posts:
    3,144
    Okay, thanks. I suspected reflection might be involved, but wasn't sure if that was compiled away somewhere. I'm probably trying to be too clever.