UnigineScript
The Language
Core Library
Engine Library
Node-Related Classes
GUI-Related Classes
Plugins Library
High-Level Systems
Samples
C++ API
API Reference
Integration Samples
Usage Examples
C++ Plugins
Content Creation
Materials
Unigine Material Library

Adding Scripts to the Project

Starting coding your project is simple with the use of UnigineScript language (no compilation is required).

For this tutorial we are going to get a ready-to-use object (a box) from a script and add game logic to rotate it.

Step 1. Create a New World

Let's start with the creating a world which will be handled by our script.

  1. Create a new world in Unigine Editor with the name new_world. By that, two files are automatically stored in the destination folder:

    new_world.world - world file in XML format that contains the list of nodes, general rendering settings and associated material libraries (though for now there are none).
    new_world.cpp - a world script file that handles main game logic and state.

  2. Add a mesh of the box in Unigine Editor. It is stored in the data/samples/common/meshes directory.

  3. Rename the node into box.
  4. Make sure that its coordinates are 0,0,0.
  5. Save the world.

Step 2. Add Script Logic

To add game logic that will rotate our box, we need to modify the world script file new_world.cpp in a plain text editor.

Notice
All .cpp and .h files that are stored in the data folder are UnigineScript scripts. They require no compilation, as they are interpreted by the engine itself during its initialization.

When created, the world script contains the following functions by default:

Source code (UnigineScript)
/*
 */
int init() {
	Player player = new PlayerSpectator();
	player.setDirection(vec3(0.755f,-1.0f,0.25f));
	engine.game.setPlayer(player);
	return 1;
}

/*
 */
int shutdown() {
	return 1;
}

/*
 */
int update() {
	return 1;
}
  • A new PlayerSpectator is created in a zero point via init() function. It is a free-flying camera that collides with objects (but does not push or interact with them). It faces a specified direction passed as a vector. Read more about engine functions.
  • update() function is used to code project logic and executed every frame.
  • shutdown() function is used to code project logic and executed when the world is closed.

Now we can start coding:

  1. Let's change the initial position and a direction of the player when the world is loaded.
    Source code (UnigineScript)
    int init() {
    
    	// create a new spectator player
    	PlayerSpectator player = new PlayerSpectator();
    	
    	// place it in the specified point
    	player.setPosition(vec3(3.5,0.0,1.3));
    	
    	// turn it in the specified direction
    	player.setDirection(vec3(-1.0,0.0,-0.3));
    	
    	// set the player as default one
    	engine.game.setPlayer(player);
    	
    	return 1;
    }
    
  2. To handle the required node, we need to add a variable. (Though, global variables are not recommended for the real project - you should create custom classes instead).
    Source code (UnigineScript)
    Node box; // add a box node
    
    int init() {
    	/* ... */
    	
    	// search the node by the specified name
    	int index = engine.editor.findNode("box");
    	
    	// get the node by its index
    	if(index != -1) {
    		box = engine.editor.getNode(index);
    	}
    	
    	return 1;
    }
    
    Notice
    Though nodes can be handled by any of the scripts (world, system or editor one) and Unigine Engine Editor (that loads and stores all the nodes from the world file), they should be owned only by one of them. Otherwise, such nodes can cause engine crash or memory leak problems.
    See Memory Management article for details.
  3. Now we can set the node transformation in the update loop. Note that we need to scale the rotation angle each frame with the frame duration (because it's different for each individual frame) to get constant angular velocity.
    Source code (UnigineScript)
    #include <unigine.h> // required, NULL is defined there
    
    /* ... */
    
    int update() {
    
    	// check whether the node exists
    	if(box != NULL) {
    		
    		// get the frame duration
    		float ifps = engine.game.getIFps();
    		
    		// set the angle of rotation
    		float angle = ifps * 90.0f;
    		
    		// get the current transformation of the node and apply rotation
    		mat4 transform = box.getTransform() * rotateZ(angle);
    		
    		// set new transformation to the node
    		box.setTransform(transform);
    	}
    	return 1;
    }
    

So the resulting script is:

Source code (UnigineScript)
#include <unigine.h> // required, NULL is defined there
	
Node box; // add a box node
	
int init() {

	// create a new spectator player
	PlayerSpectator player = new PlayerSpectator();
	
	// place it in the specified point
	player.setPosition(vec3(3.5,0.0,1.3));
	
	// turn it in the specified direction
	player.setDirection(vec3(-1.0,0.0,-0.3));
	
	// set the player as default one
	engine.game.setPlayer(player);
	
	// search the node by the specified name
	int index = engine.editor.findNode("box");
	
	// get the node by its index
	if(index != -1) {
		box = engine.editor.getNode(index);
	}		
	return 1;
}

int shutdown() {
	return 1;
}

int update() {

	// check whether the node exists
	if(box != NULL) {
		
		// get the frame duration
		float ifps = engine.game.getIFps();
		
		// set the angle of rotation
		float angle = ifps * 90.0f;
		
		// get the current transformation of the node and calculate rotation
		mat4 transform = box.getTransform() * rotateZ(angle);
		
		// set new transformation to the node
		box.setTransform(transform);
	}
	return 1;
}
Add your script by saving it.

Step 3. Quick Look at Your Project

Now when the script is added, lets take a quick look at what we've got. Load your world in the Unigine Editor to see the result.

Last update: 2017-07-03