namespace Urho3D { /** \page Containers Container types Urho3D implements its own string type and template containers instead of using STL. The rationale for this consists of the following: - Increased performance in some cases, for example when using the PODVector class. - Guaranteed binary size of strings and containers, to allow eg. embedding inside the Variant object. - Reduced compile time. - Straightforward naming and implementation that aids in debugging and profiling. - Convenient member functions can be added, for example String::Split() or Vector::Compact(). - Consistency with the rest of the classes, see \ref CodingConventions "Coding conventions". The classes in question are String, Vector, PODVector, List, HashSet and HashMap. PODVector is only to be used when the elements of the vector need no construction or destruction and can be moved with a block memory copy. The list, set and map classes use a fixed-size allocator internally. This can also be used by the application, either by using the procedural functions AllocatorInitialize(), AllocatorUninitialize(), AllocatorReserve() and AllocatorFree(), or through the template class Allocator. In script, the String class is exposed as it is. The template containers can not be directly exposed to script, but instead a template Array type exists, which behaves like a Vector, but does not expose iterators. In addition the VariantMap is available, which is a HashMap. \section Containers_cxx11 C++11 features Aggregate initializers: \code VariantMap parameters = { {"Key1", "Value1"}, {"Key2", "Value2"} }; \endcode Range-base for loop: \code for (auto&& item: container) { } \endcode \page ObjectTypes Object types and factories Classes that derive from Object contain type-identification, they can be created through object factories, and they can send and receive \ref Events "events". Examples of these are all Component, Resource and UIElement subclasses. To be able to be constructed by a factory, they need to have a constructor that takes a Context pointer as the only parameter. %Object factory registration and object creation through factories are directly accessible only in C++, not in script. The definition of an Object subclass must contain the URHO3D_OBJECT(className, baseTypeName) macro. Type identification is available both as text (GetTypeName() or GetTypeNameStatic()) and as a 32-bit hash of the type name (GetType() or GetTypeStatic()). To register an object factory for a specific type, call the \ref Context::RegisterFactory "RegisterFactory()" template function on Context. You can get its pointer from any Object either via the \ref Object::context_ "context_" member variable, or by calling \ref Object::GetContext "GetContext()". An example: \code context_->RegisterFactory(); \endcode To create an object using a factory, call Context's \ref Context::CreateObject "CreateObject()" function. This takes the 32-bit hash of the type name as a parameter. The created object (or null if there was no matching factory registered) will be returned inside a SharedPtr. For example: \code SharedPtr newComponent = context_->CreateObject(type)); \endcode \page Subsystems Subsystems Any Object can be registered to the Context as a subsystem, by using the function \ref Context::RegisterSubsystem "RegisterSubsystem()". They can then be accessed by any other Object inside the same context by calling \ref Object::GetSubsystem "GetSubsystem()". Only one instance of each object type can exist as a subsystem. After Engine initialization, the following subsystems will always exist: - Time: manages frame updates, frame number and elapsed time counting, and controls the frequency of the operating system low-resolution timer. - WorkQueue: executes background tasks in worker threads. - FileSystem: provides directory operations. - Log: provides logging services. - ResourceCache: loads resources and keeps them cached for later access. - Network: provides UDP networking and scene replication. - Input: handles keyboard and mouse input. Will be inactive in headless mode. - UI: the graphical user interface. Will be inactive in headless mode. - Audio: provides sound output. Will be inactive if sound disabled. - Engine: creates the other subsystems and controls the main loop iteration and framerate limiting. The following subsystems are optional, so GetSubsystem() may return null if they have not been created: - Profiler: Provides hierarchical function execution time measurement using the operating system performance counter. Exists if profiling has been compiled in (configurable from the root CMakeLists.txt) - EventProfiler: Same as Profiler but for events. - Graphics: Manages the application window, the rendering context and resources. Exists if not in headless mode. - Renderer: Renders scenes in 3D and manages rendering quality settings. Exists if not in headless mode. - Script: Provides the AngelScript execution environment. Needs to be created and registered manually. - Console: provides an interactive AngelScript console and log display. Created by calling \ref Engine::CreateConsole "CreateConsole()". - DebugHud: displays rendering mode information and statistics and profiling data. Created by calling \ref Engine::CreateDebugHud "CreateDebugHud()". - Database: Manages database connections. The build option for the database support needs to be enabled when building the library. In script, the subsystems are available through the following global properties: time, fileSystem, log, cache, network, input, ui, audio, engine, graphics, renderer, script, console, debugHud, database. Note that WorkQueue and Profiler are not available to script due to their low-level nature. \page Events Events The Urho3D event system allows for data transport and function invocation without the sender and receiver having to explicitly know of each other. Both the event sender and receiver must derive from Object. An event receiver must subscribe to each event type it wishes to receive: one can either subscribe to the event coming from any sender, or from a specific sender. The latter is useful for example when handling events from the user interface elements. Events themselves do not need to be registered. They are identified by 32-bit hashes of their names. Event parameters (the data payload) are optional and are contained inside a VariantMap, identified by 32-bit parameter name hashes. For the inbuilt Urho3D events, event type (E_UPDATE, E_KEYDOWN, E_MOUSEMOVE etc.) and parameter hashes (P_TIMESTEP, P_DX, P_DY etc.) are defined as namespaced constants inside include files such as CoreEvents.h or InputEvents.h, using the helper macros URHO3D_EVENT & URHO3D_PARAM. When subscribing to an event, a handler function must be specified. In C++ these must have the signature void HandleEvent(StringHash eventType, VariantMap& eventData). The URHO3D_HANDLER(className, function) macro helps in defining the required class-specific function pointers. For example: \code SubscribeToEvent(E_UPDATE, URHO3D_HANDLER(MyClass, MyEventHandler)); \endcode In script events are identified by their string names instead of name hashes (though these are internally converted to hashes.) %Script event handlers can either have the same signature as in C++, or a simplified signature void HandleEvent() when event type and parameters are not required. The same event subscription would look like: \code SubscribeToEvent("Update", "MyEventHandler"); \endcode In C++ events must always be handled by a member function. In script procedural event handling is also possible; in this case the ScriptFile where the event handler function is located becomes the event receiver. See \ref Scripting "Scripting" for more details. Events can also be unsubscribed from. See \ref Object::UnsubscribeFromEvent "UnsubscribeFromEvent()" for details. To send an event, fill the event parameters (if necessary) and call \ref Object::SendEvent "SendEvent()". For example, this (in C++) is how the Engine subsystem sends the Update event on each frame. For performance reason, in C++ the same map objects are being reused in each frame by calling \ref Context::GetEventDataMap "GetEventDataMap()" instead of creating a new VariantMap object each time. Note the parameter name hashes being inside a namespace which matches the event name: \code using namespace Update; VariantMap& eventData = GetEventDataMap(); eventData[P_TIMESTEP] = timeStep_; SendEvent(E_UPDATE, eventData); \endcode In script event parameters, like event types, are referred to with strings, so the same code would look like: \code VariantMap eventData; eventData["TimeStep"] = timeStep; SendEvent("Update", eventData); \endcode \section Events_AnotherObject Sending events through another object Because the \ref Object::SendEvent "SendEvent()" function is public, an event can be "masqueraded" as originating from any object, even when not actually sent by that object's member function code. This can be used to simplify communication, particularly between components in the scene. For example, the \ref Physics "physics simulation" signals collision events by using the participating \ref Node "scene nodes" as senders. This means that any component can easily subscribe to its own node's collisions without having to know of the actual physics components involved. The same principle can also be used in any game-specific messaging, for example making a "damage received" event originate from the scene node, though it itself has no concept of damage or health. \section Events_cxx11 C++11 event binding and sending Events can be bound to lambda functions including capturing context: \code SubscribeToEvent(E_UPDATE, [&](StringHash type, VariantMap& args) { }); \endcode std::bind() class methods: \code void MyObject::OnUpdate(StringHash type, VariantMap& args) { } SubscribeToEvent(E_UPDATE, std::bind(&MyObject::OnUpdate, this, std::placeholders::_1, std::placeholders::_2))); \endcode std::bind() discarding unneeded parameters: \code void Class::OnUpdate(VariantMap& args) { } using namespace std::placeholders; SubscribeToEvent(E_UPDATE, std::bind(&Class::OnUpdate, this, _2))); \endcode There is a convenient method to send event using C++ variadic template which reduces the amount of boilerplate code required. Using the same example above, in C++11 standard the code can be rewritten as: \code using namespace Update; SendEvent(E_UPDATE, P_TIMESTEP, timeStep_); \endcode There is only one parameter pair in the above example, however, this overload method accepts any number of parameter pairs. \page MainLoop Engine initialization and main loop Before a Urho3D application can enter its main loop, the Engine subsystem object must be created and initialized by calling its \ref Engine::Initialize "Initialize()" function. Parameters sent in a VariantMap can be used to direct how the Engine initializes itself and the subsystems. One way to configure the parameters is to parse them from the command line like the Urho3DPlayer application does: this is accomplished by the helper function \ref Engine::ParseParameters "ParseParameters()". The full list of supported parameters, their datatypes and default values: (also defined as constants in Engine/EngineDefs.h) - Headless (bool) Headless mode enable. Default false. - LogLevel (int) %Log verbosity level. Default LOG_INFO in release builds and LOG_DEBUG in debug builds. - LogQuiet (bool) %Log quiet mode, ie. to not write warning/info/debug log entries into standard output. Default false. - LogName (string) %Log filename. Default "Urho3D.log". - FrameLimiter (bool) Whether to cap maximum framerate to 200 (desktop) or 60 (Android/iOS/tvOS). Default true. - WorkerThreads (bool) Whether to create worker threads for the %WorkQueue subsystem according to available CPU cores. Default true. - %EventProfiler (bool) Whether to create the EventProfiler subsystem. Default true. - ResourcePrefixPaths (string) A semicolon-separated list of resource prefix paths to use. If not specified then the default prefix path is set to executable path. The resource prefix paths can also be defined using URHO3D_PREFIX_PATH env-var. When both are defined, the paths set by -pp takes higher precedence. - ResourcePaths (string) A semicolon-separated list of resource paths to use. If corresponding packages (ie. Data.pak for Data directory) exist they will be used instead. Default "Data;CoreData". - ResourcePackages (string) A semicolon-separated list of resource packages to use. Default empty. - AutoloadPaths (string) A semicolon-separated list of autoload paths to use. Any resource packages and subdirectories inside an autoload path will be added to the resource system. Default "Autoload". - ExternalWindow (void ptr) External window handle to use instead of creating an application window. Default null. - WindowIcon (string) %Window icon image resource name. Default empty (use application default icon.) - WindowTitle (string) %Window title. Default "Urho3D". - WindowWidth (int) %Window horizontal dimension. Default 0 (use desktop resolution, or 1024 in windowed mode.) - WindowHeight (int) %Window vertical dimension. Default 0 (use desktop resolution, or 768 in windowed mode.) - WindowPositionX (int) %Window horizontal position. Default center to screen. - WindowPositionY (int) %Window vertical position. Default center to screen. - FullScreen (bool) Whether to create a full-screen window. Default true. - Borderless (bool) Whether to create the window as borderless. Default false. - WindowResizable (bool) Whether window is resizable. Default false. - HighDPI (bool) Whether window is high DPI. Default true. Currently only supported by Apple platforms (macOS, iOS, and tvOS). - TripleBuffer (bool) Whether to use triple-buffering. Default false. - VSync (bool) Whether to wait for vertical sync when presenting rendering window contents. Default false. - FlushGPU (bool) Whether to flush GPU command buffer each frame (Direct3D9) or limit the amount of buffered frames (Direct3D11) for less input latency. Ineffective on OpenGL. Default false. - ForceGL2 (bool) When true, forces OpenGL 2 use even if OpenGL 3 is available. No effect on Direct3D or mobile builds. Default false. - Multisample (int) Hardware multisampling level. Default 1 (no multisampling.) - Orientations (string) Space-separated list of allowed orientations. Effective only on iOS. All possible values are "LandscapeLeft", "LandscapeRight", "Portrait" and "PortraitUpsideDown". Default "LandscapeLeft LandscapeRight". - Monitor (int) Monitor number to use. 0 is the default (primary) monitor. - RefreshRate (int) Monitor refresh rate in Hz to use. - DumpShaders (string) Filename to dump used shader variations to for precaching. - %RenderPath (string) Default renderpath resource name. Default empty, which causes forward rendering (bin/CoreData/RenderPaths/Forward.xml) to be used. - Shadows (bool) Shadow rendering enable. Default true. - LowQualityShadows (bool) Low-quality (1 sample) shadow mode. Default false. - MaterialQuality (int) %Material quality level. Default 2 (high) - TextureQuality (int) %Texture quality level. Default 2 (high) - TextureFilterMode (int) %Texture default filter mode. Default 2 (trilinear) - TextureAnisotropy (int) %Texture anisotropy level. Default 4. This has only effect for anisotropically filtered textures. - %Sound (bool) %Sound enable. Default true. - SoundBuffer (int) %Sound buffer length in milliseconds. Default 100. - SoundMixRate (int) %Sound output frequency in Hz. Default 44100. - SoundStereo (bool) Stereo sound output mode. Default true. - SoundInterpolation (bool) Interpolated sound output mode to improve quality. Default true. - TouchEmulation (bool) %Touch emulation on desktop platform. Default false. - ShaderCacheDir (string) Shader binary cache directory for Direct3D. Default "urho3d/shadercache" within the user's application preferences directory. - PackageCacheDir (string) Package cache directory for Network subsystem. Not specified by default. \section MainLoop_Frame Main loop iteration The main loop iteration (also called a frame) is driven by the Engine. In contrast it is the program's (for example Urho3DPlayer) responsibility to continuously loop this iteration by calling \ref Engine::RunFrame "RunFrame()". This function calls in turn the Time subsystem's \ref Time::BeginFrame "BeginFrame()" and \ref Time::EndFrame "EndFrame()" functions, and sends various update events in between. The event order is: - E_BEGINFRAME: signals the beginning of the new frame. Input and Network react to this to check for operating system window messages and arrived network packets. - E_UPDATE: application-wide logic update event. By default each update-enabled Scene reacts to this and triggers the scene update (more on this below.) - E_POSTUPDATE: application-wide logic post-update event. The UI subsystem updates its logic here. - E_RENDERUPDATE: Renderer updates its viewports here to prepare for rendering, and the UI generates render commands necessary to render the user interface. - E_POSTRENDERUPDATE: by default nothing hooks to this. This can be used to implement logic that requires the rendering views to be up-to-date, for example to do accurate raycasts. Scenes may not be modified at this point; especially scene objects may not be deleted or crashes may occur. - E_ENDFRAME: signals the end of the frame. Before this, rendering the frame and measuring the next frame's timestep will have occurred. The update of each Scene causes further events to be sent: - E_SCENEUPDATE: variable timestep scene update. This is a good place to implement any scene logic that does not need to happen at a fixed step. - E_SCENESUBSYSTEMUPDATE: update scene-wide subsystems. Currently only the PhysicsWorld component listens to this, which causes it to step the physics simulation and send the following two events for each simulation step: - E_PHYSICSPRESTEP: called before the simulation iteration. Happens at a fixed rate (the physics FPS.) If fixed timestep logic updates are needed, this is a good event to listen to. - E_PHYSICSPOSTSTEP: called after the simulation iteration. Happens at the same rate as E_PHYSICSPRESTEP. - E_SMOOTHINGUPDATE: update SmoothedTransform components in network client scenes. - E_SCENEPOSTUPDATE: variable timestep scene post-update. ParticleEmitter and AnimationController update themselves as a response to this event. Variable timestep logic updates are preferable to fixed timestep, because they are only executed once per frame. In contrast, if the rendering framerate is low, several physics simulation steps will be performed on each frame to keep up the apparent passage of time, and if this also causes a lot of logic code to be executed for each step, the program may bog down further if the CPU can not handle the load. Note that the Engine's \ref Engine::SetMinFps "minimum FPS", by default 10, sets a hard cap for the timestep to prevent spiraling down to a complete halt; if exceeded, animation and physics will instead appear to slow down. \section MainLoop_ApplicationState Main loop and the application activation state The application window's state (has input focus, minimized or not) can be queried from the Input subsystem. It can also effect the main loop in the following ways: - Rendering is always skipped when the window is minimized. - To avoid spinning the CPU and GPU unnecessarily, it is possible to define a smaller maximum FPS when no input focus. See \ref Engine::SetMaxInactiveFps "SetMaxInactiveFps()" - It is also possible to automatically pause update events and audio when the window is minimized. Use \ref Engine::SetPauseMinimized "SetPauseMinimized()" to control this behaviour. By default it is not enabled on desktop, and enabled on mobile devices (Android and iOS/tvOS). For singleplayer games this is recommended to avoid unwanted progression while away from the program. However in a multiplayer game this should not be used, as the missing scene updates would likely desync the client with the server. - On mobile devices the window becoming minimized can mean that it will never become maximized again, in case the OS decides it needs to free memory and kills your program. Therefore you should listen for the E_INPUTFOCUS event from the Input subsystem and immediately save your program state as applicable if the program loses input focus or is minimized. - On mobile devices it is also unsafe to access or create any graphics resources while the window is minimized (as the graphics context may be destroyed during this time); doing so can crash the program. It is recommended to leave the pause-minimized feature on to ensure you do not have to check for this in your update code. Note that on iOS/tvOS calling \ref Engine::Exit "Exit()" is a no-op as there is no officially sanctioned way to manually exit your program. On Android it will cause the activity to manually exit. \section MainLoop_ApplicationFramework Application framework The Application class provides a minimal framework for a Urho3D C++ application with a main loop. It has virtual functions Setup(), Start() and Stop() which can be defined by the application subclass. The header file also provides a macro for defining a program entry point, which will instantiate the Context object and then the user-specified application class. A minimal example, which would just display a blank rendering window and exit by pressing ESC: \code #include #include #include using namespace Urho3D; class MyApp : public Application { public: MyApp(Context* context) : Application(context) { } virtual void Setup() { // Called before engine initialization. engineParameters_ member variable can be modified here } virtual void Start() { // Called after engine initialization. Setup application & subscribe to events here SubscribeToEvent(E_KEYDOWN, URHO3D_HANDLER(MyApp, HandleKeyDown)); } virtual void Stop() { // Perform optional cleanup after main loop has terminated } void HandleKeyDown(StringHash eventType, VariantMap& eventData) { using namespace KeyDown; // Check for pressing ESC. Note the engine_ member variable for convenience access to the Engine object int key = eventData[P_KEY].GetInt(); if (key == KEY_ESCAPE) engine_->Exit(); } }; URHO3D_DEFINE_APPLICATION_MAIN(MyApp) \endcode \page SceneModel Scene model Urho3D's scene model can be described as a component-based scene graph. The Scene consists of a hierarchy of scene nodes, starting from the root node, which also represents the whole scene. Each Node has a 3D transform (position, rotation and scale), a name and an ID + optionally tag(s) and a freeform VariantMap for \ref Node::GetVars "user variables", but no other functionality. \section SceneModel_Components Components Rendering 3D objects, sound playback, physics and scripted logic updates are all enabled by creating different \ref Component "Components" into the nodes by calling \ref Node::CreateComponent "CreateComponent()". As with events, in C++ components are identified by type name hashes, and template forms of the component creation and retrieval functions exist for convenience. For example: \code Light* light = node->CreateComponent(); \endcode In script, strings are used to identify component types instead, so the same code would look like: \code Light@ light = node.CreateComponent("Light"); \endcode Because components are created using \ref ObjectTypes "object factories", a factory must be registered for each component type. Components created into the Scene itself have a special role: to implement scene-wide functionality. They should be created before all other components, and include the following: - Octree: implements spatial partitioning and accelerated visibility queries. Without this 3D objects can not be rendered. - PhysicsWorld: implements physics simulation. Physics components such as RigidBody or CollisionShape can not function properly without this. - DebugRenderer: implements debug geometry rendering. "Ordinary" components like Light, Camera or StaticModel should not be created directly into the Scene, but rather into child nodes. \section SceneModel_Identification Identification and queries Nodes can be queried by name from the Scene (or any parent node) with the function \ref Node::GetChild "GetChild()". The query can be optionally recursive, meaning it traverses into child hierarchies. This is relatively slow, since string compares are involved. Unlike nodes, components do not have names; components inside the same node are only identified by their type, and index in the node's component list, which is filled in creation order. See the various overloads of \ref Node::GetComponent "GetComponent()" or \ref Node::GetComponents "GetComponents()" for details. When created, both nodes and components get scene-global integer IDs. They can be queried from the Scene by using the functions \ref Scene::GetNode "GetNode()" and \ref Scene::GetComponent "GetComponent()". This is much faster than for example doing recursive name-based scene node queries. %String tags can be optionally assigned into scene nodes to aid in identification. See e.g. the functions \ref Node::AddTag "AddTag()", \ref Node::RemoveTag "RemoveTag()" and \ref Node::SetTags "SetTags()". Nodes with a specific tag can be queried from the Scene by calling the \ref Scene::GetNodesWithTag "GetNodesWithTag()" function. \section SceneModel_Hierarchy Scene hierarchy There is no inbuilt concept of an entity or a game object; rather it is up to the programmer to decide the node hierarchy, and in which nodes to place any logic. Typically, free-moving objects in the 3D world would be created as children of the root node. Nodes can be created either with or without a name, see \ref Node::CreateChild "CreateChild()". Uniqueness of node names is not enforced. Whenever there is some hierarchical composition, it is recommended (and in fact necessary, because components do not have their own 3D transforms) to create a child node. For example if a character was holding an object in his hand, the object should have its own node, which would be parented to the character's hand bone (also a Node.) The exception is the physics CollisionShape, which can be offsetted and rotated individually in relation to the node. See \ref Physics "Physics" for more details. Note that Scene's own transform is purposefully ignored as an optimization when calculating world derived transforms of child nodes, so changing it has no effect and it should be left as it is (position at origin, no rotation, no scaling.) %Scene nodes can be freely reparented. In contrast components are always created to the node they belong to, and can not be moved between nodes. Both child nodes and components are stored using SharedPtr containers; this means that detaching a child node from its parent or removing a component will also destroy it, if no other references to it exist. Both Node & Component provide the \ref Node::Remove "Remove()" function to accomplish this without having to go through the parent. Note that no operations on the node or component in question are safe after calling that function. It is also legal to create a Node that does not belong to a scene. This is useful for example with a camera moving in a scene that may be loaded or saved, because then the camera will not be saved along with the actual scene, and will not be destroyed when the scene is loaded. However, depending on the components used, creating components to a node outside the scene, then moving the node to a scene later may not work completely as expected. For example, a RigidBody component can not store its velocities if it does not have access to the scene's physics world component to actually create the Bullet rigid body object. \section SceneModel_Update Scene updates A Scene whose updates are enabled (default) will be automatically updated on each main loop iteration. See \ref Scene::SetUpdateEnabled "SetUpdateEnabled()". Nodes and components can be excluded from the scene update by disabling them, see \ref Node::SetEnabled "SetEnabled()". Disabling for example a drawable component also makes it invisible, a sound source component becomes inaudible etc. If a node is disabled, all of its components are treated as disabled regardless of their own enable/disable state. \section SceneModel_Logic Creating logic functionality To implement your game logic you typically either create script objects (when using scripting) or new components (when using C++). %Script objects exist in a C++ placeholder component, but can be basically thought of as components themselves. For a simple example to get you started, check the 05_AnimatingScene sample, which creates a Rotator object to scene nodes to perform rotation on each frame update. Unless you have extremely serious reasons for doing so, you should not subclass the Node class in C++ for implementing your own logic. Doing so will theoretically work, but has the following drawbacks: - Loading and saving will not work properly without changes. It assumes that the root node is a %Scene, and all the child nodes are of the %Node class. It will not know how to instantiate your custom subclass. - The Editor does not know how to edit your subclass. \section SceneModel_LoadSave Loading and saving scenes Scenes can be loaded and saved in either binary, JSON, or XML formats; see the functions \ref Scene::Load "Load()", \ref Scene::LoadXML "LoadXML()", \ref Scene::LoadJSON "LoadJSON", \ref Scene::Save "Save()" and \ref Scene::SaveXML "SaveXML()", and \ref Scene::SaveJSON "SaveJSON()". See \ref Serialization "Serialization" for the technical details on how this works. When a scene is loaded, all existing content in it (child nodes and components) is removed first. Nodes and components that are marked temporary will not be saved. See \ref Serializable::SetTemporary "SetTemporary()". To be able to track the progress of loading a (large) scene without having the program stall for the duration of the loading, a scene can also be loaded asynchronously. This means that on each frame the scene loads resources and child nodes until a certain amount of milliseconds has been exceeded. See \ref Scene::LoadAsync "LoadAsync()" and \ref Scene::LoadAsyncXML "LoadAsyncXML()". Use the functions \ref Scene::IsAsyncLoading "IsAsyncLoading()" and \ref Scene::GetAsyncProgress "GetAsyncProgress()" to track the loading progress; the latter returns a float value between 0 and 1, where 1 is fully loaded. The scene will not update or render before it is fully loaded. \section SceneModel_Instantiation Object prefabs Just loading or saving whole scenes is not flexible enough for eg. games where new objects need to be dynamically created. On the other hand, creating complex objects and setting their properties in code will also be tedious. For this reason, it is also possible to save a scene node (and its child nodes, components and attributes) to either binary, JSON, or XML to be able to instantiate it later into a scene. Such a saved object is often referred to as a prefab. There are three ways to do this: - In code by calling \ref Node::Save "Save()", \ref Node::SaveJSON "SaveJSON()", or \ref Node::SaveXML "SaveXML()" on the Node in question. - In the editor, by selecting the node in the hierarchy window and choosing "Save node as" from the "File" menu. - Using the "node" command in AssetImporter, which will save the scene node hierarchy and any models contained in the input asset (eg. a Collada file) To instantiate the saved node into a scene, call \ref Scene::Instantiate "Instantiate()", \ref Scene::InstantiateJSON() or \ref Scene::InstantiateXML "InstantiateXML()" depending on the format. The node will be created as a child of the Scene but can be freely reparented after that. Position and rotation for placing the node need to be specified. The NinjaSnowWar example uses XML format for its object prefabs; these exist in the bin/Data/Objects directory. \section SceneModel_Events Scene graph events The Scene object sends events on scene graph modification, such as nodes or components being added or removed, the enabled status of a node or component being changed, or name or tags being changed. These are used in the Editor to implement keeping the scene hierarchy window up to date. See the include file SceneEvents.h. Note that when a node is removed from the scene, individual component removals are not signaled. \section SceneModel_FurtherInformation Further information For more information on the component-based scene model, see for example http://cowboyprogramming.com/2007/01/05/evolve-your-heirachy/. Note that the Urho3D scene model is not a pure Entity-Component-System design, which would have the components just as bare data containers, and only systems acting on them. Instead the Urho3D components contain logic of their own, and actively communicate with the systems (such as rendering, physics or script engine) they depend on. \page Resources Resources Resources include most things in Urho3D that are loaded from mass storage during initialization or runtime: - Animation - Image - Model - Material - ParticleEffect - ScriptFile - Shader - Sound - Technique - Texture2D - Texture2DArray - Texture3D - TextureCube - XMLFile - JSONFile They are managed and loaded by the ResourceCache subsystem. Like with all other \ref ObjectTypes "typed objects", resource types are identified by 32-bit type name hashes (C++) or type names (script). An object factory must be registered for each resource type. The resources themselves are identified by their file paths, relative to the registered resource directories or \ref PackageFile "package files". By default, the engine registers the resource directories Data and CoreData, or the packages Data.pak and CoreData.pak if they exist. If loading a resource fails, an error will be logged and a null pointer is returned. Typical C++ example of requesting a resource from the cache, in this case, a texture for a UI element. Note the use of a convenience template argument to specify the resource type, instead of using the type hash. \code healthBar->SetTexture(GetSubsystem()->GetResource("Textures/HealthBarBorder.png")); \endcode The same in script would look like this (note the use of a property instead of a setter function): \code healthBar.texture = cache.GetResource("Texture2D", "Textures/HealthBarBorder.png"); \endcode Resources can also be created manually and stored to the resource cache as if they had been loaded from disk. Memory budgets can be set per resource type: if resources consume more memory than allowed, the oldest resources will be removed from the cache if not in use anymore. By default the memory budgets are set to unlimited. \section Resources_Background Background loading of resources Normally, when requesting resources using \ref ResourceCache::GetResource "GetResource()", they are loaded immediately in the main thread, which may take several milliseconds for all the required steps (load file from disk, parse data, upload to GPU if necessary) and can therefore result in framerate drops. If you know in advance what resources you need, you can request them to be loaded in a background thread by calling \ref ResourceCache::BackgroundLoadResource "BackgroundLoadResource()". The event E_RESOURCEBACKGROUNDLOADED will be sent after the loading is complete; it will tell if the loading actually was a success or a failure. Depending on the resource, only a part of the loading process may be moved to a background thread, for example the finishing GPU upload step always needs to happen in the main thread. Note that if you call GetResource() for a resource that is queued for background loading, the main thread will stall until its loading is complete. The asynchronous scene loading functionality \ref Scene::LoadAsync "LoadAsync()", \ref Scene::LoadAsyncJSON "LoadAsyncJSON()" and \ref Scene::LoadAsyncXML "LoadAsyncXML()" have the option to background load the resources first before proceeding to load the scene content. It can also be used to only load the resources without modifying the scene, by specifying the LOAD_RESOURCES_ONLY mode. This allows to prepare a scene or object prefab file for fast instantiation. Finally the maximum time (in milliseconds) spent each frame on finishing background loaded resources can be configured, see \ref ResourceCache::SetFinishBackgroundResourcesMs "SetFinishBackgroundResourcesMs()". \section Resources_BackgroundImplementation Implementing background loading When writing new resource types, the background loading mechanism requires implementing two functions: \ref Resource::BeginLoad "BeginLoad()" and \ref Resource::EndLoad "EndLoad()". BeginLoad() is potentially called in a background thread and should do as much work (such as file I/O) as possible without violating the \ref Multithreading "multithreading" rules. EndLoad() should perform the main thread finishing step, such as GPU upload. Either step can return false to indicate failure to load the resource. If a resource depends on other resources, writing efficient threaded loading for it can be hard, as calling GetResource() is not allowed inside BeginLoad() when background loading. There are a few options: it is allowed to queue new background load requests by calling BackgroundLoadResource() within BeginLoad(), or if the needed resource does not need to be permanently stored in the cache and is safe to load outside the main thread (for example Image or XMLFile, which do not possess any GPU-side data), \ref ResourceCache::GetTempResource "GetTempResource()" can be called inside BeginLoad. \page Localization Localization The Localization subsystem provides a simple way to creating multilingual applications. \section LocalizationInit Initialization Before using the subsystem, the localization string collection(s) need to be loaded. A common practice is to do this at application startup. Multiple collection files can be loaded, and each can define either just one or several languages. For example: \code Localization* l10n = GetSubsystem(); l10n->LoadJSONFile("StringsEnRu.json"); l10n->LoadJSONFile("StringsDe.json"); \endcode JSON files must be in UTF8 encoding without BOM. Sample files are in the bin/Data directory. The JSON files have the following format: \code { "string id 1":{ "language 1":"value11", "language 2":"value12", "language 3":"value13" }, "string id 2":{ "language 1":"value21", "language 2":"value22", "language 3":"value23" } } \endcode Any number of languages can be defined. Remember that language names and string identifiers are case sensitive. "En" and "en" are considered different languages. During the loading process languages are numbered in order of finding. Indexing starts from zero. The first found language is set to be initially active. \section LocalizationUsing Using The Get function returns a string with the specified string identifier in the current language. \code Text* t = new Text(context_); t->SetName("Text1"); Localization* l10n = GetSubsystem(); t->SetText(l10n->Get("string 1")); \endcode If the string id is empty, an empty string will be returned. If the translation is not found, the id will be returned unmodified and a warning will be logged. Use SetLanguage() function to change language at runtime. \code Localization* l10n = GetSubsystem(); l10n->SetLanguage("language 2"); \endcode When the language is changed, the E_CHANGELANGUAGE event will be sent. Subscribe to it to perform the necessary relocalization of your user interface (texts, sprites etc.) \code SubscribeToEvent(E_CHANGELANGUAGE, URHO3D_HANDLER(Game, HandleChangeLanguage)); void Game::HandleChangeLanguage(StringHash eventType, VariantMap& eventData) { Localization* l10n = GetSubsystem(); ... Text* t = static_cast(uiRoot->GetChild("Text1", true)); t->SetText(l10n->Get("string 1")); } \endcode Text %UI elements also support automatic translation to avoid manual work. \code Text* t2 = new Text(context_); t2->SetText("string 2"); t2->SetAutoLocalizable(true); \endcode Wherein text value is used as an identifier. Also see the example 40_Localization. \page Scripting Scripting To enable AngelScript scripting support, the Script subsystem needs to be created and registered after initializing the Engine. This is accomplished by the following code, seen eg. in Tools/Urho3DPlayer/Urho3DPlayer.cpp: \code context_->RegisterSubsystem(new Script(context_)); \endcode There are three ways the AngelScript language can be interacted with in Urho3D: \section Scripting_Immediate Immediate execution Immediate execution takes one line of AngelScript, compiles it, and executes. This is not recommended for anything that needs high performance, but can be used for example to implement a developer console. Call the Script subsystem's \ref Script::Execute "Execute()" function to use. For example: \code GetSubsystem