UnigineEditor
Interface Overview
Assets Workflow
Settings and Preferences
Adjusting Node Parameters
Setting Up Materials
Setting Up Properties
Landscape Tool
Using Editor Tools for Specific Tasks
FAQ
Programming
Fundamentals
Setting Up Development Environment
Usage Examples
C++
C#
UUSL (Unified UNIGINE Shader Language)
File Formats
Rebuilding the Engine and Tools
GUI
Double Precision Coordinates
API
Containers
Common Functionality
Controls-Related Classes
Engine-Related Classes
Filesystem Functionality
GUI-Related Classes
Math Functionality
Node-Related Classes
Networking Functionality
Pathfinding-Related Classes
Physics-Related Classes
Plugins-Related Classes
CIGI Client Plugin
Rendering-Related Classes

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 primitive object (a box) from a script and add game logic to rotate it.

Step 1. Add The Primitive Object To The World

  1. Run the project with the loaded editor via the SDK Browser.

  2. On the Menu bar, choose Create -> Primitive -> Box to create a box object.

  3. In Create Box window that opens, specify the size of the box and click Ok.

  4. Click the left mouse button to place the box.

  5. On the Menu bar, click Windows -> Nodes or press N to open the Nodes window.

  6. Choose added node and rename it to box. Change the position to 0, 0, 1.

  7. On the Menu bar, click File -> Save world or press CTRL + S to save the world.

Step 2. Add Script Logic

There are two methods to add script to the object:

1 Method: By Editing the .cpp World Script File

To add logic that will rotate the box, you should modify the <your_project_name>.cpp world script file in a plain text editor.

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

  1. Open the project folder via the SDK Browser.

  2. Open <your_project_name>.cpp script file located in your data/<your_project_name> folder by using plain text editor.

    Source code (UnigineScript)
    #include <core/unigine.h>
    
    int init() {
    	PlayerSpectator camera = new PlayerSpectator();
    	camera.setPosition(Vec3(2.0f,0.0f,1.5f));
    	camera.setDirection(Vec3(-1.0f,0.0f,-0.5f));
    	engine.game.setPlayer(camera);
    									
    	return 1;
    }
    
    int shutdown() {
    	return 1;
    }
    
    int update() {
    	return 1;
    }

    The world script contains the following functions by default:

    • init() function is used to create objects and initialize all other necessary resources on the world load.
    • 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 unloaded.

    This part of init() function code creates a new free-flying game camera that collides with objects (but does not push or interact with them). Read more about engine functions.

    Source code (UnigineScript)
    // create a new spectator player
    PlayerSpectator camera = new PlayerSpectator();
    
    // turn it in the specified direction
    camera.setPosition(Vec3(2.0f,0.0f,1.5f));
    
    // place it in the specified point
    camera.setDirection(Vec3(-1.0f,0.0f,-0.5f));
    
    // set the player as default one
    engine.game.setPlayer(camera);
    Notice
    Comments were added to explain to you the meaning of each line of code.
  3. Add a variable to handle the required box node before the init() function.
    Warning
    We do NOT recommend you to create global variables for the real project.
    Source code (UnigineScript)
    Node box; // add a box node
    
    int init() {
    	/* ... */
    	}
  4. Put this code into the init() function to get the box node.
    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.
  5. Set the node transformation in the update() loop. Note that it is necessary 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)
    /* ... */
    
    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;
    }
    Thus, the resulting script is:
    Source code (UnigineScript)
    #include <core/unigine.h>
    						
    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;
    }
  6. Save all the changes in the <your_project_name>.cpp world script file.
  7. If you have already opened your project, open console by pressing the grave accent (`) key, placed under the ESC key.

  8. Type the command and press Enter to see the result.
    Source code
    world_reload

2 Method: By Using WorldExpression Objects

You can add the script to the box by using the WorldExpression object.

  1. On the Menu bar, choose Create -> World -> Expression to create the WorldExpression object.

  2. Click the left mouse button to place the box.

  3. On the Menu bar, click Windows -> Nodes or press N to open the Nodes window.

  4. Choose the added WorldExpression node and change the position to 1, -1, 0.5. Now you have the primitive box and the World Expression object on a plane.

  5. Choose the WorldExpression node and open the Expression tab.

  6. Put code into the Source field.
    Source code (UnigineScript)
    {
    	// get the WorldExpression node via its internal function
    	Node worldExpression = getNode();
    	
    	// 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 = worldExpression.getTransform() * rotateZ(angle);
    
    	// set new transformation to the node
    	worldExpression.setTransform(transform);
    }
    Warning
    Curly braces are mandatory!

    Other ways of attaching scripts to the World Expression object you can read here.

  7. Drag the box node with ALT button pressed to the worldExpression node in the Nodes hierarchy list.

    Now the box object is the child of the worldExpression object. It means that the box object inherits all expression transformations of the World Expression object.
    Notice
    All the objects that are children of the World Expression object inherit expression transformations.
    If the box node gets outside the viewing frustum, but the bounding box is still in the viewing frustum or the camera is inside this bounding box, the playback of the transformation sequence will continue.
  8. Close the Nodes window to see the result.

Last update: 2018-08-10