c# Xna turned off FixedTimeStep but still update calls max. 60 times - c#

Hi guys i just made a small Algorithm to display the fps to my screen.
frames_temp++;
frames_Time += (int)gameTime.ElapsedGameTime.TotalMilliseconds;
if (frames_Time >= 1000)
{
frames = frames_temp;
frames_temp = 0; frames_Time = 0;
}
this code snipped is located in the Update-method. The frame variable stores the actual value drawn to the screen(just posting that code, to make sure there is no fault, eventhough i checked it already).
Now the problem is that i can't turn off the IsFixedTimeStep. I set it to false inside the constructor, initialize and even the update-method but still the programm limits my fps to ~60. I either put in a for() query into my update-method running many million loops without frame-drops to make sure its not my cpu beeing too slow .Another thing i already tried is to use my own timeSpan and the systemtime to get the elapsed time between the calls of Update(), wich gives me kinda the same output. Now it is 99% sure that update only runs 60 times a second.
So why can't i call the Update-Method as often as possible as it should be when IsFixedTimeStep is false
Ty for replies

I believe that you problem is Vertical Syncing, this function of the graphics device is locking the frame rate to your monitor refresh rate. To solve this problem you need to turn off VSync (SynchronizeWithVerticalRetrace) in the GraphicsDeviceManager:
graphicsDeviceManager.SynchronizeWithVerticalRetrace = false;
graphicsDeviceManager.ApplyChanges();
graphicsDeviceManager is your game's GraphicsDeviceManager

If I recall correct fixed timestep = false results in the update being called before the draw method, not calling it as often as possible. Therefore you should check wheter Vsync or something else is limiting your application to 60fps.

Related

C# Console application: Console.Readkey() has odd initial skipping behaviour on high framerates

For the challenge and educational gain, i am currently trying to make a simple game in the console window. I use a very primitive "locked" framerate system as such:
using System.Threading;
// ...
static private void Main(string[] args)
{
AutoResetEvent autoEvent = new AutoResetEvent(false);
Timer timer = new Timer(Update);
timer.Change(0, GameSpeed);
autoEvent.WaitOne();
}
So, a timer ticks every GameSpeed miliseconds, and calls the method Update().
The way that i have understood input in the console window so far is as follows:
The console application has a "queue" where it stores any keyboard input as metadata + an instance of a ConsoleKey enum. The user can add to this queue at any time. If the user holds down, say A, it will add A every computer frame. That is, the actual fastest amount the computer can do, not the locked frames i am working with.
Calling Console.Readkey() will remove and return the first element on this list. Console.KeyAvailable returns a bool indicating whether the list is empty.
If GameSpeedis set to anything higher than 400 everything consistently works fine. The below image displays the results of some Console.WriteLine() debug messages that give the amount of keyboard inputs detected in this locked/custom frame, using the following code:
int counter = 0;
while (Console.KeyAvailable) { counter++; Console.ReadKey(true); }
Console.WriteLine(counter);
Results
I use only the A key. I hold it for some time, then release it again. The GameSpeed is set to 1000. As expected, the first frames give low numbers as i might start pressing half into the frame, and so too with the last frames, as i might release the A early.
Now, the exact same experiment but with a GameSpeed of only 200
As you can see, i've marked the places i begun pressing with yellow. It always, perfectly gets the first frame. But then theres either one, two, or three frames where it acts as if it has gotten no inputs, but then after those frames it's fine and gets around 7 inputs pr frame.
I recognize that you are not supposed to make games in the console window. It is not made for scenarios like this. That does not however eliminate the possibility that there is some specific, logical reason this happens, that i might be able to fix. So, concretely the question is: can anyone provide some knowledge / ideas of why this happens?
If computer specs are needed, just say so in the comments and i'll add them.
Edit:
I think i have found the cause of this error, and it is windows keyboard repeat delay. While you can change this in the control panel, i have searched the web and found no examples of how you would change it in a c# application. The question then boils down to: how do you change windows keyboard repeat delay?

How to get time since frame start in Unity for loading purposes

