This page has been translated automatically.
Видеоуроки
Interface
Essentials
Advanced
Полезные советы
Программирование на C#
Принципы работы
Свойства (properties)
Компонентная Система
Рендер
Физика
Редактор UnigineEditor
Обзор интерфейса
Работа с ассетами
Настройки и предпочтения
Работа с проектами
Настройка параметров узла
Setting Up Materials
Setting Up Properties
Освещение
Landscape Tool
Sandworm (Experimental)
Использование инструментов редактора для конкретных задач
Extending Editor Functionality
Встроенные объекты
Nodes
Objects
Effects
Decals
Light Sources
Geodetics
World Objects
Sound Objects
Pathfinding Objects
Players
Программирование
Основы
Настройка среды разработки
Примеры использования
UnigineScript
C++
C#
Унифицированный язык шейдеров UUSL
File Formats
Rebuilding the Engine Tools
GUI
Двойная точность координат
API
Containers
Common Functionality
Controls-Related Classes
Engine-Related Classes
Filesystem Functionality
GUI-Related Classes
Math Functionality
Node-Related Classes
Objects-Related Classes
Networking Functionality
Pathfinding-Related Classes
Physics-Related Classes
Plugins-Related Classes
IG Plugin
CIGIConnector Plugin
Rendering-Related Classes
Работа с контентом
Оптимизация контента
Материалы
Art Samples
Tutorials
Внимание! Эта версия документация УСТАРЕЛА, поскольку относится к более ранней версии SDK! Пожалуйста, переключитесь на самую актуальную документацию для последней версии SDK.
Внимание! Эта версия документации описывает устаревшую версию SDK, которая больше не поддерживается! Пожалуйста, обновитесь до последней версии SDK.

2. Creating and Deleting Nodes at Runtime

<< RETURN TO THE PREVIOUS SECTION

Nodes can be created and deleted at runtime almost as easy as in the Editor. The basic set of actions is as follows:

  • Creation. To create a node we should declare a smart pointer for the type of the node we are going to create and call a constructor of the corresponding class providing construction parameters if necessary.
  • Deletion. To delete a node we simply call the deleteLater() method for the node we are going to remove.
Source code (C++)
// creating a node of the NodeType named nodename
<NodeType>Ptr nodename = <NodeType>::create(<construction_parameters>);
	
// removing the node
nodename.deleteLater();

Now let us illustrate the process of creating and deleting a node using a simple static mesh (ObjectMeshStatic) by both creating a box surface and loading a mesh from an asset as an example.

Source code (C++)
#include <UnigineObjects.h>
using namespace Unigine;

/* .. */
int AppWorldLogic::init() 
{
	// first, we're creating a mesh instance as it is required to call an ObjectMeshStatic constructor
	MeshPtr mesh = Mesh::create();

	// loading a mesh from an fbx model imported to the data/fbx/ folder using the Editor
	mesh->load("fbx/model.fbx/model.mesh");

	// creating a box surface with a given size to the mesh
	mesh->addBoxSurface("box_surface", Math::vec3(0.5f, 0.5f, 0.5f));

	//create an ObjectMeshStatic node
	ObjectMeshStaticPtr my_object = ObjectMeshStatic::create(mesh);

	// removing the node
	my_object.deleteLater();

	// clearing the mesh
	mesh.clear();

	return 1;
}

Additional information:

Project Progress#

In our project we are going to need some objects, so let us:

  • write an auxiliary method to create an ObjectMeshDynamic node (addMeshToScene),
  • write an auxiliary method to append some initial set of objects to our scene(initObjects),
  • store the list of nodes created at runtime in a Vector.

In the AppWorldLogic.h file, we include the UnigineObjects.h library to work with ObjectMeshDynamic class, define the scene objects vector and declare our methods: addMeshToScene and initObjects.

Source code (C++)
// AppWorldLogic.h

#include <UnigineObjects.h>

using namespace Unigine;

/* ... */

class AppWorldLogic : public WorldLogic {
	
public:

/* .. */

private:

/* .. */

