UnigineEditor
Interface Overview
Assets Workflow
Settings and Preferences
Working With Projects
Adjusting Node Parameters
Setting Up Materials
Setting Up Properties
Landscape Tool
Using Editor Tools for Specific Tasks
Extending Editor Functionality
FAQ
Programming
Fundamentals
Setting Up Development Environment
Usage Examples
UnigineScript
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
Objects-Related Classes
Networking Functionality
Pathfinding-Related Classes
Physics-Related Classes
Plugins-Related Classes
Rendering-Related Classes

API Migration

Major Changes#

Breaking Changes#

More or less often our users have complained that our API (as well as memory management) is a bit complicated and requires some effort to use it safely. In UNIGINE 2.10, we have significantly refactored our API to make it simpler and safer, so you could concentrate on application logic.

We understand that the changes listed below may require quite a lot of code modifications to be made on your side. But this is the price we pay for stability (less crashes and memory leaks), convenience, thread safety, code readability, and overall development productivity in the future.

There were some changes introduced in UNIGINE 2.9, but the main migration case to 2.10 will most likely be from 2.8 and earlier versions. So this article is primarily focused on the major migration flow with additional info provided for users migrating from 2.9.

So, the changes…

C++ API#

Singletons#

Working with Engine’s singletons has become safer and simpler. Previously, to access their functionality, you would first type get() before specifying the desired method. This was not thread safe, as calling get() methods from several threads could potentially lead to initialization issues. Now the functionality of Engine’s singletons is accessed via static methods of the corresponding class, improving thread safety, as well as reducing the number of symbols and making your code look better:

Earlier Versions

Source code (C++)
float ifps = Game::get()->getIFps();

// ...
Physics::get()->setGravity(vec3(0.0f, 0.0f, -9.8f * 2.0f));
Physics::get()->setFrozenLinearVelocity(0.1f);

2.10

Source code (C++)
float ifps = Game::getIFps();

// ...
Physics::setGravity(vec3(0.0f, 0.0f, -9.8f * 2.0f));
Physics::setFrozenLinearVelocity(0.1f);

