This page has been translated automatically.
Unigine Basics
1. Introduction
2. Managing Virtual Worlds
3. Preparing 3D Models
4. Materials
5. Cameras and Lighting
7. Making Cutscenes and Recording Videos
8. Preparing Your Project for Release
9. Physics
10. Optimization Basics
11. PROJECT2: First-Person Shooter
12. PROJECT3: Third-Person Cross-Country Arcade Racing Game
13. PROJECT4: VR Application With Simple Interaction

Working With Time (IFps)

Brief overview of the frame duration and separating the application logic from FPS. Making the fan rotation created via the Fan component smooth.

The application frame rate may vary (i.e. the update() method will be called more or less frequently) depending on the hardware. If we want a specific action to be performed at a certain frequency regardless of the frame rate (e.g. an indicator blinks once per second, etc.), then we must untie the application logic from the FPS. To do this, we can use the scaling multiplier (time in seconds taken to process the last frame) returned by the following methods:

  • Engine::getIFps() returns the inverse of the FPS value for your application.
  • Game::getIFps() returns the scaled inverse FPS value. This class is to be used when you want to speed up, slow down, or pause rendering, physics, or game logic.

To adjust the transformations, you can use the following code:

Source code (C++)
int AppWorldLogic::update() {
	
	// getting an inverse FPS value (the time in seconds it took to complete the last frame)
	float ifps = Game::getIFps();
	
	// moving the node up by 0.3 units every second instead of every frame
	node->worldTranslate(Math::Vec3(0.0f, 0.0f, 0.3f * ifps));

	return 1;
}

To perform some changes once in a certain period of time you can use the following code:

Source code (C++)
#include <UnigineGame.h>

// injecting Unigine namespace to the global namespace
using namespace Unigine;
// AppWorldLogic.cpp

	const float INTERVAL_DURATION = 5;		// interval duration
	float elapsed_time = INTERVAL_DURATION;	// current time left to make changes
	
/* .. */

int AppWorldLogic::update() {
	
	// getting an inverse FPS value (the time in seconds it took to complete the last frame)
	float ifps = Game::getIFps();

	// checking if it's time to make changes
	if (elapsed_time < 0.0f)
	{
		
		/* .. DO SOME CHANGES .. */

		// resetting elapsed time counter
		elapsed_time = INTERVAL_DURATION;
	}

	// decreasing elapsed time counter
	elapsed_time -= ifps;
	
	return 1;
}
/* .. */

Practice#

In our project the fan is still rotating at an indeterminate speed (by 10 degrees per frame, and frame time is an unstable value). Let's assume that we want to set the rotation speed in revolutions per second. This can be easily achieved by adding a multiplier into the existing code:

Fan.cpp
#include "Fan.h"
${#HL}$ #include <UnigineGame.h>${HL#}$
// registering the Fan component
REGISTER_COMPONENT(Fan);

// inject necessary namespaces
using namespace Unigine;
using namespace Math;

// component's update method called each frame
void Fan::update()
{
	// if the fan node is not assigned, do nothing
	if (!fan_node)
		return;
	// rotate the node with the specified speed
	fan_node->rotate(0, speed ${#HL}$ * Game::getIFps() ${HL#}$ , 0);
}

Now the blades rotate precisely at the specified speed regardless of the frame rate.

Last update: 2024-11-06
Build: ()