	// auxiliary functions
	int addMeshToScene(const char *file_name, const char *mesh_name, const char *material_name, Math::Vec3 position);
	int initObjects();
	
/* .. */	
	
	// scene objects vector
	Vector<ObjectMeshDynamicPtr> Objects;
	
/* .. */	
};

In the AppWorldLogic.cpp file let us implement our methods and insert initObjects method into the AppWorldLogic::init() method. We are also going to do some cleanup (delete all created nodes) in the AppWorldLogic::shutdown() method.

Source code (C++)
// AppWorldLogic.cpp
/* .. */

/// method adding a Dynamic Mesh Object to the scene. 
/// if an empty filename is passed the method creates a default box; 
/// otherwise, loads a mesh-file with a given name.
int AppWorldLogic::addMeshToScene(const char *file_name, const char *mesh_name, const char *material_name, Math::Vec3 position)
{
	MeshPtr mesh = Mesh::create();
	ObjectMeshDynamicPtr omd;

	if (file_name){				// loading a mesh from a specified file
		if (!mesh->load(file_name))
		{
			Log::error("\nError opening .mesh file!\n");
			mesh.clear();
			
			return 0;
		}
		else omd = ObjectMeshDynamic::create(mesh);
	}
	else								//creating a default box
	{
		mesh->addBoxSurface("box_surface", Math::vec3(0.5f, 0.5f, 0.5f));

		omd = ObjectMeshDynamic::create(mesh);
	}
	
	// setting node material, name and transformation
	omd->setMaterial(material_name, "*");
	omd->setName(mesh_name);
	omd->setWorldPosition(position);

	// updating the list of scene objects
	Objects.append(omd);

	//reporting progress to the console
	Log::message("-> Object %s added to the scene.\n", mesh_name);

	// clearing the mesh
	mesh.clear();

	return 1;
}

/* .. */

/// method performing initialization of objects
int AppWorldLogic::initObjects()
{
	int index = 0;
	for (int x = 0; x < 2; x++)
	{
		for (int y = 0; y < 2; y++)
		{
			addMeshToScene(NULL, String::format("my_meshdynamic_%d", index), "mesh_base", Math::Vec3(x, y, 1.0f));
			index++;
		}
	}
	// reporting progress to the console
	Log::warning("Objects generation OK!\n\n");
	
	return 1;
}

/* .. */
	
int AppWorldLogic::init() 
{

	// creating objects
	initObjects();

/* .. */
	
	return 1;
}

/* .. */

int AppWorldLogic::shutdown() {
	
	// deleting all created nodes
	for(int i = 0; i < Objects.size(); i++)
	{
		// removing current node from the scene
		Objects[i].deleteLater();
	}
	
	// updating the list of scene objects
	Objects.clear();

	return 1;
}
/* .. */

Source Files

You can copy the code below and paste it to the corresponding source files of your project:

AppWorldLogic.h

Source code (C++)
#ifndef __APP_WORLD_LOGIC_H__
#define __APP_WORLD_LOGIC_H__

#include <UnigineLogic.h>
#include <UnigineStreams.h>
#include <UnigineObjects.h>

using namespace Unigine;

class AppWorldLogic : public WorldLogic {
	
public:
	AppWorldLogic();
	virtual ~AppWorldLogic();
	
	virtual int init();
	
	virtual int update();
	virtual int postUpdate();
	virtual int updatePhysics();
	
	virtual int shutdown();
	
	virtual int save(const StreamPtr &stream);
	virtual int restore(const StreamPtr &stream);
private:

	//auxiliary functions
	int addMeshToScene(const char *file_name, const char *mesh_name, const char *material_name, Math::Vec3 position);

	// initialization functions
	int initObjects();

	// scene objects vector
	Vector<ObjectMeshDynamicPtr> Objects;
};

#endif // __APP_WORLD_LOGIC_H__

AppWorldLogic.cpp