I am building a big world (1000+ game objects). It takes 2s on the device. I am doing it in the background (the world is hidden until fully loaded). I have figured out that I can maintain the FPS of the active scene by switching to coroutines and making yield return null;.
The main issue is when to fire yield return null;. If I do it too often, then it will slow down the loading. If I do it too rarely, it will reduce FPS on low-end devices.
My idea is simple to detect how much milliseconds have passed since the start of the frame and fire yield return null; just after I have spent for example 12ms (to leave some time to render everything else and maintain something near 60FPS).
However, I can not find an efficient way of getting the time since frame start? Unity should have something as the async loading of assets seems to consume just right time to maintain stable FPS.
DMGregory has given the great and right answer on GameDev StackExchange.
You can use and assign Time.time to some variable (example lastFrameTime) and in next frame check if Time.time - lastFrameTime > amountOfTimeToRefresh...
Or Time.delta time assign to lastFrameTime and do the same if...
and if that condition is true do whatever you want and reset lastFrameTime to 0
Hope it helps...

How to set target frame rate with Application.targetFrameRate to fix bad frame rate (vsync)

After noticing my game was quite jittery when building it to my iOS device I checked the profiler and found out that vsync was responsible. After a little of research I figured in order to resolve the jitteriness of my game I had to set the target frame rate to 60 as its value was set to 30 by default.
So in one of my scripts in attached to a gameObject in my gameplay scene I I included the code:
void Awake(){
Application.targetFrameRate = 60;
}
After building my app again I am not sure if this made a difference so I am posting this question to ask how to set the target frame rate correctly as my way seems to not be working...(maybe use qualitysettings.vsynccount although I am not sure if that is meant for iOS)
You don't need to worry about VSync "using" a lot of CPU in the profiler. I remember I was confused by this. VSync is not causing the performance issues you're having.
You can look at this link for a good explanation: http://answers.unity3d.com/questions/994225/vsync-decreases-performances.html
Also if for some reason you still want to disable VSync, you can do this by going to
Edit > ProjectSettings > Quality
and setting VSyncCount to Dont Sync
If you want to do this using code, I think the following statement also works:
QualitySettings.vSyncCount = 1;

c# console app - how to execute a function when a value not changed for x amount of time(repeating frame)

My main problem is, I'm coding a movement simulaltor for a game,
What I want to do is, to check if the character got stuck and its position is not changing.
So What I thought is something like this:
If Me.Location3D is the same for X Amount of time -> Me.SetLocation(Location3D.X = Location3D.X +1, Location3D.Y = Location3D.Y +1)
public void Pulse(float dt)
{
Skandia.Update();
Me = Skandia.Me;
if (Me == null)
{
return;
}
//This void repeats every frame of the game
//functions should take place below
}
If anyone got an idea how to check the elapsed time, that'd be great.
Sadly I havent found such a specific thing on stackoverflow yet, just saying cause the topic sound pretty general.
greetings
If you are working a game, you should use a main loop.
The solution is pretty simple.
Each time you get Inside this method, check the time elapsed between your actions.
You should read this link: https://msdn.microsoft.com/en-us/library/bb203873.aspx
Variable-Step Game Loops
A variable-step game calls its Update and Draw methods in a continuous loop without regard to the TargetElapsedTime. Setting Game.IsFixedTimeStep to false causes a Game to use a variable-step game loop.
Animation and Timing
For operations that require precise timing, such as animation, the type of game loop your game uses (fixed-step or variable-step) is important.
Using a fixed step allows game logic to use the TargetElapsedTime as its basic unit of time and assume that Update will be called at that interval. Using a variable step requires the game logic and animation code to be based on ElapsedGameTime to ensure smooth gameplay. Because the Update method is called immediately after the previous frame is drawn, the time between calls to Update can vary. Without taking the time between calls into account, the game would seem to speed up and slow down. The time elapsed between calls to the Update method is available in the Update method's gameTime parameter. You can reset the elapsed times by calling ResetElapsedTime.
When using a variable-step game loop, you should express rates—such as the distance a sprite moves—in game units per millisecond (ms). The amount a sprite moves in any given update can then be calculated as the rate of the sprite times the elapsed time. Using this approach to calculate the distance the sprite moved ensures that the sprite will move consistently if the speed of the game or computer varies.
I would usually comment with a short answer like this but I'm short 3 reputation.
My solution is just track it with a variable and reset when needed, in your case when character moves.
Double elapsedTimeInMS = 0;
private void YourTimer(object sender, EventArgs e)
{
//Every 10 ms
elapsedTimeInMS += 10;
}
private void btnClick(object sender, EventArgs e)
{
//In your case the character moves
MessageBox.Show(elapsedTimeInMS + "");
elapsedTimeInMS = 0;
}
After edit
You would need to implement a check in your timer to see if elapsed time isn't getting too high.

