I'm using SharpDX 2.5.0 and I have a game class, and I try to disable the fixed time step, however it doesn't seem to work, I still get 59-60 FPS. I'm only drawing a utah teapot, so I'm pretty sure it must work with a lot more (like 1000) FPS. Here is what I do:
protected override void LoadContent()
{
// ...
// Disabling fix time step.
this.IsFixedTimeStep = false;
// ...
base.LoadContent();
}
Do I forget something? Do I have to apply this change somehow? Or am I doing it in the wrong place (I also tried doing it elsewhere without any success)? Thanks for the answers:
Muad'Dib
You need to disable both vsync and fixed timestep, try to add this to the game constructor:
// GraphicsDeviceManager is mandatory for a Toolkit Game
_graphicsDeviceManager = new GraphicsDeviceManager(this);
// disable vsync
_graphicsDeviceManager.SynchronizeWithVerticalRetrace = false;
// disable fixed timestep
this.IsFixedTimeStep = false;
Have you also tried disabling vsync? If vsync is enabled and your monitor is running at 60Hz (very likely) then you will also see this behaviour. I'm not sure about the Game class but I usually do it in the PresentationParameters when creating the device.
new PresentParameters(width, height) {
PresentationInterval = PresentInterval.Immediate
}
"Immediate" indicates that present will not wait for the monitor to refresh.
This is assuming D3D9, which version of DirectX are you using?
Related
As the title says, I'm trying to enable/disable VR between different applications, and I need to do it as many times as I want.
I'm using Unity 2017.4 and SteamVR 2.0.1. I'm trying to do it with two different scenes of the same project (testing one in the editor, and launching the other as .exe).
This solution is not working, since apparently Actions and Poses are not handled correctly when VR is stopped with XRSettings.enabled = false.
Did anyone experienced the same behaviour?
I tried to find a workaround:
1) Disabling/enabling also Player and Hands
...
// ** ENABLE VR **
if (enable)
{
print("Enabling VR ...");
XRSettings.LoadDeviceByName("OpenVR");
yield return null;
print("Loaded device: " + XRSettings.loadedDeviceName);
XRSettings.enabled = enable;
EnablePlayerAndHands(true);
}
// ** DISABLE VR **
else
{
print("Disabling VR ...");
EnablePlayerAndHands(false);
XRSettings.LoadDeviceByName("");
yield return null;
print("Loaded device: " + XRSettings.loadedDeviceName);
XRSettings.enabled = false;
}
...
2) Added these lines in the SteamVR.cs file:
private void Dispose(bool disposing)
{
...
// added code
SteamVR_Input.initialized = false;
SteamVR_Behaviour.instance = null;
}
(In order to make it work, I had to add a public setter for the SteamVR_Behaviour.instance property).
3) In SteamVR_Behaviour, I added a check inside Update(), LateUpdate() and FixedUpdate():
if (_instance != null) ... // do update
These modifications won't fix the problems actually, because I still have some exceptions when I enable back VR, for example:
GetPoseActionData error (/actions/default/in/SkeletonLeftHand): InvalidHandle handle: 1152990670760182193
UnityEngine.Debug:LogError(Object)
Valve.VR.SteamVR_Action_Pose:UpdateValue(SteamVR_Input_Sources, Boolean) (at Assets/SteamVR/Input/SteamVR_Action_Pose.cs:96)
Valve.VR.SteamVR_Action_Skeleton:UpdateValue(SteamVR_Input_Sources, Boolean) (at Assets/SteamVR/Input/SteamVR_Action_Skeleton.cs:75)
Valve.VR.SteamVR_Input:UpdateSkeletonActions(SteamVR_Input_Sources, Boolean) (at Assets/SteamVR/Input/SteamVR_Input.cs:487)
Valve.VR.SteamVR_Input:UpdateSkeletonActions(Boolean) (at Assets/SteamVR/Input/SteamVR_Input.cs:462)
Valve.VR.SteamVR_Input:LateUpdate() (at Assets/SteamVR/Input/SteamVR_Input.cs:352)
Valve.VR.SteamVR_Behaviour:LateUpdate() (at Assets/SteamVR/Scripts/SteamVR_Behaviour.cs:224)
...but they are raised just a few times and then they stop. It could be due to some bad timing. Btw, I put an Interactable gameobject inside the empty scene just to test if I could still interact with it after disabling/enabling, and it seems that I can.
Still, I would expect some easier and cleaner method to achieve my goal. Am I missing something obvious or is it a bug from SteamVR newest version?
Thanks in advance for any help.
Please see this link for reference
https://docs.unity3d.com/ScriptReference/XR.XRSettings-enabled.html
Stopping a VR session is not supported in GearVR, not sure about SteamVR
Since yesterday, my unity game is locked 30fps on an android device. Before it was like 150fps.. I disabled v-sync. This is the only script I added yesterday:
public static class SaveLoadProgress {
public static void Save()
{
LevelManager levelManager = GameObject.Find ("GameManager").GetComponent<LevelManager> ();
BinaryFormatter bf = new BinaryFormatter();
FileStream file = File.Create (Application.persistentDataPath + "/savedProgress.1912");
bf.Serialize(file, levelManager.levelReached);
file.Close();
}
public static void Load()
{
LevelManager levelManager = GameObject.Find ("GameManager").GetComponent<LevelManager> ();
if(File.Exists(Application.persistentDataPath + "/savedProgress.1912"))
{
BinaryFormatter bf = new BinaryFormatter();
FileStream file = File.Open(Application.persistentDataPath + "/savedProgress.1912", FileMode.Open);
levelManager.levelReached = (int)bf.Deserialize(file);
file.Close();
}
}
}
I don't this can be the problem.
I added this to the GameManager:
void Awake()
{
Application.targetFrameRate = -1;
QualitySettings.vSyncCount = 0;
}
The profiler shows this:
What should I do to unlock it from 30fps?
By default, Unity locks fps for specific values, according to the current platform. Documentation says that the default for Android is 30, which is used by most Android devices. Also it says:
The default targetFrameRate is a special value -1, which indicates that the game should render at the platform's default frame rate.
Which is 30 for mobile as it's said in the article.
Also, you can have as much fps as possible while running your game in editor, it maybe 150 or more, but it's really bad practice to have more than 60 (max value for iPhones and some Androids). If you have more than 60 fps you can't actually see the difference because device's display can't actually render more than 60 frames per second, but it takes battery and CPU resources and all those calculations (for extra 60+ fps) are useless and even bad.
To make your fps more than 30, you can set it for 60 as you are doing in your code:
Application.targetFrameRate = 60;
Also v-sync is mostly don't work on mobile, so you don't need to bother with this.
Not an answer but more of an extended comment to #vmchar's answer:
I disagree that VSync doesn't work on mobile. We had Application.targetFrameRate set to 60, however, we still had an issue with the CPU trashing the GPU. Setting VSync forces it to wait. Framerate went from https://imgur.com/a/lE0LedF to https://imgur.com/a/EPq6q7T.
Unity don't recommend using both at once though:
Application.targetFrameRate is a "soft" vsync and is useful to limit simulation rate without hardware vsync set (e.g. on servers). It is not desirable to use targegFrameRate with vSyncCount set, as CPU frame might drift and cause rendercommands to be scheduled later and miss next vsync.
VSync settings aren't respected in the Editor though, so you can still have issues there.
Full thread: https://forum.unity.com/threads/gfx-presentframe-taking-4x-as-long-but-only-for-intermittent-periods.538254
As stated in other answer, if Unity locks your framerate to 30 or something. Mine was locked at 30 FPS, Just add Application.targetFrameRate = 60; in your Start()method, or whenever you want to set the Framerate in the application lifetime.
void Start()
{
Application.targetFrameRate = 60;
}
If you have the Adaptive Performance Samsung Android package installed it will override any changes to Application.targetFrameRate.
If you want to keep the package installed then you will need to play with the settings. To access the settings: Edit > Project Settings > Adaptive Performance > Samsung (Android)
Unchecking everything removed the cap set by Adaptive Performance for me. You can then re-enable the settings you need from there.
This question already has an answer here:
monogame screen resolution is incorrect
(1 answer)
Closed 8 years ago.
I created a simple test app using MonoGame (version 3.2, last official at the time of writing), but I cannot make the app go fullscreen.
I found this code elsewhere:
protected override void Initialize()
{
graphics.IsFullScreen = true;
graphics.PreferredBackBufferWidth = GraphicsDevice.DisplayMode.Width;
graphics.PreferredBackBufferHeight = GraphicsDevice.DisplayMode.Height;
graphics.ApplyChanges();
Window.IsBorderless = true;
Window.Position = new Point(0, 0);
base.Initialize();
}
But the problem is that GraphicsDevice.DisplayMode is always returning a screen size of 800x600. Also, the GraphicsAdapter.Adapters collection only contains a single adapter, with a single supported display mode (800x600).
What could be the problem here? My current resolution is 1920x1080, and I get the same results if I connect two monitors as an extended desktop (which is my usual setup).
Update
At the end I simply added a reference to System.Windows.Forms and used:
graphics.IsFullScreen = true;
graphics.PreferredBackBufferWidth = System.Windows.Forms.Screen.PrimaryScreen.Bounds.Width;
graphics.PreferredBackBufferHeight = System.Windows.Forms.Screen.PrimaryScreen.Bounds.Height;
graphics.ApplyChanges();
I still wonder why MonoGame doesn't detect any adapters/screens properly.
Update 2 The issue was fixed in a non-official build (at the time of writing), as mentioned in this answer.
Try moving the graphics code to after the base.Initialize call - this is because the system hasn't initialized, and initializes to some default settings. Typically, we would want to be able to change the graphics during the course of the game (ie after initialization), in case the User changes any settings in-game.
Every time I run my game using integrated graphics card it works fine at 60 FPS. But sometimes it lags too much when there're a lot of particles on screen.
So I switched to Nvidia GeForce 640M, but framerate keeps at 30 instead of 60. I tried both Reach and HiDef but neither of them could fix the framerate problem. I also tried
this.TargetElapsedTime = TimeSpan.FromMilliseconds(15);
but FPS was still 30.
Also tried this but didn't work:
public Game1()
{
graphics = new GraphicsDeviceManager(this);
Content.RootDirectory = "Content";
graphics.PreparingDeviceSettings += new EventHandler<PreparingDeviceSettingsEventArgs>(graphics_PreparingDeviceSettings);
}
private void graphics_PreparingDeviceSettings(object sender, PreparingDeviceSettingsEventArgs e)
{
e.GraphicsDeviceInformation.PresentationParameters.MultiSampleCount = 4;
e.GraphicsDeviceInformation.PresentationParameters.PresentationInterval = PresentInterval.One;
}
What can I do to fix the framerate on Nvidia graphics card?
Have you tried changing the PresentationParameters.PresentationInterval?
If I recall correctly, if you set this to PresentInterval.One, it "pulls out all the stops" and tries to match the maximum refresh rate.
Been a while since I tinkered with XNA tho...
May have something to do with your vsync settings. Try the following
graphics.SynchronizeWithVerticalRetrace = false;
I've been playing around with IsFixedTimeStep and TargetElapsedTime but I'm unable to get an fps above the 30fps. This is in both the emulator and on my HTC HD7 phone.
I'm trying to get the World.Step() setting correct in Farseer too, but havent found a good setting for this.
If I want to get it running at 60fps what should the three settings (IsFixedTimeStep, TargetElapsedTime and World.Step) ideally be?
Thanks!
You can make your game run at 60fps as long as you are running a Mango Deployed App
the code below was lifted from: MSDN: Game at 60fps
game timer interval run at 60Hz
timer.UpdateInterval = TimeSpan.FromTicks(166667);
Create the event handler
public Game1()
{
graphics = new GraphicsDeviceManager(this);
graphics.PreparingDeviceSettings += new EventHandler<PreparingDeviceSettingsEventArgs>(graphics_PreparingDeviceSettings);
// Frame rate is 60 fps
TargetElapsedTime = TimeSpan.FromTicks(166667);
}
Then implement the handler
void graphics_PreparingDeviceSettings(object sender, PreparingDeviceSettingsEventArgs e)
{
e.GraphicsDeviceInformation.PresentationParameters.PresentationInterval = PresentInterval.One;
}