Programmatically control Unity Game loop to sync with external hardware/software
We would like to run the Unity Game Loop in sync with external hardware and applications running on a different computer. We want to arrive at something that work similar (but does not have to be identical to this).
Receive remote TCP packet with a list of new locations (etc.) for GameObjects [For low latency, would we put this in a FixedUpdate loop, set at a high Hz?] [Is this best done in a [Manager Singleton][1]?]
Send these updates from this "singleton" to all game objects [One way might be to just have the object pick up the data in the Update cycle, which would happen after the fixedUpdate is done]. [Is a better idea to forget about the gameloop, and just use C# events to broadcast the updates to the gameobject attached scripts?] Each GameObject will then update its location
Once all is stable (i.e. step #2 is completely done by all objects), we need to do measurements (scene read only) (with Raycast and LineCast) from each object to each other to see what is occluded and what is visible [Can we rely on LateUpdate to run afterwards, or should we avoid the game loop] [How do we know that all gameobjects have finished updating?]
Finally we need to post the visibility results back via a TCP packet.
The overall goal here is to make all four steps run as fast (back-to-back) as possible, Best would be to be able to speed up the frame rate (or slow it down) based on when each phase is done. But we can live with a fixed 60Hz if needed.
Other questions, have to do with the Async nature of TCP (or UDP) clients inside of Unity, and the issues of not being able to use the API from a separate thread (e.g. the async results of the TCP receive]. Has anyone pointers to solutions to that?
We need no help writing the code, but the internal execution model of Unity3D at this level of detail is not clear in the manuals.
We think this has wide applicability for VR, AR, and various robot co-sync with games.
[1]: http://redframe-game.com/blog/global-managers-with-generic-singletons/
$$anonymous$$essages come in via custom TCP packets, and go out also as TCP messages. The UnityEngine may be running in -batchmode with no display.
What's the question? If you're asking how to change the update order, you can't. Have you read the documentation on this?
Is this a game? It doesn't sound like it. If it's some sort of simulation, why are you using Unity?
Because it's free and powerful. $$anonymous$$any developer choose it for non-game projects for that reason. I started making android tools for my personal use and later got into game making.
What is the question here? You just explained what you want to achieve. Please update (edit) your question to contain an actual question about a problem you are having.
You guys are right, I don't like the way I wrote this. Give me a $$anonymous$$ute to rewrite. Yes, I read the execution loop in detail, True, this is not a game, it is for simulation (but free display will help, but it does not need to be perfectly smooth). I have compared Unity with a wide set of tools (DARPA Gazebo (nice, but no raycast), Panda, Bablyon, Cesium, Unreal, etc.) I realize this is not what Unity3D is designed for, but I am comfortable hacking it to get it to do what we want. I just need a few tips on what is not feasible.
Answer by DrYSG · Jun 09, 2016 at 07:23 PM
I came up with a very elegant solution for this problem. Thanks to some help from @DMGregory
First, I learned the truth about FixedUpdate. I hightly recommend this thread:
http://forum.unity3d.com/threads/the-truth-about-fixedupdate.231637/
That led me to realize that I should stick to the standard Unity stages of Update(), CoRoutines, LastUpdate, etc. and do everything by spinning the FrameRate as fast as possible.
Read these excellent arctiles on CoRoutines:
The outline of my approach is to:
Use Update() [read] and waitForEndOfFrame() [write] for my tcp work and putting the rest in co-routines and lastDone, I can effecting seperate the 4 phases the computation and get about 1500FPS of externally clocked simulation, SWIL work done. I am impressed. It all works in lock step with the hardware. Sweet.
My insight came when I thought of the problem as using the UnityGameEngine GameLoop as a big Co-Routine that runs in lock-step with the "frame rate" of external software and hardware.
public class Tools
{
public static string timeStamp()
{
return string.Format("{0} - {1:H:mm:ss.ffffff}", Time.time, System.DateTime.Now);
}
}
public class TargetScript : MonoBehaviour
{
void Start()
{
StartCoroutine(CoDo());
}
void Update()
{
Debug.Log(string.Format("{0}: {1} update: {2}", Time.frameCount, gameObject.name, Tools.timeStamp()));
}
IEnumerator CoDo()
{
while (true)
{
yield return null;
Debug.Log(string.Format("{0}: {1} codo: {2}", Time.frameCount, gameObject.name, Tools.timeStamp()));
}
}
void LateUpdate()
{
Debug.Log(string.Format("{0}: {1} late: {2}", Time.frameCount, gameObject.name, Tools.timeStamp()));
}
IEnumerator Done()
{
while (true)
{
yield return new WaitForEndOfFrame();
Debug.Log(string.Format("{0}: {1} done: {2}", Time.frameCount, gameObject.name, Tools.timeStamp()));
}
}
}