axel.goris Posted June 19, 2025 Posted June 19, 2025 Hello! I am in the process of writing a design for moving our code from Unigine Script for everything to using C++ for everything. One of the things we use a lot is the tracker, to animate clouds, sun, fog, lights, etc, etc. Except I don't see a clear replacement yet for the tracker in C++? There is the animation class but it clearly states that it is experimental. Any indication as to how we should be moving forward? As a side note, Unigine Script is not getting many updates nowadays so we'd rather move out of using it for most of our stuff. But do we have any visibility on the deprecation of Unigine Script and what can be expected to keep on working/be broken? Have a great day! Axel
bmyagkov Posted June 19, 2025 Posted June 19, 2025 Hello Axel, 6 hours ago, axel.goris said: I am in the process of writing a design for moving our code from Unigine Script for everything to using C++ for everything. One of the things we use a lot is the tracker, to animate clouds, sun, fog, lights, etc, etc. As for now, UnigineScript remains the primary language for working with the Tracker Tool while C++ support is still in an experimental phase. Currently, the C++ API is wrapped around and limited to controlling existing tracks and does not yet offer full control over the Tracker Tool—therefore, it cannot fully replace UnigineScript at this time. A "Tracker Playback" example demonstrating the current C++ capabilities is available in our samples: https://developer.unigine.com/en/docs/2.19.1/sdk/demos/cpp_samples/tracker?rlang=cpp However, please note that track creation is still exclusively tied to the Tracker Tool which currently relies on UnigineScript. That said, we are planning a complete revamp of the Tracker Tool to be introduced alongside with advanced animation system. While we are not able to provide a specific ETA at the moment development is already underway and these features are planned for a future releases. To clarify our roadmap: we have no plans to discontinue UnigineScript although further development of the language itself is not currently planned. As long as it remains the only way to fully utilize the Tracker Tool it will continue to be both viable and supported. In the meantime, we recommend continuing to use UnigineScript for Tracker-related tasks until the updated Tracker Tool and extended C++ API become available. Thanks! 1
axel.goris Posted June 20, 2025 Author Posted June 20, 2025 Yep, I saw the tracker playback :) Alright, thanks a lot, I'll see what we can do and how. I did not check but are UnigineScript API changes mentioned in release notes and such? Can we expect UnigineScript to stay the same through all releases? Thank you!
bmyagkov Posted June 20, 2025 Posted June 20, 2025 Hello! 4 hours ago, axel.goris said: I did not check but are UnigineScript API changes mentioned in release notes and such? Can we expect UnigineScript to stay the same through all releases? Yes, absolutely! Even though UnigineScript hasn't received significant updates for quite a while it remains stable and unchanged. You can generally expect it to stay the same across releases. Thanks!
axel.goris Posted June 25, 2025 Author Posted June 25, 2025 Hey! Do you happen to have a performance comparison between the tracker tool and the new animation API? One of my colleague (Kevin) is currently investigating performance issue and it was recommended to move stuff via code instead of using the tracker tool. But we have a looooooot of track files and if we could get a performance boost by moving towards the animation API, that might be easier for us. Thanks a lot!
bmyagkov Posted June 25, 2025 Posted June 25, 2025 Hello! 8 hours ago, axel.goris said: Do you happen to have a performance comparison between the tracker tool and the new animation API? One of my colleague (Kevin) is currently investigating performance issue and it was recommended to move stuff via code instead of using the tracker tool. But we have a looooooot of track files and if we could get a performance boost by moving towards the animation API, that might be easier for us. From our earlier testing using the C++ API showed approximately a 2–3x performance improvement compared to the traditional method of moving tracks via UnigineScript. So, if you're willing to explore this route, it might well be worth trying. That said, please keep in mind that this feature is currently in an experimental stage — so unexpected behavior may occur and the API could change in future updates. As mentioned in our support ticket response using code-driven movement (via C++ or C#) and directly controlling nodes or objects is a more scalable and maintainable approach overall. However, if you're open to exploring the approach using the C++ API here’s something that could help streamline the process: We’ve added a new Animation Playback Node (NodeAnimationPlayback) that showcases the new animation system. It allows you to: Play animation tracks in the new .utrack format Convert legacy .track files in a selected folder (or the entire data directory) into .utrack format Convert .track files to .uplay format for direct use via code (an intermediate .utrack will also be created) You can find detailed documentation here: https://developer.unigine.com/en/docs/2.19.1/principles/animations/?rlang=cpp#animation_playback_node You can find details on track conversion via the API at the following link: https://developer.unigine.com/en/docs/2.19.1/api/library/animations/class.animations?rlang=cpp#convertToUanims_VECString_VECString_void We’ve also attached a short video to this message showcasing how the system works. If you decide to give this a try and need any assistance, we’ll be happy to help — just let us know. Thanks! Foxhole 2025.06.25 - 11.09.48.01.mp4 1
axel.goris Posted June 26, 2025 Author Posted June 26, 2025 Hey, That is super awesome, thank you for the detailed answer!! I think the plan will be to move stuff from the tracker to direct C++ code but the animation API is still rather interesting, mostly for performance reasons. I'll try to keep you updated if I discover/have to ask anything else! 1
bmyagkov Posted July 3, 2025 Posted July 3, 2025 Hello Axel, We understand that the current instructions might not be entirely clear and we hope they will be improved in the future to provide additional clarity regarding their usage. That said, since you are looking for a performance-oriented solution the tracker_wrapper is probably not what you need. This solution is based on an older approach to handling nodes essentially serving as a simple C++ wrapper around USC. The alternative approach we discussed before is part of the new Animation System which is currently in an experimental stage. Please note that this system is not yet fully covered by the documentation as its internals may undergo significant changes in future updates. It is worth mentioning that this new approach is entirely different: it has been written from scratch in C++ which is why it demonstrates the performance improvements you are looking for. However, the old wrapper allows you to play existing .track files "as is" without the need for any additional steps while still utilizing the C++ API. On the other hand the new approach requires you to convert .track files into the new format before they can be used. For your reference, we have attached the source code along with a video demonstrating the process. You can convert old .track files into the new .utrack and .uplay formats using the following method: https://developer.unigine.com/en/docs/2.19.1/api/library/animations/class.animations?rlang=cpp#convertToUanims_cstr_VECString_void .utrack files store the actual animation tracks. These files can represent simple node movements or more complex animations, though the current documentation may not describe this in detail. .uplay files act as playbacks. They can include multiple tracks and allow you to control playback options such as speed, looping, etc. Here is an example of how to perform the conversion: Vector<String> track_file; track_file.append("hellotrack.track"); Animations::convertToUanims(track_file, track_file); This code converts the old hellotrack.track file into hellotrack.utrack and hellotrack.uplay files which will be saved alongside the original file. Both files are required because the .uplay references the .utrack. To load the converted playback, please use loadPlayback: Animations::loadPlayback("hellotrack.uplay"); You can then retrieve the playback object like this: AnimationPlaybackPtr playback = Animations::getPlaybackByPath("hellotrack.uplay"); Once you have the playback object you can control it as needed, for example: playback->setLoop(true); playback->play(); This will loop and start the animation playback. Please feel free to reach out if you have any further questions! 2025-07-03 13-54-18.mp4 AppWorldLogic.cpp 2
axel.goris Posted July 4, 2025 Author Posted July 4, 2025 (edited) Heeeeey!! Oups, sorry, I managed to get the tracker working fine and deleted my text in the meantime but I really appreciate that detailed answer!! What I had so far looked like that and it did not seem to work as getLayerTrackEndTime always returned 0 :( /* * Unigine Animation system works using animation tracks and playback * The global animations class alows to convert stuff * */ // Create vectors for the conversion function Vector<String> tracks; Vector<String> playbacks; tracks.append(fileName); playbacks.append(fileName); Animations::convertToUanims(tracks, playbacks); // Update the file path to use the new extension String convertedPath = fileName; convertedPath.replace(".track", ".utrack"); AnimationTrackPtr animation_track = Animations::getTrackByPath(convertedPath); animation_playback = AnimationPlayback::create(); animation_playback->setTrack(animation_track); I'll give it another go with loadPlayback, thanks a lot for the example!! Edit: The part that was a bit confusing was the "loadPlayback" then "getPlayback", that part seems unintuitive. In my mind, if you load it, it should be returned as part of the same call: Animations::RESULT loadPlayback(const char * path) Would be available as: AnimationPlaybackPtr loadPlayback(const char * path) I understand how/why it is done like that (Maybe you want to load stuff at initialization but might not use it until later) but it could be slightly easier. Thank you!! PS: Seems like editing your answer is a bit broken for the formatting option on Firefox. (Attached picture top toolbar!) Edited July 4, 2025 by axel.goris
axel.goris Posted July 4, 2025 Author Posted July 4, 2025 Hey hey, So I've tried the new Animation Playback load stuff but I'm getting errors: // Create vectors for the conversion function Vector<String> tracks; Vector<String> playbacks; tracks.append(fileName); playbacks.append(fileName); Animations::convertToUanims(tracks, playbacks); // Update the file path to use the new extension String convertedUTrack = fileName; String convertedUPlay = fileName; convertedUTrack.replace(".track", ".utrack"); convertedUPlay.replace(".track", ".uplay"); // load it into the engine? Log::message("Animation track loaded? %i", Animations::loadTrack(convertedUTrack)); Log::message("Animation playback loaded? %i", Animations::loadPlayback(convertedUPlay)); // Access the loaded playback animation_playback = Animations::getPlaybackByPath(convertedUPlay); My "animation_playback" is a null pointer, loadTrack returns RESULT_TRACK_ERROR = 0, loadPlayback returns RESULT_PLAYBACK_ERROR = 6. But I do have a cloud.utrack and cloud.uplay file created next to my .track file. Do note that using the same filename ("blabla/cloud.track") with the tracker wrapper works fine.cloud.track I've attached the .track file if you can have a look and tell me if that's alright or if it is normal for it not to be handled? As for the documentation, for feedback, there are lots of small issues in the doc: Ptr<AnimationPlayback> getPlaybackByPath ( const char * path ) const Returns an animation playback by the path to the animation track file (.uplay). ... const char * path - Path to the animation playback file (.uplay). Like, this should be "by the path to the animation playback file" in the description (as written below in the arguments). The return value for Ptr<AnimationPlayback> getPlaybackByFileGUID ( const UGUID & guid ) const is also confusing. Return value Animation track with the specified file GUID. So on and so forth. So yep, a bit tough to follow!
bmyagkov Posted July 4, 2025 Posted July 4, 2025 Hello Axel, Thank you very much for your feedback! As previously mentioned, this feature is still under development and currently in its experimental stage. Some inconsistencies are to be expected at this point but your input is truly appreciated—it will certainly help us improve its behavior moving forward :) 3 hours ago, axel.goris said: PS: Seems like editing your answer is a bit broken for the formatting option on Firefox. (Attached picture top toolbar!) This is a known issue caused by "Dark Mode" and disabling it might help mitigate the problem for now. We hope to have this addressed in a future update. 1 hour ago, axel.goris said: I've attached the .track file if you can have a look and tell me if that's alright or if it is normal for it not to be handled? Would you mind providing a simple sample that reproduces the issue? Unfortunately, the track file alone was not sufficient for us to identify the problem at first glance. You can easily create and share a minimal package directly from the embedded packager in the Editor as shown in the attached image. Please use the "Add External Files" option to include the relevant source files within the archive. However, the issue most likely lies within the following lines: convertedUTrack.replace(".track", ".utrack"); convertedUPlay.replace(".track", ".uplay"); Replacing them with the following should address the problem: convertedUTrack = convertedUTrack.replace(".track", ".utrack"); convertedUPlay = convertedUPlay.replace(".track", ".uplay"); Thanks! 1
axel.goris Posted July 4, 2025 Author Posted July 4, 2025 Ahahahahahahah damn, you were totally right, it is just the replace part where I missed it. Awesome job, thanks!! I've got another build issue after reverting some unrelated changes but that should be good to go! I'll keep you posted if something goes wrong!! 1
Recommended Posts