Source code (C++)
#include "AppWorldLogic.h"
// World logic, it takes effect only when the world is loaded.
// These methods are called right after corresponding world script's (UnigineScript) methods.
//-----------------------------------------------------------------------------------------------------------------------------
//---------------------------------------------- AUXILIARY FUNCTIONS AND METHODS ----------------------------------------------
//-----------------------------------------------------------------------------------------------------------------------------

/// method adding a Dynamic Mesh Object to the scene. If an empty filename is passed the method creates a default box; otherwise, loads a mesh-file with a given name.
int AppWorldLogic::addMeshToScene(const char *file_name, const char *mesh_name, const char *material_name, Math::Vec3 position)
{
	MeshPtr mesh = Mesh::create();
	ObjectMeshDynamicPtr omd;

	if (file_name) {				// loading a mesh from a specified file
		if (!mesh->load(file_name))
		{
			Log::error("\nError opening .mesh file!\n");
			mesh.clear();

			return 0;
		}
		else omd = ObjectMeshDynamic::create(mesh);
	}
	else																// creating a default box
	{
		mesh->addBoxSurface("box_surface", Math::vec3(0.5f));

		omd = ObjectMeshDynamic::create(mesh);
	}

	// setting node material, name and position
	omd->setMaterial(material_name, "*");
	omd->setName(mesh_name);
	omd->setWorldPosition(position);

	// updating the list of scene objects
	Objects.append(omd);

	// reporting progress to the console
	Log::message("-> Object %s added to the scene.\n", mesh_name);

	// clearing the mesh
	mesh.clear();

	return 1;

}
//-----------------------------------------------------------------------------------------------------------------------------
//---------------------------------------------- INITIALIZATION METHODS -------------------------------------------------------
//-----------------------------------------------------------------------------------------------------------------------------
/// method performing initialization of the set of 4 boxes
int AppWorldLogic::initObjects()
{
	int index = 0;

	for (int x = 0; x < 2; x++)
	{
		for (int y = 0; y < 2; y++)
		{
			addMeshToScene(NULL, String::format("my_meshdynamic_%d", index), "mesh_base", Math::Vec3(x, y, 1.0f));
			index++;
		}
	}

	// reporting progress to the console
	Log::warning("Objects generation OK!\n\n");

	return 1;
}
//-----------------------------------------------------------------------------------------------------------------------------
AppWorldLogic::AppWorldLogic() {

}

AppWorldLogic::~AppWorldLogic() {

}

int AppWorldLogic::init() {
	// Write here code to be called on world initialization: initialize resources for your world scene during the world start.

	// creating objects
	initObjects();

	return 1;
}

// start of the main loop
int AppWorldLogic::update() {
	// Write here code to be called before updating each render frame: specify all graphics-related functions you want to be called every frame while your application executes.

	return 1;
}

int AppWorldLogic::postUpdate() {
	// The engine calls this function before rendering each render frame: correct behavior after the state of the node has been updated.

	return 1;
}

int AppWorldLogic::updatePhysics() {
	// Write here code to be called before updating each physics frame: control physics in your application and put non-rendering calculations.
	// The engine calls updatePhysics() with the fixed rate (60 times per second by default) regardless of the FPS value.
	// WARNING: do not create, delete or change transformations of nodes here, because rendering is already in progress.

	return 1;
}
// end of the main loop

int AppWorldLogic::shutdown() {

	// deleting all created nodes
	for (int i = 0; i < Objects.size(); i++)
	{
		// removing current node from the scene
		Objects[i]->deleteLater();
	}

	// updating the list of scene objects
	Objects.clear();

	return 1;
}

int AppWorldLogic::save(const StreamPtr &stream) {
	// Write here code to be called when the world is saving its state (i.e. state_save is called): save custom user data to a file.

	UNIGINE_UNUSED(stream);
	return 1;
}

int AppWorldLogic::restore(const StreamPtr &stream) {
	// Write here code to be called when the world is restoring its state (i.e. state_restore is called): restore custom user data to a file here.

	UNIGINE_UNUSED(stream);
	return 1;
}


PROCEED TO THE NEXT SECTION >>

Last update: 24.11.2020
Build: ()