Please mind the following exceptions, that are operated as before via the get() method:

  • Engine class in C++ API (in C# it is also static).
  • Gui class as it may be both a singleton as well as not a singleton.

App Class Functionality#

The App class was previously used to control Unigine application (change window parameters, manage graphic context and keyboard/mouse events, etc.) as well as to create a custom user application by inheriting a new class from it.

To make the functions more distinct and manage them clearly, we‘ve split this functionality into two classes:

  • App class - used to control your application;
  • CustomApp class - used to create custom user applications via inheriting from it and implementing necessary functionality.

Refactored World and Editor Classes#

Historically node management (i.e. finding, adding, removing nodes, etc.) was performed by the Editor class, which was sometimes confusing for new users. For example, in order to be able to find a node by its name, you’d first have to add it to the Editor (even if you think you don’t actually use it).

To make node management process clearer we removed this functionality from the Editor class (it does not manage nodes anymore) and passed it to the World class, as you usually add nodes to a world and remove them from it.

So, now all new nodes are added to the current world, and you can find them via the corresponding method of the World class without any additional operations:

2.8 and Earlier Versions

Source code (C++)
// creating a player and setting its name
PlayerSpectatorPtr spectator = PlayerSpectator::create();
spectator->setName("my_player");


// adding the node to the Editor
spectator->release();
Editor::get()->addNode(spectator->getNode());

// trying to find our node by its name
NodePtr node = Editor::get()->getNodeByName("my_player");

// deleting a node with all its hierarchy
Editor::get()->removeNode(node);

// -------------------------------------------
// a case of managing nodes without the Editor
class SomeClass
{
public:
    SomeClass()
    {
        dummy = ObjectDummy::create();
        //...
    }

private:
    ObjectDummyPtr dummy;
    // ...
};

2.10

Source code (C++)
// creating a player and setting its name
PlayerSpectatorPtr spectator = PlayerSpectator::create();
spectator->setName("my_player");

// trying to find our node by its name
NodePtr node = World::getNodeByName("my_player");

// deleting a node with all its hierarchy
node.deleteLater();

// -------------------------------------------
// a case of managing nodes without the Editor
class SomeClass
{
public:
    SomeClass()
    {
        dummy = ObjectDummy::create();
        // ...
    }

    ~SomeClass()
    {
       // explicit deletion is required
        dummy.deleteLater();
        // ...
    }

private:
    ObjectDummyPtr dummy;
    // ...
};

2.9

Source code (C++)
// creating a player and setting its name
PlayerSpectatorPtr spectator = PlayerSpectator::create();
spectator->setName("my_player");

// trying to find our node by its name
NodePtr node = Editor::get()->getNodeByName("my_player");

// deleting a node with all its hierarchy
Editor::get()->removeNode(node);

2.10

Source code (C++)
// creating a player and setting its name
PlayerSpectatorPtr spectator = PlayerSpectator::create();
spectator->setName("my_player");

// trying to find our node by its name
NodePtr node = World::getNodeByName("my_player");

// deleting a node with all its hierarchy
node.deleteLater();

All methods related to node management were removed from the Editor class, with the following ones transferred to the World class:

Main Loop Changes#

The following stages of the Main Loop were renamed for better understanding:

  • render() -> postUpdate()
  • flush() -> updatePhysics()
  • destroy() -> destroyRenderResources()

New Smart Pointers#

UNIGINE’s smart pointers were significantly refactored in order to avoid dangling pointers, unexpected object deletions (e.g. when getting out of scope) as well as double deletions (in case an object has more than one owner) leading to crashes.

2.8 and Earlier Versions

Source code (C++)
Vector<PlayerPtr> players;

void createMyActor()
{
  PlayerActorPtr actor = PlayerActor::create();
  players.append(actor->getPlayer());

  // this pointer (in the players vector) will be bad after leaving the scope
}

void createMySpectator()
{
  PlayerSpectatorPtr spectator = PlayerSpectator::create();
  spectator->release();
  PlayerPtr player = spectator->getPlayer();
  player->grab();
  players.append(player);
  // this pointer (in the players vector) will be ok after leaving the scope
}

2.10

Source code (C++)
Vector<PlayerPtr> players;

void createMySpectator()
{
    players.append(PlayerSpectator::create());
}

void createMyActor()
{
    players.append(PlayerActor::create());
}

// all pointers in the players vector will be ok after leaving the scopes

UNIGINE’s smart pointers are based on reference counting. We can now divide all objects into two groups regarding the way their lifetime is managed:

  • ownership objects (Image, Texture, Mesh, Tileset, etc.) these objects are managed in accordance with reference counter, as it was before: the object is deleted as the counter reaches zero (if the object is owned by the pointer). In this case it is assumed that the object is no longer needed (the Engine doesn’t know anything about it, and the user has got no pointer to be able to use it) and, therefore, it is deleted. (e.g. such objects declared within a scope will be automatically deleted when leaving the scope).
  • non-ownership objects (Node, Widget, Material, Property, etc.) - these objects interact with the Engine and become managed by it since the moment of their creation (they are engaged in the main loop, can be retrieved by names, etc.). The lifetime of these objects is not determined by the reference counter, they provide the mechanism of weak references, so you can check whether an object was deleted or not. To delete such objects you should use deleteLater() or a corresponding manager’s method (e.g.: Materials::removeMaterial()).
Source code (C++)
NodePtr node1;
NodePtr node2;
init()
{
  node1 = World::getNodeByName("my_player");
  node2 = World::getNodeByName("my_player");
  node1.deleteLater();
}

void update()
{
  if (node2 == nullptr)
    Log::message("my_player is deleted"); // no dangling pointer
}

Instead of managing references for nodes manually, now you can simply choose lifetime management policy for it:

  • World-lifetime - in this case a node has the same lifetime as the world, and shall be deleted when the world is closed. This policy is used by default for each new node.
  • Engine-lifetime - in this case a node has the same lifetime as the Engine, and shall be deleted automatically on Engine shutdown (can be used for nodes that should be kept when changing worlds).
    Source code (C++)
    // loading a node from a file (by default its lifetime is the same as the lifetime of the current world)
    NodePtr node = World::loadNode("mynode.node");
    
    // changing node's lifetime to Engine to prevent its deletion when changing worlds
    node->setLifetime(Node::LIFETIME_ENGINE);

Lifetime of each node in the hierarchy is defined by its root (either parent or possessor). Setting lifetime management type for a child node different from the one set for the root has no effect.

Deleting Objects#

Objects can be deleted via one of the following methods:

  • deleteLater() - performs delayed deletion, in this case the object will be deleted during the next swap stage of the main loop (rendering of the object ceases immediately, but it still exists in memory for a while, so you can get it from its parent, for example). This method simplifies object deletion from a secondary thread, so you can call it and forget about the details, letting the Engine take control over the process of deletion, which can be used for future optimizations;
  • deleteForce() - performs immediate deletion, which might be necessary in some cases. Calling this method for main-loop-dependent objects (e.g., nodes) is safe only when performed from the Main thread.

Both these methods can be safely called more than once for a single object (as well as after an object has been deleted by the Engine) without causing a double deletion. So, no worries, call it whenever an object is no longer needed.

Notice
Although these two methods are available for all objects, they were not actually designed for ownership ones, as the major use case for them is counter-based lifetime management.
Multithreading#

Thread safety is ensured by synchronization of all Engine’s threads dealing with main-loop-dependent objects with Engine::swap(), where delayed deletion of objects is performed. But user threads can be executed in parallel with Engine::swap() in the main thread, in such cases you shouldn’t perform any manipulations with main-loop dependent objects (such as nodes) during Engine::swap().

Previous Ptr implementation had a non-atomic reference counter. So, modifying it from parallel threads might lead to a race condition (e.g. transferring a Ptr<Node> to another thread and then making manipulations with it, while doing the same in the main thread might end up in a crash due to unexpected object deletion). Now reference counters have become atomic.

Upcasting and Downcasting#

Upcasting (i.e. converting from a pointer-to-derived to a pointer-to-base) has become automatic, previously you would have to use the corresponding method of the derived class (e.g. getPlayer(), getWidget(), getObject(), etc.).

Earlier Versions

Source code (C++)
PlayerPersecutorPtr player = PlayerPersecutor::create();
Game::get()->setPlayer(player->getPlayer());

// ------------
gui->addChild(widget_button->getWidget(), Gui::ALIGN_OVERLAP | Gui::ALIGN_FIXED);

// ------------
ObjectMeshDynamicPtr OMD;
BodyRigidPtr body = BodyRigid::create(OMD->getObject());
body->addShape(ShapeBox::create(size)->getShape(), translate(vec3(0.0f)));

2.10

Source code (C++)
PlayerPersecutorPtr player = PlayerPersecutor::create();
Game::setPlayer(player);

// ------------
gui->addChild(widget_button, Gui::ALIGN_OVERLAP | Gui::ALIGN_FIXED);

// ------------
ObjectMeshDynamicPtr OMD;
BodyRigidPtr body = BodyRigid::create(OMD);
body->addShape(ShapeBox::create(size), translate(vec3(0.0f)));

Downcasting (i.e. converting from a pointer-to-base to a pointer-to-derived) performed earlier via cast() methods of derived classes was pretty ambiguous, it was not clear if it is a static or dynamic cast, with type checking performed in certain cases and sometimes without them. To eliminate ambiguity and make casting semantics clear and more C++ style, all ambiguous cast() methods of derived classes were removed while the following methods were introduced:

  • checked_ptr_cast - downcasting with automatic type checking performed (recommended)
  • static_ptr_cast - static casting without any checks (in accordance with C++ semantics)
  • dynamic_ptr_cast - dynamic casting (in accordance with C++ semantics)

Downcasting can be used, for example, when we have a NodePtr value (e.g., returned by World::getNodeByName()), which is a pointer to the base class, and want to perform operations with a certain object (e.g., a Player):

Earlier Versions

Source code (C++)
PlayerPtr camera= Player::cast(Editor::getNodeByName("main_camera"));
camera->setFov(60.0f);

if(stream->getType() == Stream::FILE)
    FilePtr file = File::cast(stream);

2.10

Source code (C++)
PlayerPtr camera = checked_ptr_cast<Player>(World::getNodeByName("main_camera"));
camera->setFov(60.0f);

if(stream->getType() == Stream::FILE)
    FilePtr file = static_ptr_cast<File>(stream);

A single wrapper-interface is now created for each object (upon the first request):

Source code (C++)
NodePtr node1 = World::getNodeByName("my_player");
NodePtr node2 = World::getNodeByName("my_player");
assert(node1.get() == node2.get());

The code above in UNIGINE 2.9 and earlier versions would create two wrapper-interfaces having different addresses. So, now the number of allocations has reduced. Type casting can be properly implemented, and we can work with raw pointers normally - cast them, compare, etc.

Pointers now support nullptr assignment, making the code more C++ idiomatic:

Earlier Versions 2.10
Source code (C++)
void foo(PlayerPtr);
foo(PlayerPtr());
Source code (C++)
void foo(PlayerPtr);
foo(nullptr);

Nodes Changes#

Apart from setting lifetime management policy, you can also choose for each node whether it should be displayed in the Editor’s hierarchy or saved to a *.world file by simply setting the corresponding flags: ShowInEditorEnabled (instead of calling Editor::addNode(node, is_runtime)) and SaveToWorldEnabled (instead of setting is_runtime = 0). By default both these options are disabled.

2.8 and Earlier Versions

Source code (C++)
// create a static mesh
ObjectMeshStaticPtr mesh = ObjectMeshStatic::create("my_mesh.mesh");

// assign a material to the mesh
mesh->setMaterial("mesh_base","*");

// adding the node to the Editor to display it in the World Hierarchy
// and setting is_runtime = 0 to enable saving the node to a .world file
mesh->release();
Editor::get()->addNode(mesh->getNode(), 0);

// change the node name
mesh->setName("my_node");
// change node transformation
mesh->setWorldTransform(translate(Vec3(0.0f, 0.0f, 2.0f)));

// save node changes in the .world file
Console::get()->run("world_save");

// delete the static mesh node
Editor::get()->removeNode(mesh->getNode());

2.10

Source code (C++)
// create a static mesh
ObjectMeshStaticPtr mesh = ObjectMeshStatic::create("my_mesh.mesh");

// assign a material to the mesh
mesh->setMaterial("mesh_base","*");

// enable saving the node to a .world file
mesh->setSaveToWorldEnabled(true);

// enable showing the node in the Editor’s World Hierarchy
mesh->setShowInEditor(true);

// change the node name
mesh->setName("my_node");
// change node transformation
mesh->setWorldTransform(translate(Vec3(0.0f, 0.0f, 2.0f)));

// save node changes in the .world file
Console::run("world_save");

// delete the static mesh node
mesh.deleteLater();

2.9

Source code (C++)
// create a static mesh
ObjectMeshStaticPtr mesh = ObjectMeshStatic::create("my_mesh.mesh");

// assign a material to the mesh
mesh->setMaterial("mesh_base","*");

// releasing the node (as it was added with is_runtime = 1 on creation)
// and adding it to the Editor again with is_runtime = 0 to display it
// in the World Hierarchy and enable saving the node to a .world file
Editor::get()->releaseNode(mesh->getNode());
Editor::get()->addNode(mesh->getNode(), 0);

// change the node name
mesh->setName("my_node");
// change node transformation
mesh->setWorldTransform(translate(Vec3(0.0f, 0.0f, 2.0f)));

// save node changes in the .world file
Console::get()->run("world_save");

// delete the static mesh node
Editor::get()->removeNode(mesh->getNode());

2.10

Source code (C++)
// create a static mesh
ObjectMeshStaticPtr mesh = ObjectMeshStatic::create("my_mesh.mesh");

// assign a material to the mesh
mesh->setMaterial("mesh_base","*");

// enable saving the node to a .world file
mesh->setSaveToWorldEnabled(true);

// enable showing the node in the Editor’s World Hierarchy
mesh->setShowInEditor(true);

// change the node name
mesh->setName("my_node");
// change node transformation
mesh->setWorldTransform(translate(Vec3(0.0f, 0.0f, 2.0f)));

// save node changes in the .world file
Console::run("world_save");

// delete the static mesh node
mesh.deleteLater();

Dealing With Hierarchies#

Earlier deleting a root of the hierarchy didn’t affect children, leading to memory leaks. So, in order to remove large hierarchies of objects (e.g., created via World::loadNode()) or widgets, you had to either manually delete all children recursively, or use the Editor class (in case of nodes).

Now, all child nodes and widgets are deleted automatically when deleting their parent, so you don’t have to manage hierarchies manually. Moreover, all created widgets are automatically deleted on Engine’s shutdown, so there will be no more annoying messages about widgets and related memory leaks.

2.8 and Earlier Versions

Source code (C++)
// ------------------- NODES -------------------------------------

// loading a node from a file and passing it to the Editor
NodePtr node = World::get()->loadNode("my_node.node");
node->release(); 
Editor::get()->addNode(node);

// deleting a node with all its hierarchy
Editor::get()->removeNode(node);

// ------------------- WIDGETS -------------------------------------
// creating widgets
gui = Gui::get();
label = WidgetLabel::create(gui);
button = WidgetButton::create(gui, "BUTTON");
label->setPosition(10, 10);
button->setPosition(10, 240);

gui->addChild(label->getWidget(), Gui::ALIGN_OVERLAP | Gui::ALIGN_FIXED);
gui->addChild(button->getWidget(), Gui::ALIGN_OVERLAP | Gui::ALIGN_FIXED);

// removing widgets
button.clear();
editline.clear();
window.clear();

2.10

Source code (C++)
// ------------------- NODES -------------------------------------
// loading a node from a file
NodePtr node = World::loadNode("my_node.node");

// deleting a node with all its hierarchy
node.deleteLater();

// ------------------- WIDGETS -------------------------------------
// creating widgets
gui = Gui::get();
label = WidgetLabel::create(gui);
button = WidgetButton::create(gui, "BUTTON");
label->setPosition(10, 10);
button->setPosition(10, 240);

gui->addChild(label, Gui::ALIGN_OVERLAP | Gui::ALIGN_FIXED);
gui->addChild(button, Gui::ALIGN_OVERLAP | Gui::ALIGN_FIXED);

// all widgets are removed automatically

2.9

Source code (C++)
// ------------------- NODES -------------------------------------

// loading a node from a file
NodePtr node = World::get()->loadNode("my_node.node");

// deleting a node with all its hierarchy
Editor::get()->removeNode(node);

// ------------------- WIDGETS -------------------------------------
// creating widgets
gui = Gui::get();
label = WidgetLabel::create(gui);
button = WidgetButton::create(gui, "BUTTON");
label->setPosition(10, 10);
button->setPosition(10, 240);

gui->addChild(label->getWidget(), Gui::ALIGN_OVERLAP | Gui::ALIGN_FIXED);
gui->addChild(button->getWidget(), Gui::ALIGN_OVERLAP | Gui::ALIGN_FIXED);

// removing widgets
button.clear();
editline.clear();
window.clear();

2.10

Source code (C++)
// ------------------- NODES -------------------------------------
// loading a node from a file
NodePtr node = World::loadNode("my_node.node");

// deleting a node with all its hierarchy
node.deleteLater();


// ------------------- WIDGETS -------------------------------------
// creating widgets
gui = Gui::get();
label = WidgetLabel::create(gui);
button = WidgetButton::create(gui, "BUTTON");
label->setPosition(10, 10);
button->setPosition(10, 240);

gui->addChild(label, Gui::ALIGN_OVERLAP | Gui::ALIGN_FIXED);
gui->addChild(button, Gui::ALIGN_OVERLAP | Gui::ALIGN_FIXED);

// all widgets are removed automatically

Multithreading Changes#

A set of new classes and functions were added to improve synchronization in multithreaded applications:

  • Added a set of atomic functions: AtomicCAS(), AtomicAdd(), AtomicSet(), and AtomicGet().
  • Implemented exponential backoff mechanism for the SpinLock reducing the impact on CPU performance.
  • Added a new Mutex class representing a simple mutex, based on atomic CAS and wrapping volatile int.
  • AtomicLock operating with volatile int was replaced with the ScopedLock, based on the new simple mutex (Mutex).
  • Added an RWMutex with write-preferred locking along with a couple of scoped locks for it (ScopedReaderLock and ScopedWriterLock).
  • Added a new Atomic<T> class enabling to read and write the value atomically.
  • Added a new ReentrantMutex, enabling a mutex to be locked multiple times by the same thread, without causing a deadlock along with a ScopedReentrantLock for it.

Plugins-Related Changes#

All engine plugins are now in the Unigine::Plugins namespace. Naming for header files of all plugins has changed:

Earlier Versions 2.10
plugins/PluginInterface.h plugins/UniginePlugin.h

Pointers to plugin interfaces can now be easily taken via the new Engine::getPlugin() method. Moreover, main classes of all plugins now have a static get() method that returns a pointer to the plugin interface. So, you don't have to get the interface via Engine::getPluginData() anymore.

Source code (C++)
// get plugin interface pointer and call a method
PluginClass *interface = Engine::get()->getPlugin<PluginClass>("PluginName");
interface->pluginMethod();

// or call plugin's method like this
Unigine::Plugins::PluginClass::get()->pluginMethod();

Earlier Versions

Source code (C++)
#include <plugins/LeapMotionInterface.h>
int init()
{
	// find LeapMotion plugin index
	int index = Engine::get()->findPlugin("LeapMotion");
	if (index == -1)
	{
		Log::error("LeapMotion isn't loaded!\n");
		return 1;
	}

	// get the LeapMotion interface
	leapmotion = (LeapMotionInterface*)Engine::get()->getPluginData(index);
	int images_count = leapmotion->getNumImages();

	return 1;
}

2.10

Source code (C++)
#include <plugins/UnigineLeapMotion.h>

int init()
{
	// get a pointer to the LeapMotion interface
	auto *leapmotion = Unigine::Plugins::LeapMotion::get();

	// if the plugin is loaded
	if (leapmotion)
	{
		int images_count = leapmotion->getNumImages();
		// ...
	}

	return 1;
}

Other Changes#

Stronger typing promotes safer and more expressive code. So, we‘ve extended the use of enums and bool values instead of int values in C++ API.

Public API implementation of UnigineBounds is now the same as the internal one eliminating divergence.

Code Migration Guide#

Warning
The changes described above will result in multiple crashes and run-time errors in almost any project based on previous SDKs.

The following workflow is recommended when migrating the code base of your projects to the new API:

  • Replace all calls to methods of Engine’s singleton classes via the get() method with static ones (except for the Engine class in C++ API and the Gui class):

    Earlier Versions

    Source code (C++)
    float ifps = Game::get()->getIFps();
    Physics::get()->setFrozenLinearVelocity(0.1f);
    MaterialPtr mesh_base = Materials::get()->findBaseMaterial("mesh_base");
    // ...

    2.10

    Source code (C++)
    float ifps = Game::getIFps();
    Physics::setFrozenLinearVelocity(0.1f);
    MaterialPtr mesh_base = Materials::findBaseMaterial("mesh_base");
    // ...
  • Replace all cast() methods of derived classes used for downcasting with the ones described above (checked, static, or dynamic).
  • Remove all upcasting methods (e.g. getPlayer(), getWidget(), getObject(), etc.).
  • Rename Main-Loop-related methods render(), flush(), and destroy() to postUpdate(), updatePhysics(), and destroyRenderResources() respectively.
  • Replace int values returned and accepted by methods with enums and bool values where necessary.
  • If you’re creating a custom user application, change the base class for your custom class to the CustomApp class, instead of the App.
  • Get rid of all grab() and release() methods. The isOwner() method is unlikely to be useful either.
  • You don't need the addNode() method of the Editor class anymore since all nodes are added to the world when created.
  • Don't use the Editor's removeNode() and destroy(node). Instead, it's recommended to remove nodes via the deleteLater() method of the Ptr class.

C# API#

C++ API changes described above made it possible to improve C# API as well, avoiding dangling pointers, unexpected object deletions and double deletions. In addition to these changes, we've made a set of C#-specific ones aimed at making C# programmers, a growing part of our community, feel even more comfortable.

C# Component System#

The Component System does not remove components from nodes transferred between worlds anymore, as their lifetime is the same as the Engine’s (Lifetime == ENGINE).

You can now check the current Component System state (total number of components, nodes having components assigned, as well as methods registered for components) via the new ComponentSystem.GetStatistics() method.

Memory Management and Garbage Collection#

Dispose pattern was implemented for each object (the Dispose() method) performing memory cleanup for Engine’s (native) resources.

A set of utilities enables you to get a pointer to a C++ object (GetPtr), check if an object exists (IsValidPtr) or was deleted with only a C# wrapper left (IsNullPtr).

Delayed object deletion is now available via the DeleteLater() method analogous to the C++ API.

Garbage Collection#

Garbage Collector behavior (Engine.GCMode) has changed with a set of modes making garbage collection management more flexible. The following modes are available:

  • DEFAULT (default) - default C# garbage collector mode. In this case heavy spikes and excessive memory consumption are imminent if you don’t manage your objects properly and do not use the Dispose() method.
  • USE_MEMORY_PRESSURE - passes the information about C++ memory consumption to C#. This results in more frequent GC calls preventing the application from eating too much memory right after startup and removing heavy spikes.
  • EVERY_FRAME - the garbage collector is called every frame. This results in overall performance reduction, but removes heavy spikes.
  • WORLD_SHUTDOWN - the garbage collector is called on closing the world. This mode is ideal if the number of memory allocations is your code is insignificant.
Source code (C#)
class UnigineApp
{
  class AppSystemLogic : SystemLogic
  {
    // ...

    public override bool Init()
    {
      Engine.GCMode = Engine.GCMODE.EVERY_FRAME;
      // ...
      return true;
    }
    // ...
}

Exceptions#

Exceptions in AppWorldLogic.cs, AppSystemLogic.cs, AppEditorLogic.cs, as well as in C# plugins won’t cause a crash of a C# .Net Core application anymore, the exception shall be written to the Console.

A new exception NativeNullReferenceException was added, which is thrown when a C# object exists while the C++ object was deleted and no longer accessible.

C# API Extension#

We keep on extending our C# API to make its capabilities as close to the ones provided by C++ API as possible. So, this release brings the following updates:

  • Math2D library is now fully available.
  • Import plugin is now fully available.
  • You can monitor memory consumption in C# API via the Engine’s Memory class.
  • The Variable class now supports the following types: PropertyParameter, Camera, Ellipsoid, Dataset, Body, Shape, Joint, TerrainGlobalLods, TerrainGlobalLod, TerrainGlobalLodHeight, TerrainGlobalDetail, RenderEnvironmentPreset
  • The following methods and properties of the Engine class are now available:
    • Engine.IsKnownArg(string arg)
    • Engine.GetPluginOrder(int num)
    • int Engine.NumPluginsPaths
    • string Engine.GetPluginPath(int num)
    • string Engine.SystemScript
    • string Engine.EditorScript
    • string Engine.SystemCache
    • string Engine.EditorCache
    • string Engine.VideoApp
    • string Engine.SoundApp
    • string Engine.ExternDefines

Plugins API#

C# API is now available for all Engine plugins, except for the IG.

No initialization is required, simply check if the plugin is loaded and use it:

Source code (C#)
using Unigine.Plugins;

// AppProjection plugin
if (AppProjection.IsLoaded)
{
    vec2[] points = new vec2[4];
    points[0] = new vec2(0.2f, 0.2f);
    points[1] = new vec2(0.8f, 0.2f);
    points[2] = new vec2(0.8f, 0.8f);
    points[3] = new vec2(0.2f, 0.8f);
    AppProjection.SetWarpPoints(0, points, 2, 2);
}

// GPUMonitor plugin
if (GPUMonitorPlugin.IsLoaded)
{
    for (int j = 0; j < GPUMonitorPlugin.GetNumMonitors(); j++)
    {
        Log.Message("Monitor: {0}\n", j);
        GPUMonitor monitor = GPUMonitorPlugin.GetMonitor(j);

        Log.Message("  Adapters: {0}\n", monitor.GetNumAdapters());
        for (int i = 0; i < monitor.GetNumAdapters(); i++)
        {
            Log.Message("    Name: {0}\n", monitor.GetAdapterName(i));
            Log.Message(" CoreClock: {0}\n", monitor.GetCoreClock(i));
            Log.Message(" MemoryClock: {0}\n", monitor.GetMemoryClock(i));
            Log.Message(" Temperature: {0}\n", monitor.GetTemperature(i));
            Log.Message(" Utilization: {0}\n", monitor.GetUtilization(i));
        }
    }
}

Other Changes#

  • Native type casting is now available, no more get() and cast() methods.
  • Improved comparison operators and added casting operator, so the following construct is now possible:
    Source code (C#)
    if (node)
    {
       Log.Message("Node exists!\n"); 
    }
  • C# functions and properties can now receive null as an argument instead of nodes making the following constructs possible:
    Source code (C#)
    node.Parent = null;
    node.SetWorldParent(null);
  • Script functions (System, World, and Editor) can now be called by their IDs, which can be obtained via the corresponding method of the Engine class:
    Source code (C#)
    // getting the ID of a system script function
    int sf_id = Engine.GetSystemFunction(name);
    // running the function with arguments
    Engine.RunSystemFunction(sf_id, ...);
    
    // getting the ID of a world script function
    int wf_id = Engine.GetWorldFunction(name);
    // running the function with arguments
    Engine.RunWorldFunction(wf_id, ...);
    
    // getting the ID of an editor script function
    int ef_id = Engine.GetEditorFunction(name);
    // running the function with arguments
    Engine.RunEditorFunction(ef_id, ...);
  • When loading a world all NodeReferences it contains are unpacked by default (the hierarchy of NodeReference’s contents is attached to it as a child). This is made to simplify working with node references for beginners in order to make it look like in the UnigineEditor.

    To disable automatic unpacking simply add the following line to the AppSystemLogic.Init() method:

    Source code (C#)
    public override bool Init()
    {
    World.UnpackNodeReferences = false;
    // ...
    }
  • The last error is written to the Log in case of an Engine crash (if it has occurred on the C# side).
  • Default Code Page is now supported.

C# API Migration Guide#

  • Replace all calls to methods of Engine’s singleton classes, including the ones of the Engine class itself via the get() method with static ones (except for the Gui class):

    Earlier Versions

    Source code (C#)
    Engine.Get().RunWorldFunction();
    
    float ifps = Game.Get().IFps;
    Physics.Get().SetFrozenLinearVelocity(0.1f);
    Material mesh_base = Materials.Get().FindBaseMaterial("mesh_base");
    // ...

    2.10

    Source code (C#)
    Engine.RunWorldFunction();
    
    float ifps = Game.IFps;
    Physics.SetFrozenLinearVelocity(0.1f);
    Material mesh_base = Materials.FindBaseMaterial("mesh_base");
    // ...
  • Replace all references to Engine’s singletons via the list (e.g. Engine.game., or Engine.input.) with names of singleton classes (e.g., Game., Input.)
  • Rename Main-Loop-related methods Render(), Flush(), and Destroy() to PostUpdate(), UpdatePhysics(), and DestroyRenderResources() respectively.
  • Rename the Engine.DoRender() method to Engine.Render().
  • Replace all Cast() methods of derived classes used for downcasting with the “as” operator. And remove all upcasting methods (e.g. GetPlayer(), GetWidget(), GetObject(), etc.) as well:

    Earlier Versions

    Source code (C#)
    // Upcasting
    NodeDummy dummy;
    Node node = dummy.GetNode();
    
    // Downcasting
    Node node;
    NodeDummy dummy  = NodeDummy.Cast(node);

    2.10

    Source code (C#)
    // Upcasting
    NodeDummy dummy;
    Node node = dummy;
    
    // Downcasting
    Node node;
    NodeDummy dummy  = node as NodeDummy;
  • Remove the first "Version" argument from the Engine.Init() method:

    Earlier Versions

    Source code (C#)
    Engine engine = Engine.Init(Engine.VERSION, app, args)

    2.10

    Source code (C#)
    Engine.Init(app, args)
  • If you’re creating a custom user application change the base class for your custom class to the CustomApp class, instead of the App.

UUSL Changes#

Macros used for type casting were replaced with special cast-functions, same for both DirectX and Open GL:

MacrosCast-Functions
#define FLOAT4(X) float4(X)

#define FLOAT3(X) float3(X)

#define FLOAT2(X) float2(X)

#define FLOAT(X) float(X)

#define INT4(X) int4(X)

#define INT3(X) int3(X)

#define INT2(X) int2(X)

#define INT(X) int(X)

#define BOOL4(X) bvec4(X)

#define BOOL3(X) bvec3(X)

#define BOOL2(X) bvec2(X)

int to_int( var )
int2 to_int2( var )
int3 to_int3( var )
int4 to_int4( var )

uint to_uint( var )
uint2 to_uint2( var )
uint3 to_uint3( var )
uint4 to_uint4( var )

float to_float( var )
float2 to_float2( var )
float3 to_float3( var )
float4 to_float4( var )

double to_double( var )
double2 to_double2( var )
double3 to_double3( var )
double4 to_double4( var )

scalar to_scalar( var )
scalar2 to_scalar2( var )
scalar3 to_scalar3( var )
scalar4 to_scalar4( var )

float4 to_gvec4(float v)
float4 to_gvec4(float2 v)
float4 to_gvec4(float3 v)
float4 to_gvec4(float4 v)

int4 to_gvec4(int v)
int4 to_gvec4(int2 v)
int4 to_gvec4(int3 v)
int4 to_gvec4(int4 v)

uint4 to_gvec4(uint v)
uint4 to_gvec4(uint2 v)
uint4 to_gvec4(uint3 v)
uint4 to_gvec4(uint4 v)
var - variable of any type

RW-texture management has changed, now separate functions are used for each specific texture format.

2.9 2.10
UUSL
#define INIT_RW_TEXTURE(NUM, NAME)
#define INIT_RW_TEXTURE_3D(NUM, NAME)

#define TEXTURE_RW_LOAD(NAME, COORD)
#define TEXTURE_RW_STORE(NAME, COORD, VALUE)
UUSL
#define INIT_RW_TEXTURE_R32U(NUM, NAME)
#define INIT_RW_TEXTURE_R32U_3D(NUM, NAME)

#define INIT_RW_TEXTURE_R32F(NUM, NAME)
#define INIT_RW_TEXTURE_R32F_3D(NUM, NAME)

#define INIT_RW_TEXTURE_RGBA8(NUM, NAME)
#define INIT_RW_TEXTURE_RGBA8_3D(NUM, NAME)

#define TEXTURE_RW_LOAD_RGBA8(NAME, COORD)
#define TEXTURE_RW_STORE_RGBA8(NAME, COORD, VALUE)

#define TEXTURE_RW_LOAD_R32U(NAME, COORD)
#define TEXTURE_RW_STORE_R32U(NAME, COORD, VALUE)

#define TEXTURE_RW_LOAD_R32F(NAME, COORD)
#define TEXTURE_RW_STORE_R32F(NAME, COORD, VALUE)

Renamed double_trigonometry.h to double_math.h:

2.9 2.10
UUSL
#include <core/shaders/common/double_trigonometry.h>
UUSL
#include <core/shaders/common/double_math.h>

Added new functions getting texture resolution:

  • #define textureResolution ( TEXTURE )
  • #define textureIResolution ( TEXTURE )

Added new scalar types, which can be either double or float depending on precision (UNIGINE_DOUBLE flag):

  • scalar
  • scalar2
  • scalar3
  • scalar4

A set of new functions having different return values depending on precision (UNIGINE_DOUBLE flag) was also added:

  • s_rsqrt ( x )
  • s_dot ( a, b )
  • s_mad ( x, y, z )
  • s_sign ( x )
  • s_abs ( x )
  • s_lerp ( a, b, w )
  • s_frac ( x )
  • s_rcp ( x )
  • s_sqrt ( x )
  • s_length2 ( x )
  • s_ilength ( x )
  • s_length ( x )
  • s_normalize ( x )

App Class#

UNIGINE 2.9 UNIGINE 2.10
doRender() Removed. Use doRender() method of the CustomApp class instead.
doSwap() Removed. Use doSwap() method of the CustomApp class instead.
doUpdate() Removed. Use doUpdate() method of the CustomApp class instead.
initD3D11() Removed. Use initD3D11() method of the CustomApp class instead.
initGL() Removed. Use initGL() method of the CustomApp class instead.
initNULL() Removed. Use initNULL() method of the CustomApp class instead.
createContext() Removed. Use createContext() method of the CustomApp class instead.
initGLContext() Removed. Use initGLContext() method of the CustomApp class instead.
initD3D11Context() Removed. Use initD3D11Context() method of the CustomApp class instead.
getGLContext() Removed. Use getGLContext() method of the CustomApp class instead.
getGLVersionMajor() Removed. Use getGLVersionMajor() method of the CustomApp class instead.
getGLVersionMinor() Removed. Use getGLVersionMinor() method of the CustomApp class instead.
destroy() Removed. Use destroy() method of the CustomApp class instead.
render() Removed. Use render() method of the CustomApp class instead.
swap() Removed. Use swap() method of the CustomApp class instead.
update() Removed. Use update() method of the CustomApp class instead.
shutdownD3D11() Removed. Use shutdownD3D11() method of the CustomApp class instead.
shutdownGL() Removed. Use shutdownGL() method of the CustomApp class instead.
shutdownNULL() Removed. Use shutdownNULL() method of the CustomApp class instead.
isD3D11Initialized() Removed. Use isD3D11Initialized() method of the CustomApp class instead.
isGLInitialized() Removed. Use isGLInitialized() method of the CustomApp class instead.
isNULLInitialized() Removed. Use isNULLInitialized() method of the CustomApp class instead.
getD3D11Context() Removed. Use getD3D11Context() method of the CustomApp class instead.
getD3D11Device() Removed. Use getD3D11Device() method of the CustomApp class instead.

New Functions#

AmbientSource Class#

UNIGINE 2.9 UNIGINE 2.10
getInterface() Removed.
isOwner() Removed.
grab() Removed.
release() Removed.

AppWall Class#

UNIGINE 2.9 UNIGINE 2.10
getHeight() Renamed to getWallHeight().
getWidth()() Renamed to getWallWidth().

BakeLighting Class#

Blob Class#

UNIGINE 2.9 UNIGINE 2.10
cast() Removed.

Body Classes#

Body Class#

UNIGINE 2.9 UNIGINE 2.10
getBody() Removed.
grab() Removed.
isOwner() Removed.
release() Removed.

New Functions#

BodyDummy Class#

UNIGINE 2.9 UNIGINE 2.10
cast() Removed.

BodyRigid Class#

UNIGINE 2.9 UNIGINE 2.10
cast() Removed.

BodyFracture Class#

UNIGINE 2.9 UNIGINE 2.10
cast() Removed.

BodyPath Class#

UNIGINE 2.9 UNIGINE 2.10
cast() Removed.

BodyRagdoll Class#

UNIGINE 2.9 UNIGINE 2.10
cast() Removed.

BodyWater Class#

UNIGINE 2.9 UNIGINE 2.10
cast() Removed.

BodyParticles Class#

UNIGINE 2.9 UNIGINE 2.10
getBodyParticles() Removed.

BodyCloth Class#

UNIGINE 2.9 UNIGINE 2.10
cast() Removed.

BodyRope Class#

UNIGINE 2.9 UNIGINE 2.10
cast() Removed.

Controls Class#

UNIGINE 2.9 UNIGINE 2.10
getControls() Removed.
grab() Removed.
isOwner() Removed.
release() Removed.
CONTROLS_SIXAXIS Renamed to CONTROLS_SIX_AXIS.
CONTROLS_XPAD360 Renamed to CONTROLS_X_PAD360.

Dataset Class#

UNIGINE 2.9 UNIGINE 2.10
grab() Removed.
isOwner() Removed.
release() Removed.

DatasetCoordinateTransformer Class#

UNIGINE 2.9 UNIGINE 2.10
grab() Removed.
isOwner() Removed.
release() Removed.

DatasetSpatialReference Class#

UNIGINE 2.9 UNIGINE 2.10
grab() Removed.
isOwner() Removed.
release() Removed.

DatasetRasterPosResolver Class#

UNIGINE 2.9 UNIGINE 2.10
grab() Removed.
isOwner() Removed.
release() Removed.

Decal Class#

UNIGINE 2.9 UNIGINE 2.10
cast() Removed.
getDecal() Removed.

Editor Class#

UNIGINE 2.9 UNIGINE 2.10
getNodeByName() Removed. Use getNodeByName() method of the World class instead.
getNodesByName() Removed. Use getNodesByName() method of the World class instead.
getNodeById() Removed. Use getNodeById() method of the World class instead.
clearBindings() Removed. Use clearBindings() method of the World class instead.
isNode() Removed.
getNumNodes() Removed.
findNode() Removed.
findNodeById() Removed.
getNode() Removed.
getNodeName() Removed.
getNodeIndex() Removed.
setNodeIndex() Removed.
isNode() Removed.
swapNodes() Removed.
isRuntimeNode() Removed. Use the isSaveToWorldEnabled() method of the Node class instead.
addNode() Removed.
removeNode() Removed.
releaseNode() Removed.
updateNode() Removed.
updateNodes() Removed.
getIntersection() Set of arguments changed.
getIntersection() Set of arguments changed.

EditorLogic Class#

UNIGINE 2.9 UNIGINE 2.10
render() Renamed to postUpdate().
destroy() Renamed to destroyRenderResources().
nodeAdded() Removed.
nodeRemoved() Removed.
nodeReleased() Removed.
nodeUpdated() Removed.

New Functions#

Engine Class#

FileSystem Class#

FileSystemMount Class#

Ffp Class#

UNIGINE 2.9 UNIGINE 2.10
get() Removed.

Field Class#

UNIGINE 2.9 UNIGINE 2.10
cast() Removed.
getField() Removed.

FieldShoreline Class#

New Functions#

File Class#

UNIGINE 2.9 UNIGINE 2.10
cast() Removed.

Gui Class#

UNIGINE 2.9 UNIGINE 2.10
grab() Removed.
isOwner() Removed.
release() Removed.

Image Class#

Input Class#

UNIGINE 2.9 UNIGINE 2.10
getMouseWheelDelta() Removed.
getMouseWheelHorizontalDelta() Removed.

Joint Classes#

Joint Class#

UNIGINE 2.9 UNIGINE 2.10
getJoint() Removed.
grab() Removed.
isOwner() Removed.
release() Removed.

JointBall Class#

UNIGINE 2.9 UNIGINE 2.10
cast() Removed.

JointCylindrical Class#

UNIGINE 2.9 UNIGINE 2.10
cast() Removed.

JointFixed Class#

UNIGINE 2.9 UNIGINE 2.10
cast() Removed.

JointHinge Class#

UNIGINE 2.9 UNIGINE 2.10
cast() Removed.

JointParticles Class#

UNIGINE 2.9 UNIGINE 2.10
cast() Removed.

JointPath Class#

UNIGINE 2.9 UNIGINE 2.10
cast() Removed.

JointPrismatic Class#

UNIGINE 2.9 UNIGINE 2.10
cast() Removed.

JointSuspension Class#

UNIGINE 2.9 UNIGINE 2.10
cast() Removed.

JointWheel Class#

UNIGINE 2.9 UNIGINE 2.10
cast() Removed.

Json Class#

UNIGINE 2.9 UNIGINE 2.10
isOwner() Removed.
grab() Removed.
release() Removed.

Light Class#

UNIGINE 2.9 UNIGINE 2.10
getLight() Removed.

Material Class#

UNIGINE 2.9 UNIGINE 2.10
isOwner() Removed.
grab() Removed.
release() Removed.
setParameter() Removed.
getParameter() Removed. Use getParameterFloat4() instead.
setParameterMask() Removed.
getParameterMask() Removed.
setParameterSlider() Removed.
getParameterSlider() Removed.
getParameterSliderMaxExpand() Removed. Use getParameterMaxExpand() instead.
getParameterSliderMaxValue() Removed. Use getParameterMaxValue() instead.
getParameterSliderMinExpand() Removed. Use getParameterMinExpand() instead.
getParameterSliderMinValue() Removed. Use getParameterMinValue() instead.
isParameterExpression() Removed. Use isParameterExpressionEnabled() instead.
PARAMETER_EXPRESSION Removed.
PARAMETER_SLIDER Removed.
PARAMETER_COLOR Removed.
PARAMETER_ARRAY Removed.

New Functions#

Mesh Class#

UNIGINE 2.9 UNIGINE 2.10
getMesh() Removed.
isOwner() Removed.
grab() Removed.
release() Removed.

MeshDynamic Class#

UNIGINE 2.9 UNIGINE 2.10
getMeshDynamic() Removed.

Node Class#

UNIGINE 2.9 UNIGINE 2.10
OBJECT_TERRAIN Removed.
WORLD_OCCLUDER_TERRAIN Removed.
setFolded() Removed.
isFolded() Removed.
IsFolded property. Removed.
deleteHierarchy() Removed.
getNode() Removed.
isOwner() Removed.
grab() Removed.
release() Removed.
getAngularVelocity() Renamed to getBodyAngularVelocity.
getLinearVelocity() Renamed to getBodyLinearVelocity.
getWorldVelocity() Renamed to getBodyWorldVelocity.

New Functions#

NodeExternBase Class#

UNIGINE 2.9 UNIGINE 2.10
grab() Removed.
isOwner() Removed.
release() Removed.

Object Class#

ObjectCloudLayer Class#

UNIGINE 2.9 UNIGINE 2.10
getWorldIntersection() Removed. Use getIntersection() method of the Object class instead.

ObjectExternBase Class#

UNIGINE 2.9 UNIGINE 2.10
grab() Removed.
isOwner() Removed.
release() Removed.

ObjectGrass Class#

ObjectIntersection Class#

ObjectMeshCluster Class#

New Functions#

ObjectMeshClutter Class#

ObjectMeshSkinned Class#

ObjectMeshStatic Class#

New Functions#

ObjectParticles Class#

ObjectWaterGlobal Class#

UNIGINE 2.9 UNIGINE 2.10
getWorldIntersection() Removed. Use getIntersection() method of the Object class instead.

Obstacle Class#

UNIGINE 2.9 UNIGINE 2.10
cast() Removed.
getObstacle() Removed.

PackageUng Class#

UNIGINE 2.9 UNIGINE 2.10
isOwner() Removed.
grab() Removed.
release() Removed.

Path Class#

UNIGINE 2.9 UNIGINE 2.10
isOwner() Removed.
grab() Removed.
release() Removed.

Physical Class#

UNIGINE 2.9 UNIGINE 2.10
cast() Removed.
getPhysical() Removed.

PhysicsIntersection Class#

Player Class#

UNIGINE 2.9 UNIGINE 2.10
cast() Removed.
getPlayer() Removed.

PlayerActor Class#

UNIGINE 2.9 UNIGINE 2.10
cast() Removed.

PlayerDummy Class#

UNIGINE 2.9 UNIGINE 2.10
cast() Removed.

PlayerPersecutor Class#

UNIGINE 2.9 UNIGINE 2.10
cast() Removed.

PlayerSpectator Class#

UNIGINE 2.9 UNIGINE 2.10
cast() Removed.

Plugin Class#

UNIGINE 2.9 UNIGINE 2.10
destroy() Renamed to destroyRenderResources().
flush() Renamed to updatePhysics().

Profiler Class#

UNIGINE 2.9 UNIGINE 2.10
get() Removed.

Properties Class#

UNIGINE 2.9 UNIGINE 2.10
get() Removed.

Property Class#

UNIGINE 2.9 UNIGINE 2.10
grab() Removed.
isOwner() Removed.
release() Removed.

PropertyParameter Class#

UNIGINE 2.9 UNIGINE 2.10
grab() Removed.
isOwner() Removed.
release() Removed.

Ptr Class#

UNIGINE 2.9 UNIGINE 2.10
getCounter() Removed.
isEmpty() Removed.
destroy() Removed.

New Functions#

Render Class#

UNIGINE 2.9 UNIGINE 2.10
setStreamingCheckDuration() Removed.
getStreamingCheckDuration() Removed.
setTerrainRefinedAlbedo() Removed.
isTerrainRefinedAlbedo() Removed.
setTerrainRefinedMask() Removed.
isTerrainRefinedMask() Removed.
setTerrainRefinedNormal() Removed.
isTerrainRefinedNormal() Removed.
renderProcedurals() Removed.
setTerrainAnisotropy() Renamed to setTerrainGlobalAnisotropy().
isTerrainAnisotropy() Renamed to getTerrainGlobalAnisotropy().
setTerrainHoles() Renamed to setTerrainGlobalHoles().
isTerrainHoles() Renamed to isTerrainGlobalHoles().
setTerrainTriplanar() Renamed to setTerrainGlobalTriplanar().
isTerrainTriplanar() Renamed to isTerrainGlobalTriplanar().
setTerrainDisplacement() Renamed to setTerrainGlobalDisplacement().
isTerrainDisplacement() Renamed to isTerrainGlobalDisplacement().
setTerrainDisplacementNormal() Renamed to setTerrainGlobalDisplacementNormal().
isTerrainDisplacementNormal() Renamed to isTerrainGlobalDisplacementNormal().

New Functions#

Renderer Class#

UNIGINE 2.9 UNIGINE 2.10
getTextureTerrainFlatPosition() Removed.

RenderState Class#

Shader Class#

UNIGINE 2.9 UNIGINE 2.10
create() Removed. Use Shader() instead.
setParameter() Removed.
setParameterBool() Removed.
setParameterInt() Set of arguments changed.
setParameterInt1() Removed.
setParameterInt2() Set of arguments changed.
setParameterInt3() Set of arguments changed.
setParameterInt4() Set of arguments changed.
setParameterUInt() Removed.
setParameterUInt1() Removed.
setParameterUInt2() Removed.
setParameterUInt3() Removed.
setParameterUInt4() Removed.
setParameterFloat() Set of arguments changed.
setParameterFloat1() Removed.
setParameterFloat2() Set of arguments changed.
setParameterFloat3() Set of arguments changed.
setParameterFloat4() Set of arguments changed.
setParameterFloatArray() Renamed to setParameterArrayFloat().
setParameterDouble() Set of arguments changed.
setParameterDouble1() Removed.
setParameterDouble2() Set of arguments changed.
setParameterDouble3() Set of arguments changed.
setParameterDouble4() Set of arguments changed.
setParameterDoubleArray() Renamed to setParameterArrayDouble().

New Functions#

Shape Class#

UNIGINE 2.9 UNIGINE 2.10
getCollision() Set of arguments changed for C# and C++.
getCollision() Set of arguments changed for C# and C++.
getShape() Removed.
isOwner() Removed.
grab() Removed.
release() Removed.

ShapeBox Class#

UNIGINE 2.9 UNIGINE 2.10
cast() Removed.

ShapeCapsule Class#

UNIGINE 2.9 UNIGINE 2.10
cast() Removed.

ShapeConvex Class#

UNIGINE 2.9 UNIGINE 2.10
cast() Removed.

ShapeCylinder Class#

UNIGINE 2.9 UNIGINE 2.10
cast() Removed.

ShapeSphere Class#

UNIGINE 2.9 UNIGINE 2.10
cast() Removed.

Socket Class#

UNIGINE 2.9 UNIGINE 2.10
cast() Removed.

Sound Class#

UNIGINE 2.9 UNIGINE 2.10
get() Removed.

Splash Class#

UNIGINE 2.9 UNIGINE 2.10
get() Removed.

SplineGraph Class#

UNIGINE 2.9 UNIGINE 2.10
isOwner() Removed.
grab() Removed.
release() Removed.

Stream Class#

UNIGINE 2.9 UNIGINE 2.10
STREAM_BLOB Renamed to BLOB.
STREAM_FILE Renamed to FILE.
STREAM_SOCKET Renamed to SOCKET.
STREAM_USER Renamed to USER.
STREAM_NUM_TYPES Renamed to NUM_STREAMS.
getInterface() Removed.
getStream() Removed.
grab() Removed.
isOwner() Removed.
release() Removed.

New Functions#

StructuredBuffer Class#

SystemLogic Class#

UNIGINE 2.9 UNIGINE 2.10
render() Renamed to postUpdate().
destroy() Renamed to destroyRenderResources().

TerrainGlobalLod Class#

UNIGINE 2.9 UNIGINE 2.10
getTerrainGlobalLod() Removed.
TERRAIN_LOD Renamed to TERRAIN_GLOBAL_LOD.
TERRAIN_LOD_HEIGHT Renamed to TERRAIN_GLOBAL_LOD_HEIGHT.

New Functions#

TerrainGlobalLodHeight Class#

UNIGINE 2.9 UNIGINE 2.10
cast() Removed.

Texture Class#

TilesetFile Class#

UNIGINE 2.9 UNIGINE 2.10
grab() Removed.
isOwner() Removed.
release() Removed.

UserInterface Class#

UNIGINE 2.9 UNIGINE 2.10
grab() Removed.
isOwner() Removed.
release() Removed.

Visualizer Class#

Widget Classes#

Widget Class#

UNIGINE 2.9 UNIGINE 2.10
getInterface() Removed.
getWidget() Removed.
grab() Removed.
isOwner() Removed.
release() Removed.
WIDGET_CHECKBOX Renamed to WIDGET_CHECK_BOX.
WIDGET_COMBOBOX Renamed to WIDGET_COMBO_BOX.
WIDGET_EDITLINE Renamed to WIDGET_EDIT_LINE.
WIDGET_EDITTEXT Renamed to WIDGET_EDIT_TEXT.
WIDGET_GRIDBOX Renamed to WIDGET_GRID_BOX.
WIDGET_GROUPBOX Renamed to WIDGET_GROUP_BOX.
WIDGET_LISTBOX Renamed to WIDGET_LIST_BOX.
WIDGET_TREEBOX Renamed to WIDGET_TREE_BOX.
WIDGET_TABBOX Renamed to WIDGET_TAB_BOX.
WIDGET_SCROLLBOX Renamed to WIDGET_SCROLL_BOX.
WIDGET_SPINBOX Renamed to WIDGET_SPIN_BOX.
WIDGET_MENUBAR Renamed to WIDGET_MENU_BAR.
WIDGET_MENUBOX Renamed to WIDGET_MENU_BOX.

New Functions#

WidgetButton Class#

UNIGINE 2.9 UNIGINE 2.10
cast() Removed.
type() Removed.
getImage() Set of arguments changed.

New Functions#

WidgetCanvas Class#

UNIGINE 2.9 UNIGINE 2.10
cast() Removed.
type() Removed.
getImage() Set of arguments changed.
getPolygonImage() Set of arguments changed.

WidgetCheckBox Class#

UNIGINE 2.9 UNIGINE 2.10
cast() Removed.
type() Removed.

New Functions#

WidgetComboBox Class#

WidgetDialog Class#

UNIGINE 2.9 UNIGINE 2.10
cast() Removed.
type() Removed.
getWidgetDialog() Removed.

WidgetDialogColor Class#

UNIGINE 2.9 UNIGINE 2.10
cast() Removed.

WidgetDialogFile Class#

UNIGINE 2.9 UNIGINE 2.10
cast() Removed.

WidgetDialogImage Class#

UNIGINE 2.9 UNIGINE 2.10
cast() Removed.
getImage() Set of arguments changed.

WidgetDialogMessage Class#

UNIGINE 2.9 UNIGINE 2.10
cast() Removed.

WidgetGridBox Class#

UNIGINE 2.9 UNIGINE 2.10
cast() Removed.
type() Removed.

WidgetGroupBox Class#

UNIGINE 2.9 UNIGINE 2.10
cast() Removed.
type() Removed.

New Functions#

WidgetEditLine Class#

WidgetEditText Class#

UNIGINE 2.9 UNIGINE 2.10
cast() Removed.
type() Removed.

New Functions#

WidgetExtern Class#

UNIGINE 2.9 UNIGINE 2.10
cast() Removed.
type() Removed.

WidgetExternBase Class#

UNIGINE 2.9 UNIGINE 2.10
cast() Removed.
isOwner() Removed.
grab() Removed.
release() Removed.

WidgetHBox Class#

UNIGINE 2.9 UNIGINE 2.10
cast() Removed.
type() Removed.

WidgetHPaned Class#

UNIGINE 2.9 UNIGINE 2.10
cast() Removed.
type() Removed.

WidgetIcon Class#

UNIGINE 2.9 UNIGINE 2.10
cast() Removed.
type() Removed.
getImage() Set of arguments changed.

WidgetLabel Class#

UNIGINE 2.9 UNIGINE 2.10
cast() Removed.
type() Removed.

WidgetListBox Class#

UNIGINE 2.9 UNIGINE 2.10
cast() Removed.
type() Removed.
getImage() Set of arguments changed.

New Functions#

WidgetManipulator Class#

UNIGINE 2.9 UNIGINE 2.10
cast() Removed.
type() Removed.
getWidgetManipulator() Removed.

WidgetManipulatorRotator Class#

UNIGINE 2.9 UNIGINE 2.10
cast() Removed.

WidgetManipulatorScaler Class#

UNIGINE 2.9 UNIGINE 2.10
cast() Removed.

WidgetManipulatorTranslator Class#

UNIGINE 2.9 UNIGINE 2.10
cast() Removed.

WidgetMenuBar Class#

UNIGINE 2.9 UNIGINE 2.10
cast() Removed.
type() Removed.

New Functions#

WidgetMenuBox Class#

UNIGINE 2.9 UNIGINE 2.10
cast() Removed.
type() Removed.
getImage() Set of arguments changed.

New Functions#

WidgetScroll Class#

UNIGINE 2.9 UNIGINE 2.10
cast() Removed.
type() Removed.

New Functions#

WidgetScrollBox Class#

WidgetSlider Class#

UNIGINE 2.9 UNIGINE 2.10
cast() Removed.

New Functions#

WidgetSpacer Class#

UNIGINE 2.9 UNIGINE 2.10
cast() Removed.
type() Removed.

WidgetSpinbox Class#

UNIGINE 2.9 UNIGINE 2.10
cast() Removed.
type() Removed.

New Functions#

WidgetSprite Class#

UNIGINE 2.9 UNIGINE 2.10
cast() Removed.
type() Removed.
getWidgetSprite() Removed.
getImage() Set of arguments changed.
getLayerImage() Set of arguments changed.

WidgetSpriteNode Class#

UNIGINE 2.9 UNIGINE 2.10
cast() Removed.

WidgetSpriteShader Class#

UNIGINE 2.9 UNIGINE 2.10
cast() Removed.

WidgetSpriteVideo Class#

UNIGINE 2.9 UNIGINE 2.10
cast() Removed.

WidgetSpriteViewport Class#

UNIGINE 2.9 UNIGINE 2.10
cast() Removed.

WidgetTreeBox Class#

UNIGINE 2.9 UNIGINE 2.10
cast() Removed.
cast() Removed.
getImage() Set of arguments changed.

New Functions#

WidgetTabBox Class#

UNIGINE 2.9 UNIGINE 2.10
cast() Removed.
type() Removed.
getImage() Set of arguments changed.

New Functions#

WidgetVBox Class#

UNIGINE 2.9 UNIGINE 2.10
cast() Removed.
type() Removed.
getWidgetVBox() Removed.

New Functions#

WidgetVPaned Class#

UNIGINE 2.9 UNIGINE 2.10
cast() Removed.
type() Removed.
getWidgetVPaned() Removed.

WidgetWindow Class#

UNIGINE 2.9 UNIGINE 2.10
cast() Removed.
type() Removed.
getWidgetWindow() Removed.

New Functions#

World Class#

UNIGINE 2.9 UNIGINE 2.10
getNode() Removed.
grabNode() Removed.
removeNode() Removed.
releaseNode() Removed.
getIntersection() Set of arguments changed.
getIntersection() Set of arguments changed.

New Functions#

WorldExternBase Class#

UNIGINE 2.9 UNIGINE 2.10
grab() Removed.
isOwner() Removed.
release() Removed.

WorldIntersection Class#

WorldLogic Class#

UNIGINE 2.9 UNIGINE 2.10
render() Renamed to postUpdate().
destroy() Renamed to destroyRenderResources().
flush() Renamed to updatePhysics().

New Functions#

Xml Class#

UNIGINE 2.9 UNIGINE 2.10
isOwner() Removed.
grab() Removed.
release() Removed.

IG::Manager Class#

UNIGINE 2.9 UNIGINE 2.10
getConfigPath() Removed. Use getConfig() instead.
getHatHot() Set of arguments changed.
setSynckerInitCallback() Removed.

New Functions#

IG::Meteo Class#

UNIGINE 2.9 UNIGINE 2.10
addRegion() Removed. Use getRegion() instead.
getRegion() Set of arguments changed.
getNumRegions() Removed. Use getRegions() instead.
removeRegion() Set of arguments changed.

New Functions#

Last update: 2020-02-20