Tessalator Posted September 6, 2025 Posted September 6, 2025 I was playing with something based on a question on Discord about low-level control of Unigine. I did this: global using NType = Unigine.Node.TYPE; global using UW = Unigine.World; global using UN = Unigine.Node; global using UO = Unigine.Object; using System; using System.Diagnostics; using System.Numerics; using Unigine; using System.Threading; static class KeyboardHAL { internal static Boolean POST => true; static KeyboardHAL() { Input.EventKeyDown.Connect(KeyDown); } static void KeyDown(Input.KEY key) { } } static class MouseHAL { internal static Boolean POST => true; static MouseHAL() { Input.EventMouseDown.Connect(MouseDown); } static void MouseDown(Input.MOUSE_BUTTON button) { } } static class EC { static Boolean runState = true; static readonly Boolean halPost; static readonly String[] args = Environment.GetCommandLineArgs(); static EC() { Engine.Init(args); // Make Engine available halPost = true && KeyboardHAL.POST && MouseHAL.POST; Visualizer.Enabled = true; Unigine.Console.Onscreen = true; Engine.Iterate(); // Make World Available new Thread(() => { // Background Systems while (!Engine.IsQuit && runState) { // dummmy } }).Start(); } [STAThread] static void Main(String[] args) { runState = halPost; while (!Engine.IsQuit && runState) { // Pre frame code Engine.Iterate(); // Post frame code } Debug.WriteLine("Exiting"); Engine.Shutdown(); } } This is just exploring. Things mostly work fine. The only issue I keep getting is that sometimes the camera shows up blurred. It seems to be related to the early call to Iterate to force world initialization, but I'm not sure. If I start the app from the editor, it clears it sometimes (I run from VS). Anyway, wanted to get some thoughts on doing things like this.
silent Posted September 8, 2025 Posted September 8, 2025 Tessalator It's not recommended to separate engine threads manually, engine internally has it's own thread pool and know when or where to use additional threads for background tasks. The most dangerous part is here: new Thread(() => { // Background Systems while (!Engine.IsQuit && runState) { // dummmy } While in theory this code should work, in practice there are many potential pitfalls that could hinder or even block development. Thanks! How to submit a good bug report --- FTP server for test scenes and user uploads: ftp://files.unigine.com user: upload password: 6xYkd6vLYWjpW6SN
Tessalator Posted September 8, 2025 Author Posted September 8, 2025 @silent Thanks. I figured there would be issues :). I do want to learn a little more if you don't mind. The scenario I had in mind there was like parallel systems. Not like background Tasks in the main flow. `new Thread` creates an OS level thread (vs Task.Run, using the main thread pool), and I was looking at the idea of monitoring or sampled systems. Something like a control system where the sim/world is the plant and the parallel systems can monitor and provide feedback without loading the main loop. while (!Engine.IsQuit && runState) { Monitor.ApplyCorrections(); // If Any Engine.Iterate(); Monitor.SendSamples(); // Usually on a slower "cloak" } Here, Monitor is a very lightweight interface to the monitoring systems. The World runs at its own speed and periodically Monitor "inspects" the state of the World. In an experiment I ran a tiny tcp/web server driving a browser dashboard as a background system. SendSamples triggered only twice/sec. Does this make sense?
silent Posted September 9, 2025 Posted September 9, 2025 Yes, that make sense. Can't see any obvious issues here right now, but they might appear later :) How to submit a good bug report --- FTP server for test scenes and user uploads: ftp://files.unigine.com user: upload password: 6xYkd6vLYWjpW6SN
Recommended Posts