What's the best way to move a sprite faster than the update rate in a simple 2d game?

At the moment, I have a sprite that I have arbitrarily set to move 1 pixel per second. The code is basically this (The code isn't optimised at all, I could do it much nicer but it is the principle I am trying to solve first:):
private const long MOVEMENT_SPEED = 10000000; // Ticks in 1 second
private long movementTimeSpan = MOVEMENT_SPEED;
protected void PerformMovement(GameTime gameTime)
{
movementTimeSpan -= gameTime.ElapsedGameTime.Ticks;
if (movementTimeSpan <= 0)
{
// Do the movement of 1 pixel in here, and set movementTimeSpan back to MOVEMENT_SPEED
}
}
Perform movement is called in a loop as you'd expect, and it equates to updating around 10 times per second. So if I lower the MOVEMENT_SPEED, my sprite speeds up, but it never gets any faster than 10 pixels per second. For projectiles and other stuff I obviously want it to update much faster than this.
If I alter the movement to 2 pixels or more, it creates issues with calculating collisions and suchlike, but these might be possible to overcome.
The other alternative is to store x and y as a float rather than an int, and increase the values as a fraction of the number of elapsed ticks. I am not sure if this will create smooth movement or not as there still has to be some rounding involved.
So my question is, does anyone know the standard way?
Should I increase the amount to more than 1 pixel and update my collision detection to be recursive, should I store X,Y as floats and move as a % of elapsed time, or is there a 3rd better way of doing it?
The standard way is to not count down a timer to move, but instead the opposite:
private const float MOVEMENT_SPEED = 10.0f; //pixels per second
private float time;
protected void PerformMovement(GameTime gameTime)
{
time = (float)gameTime.ElapsedGameTime.TotalSeconds;
character.X += MOVEMENT_SPEED * time;
}
Make the movement based on the time elapsed. The reason floats are commonly used is to get the fractional value of motion. Fixed-point is another common fractional representation but uses ints instead.
As for collision, collision can be very tricky but in general you don't absolutely need to do it once per pixel of motion (as you suggested with recursion); that's overkill and will lead to terrible performance in no time. If you are currently having trouble with 2-pixel motion, I would reevaluate how you're doing your collisions. In general, it becomes problematic when you're moving very fast to the point of skipping over thin walls, or even passing over to the "wrong side" of a wall, depending on how your collision is set up. This is known as "tunnelling". There are many ways of solving this. Look here and scroll down to "Preventing Tunnelling". As the article states many people just cap their speed at a safe value. But another common method is to "step" through your algorithm in smaller time steps than is currently being passed in. For example, if the current elapsed time is 0.1, you could step by 0.01 within a loop and check each small step.
A way to do what you request, although not very recommended, is to increase your game's update frequency to a higher value than the usual 30 or 60 fps, but only draw to the screen every N frames. You can do it by just having your graphics engine ignore Draw calls until a count or timer reaches the desired value.
Of course, this solution should be avoided unless it is specifically desired, because performance can degrade quite fast as the number of updated elements increases.
For example, Proun (not an XNA game) uses this trick for exactly your reasons.
With the default of IsFixedTimeStep = true, XNA behaves in a similar fashion, skipping calls to Draw if Update takes too long.

Categories

Resources