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.
- 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. - Add a mesh of the box in Unigine Editor. It is stored in the data/samples/common/meshes directory.
- Rename the node into box.
- Make sure that its coordinates are 0,0,0.
- 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.
When created, the world script contains the following functions by default:
/*
*/
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:
- Let's change the initial position and a direction of the player when the world is loaded.
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; }
- 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).
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; }
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. - 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.
#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:
#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;
}
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.